From b3037afae477d697a9c394c74319be777aedc681 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Fri, 3 Nov 2017 13:55:45 +0000
Subject: [PATCH 01/78] QSPI HAL addition
Adding new QSPI HAL header file. This should help to use memory-maped devices
as memories, graphical displays.
The API consist of few functions, most important are read/write/write_command functions.
The command format is:
```
----------------------------------------------
| Instruction | Address | Alt | Dummy | Data |
----------------------------------------------
```
We define only synch API at the moment.
---
hal/qspi_api.h | 186 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 186 insertions(+)
create mode 100644 hal/qspi_api.h
diff --git a/hal/qspi_api.h b/hal/qspi_api.h
new file mode 100644
index 0000000000..0c6503446e
--- /dev/null
+++ b/hal/qspi_api.h
@@ -0,0 +1,186 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2017 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_QSPI_API_H
+#define MBED_QSPI_API_H
+
+#include "device.h"
+
+#if DEVICE_QSPI
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup hal_qspi QSPI HAL
+ * @{
+ */
+
+/** QSPI HAL object declaration
+ */
+typedef struct qspi_s qspi_t;
+
+/** QSPI Bus width
+ *
+ * Some parts of commands provide variable bus width
+ */
+typedef enum qspi_bus_width {
+ QSPI_CFG_BUS_SINGLE,
+ QSPI_CFG_BUS_DUAL,
+ QSPI_CFG_BUS_QUAD,
+} qspi_bus_width_t;
+
+/** Address size
+ */
+typedef enum qspi_address_size {
+ QSPI_CFG_ADDR_SIZE_8,
+ QSPI_CFG_ADDR_SIZE_16,
+ QSPI_CFG_ADDR_SIZE_24,
+ QSPI_CFG_ADDR_SIZE_32,
+} qspi_address_size_t;
+
+/** Alternative size
+ */
+typedef enum qspi_alt_size {
+ QSPI_CFG_ALT_SIZE_8,
+ QSPI_CFG_ALT_SIZE_16,
+ QSPI_CFG_ALT_SIZE_24,
+ QSPI_CFG_ALT_SIZE_32,
+} qspi_alt_size_t;
+
+/** QSPI command declaration
+ *
+ * Defines a frame format
+ */
+typedef struct qspi_command {
+ struct instruction {
+ qspi_bus_width_t bus_width; /**< Bus width for the instruction >*/
+ uint8_t value; /**< Instruction, 0 - disabled, non-zero defined value used >*/
+ };
+ struct address {
+ qspi_bus_width_t bus_width; /**< Bus width for the address >*/
+ qspi_address_size_t size; /**< Address size >*/
+ uint32_t value; /**< Address, 0 - disabled, non-zero defined value used >*/
+ };
+ struct alt {
+ qspi_bus_width_t bus_width; /**< Bus width for alternative >*/
+ qspi_alt_size_t size; /**< Alternative size >*/
+ uint32_t value; /**< Alternative, 0 - disabled, non-zero defined value used >*/
+ };
+ uint8_t dummy_count; /**< Dummy cycles count >*/
+ struct data {
+ qspi_bus_width_t bus_width; /**< Bus width for data >*/
+ };
+} qspi_command_t;
+
+/** QSPI return status
+ */
+typedef enum qspi_status {
+ QSPI_STATUS_ERROR = -1, /**< Generic error >*/
+ QSPI_STATUS_INVALID_PARAMETER = -2, /**< The parameter is invalid >*/
+ QSPI_STATUS_OK = 0, /**< Function executed sucessfully >*/
+} qspi_status_t;
+
+/** Initialize QSPI peripheral.
+ *
+ * It should initialize QSPI pins (io0-io3, sclk and ssel), set frequency and SPI mode. The clock for the peripheral should be enabled
+ *
+ * @param obj QSPI object
+ * @param io0 Data pin 0
+ * @param io1 Data pin 1
+ * @param io2 Data pin 2
+ * @param io3 Data pin 3
+ * @param sclk The clock pin
+ * @param ssel The chip select pin
+ * @param hz The bus frequency
+ * @param mode SPI mode
+ * @return QSPI_STATUS_OK if initialisation successfully executed
+ QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
+ QSPI_STATUS_ERROR otherwise
+ */
+qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel, uint32_t hz, uint8_t mode);
+
+/** Deinitilize QSPI peripheral
+ *
+ * It should release pins that are associated with the QSPI object, and disable clocks for QSPI peripheral module that was associated with the object
+ *
+ * @param obj QSPI object
+ * @return QSPI_STATUS_OK if deinitialisation successfully executed
+ QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
+ QSPI_STATUS_ERROR otherwise
+ */
+qspi_status_t qspi_free(qspi_t *obj);
+
+/** Set the QSPI baud rate
+ *
+ * Actual frequency may differ from the desired frequency due to available dividers and the bus clock
+ * Configures the QSPI peripheral's baud rate
+ * @param obj The SPI object to configure
+ * @param hz The baud rate in Hz
+ * @return QSPI_STATUS_OK if frequency was set
+ QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
+ QSPI_STATUS_ERROR otherwise
+ */
+qspi_status_t qspi_frequency(qspi_t *obj, int hz);
+
+/** Send only QSPI command
+ *
+ * @param obj QSPI object
+ * @param command QSPI command
+ * @return QSPI_STATUS_OK if command was sent without any error
+ QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
+ QSPI_STATUS_ERROR otherwise
+ */
+qspi_status_t qspi_write_command(qspi_t *obj, const qspi_command_t *command);
+
+/** Send a command and block of data
+ *
+ * @param obj QSPI object
+ * @param command QSPI command
+ * @param data TX buffer
+ * @param length TX buffer length in bytes
+ * @return QSPI_STATUS_OK if the data has been succesfully sent
+ QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
+ QSPI_STATUS_ERROR otherwise
+ */
+qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void *data, size_t length);
+
+/** Receive a command and block of data
+ *
+ * @param obj QSPI object
+ * @param command QSPI command
+ * @param data RX buffer
+ * @param length RX buffer length in bytes
+ * @return QSPI_STATUS_OK if data has been succesfully received
+ QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
+ QSPI_STATUS_ERROR otherwise
+ */
+qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t length);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+/** @}*/
From 510d743051a43e2758f5c7e8164453343d77461c Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 7 Nov 2017 14:31:24 +0000
Subject: [PATCH 02/78] QSPI: fix address/alt variable sizes (can be skipped)
Fixing by adding NONE values for both
---
hal/qspi_api.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/hal/qspi_api.h b/hal/qspi_api.h
index 0c6503446e..2b94fe9b84 100644
--- a/hal/qspi_api.h
+++ b/hal/qspi_api.h
@@ -49,6 +49,7 @@ typedef enum qspi_bus_width {
/** Address size
*/
typedef enum qspi_address_size {
+ QSPI_CFG_ADDR_SIZE_NONE,
QSPI_CFG_ADDR_SIZE_8,
QSPI_CFG_ADDR_SIZE_16,
QSPI_CFG_ADDR_SIZE_24,
@@ -58,6 +59,7 @@ typedef enum qspi_address_size {
/** Alternative size
*/
typedef enum qspi_alt_size {
+ QSPI_CFG_ALT_SIZE_NONE,
QSPI_CFG_ALT_SIZE_8,
QSPI_CFG_ALT_SIZE_16,
QSPI_CFG_ALT_SIZE_24,
@@ -71,12 +73,12 @@ typedef enum qspi_alt_size {
typedef struct qspi_command {
struct instruction {
qspi_bus_width_t bus_width; /**< Bus width for the instruction >*/
- uint8_t value; /**< Instruction, 0 - disabled, non-zero defined value used >*/
+ uint8_t value; /**< Instruction value >*/
};
struct address {
qspi_bus_width_t bus_width; /**< Bus width for the address >*/
qspi_address_size_t size; /**< Address size >*/
- uint32_t value; /**< Address, 0 - disabled, non-zero defined value used >*/
+ uint32_t value; /**< Address value >*/
};
struct alt {
qspi_bus_width_t bus_width; /**< Bus width for alternative >*/
From 4564383ba8347df2286444a5dedfff4ce8f22530 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 7 Nov 2017 14:36:16 +0000
Subject: [PATCH 03/78] QSPI: change length to be in/out parameter
This provides a way to return how many bytes have been written/read (as status codes
are returned via func ret value)
---
hal/qspi_api.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/hal/qspi_api.h b/hal/qspi_api.h
index 2b94fe9b84..0348c15d17 100644
--- a/hal/qspi_api.h
+++ b/hal/qspi_api.h
@@ -156,24 +156,24 @@ qspi_status_t qspi_write_command(qspi_t *obj, const qspi_command_t *command);
* @param obj QSPI object
* @param command QSPI command
* @param data TX buffer
- * @param length TX buffer length in bytes
+ * @param[in,out] in - length TX buffer length in bytes, out - number of bytes written
* @return QSPI_STATUS_OK if the data has been succesfully sent
QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
QSPI_STATUS_ERROR otherwise
*/
-qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void *data, size_t length);
+qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void *data, size_t *length);
/** Receive a command and block of data
*
* @param obj QSPI object
* @param command QSPI command
* @param data RX buffer
- * @param length RX buffer length in bytes
+ * @param[in,out] in - length RX buffer length in bytes, out - number of bytes read
* @return QSPI_STATUS_OK if data has been succesfully received
QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
QSPI_STATUS_ERROR otherwise
*/
-qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t length);
+qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t *length);
/**@}*/
From 10e7b5f6d004cfdb140b482b4603fe6b3096f3cc Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Wed, 8 Nov 2017 13:58:57 +0000
Subject: [PATCH 04/78] QSPI: improve mode documentation
SPI mode means Clock polarity and phase mode (0 - 3)
---
hal/qspi_api.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hal/qspi_api.h b/hal/qspi_api.h
index 0348c15d17..c6475196e7 100644
--- a/hal/qspi_api.h
+++ b/hal/qspi_api.h
@@ -101,7 +101,7 @@ typedef enum qspi_status {
/** Initialize QSPI peripheral.
*
- * It should initialize QSPI pins (io0-io3, sclk and ssel), set frequency and SPI mode. The clock for the peripheral should be enabled
+ * It should initialize QSPI pins (io0-io3, sclk and ssel), set frequency, clock polarity and phase mode. The clock for the peripheral should be enabled
*
* @param obj QSPI object
* @param io0 Data pin 0
@@ -111,7 +111,7 @@ typedef enum qspi_status {
* @param sclk The clock pin
* @param ssel The chip select pin
* @param hz The bus frequency
- * @param mode SPI mode
+ * @param mode Clock polarity and phase mode (0 - 3)
* @return QSPI_STATUS_OK if initialisation successfully executed
QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
QSPI_STATUS_ERROR otherwise
From a3c8117b0e1c662f3219f8076f6b29775b52a7c4 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Fri, 10 Nov 2017 13:11:59 +0000
Subject: [PATCH 05/78] QSPI: fix command declaration names
---
hal/qspi_api.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/hal/qspi_api.h b/hal/qspi_api.h
index c6475196e7..12667e0fdb 100644
--- a/hal/qspi_api.h
+++ b/hal/qspi_api.h
@@ -71,24 +71,24 @@ typedef enum qspi_alt_size {
* Defines a frame format
*/
typedef struct qspi_command {
- struct instruction {
+ struct {
qspi_bus_width_t bus_width; /**< Bus width for the instruction >*/
uint8_t value; /**< Instruction value >*/
- };
- struct address {
+ } instruction;
+ struct {
qspi_bus_width_t bus_width; /**< Bus width for the address >*/
qspi_address_size_t size; /**< Address size >*/
uint32_t value; /**< Address value >*/
- };
- struct alt {
+ } address;
+ struct {
qspi_bus_width_t bus_width; /**< Bus width for alternative >*/
qspi_alt_size_t size; /**< Alternative size >*/
uint32_t value; /**< Alternative, 0 - disabled, non-zero defined value used >*/
- };
+ } alt;
uint8_t dummy_count; /**< Dummy cycles count >*/
- struct data {
+ struct {
qspi_bus_width_t bus_width; /**< Bus width for data >*/
- };
+ } data;
} qspi_command_t;
/** QSPI return status
From d1b51b6328623dcd88b926e5ad668a5c7d74d9ca Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Fri, 10 Nov 2017 12:24:13 +0000
Subject: [PATCH 06/78] QSPI: initial HAL nrf52840 version
This commit adds QSPI HAL implementation for nrf52840 MCU targets
---
.../TARGET_MCU_NRF52840/config/sdk_config.h | 130 +++++++++++
.../TARGET_NRF5x/TARGET_NRF52/objects.h | 11 +
targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c | 214 ++++++++++++++++++
targets/targets.json | 3 +-
4 files changed, 357 insertions(+), 1 deletion(-)
create mode 100644 targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/config/sdk_config.h b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/config/sdk_config.h
index 201402a18e..203602ec0a 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/config/sdk_config.h
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/config/sdk_config.h
@@ -2748,6 +2748,136 @@
//
+// QSPI_ENABLED - nrf_drv_qspi - QSPI peripheral driver.
+//==========================================================
+#ifndef QSPI_ENABLED
+#define QSPI_ENABLED 1
+#endif
+#if QSPI_ENABLED
+// QSPI_CONFIG_SCK_DELAY - tSHSL, tWHSL and tSHWL in number of 16 MHz periods (62.5 ns). <0-255>
+
+
+#ifndef QSPI_CONFIG_SCK_DELAY
+#define QSPI_CONFIG_SCK_DELAY 1
+#endif
+
+// QSPI_CONFIG_READOC - Number of data lines and opcode used for reading.
+
+// <0=> FastRead
+// <1=> Read2O
+// <2=> Read2IO
+// <3=> Read4O
+// <4=> Read4IO
+
+#ifndef QSPI_CONFIG_READOC
+#define QSPI_CONFIG_READOC 4
+#endif
+
+// QSPI_CONFIG_WRITEOC - Number of data lines and opcode used for writing.
+
+// <0=> PP
+// <1=> PP2O
+// <2=> PP4O
+// <3=> PP4IO
+
+#ifndef QSPI_CONFIG_WRITEOC
+#define QSPI_CONFIG_WRITEOC 3
+#endif
+
+// QSPI_CONFIG_ADDRMODE - Addressing mode.
+
+// <0=> 24bit
+// <1=> 32bit
+
+#ifndef QSPI_CONFIG_ADDRMODE
+#define QSPI_CONFIG_ADDRMODE 0
+#endif
+
+// QSPI_CONFIG_MODE - SPI mode.
+
+// <0=> Mode 0
+// <1=> Mode 1
+
+#ifndef QSPI_CONFIG_MODE
+#define QSPI_CONFIG_MODE 0
+#endif
+
+// QSPI_CONFIG_FREQUENCY - Frequency divider.
+
+// <0=> 32MHz/1
+// <1=> 32MHz/2
+// <2=> 32MHz/3
+// <3=> 32MHz/4
+// <4=> 32MHz/5
+// <5=> 32MHz/6
+// <6=> 32MHz/7
+// <7=> 32MHz/8
+// <8=> 32MHz/9
+// <9=> 32MHz/10
+// <10=> 32MHz/11
+// <11=> 32MHz/12
+// <12=> 32MHz/13
+// <13=> 32MHz/14
+// <14=> 32MHz/15
+// <15=> 32MHz/16
+
+#ifndef QSPI_CONFIG_FREQUENCY
+#define QSPI_CONFIG_FREQUENCY 1
+#endif
+
+// QSPI_PIN_SCK - SCK pin value.
+#ifndef QSPI_PIN_SCK
+#define QSPI_PIN_SCK NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// QSPI_PIN_CSN - CSN pin value.
+#ifndef QSPI_PIN_CSN
+#define QSPI_PIN_CSN NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// QSPI_PIN_IO0 - IO0 pin value.
+#ifndef QSPI_PIN_IO0
+#define QSPI_PIN_IO0 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// QSPI_PIN_IO1 - IO1 pin value.
+#ifndef QSPI_PIN_IO1
+#define QSPI_PIN_IO1 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// QSPI_PIN_IO2 - IO2 pin value.
+#ifndef QSPI_PIN_IO2
+#define QSPI_PIN_IO2 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// QSPI_PIN_IO3 - IO3 pin value.
+#ifndef QSPI_PIN_IO3
+#define QSPI_PIN_IO3 NRF_QSPI_PIN_NOT_CONNECTED
+#endif
+
+// QSPI_CONFIG_IRQ_PRIORITY - Interrupt priority
+
+
+// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef QSPI_CONFIG_IRQ_PRIORITY
+#define QSPI_CONFIG_IRQ_PRIORITY 7
+#endif
+
+#endif //QSPI_ENABLED
+
+//
+
+//
+
// TIMER_ENABLED - nrf_drv_timer - TIMER periperal driver
//==========================================================
#ifndef TIMER_ENABLED
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/objects.h b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/objects.h
index 47e6276a82..1a26f28db4 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/objects.h
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/objects.h
@@ -142,6 +142,17 @@ struct flash_s {
uint32_t placeholder;
};
+#if DEVICE_QSPI
+
+// #include "nrf_drv_qspi.h"
+
+struct qspi_s {
+ uint32_t placeholder;
+ // nrf_drv_qspi_config_t config;
+};
+
+#endif
+
#include "gpio_object.h"
#ifdef __cplusplus
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
new file mode 100644
index 0000000000..b3f547e074
--- /dev/null
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2017 Nordic Semiconductor ASA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
+ * integrated circuit in a product or a software update for such product, must reproduce
+ * the above copyright notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary or object form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "qspi_api.h"
+
+#if DEVICE_QSPI
+
+#include "nrf_drv_common.h"
+#include "nrf_drv_qspi.h"
+
+/*
+TODO
+ - config inside obj - nordic headers have some problems with inclusion
+ - free - is it really empty, nothing to do there?
+ - prepare command - support more protocols that nordic can do (now limited)
+ - nordic does not support
+ - alt
+ - dummy cycles
+*/
+
+#define MBED_HAL_QSPI_HZ_TO_CONFIG(hz) ((32000000/(hz))-1)
+#define MBED_HAL_QSPI_MAX_FREQ 32000000UL
+
+static nrf_drv_qspi_config_t config;
+
+qspi_status_t qspi_prepare_command(qspi_t *obj, const qspi_command_t *command, bool write)
+{
+ // we need to remap to command-address-data - x_x_x
+ // most commmon are 1-1-1, 1-1-4, 1-4-4
+ // 1-1-1
+ if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->data.bus_width == QSPI_CFG_BUS_SINGLE) {
+ if (write) {
+ config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP;
+ } else {
+ config.prot_if.readoc = NRF_QSPI_READOC_FASTREAD;
+ }
+ // 1-1-4
+ } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->data.bus_width == QSPI_CFG_BUS_QUAD) {
+ // 1_1_4
+ if (write) {
+ config.prot_if.writeoc = QSPI_IFCONFIG0_WRITEOC_PP4O;
+ } else {
+ config.prot_if.readoc = NRF_QSPI_READOC_READ4O;
+ }
+ // 1-4-4
+ } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->address.bus_width == QSPI_CFG_BUS_QUAD &&
+ command->data.bus_width == QSPI_CFG_BUS_QUAD) {
+ // 1_4_4
+ if (write) {
+ config.prot_if.writeoc = QSPI_IFCONFIG0_WRITEOC_PP4IO;
+ } else {
+ config.prot_if.readoc = NRF_QSPI_READOC_READ4IO;
+ }
+ }
+
+ qspi_status_t ret = QSPI_STATUS_OK;
+
+ // supporting only 24 or 32 bit address
+ if (command->address.size == QSPI_CFG_ADDR_SIZE_24) {
+ config.prot_if.addrmode = NRF_QSPI_ADDRMODE_24BIT;
+ } else if (command->address.size == QSPI_CFG_ADDR_SIZE_32) {
+ config.prot_if.addrmode = QSPI_CFG_ADDR_SIZE_32;
+ } else {
+ ret = QSPI_STATUS_INVALID_PARAMETER;
+ }
+ return ret;
+}
+
+qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel, uint32_t hz, uint8_t mode)
+{
+ (void)(obj);
+ if (hz > MBED_HAL_QSPI_MAX_FREQ) {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ }
+
+ // memset(config, 0, sizeof(config));
+
+ config.pins.sck_pin = (uint32_t)sclk;
+ config.pins.csn_pin = (uint32_t)ssel;
+ config.pins.io0_pin = (uint32_t)io0;
+ config.pins.io1_pin = (uint32_t)io1;
+ config.pins.io2_pin = (uint32_t)io2;
+ config.pins.io3_pin = (uint32_t)io3;
+ config.irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY;
+
+ config.phy_if.sck_freq = MBED_HAL_QSPI_HZ_TO_CONFIG(hz),
+ config.phy_if.sck_delay = 0x05,
+ config.phy_if.dpmen = false;
+ config.phy_if.spi_mode = mode == 0 ? NRF_QSPI_MODE_0 : NRF_QSPI_MODE_1;
+
+ nrf_drv_qspi_init(&config, NULL , NULL);
+
+ return 0;
+}
+
+qspi_status_t qspi_free(qspi_t *obj)
+{
+ (void)(obj);
+ // possibly here uninit from SDK driver
+ return QSPI_STATUS_OK;
+}
+
+qspi_status_t qspi_frequency(qspi_t *obj, int hz)
+{
+ config.phy_if.sck_freq = MBED_HAL_QSPI_HZ_TO_CONFIG(hz);
+ // use sync version, no handler
+ ret_code_t ret = nrf_drv_qspi_init(&config, NULL , NULL);
+ if (ret == NRF_SUCCESS ) {
+ return QSPI_STATUS_OK;
+ } else if (ret == NRF_ERROR_INVALID_PARAM) {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ } else {
+ return QSPI_STATUS_ERROR;
+ }
+}
+
+qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void *data, size_t *length)
+{
+ qspi_status_t status = qspi_prepare_command(obj, command, true);
+ if (status != QSPI_STATUS_OK) {
+ return status;
+ }
+
+ // write here does not return how much it transfered, we return transfered all
+ ret_code_t ret = nrf_drv_qspi_write(data, *length, command->address.value);
+ if (ret == NRF_SUCCESS ) {
+ return QSPI_STATUS_OK;
+ } else {
+ return QSPI_STATUS_ERROR;
+ }
+}
+
+qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t *length)
+{
+ qspi_status_t status = qspi_prepare_command(obj, command, false);
+ if (status != QSPI_STATUS_OK) {
+ return status;
+ }
+
+ ret_code_t ret = nrf_drv_qspi_read(data, *length, command->address.value);
+ if (ret == NRF_SUCCESS ) {
+ return QSPI_STATUS_OK;
+ } else {
+ return QSPI_STATUS_ERROR;
+ }
+}
+
+// they provide 2 functions write or nrf_drv_qspi_cinstr_xfer
+// nrf_drv_qspi_cinstr_xfer seems like it accepts simplified config that is very simplified
+// and might not be useful for us.
+// write on other hand, needs to write some data (errors if buffer is NULL!)
+qspi_status_t qspi_write_command(qspi_t *obj, const qspi_command_t *command)
+{
+ // use simplified API, as we are sending only instruction here
+ nrf_qspi_cinstr_conf_t config;
+ config.length = NRF_QSPI_CINSTR_LEN_1B; // no data
+ config.opcode = command->instruction.value;
+ config.io2_level = false;
+ config.io3_level = false;
+ config.wipwait = false;
+ config.wren = false;
+
+ // no data phase, send only config
+ ret_code_t ret = nrf_drv_qspi_cinstr_xfer(&config, NULL, NULL);
+ if (ret == NRF_SUCCESS ) {
+ return QSPI_STATUS_OK;
+ } else {
+ return QSPI_STATUS_ERROR;
+ }
+}
+
+#endif
+
+/** @}*/
diff --git a/targets/targets.json b/targets/targets.json
index 85b6623557..88c57e7871 100755
--- a/targets/targets.json
+++ b/targets/targets.json
@@ -3873,7 +3873,8 @@
"SPI_ASYNCH",
"STCLK_OFF_DURING_SLEEP",
"TRNG",
- "USTICKER"
+ "USTICKER",
+ "QSPI"
],
"extra_labels": [
"NORDIC",
From 2df58e2d2589aa6ce9c315582567f0704d5f4da7 Mon Sep 17 00:00:00 2001
From: Senthil Ramakrishnan
Date: Wed, 22 Nov 2017 19:02:56 -0600
Subject: [PATCH 07/78] Modify QSPI HAL API to include an API for
command-transfer operations
---
hal/qspi_api.h | 26 +--
targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c | 162 ++++++++++++------
2 files changed, 122 insertions(+), 66 deletions(-)
diff --git a/hal/qspi_api.h b/hal/qspi_api.h
index 12667e0fdb..8982aea502 100644
--- a/hal/qspi_api.h
+++ b/hal/qspi_api.h
@@ -141,16 +141,6 @@ qspi_status_t qspi_free(qspi_t *obj);
*/
qspi_status_t qspi_frequency(qspi_t *obj, int hz);
-/** Send only QSPI command
- *
- * @param obj QSPI object
- * @param command QSPI command
- * @return QSPI_STATUS_OK if command was sent without any error
- QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
- QSPI_STATUS_ERROR otherwise
- */
-qspi_status_t qspi_write_command(qspi_t *obj, const qspi_command_t *command);
-
/** Send a command and block of data
*
* @param obj QSPI object
@@ -163,6 +153,22 @@ qspi_status_t qspi_write_command(qspi_t *obj, const qspi_command_t *command);
*/
qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void *data, size_t *length);
+/** Send a command (and optionally data) and get the response. Can be used to send/receive device specific commands.
+ *
+ * @param obj QSPI object
+ * @param command QSPI command
+ * @param tx_data TX buffer
+ * @param tx_length pointer to variable holding TX buffer length
+ * @param rx_data TX buffer
+ * @param rx_length pointer to variable holding TX buffer length
+ * @return QSPI_STATUS_OK if the data has been succesfully sent
+ QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
+ QSPI_STATUS_ERROR otherwise
+ */
+
+qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command, const void *tx_data, size_t tx_size, void *rx_data, size_t rx_size);
+
+
/** Receive a command and block of data
*
* @param obj QSPI object
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
index b3f547e074..10c8e6b1fc 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
@@ -53,56 +53,79 @@ TODO
- dummy cycles
*/
-#define MBED_HAL_QSPI_HZ_TO_CONFIG(hz) ((32000000/(hz))-1)
-#define MBED_HAL_QSPI_MAX_FREQ 32000000UL
+#define MBED_HAL_QSPI_HZ_TO_CONFIG(hz) ((32000000/(hz))-1)
+#define MBED_HAL_QSPI_MAX_FREQ 32000000UL
static nrf_drv_qspi_config_t config;
qspi_status_t qspi_prepare_command(qspi_t *obj, const qspi_command_t *command, bool write)
{
- // we need to remap to command-address-data - x_x_x
- // most commmon are 1-1-1, 1-1-4, 1-4-4
- // 1-1-1
- if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
- command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
- command->data.bus_width == QSPI_CFG_BUS_SINGLE) {
+ //Use custom command if provided by the caller
+ if(command->instruction.value != 0) {
+ //Use custom command if provided
if (write) {
- config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP;
+ config.prot_if.writeoc = (nrf_qspi_writeoc_t)command->instruction.value;
} else {
- config.prot_if.readoc = NRF_QSPI_READOC_FASTREAD;
+ config.prot_if.readoc = (nrf_qspi_readoc_t)command->instruction.value;
}
- // 1-1-4
- } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
- command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
- command->data.bus_width == QSPI_CFG_BUS_QUAD) {
- // 1_1_4
- if (write) {
- config.prot_if.writeoc = QSPI_IFCONFIG0_WRITEOC_PP4O;
- } else {
- config.prot_if.readoc = NRF_QSPI_READOC_READ4O;
+ } else {
+ // we need to remap to command-address-data - x_x_x
+ // most commmon are 1-1-1, 1-1-4, 1-4-4
+ // 1-1-1
+ if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->data.bus_width == QSPI_CFG_BUS_SINGLE) {
+ if (write) {
+ config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP;
+ } else {
+ config.prot_if.readoc = NRF_QSPI_READOC_FASTREAD;
+ }
+ // 1-1-4
+ } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->data.bus_width == QSPI_CFG_BUS_QUAD) {
+ // 1_1_4
+ if (write) {
+ config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4O;
+ } else {
+ config.prot_if.readoc = NRF_QSPI_READOC_READ4O;
+ }
+ // 1-4-4
+ } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->address.bus_width == QSPI_CFG_BUS_QUAD &&
+ command->data.bus_width == QSPI_CFG_BUS_QUAD) {
+ // 1_4_4
+ if (write) {
+ config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4IO;
+ } else {
+ config.prot_if.readoc = NRF_QSPI_READOC_READ4IO;
+ }
}
- // 1-4-4
- } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
- command->address.bus_width == QSPI_CFG_BUS_QUAD &&
- command->data.bus_width == QSPI_CFG_BUS_QUAD) {
- // 1_4_4
- if (write) {
- config.prot_if.writeoc = QSPI_IFCONFIG0_WRITEOC_PP4IO;
- } else {
- config.prot_if.readoc = NRF_QSPI_READOC_READ4IO;
- }
- }
-
+ }
+
qspi_status_t ret = QSPI_STATUS_OK;
// supporting only 24 or 32 bit address
if (command->address.size == QSPI_CFG_ADDR_SIZE_24) {
config.prot_if.addrmode = NRF_QSPI_ADDRMODE_24BIT;
} else if (command->address.size == QSPI_CFG_ADDR_SIZE_32) {
- config.prot_if.addrmode = QSPI_CFG_ADDR_SIZE_32;
+ config.prot_if.addrmode = NRF_QSPI_ADDRMODE_32BIT;
} else {
ret = QSPI_STATUS_INVALID_PARAMETER;
}
+
+ //Configure QSPI with new command format
+ if(ret == QSPI_STATUS_OK) {
+ ret_code_t ret_status = nrf_drv_qspi_init(&config, NULL , NULL);
+ if (ret_status != NRF_SUCCESS ) {
+ if (ret_status == NRF_ERROR_INVALID_PARAM) {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ } else {
+ return QSPI_STATUS_ERROR;
+ }
+ }
+ }
+
return ret;
}
@@ -123,14 +146,19 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
config.pins.io3_pin = (uint32_t)io3;
config.irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY;
- config.phy_if.sck_freq = MBED_HAL_QSPI_HZ_TO_CONFIG(hz),
+ config.phy_if.sck_freq = (nrf_qspi_frequency_t)MBED_HAL_QSPI_HZ_TO_CONFIG(hz),
config.phy_if.sck_delay = 0x05,
config.phy_if.dpmen = false;
config.phy_if.spi_mode = mode == 0 ? NRF_QSPI_MODE_0 : NRF_QSPI_MODE_1;
- nrf_drv_qspi_init(&config, NULL , NULL);
-
- return 0;
+ ret_code_t ret = nrf_drv_qspi_init(&config, NULL , NULL);
+ if (ret == NRF_SUCCESS ) {
+ return QSPI_STATUS_OK;
+ } else if (ret == NRF_ERROR_INVALID_PARAM) {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ } else {
+ return QSPI_STATUS_ERROR;
+ }
}
qspi_status_t qspi_free(qspi_t *obj)
@@ -142,7 +170,7 @@ qspi_status_t qspi_free(qspi_t *obj)
qspi_status_t qspi_frequency(qspi_t *obj, int hz)
{
- config.phy_if.sck_freq = MBED_HAL_QSPI_HZ_TO_CONFIG(hz);
+ config.phy_if.sck_freq = (nrf_qspi_frequency_t)MBED_HAL_QSPI_HZ_TO_CONFIG(hz);
// use sync version, no handler
ret_code_t ret = nrf_drv_qspi_init(&config, NULL , NULL);
if (ret == NRF_SUCCESS ) {
@@ -185,30 +213,52 @@ qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data,
}
}
-// they provide 2 functions write or nrf_drv_qspi_cinstr_xfer
-// nrf_drv_qspi_cinstr_xfer seems like it accepts simplified config that is very simplified
-// and might not be useful for us.
-// write on other hand, needs to write some data (errors if buffer is NULL!)
-qspi_status_t qspi_write_command(qspi_t *obj, const qspi_command_t *command)
+qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command, const void *tx_data, size_t tx_size, void *rx_data, size_t rx_size)
{
- // use simplified API, as we are sending only instruction here
- nrf_qspi_cinstr_conf_t config;
- config.length = NRF_QSPI_CINSTR_LEN_1B; // no data
- config.opcode = command->instruction.value;
- config.io2_level = false;
- config.io3_level = false;
- config.wipwait = false;
- config.wren = false;
-
- // no data phase, send only config
- ret_code_t ret = nrf_drv_qspi_cinstr_xfer(&config, NULL, NULL);
- if (ret == NRF_SUCCESS ) {
- return QSPI_STATUS_OK;
- } else {
+ ret_code_t ret_code;
+ uint32_t i;
+ uint8_t data[8];
+ uint32_t data_size = tx_size + rx_size;
+
+ nrf_qspi_cinstr_conf_t qspi_cinstr_config;
+ qspi_cinstr_config.opcode = command->instruction.value;
+ qspi_cinstr_config.io2_level = false;
+ qspi_cinstr_config.io3_level = false;
+ qspi_cinstr_config.wipwait = false;
+ qspi_cinstr_config.wren = false;
+
+ if (data_size < 9)
+ {
+ qspi_cinstr_config.length = (nrf_qspi_cinstr_len_t)(NRF_QSPI_CINSTR_LEN_1B + data_size);
+ }
+ else
+ {
return QSPI_STATUS_ERROR;
}
+
+ // preparing data to send
+ for (i = 0; i < tx_size; ++i)
+ {
+ data[i] = ((uint8_t *)tx_data)[i];
+ }
+
+ ret_code = nrf_drv_qspi_cinstr_xfer(&qspi_cinstr_config, data, data);
+ if (ret_code != NRF_SUCCESS)
+ {
+ return QSPI_STATUS_ERROR;
+ }
+
+ // preparing received data
+ for (i = 0; i < rx_size; ++i)
+ {
+ // Data is sending as a normal SPI transmission so there is one buffer to send and receive data.
+ ((uint8_t *)rx_data)[i] = data[i];
+ }
+
+ return QSPI_STATUS_OK;
}
+
#endif
/** @}*/
From 009cc8b474fb97f07d6da78aedcd3a06df3b0f9c Mon Sep 17 00:00:00 2001
From: Senthil Ramakrishnan
Date: Wed, 22 Nov 2017 19:07:47 -0600
Subject: [PATCH 08/78] Enabling QSPI headers in Nordic HAL implementation and
fix for UART STDIO definitions
---
targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/objects.h | 4 ++--
.../TARGET_SDK_14_2/drivers_nrf/qspi/nrf_drv_qspi.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/objects.h b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/objects.h
index 1a26f28db4..10e19c7b50 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/objects.h
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/objects.h
@@ -144,11 +144,11 @@ struct flash_s {
#if DEVICE_QSPI
-// #include "nrf_drv_qspi.h"
+#include "nrf_drv_qspi.h"
struct qspi_s {
uint32_t placeholder;
- // nrf_drv_qspi_config_t config;
+ nrf_drv_qspi_config_t config;
};
#endif
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/qspi/nrf_drv_qspi.c b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/qspi/nrf_drv_qspi.c
index 83287313a5..6e8a6aae99 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/qspi/nrf_drv_qspi.c
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/qspi/nrf_drv_qspi.c
@@ -122,10 +122,10 @@ ret_code_t nrf_drv_qspi_init(nrf_drv_qspi_config_t const * p_config,
nrf_drv_qspi_handler_t handler,
void * p_context)
{
- if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED)
+ /*if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED)
{
return NRF_ERROR_INVALID_STATE;
- }
+ }*/
if (!qspi_pins_configure(&p_config->pins))
{
From 219d0c6e700b7aaa94f49a0d981a3bcbcf98d85c Mon Sep 17 00:00:00 2001
From: Senthil Ramakrishnan
Date: Wed, 22 Nov 2017 19:12:13 -0600
Subject: [PATCH 09/78] QSPI driver implementation
---
drivers/QSPI.cpp | 297 +++++++++++++++++++++++++++++++++++++++++++++++
drivers/QSPI.h | 232 ++++++++++++++++++++++++++++++++++++
2 files changed, 529 insertions(+)
create mode 100644 drivers/QSPI.cpp
create mode 100644 drivers/QSPI.h
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
new file mode 100644
index 0000000000..97e91f8aea
--- /dev/null
+++ b/drivers/QSPI.cpp
@@ -0,0 +1,297 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "drivers/QSPI.h"
+#include "platform/mbed_critical.h"
+
+#if DEVICE_QSPI
+#define IS_BUS_WIDTH_VALID(width) ((width == 1) || (width == 2) || (width == 4))
+#define IS_SIZE_VALID(size) ((size == 8) || (size == 16) || (size == 24) || (size == 32))
+#define IS_ALT_SIZE_VALID(alt_size) ((alt_size == 0) || (alt_size == 8) || (alt_size == 16) || (alt_size == 24) || (alt_size == 32))
+
+namespace mbed {
+
+QSPI* QSPI::_owner = NULL;
+SingletonPtr QSPI::_mutex;
+
+QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel) :
+ _qspi(),
+ _inst_width(QSPI_DEFAULT_INST_WIDTH),
+ _address_width(QSPI_DEFAULT_ADDRESS_WIDTH),
+ _address_size(QSPI_DEFAULT_ADDRESS_SIZE),
+ _alt_width(QSPI_DEFAULT_ALT_WIDTH),
+ _alt_size(QSPI_DEFAULT_ALT_SIZE),
+ _data_width(QSPI_DEFAULT_DATA_WIDTH),
+ _num_dummy_cycles(QSPI_DEFAULT_DUMMY_CYCLES),
+ _hz(QSPI_DEFAULT_HZ) {
+ // No lock needed in the constructor
+ _qspi_io0 = io0;
+ _qspi_io1 = io1;
+ _qspi_io2 = io2;
+ _qspi_io3 = io3;
+ _qspi_clk = sclk;
+ _qspi_cs = ssel;
+}
+
+bool QSPI::configure_format(int inst_width,
+ int address_width, int address_size,
+ int alt_width, int alt_size,
+ int data_width,
+ int dummy_cycles,
+ int mode ) {
+ if(!IS_BUS_WIDTH_VALID(inst_width)) return false;
+ if(!IS_BUS_WIDTH_VALID(address_width)) return false;
+ if(!IS_SIZE_VALID(address_size)) return false;
+ if(!IS_BUS_WIDTH_VALID(alt_width)) return false;
+ if(!IS_ALT_SIZE_VALID(alt_size)) return false;
+ if(!IS_BUS_WIDTH_VALID(data_width)) return false;
+ if(dummy_cycles < 0) return false;
+ if(mode != 0 && mode != 1) return false;
+
+ lock();
+ switch(inst_width) {
+ case 1:_inst_width = QSPI_CFG_BUS_SINGLE; break;
+ case 2:_inst_width = QSPI_CFG_BUS_DUAL; break;
+ case 4:_inst_width = QSPI_CFG_BUS_QUAD; break;
+ default:_inst_width = QSPI_CFG_BUS_SINGLE;
+ }
+
+ switch(address_width) {
+ case 1:_address_width = QSPI_CFG_BUS_SINGLE; break;
+ case 2:_address_width = QSPI_CFG_BUS_DUAL; break;
+ case 4:_address_width = QSPI_CFG_BUS_QUAD; break;
+ default:_address_width = QSPI_CFG_BUS_SINGLE;
+ }
+
+ switch(address_size) {
+ case 8:_address_size = QSPI_CFG_ADDR_SIZE_8; break;
+ case 16:_address_size = QSPI_CFG_ADDR_SIZE_16; break;
+ case 24:_address_size = QSPI_CFG_ADDR_SIZE_24; break;
+ case 32:_address_size = QSPI_CFG_ADDR_SIZE_32; break;
+ default:_address_size = QSPI_CFG_ADDR_SIZE_8;
+ }
+
+ switch(alt_width) {
+ case 1:_alt_width = QSPI_CFG_BUS_SINGLE; break;
+ case 2:_alt_width = QSPI_CFG_BUS_DUAL; break;
+ case 4:_alt_width = QSPI_CFG_BUS_QUAD; break;
+ default:_alt_width = QSPI_CFG_BUS_SINGLE;
+ }
+
+ switch(alt_size) {
+ case 0:_alt_size = QSPI_CFG_ALT_SIZE_NONE; break;
+ case 8:_alt_size = QSPI_CFG_ALT_SIZE_8; break;
+ case 16:_alt_size = QSPI_CFG_ALT_SIZE_16; break;
+ case 24:_alt_size = QSPI_CFG_ALT_SIZE_24; break;
+ case 32:_alt_size = QSPI_CFG_ALT_SIZE_32; break;
+ default:_alt_size = QSPI_CFG_ALT_SIZE_NONE;
+ }
+
+ switch(data_width) {
+ case 1:_data_width = QSPI_CFG_BUS_SINGLE; break;
+ case 2:_data_width = QSPI_CFG_BUS_DUAL; break;
+ case 4:_data_width = QSPI_CFG_BUS_QUAD; break;
+ default:_data_width = QSPI_CFG_BUS_SINGLE;
+ }
+
+ _num_dummy_cycles = dummy_cycles;
+ _mode = mode;
+ unlock();
+
+ return true;
+}
+
+bool QSPI::set_frequency(int hz) {
+
+ lock();
+ _hz = hz;
+
+ //If the same owner, just change freq.
+ //Otherwise we may have to change mode as well, so call _acquire
+ if (_owner == this) {
+ qspi_frequency(&_qspi, _hz);
+ } else {
+ _acquire();
+ }
+ unlock();
+
+ return true;
+}
+
+bool QSPI::initialize() {
+ lock();
+ qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode );
+ unlock();
+
+ return ( ret == QSPI_STATUS_OK )? true:false;
+}
+
+int QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_length) {
+ int ret = 0;
+
+ if( (rx_length != NULL) && (rx_buffer != NULL) ) {
+ if(*rx_length != 0) {
+ lock();
+ if( true == _acquire()) {
+ qspi_command_t *qspi_cmd = _build_qspi_command(-1, address, -1);
+ if(QSPI_STATUS_OK == qspi_read(&_qspi, qspi_cmd, rx_buffer, rx_length)) {
+ ret = 1;
+ }
+ }
+ unlock();
+ }
+ }
+
+ return ret;
+}
+
+int QSPI::write(unsigned int address, const char *tx_buffer, size_t *tx_length) {
+ int ret = 0;
+
+ if( (tx_length != NULL) && (tx_buffer != NULL) ) {
+ if(*tx_length != 0) {
+ lock();
+ if(true == _acquire()) {
+ qspi_command_t *qspi_cmd = _build_qspi_command(-1, address, -1);
+ if(QSPI_STATUS_OK == qspi_write(&_qspi, qspi_cmd, tx_buffer, tx_length)) {
+ ret = 1;
+ }
+ }
+ unlock();
+ }
+ }
+
+ return ret;
+}
+
+int QSPI::read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length) {
+ int ret = 0;
+
+ if( (rx_length != NULL) && (rx_buffer != NULL) ) {
+ if(*rx_length != 0) {
+ lock();
+ if( true == _acquire()) {
+ qspi_command_t *qspi_cmd = _build_qspi_command(instruction, address, alt);
+ if(QSPI_STATUS_OK == qspi_read(&_qspi, qspi_cmd, rx_buffer, rx_length)) {
+ ret = 1;
+ }
+ }
+ unlock();
+ }
+ }
+
+ return ret;
+}
+
+int QSPI::write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length) {
+ int ret = 0;
+
+ if( (tx_length != NULL) && (tx_buffer != NULL) ) {
+ if(*tx_length != 0) {
+ lock();
+ if(true == _acquire()) {
+ qspi_command_t *qspi_cmd = _build_qspi_command(instruction, address, alt);
+ if(QSPI_STATUS_OK == qspi_write(&_qspi, qspi_cmd, tx_buffer, tx_length)) {
+ ret = 1;
+ }
+ }
+ unlock();
+ }
+ }
+
+ return ret;
+}
+
+int QSPI::command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length) {
+ int ret = 1;
+
+ lock();
+ if(true == _acquire()) {
+ qspi_command_t *qspi_cmd = _build_qspi_command(instruction, -1, -1); //We just need the command
+ if(QSPI_STATUS_OK != qspi_command_transfer(&_qspi, qspi_cmd, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
+ //We got error status, return 0
+ ret = 0;
+ }
+ } else {
+ ret = 0;
+ }
+ unlock();
+
+ return ret;
+}
+
+void QSPI::lock() {
+ _mutex->lock();
+}
+
+void QSPI::unlock() {
+ _mutex->unlock();
+}
+
+// Note: Private function with no locking
+bool QSPI::_acquire() {
+ qspi_status_t ret = QSPI_STATUS_OK;
+
+ if (_owner != this) {
+ //This will set freq as well
+ ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode );
+ _owner = this;
+ }
+
+ return ( ret == QSPI_STATUS_OK )? true:false;
+}
+
+qspi_command_t *QSPI::_build_qspi_command(int instruction, int address, int alt) {
+
+ memset( &_qspi_command, 0, sizeof(qspi_command_t) );
+ //Set up instruction phase parameters
+ _qspi_command.instruction.bus_width = _inst_width;
+ if(instruction != -1) {
+ _qspi_command.instruction.value = instruction;
+ } else {
+ _qspi_command.instruction.value = 0;
+ }
+
+ //Set up address phase parameters
+ _qspi_command.address.bus_width = _address_width;
+ _qspi_command.address.size = _address_size;
+ if(address != -1) {
+ _qspi_command.address.value = address;
+ } else {
+ _qspi_command.address.value = 0;
+ }
+
+ //Set up alt phase parameters
+ _qspi_command.alt.bus_width = _alt_width;
+ _qspi_command.alt.size = _alt_size;
+ if(alt != -1) {
+ _qspi_command.alt.value = alt;
+ } else {
+ //In the case alt phase is absent, set the alt size to be NONE
+ _qspi_command.alt.value = 0;
+ }
+
+ //Set up dummy cycle count
+ _qspi_command.dummy_count = _num_dummy_cycles;
+
+ //Set up bus width for data phase
+ _qspi_command.data.bus_width = _data_width;
+
+ return &_qspi_command;
+}
+
+} // namespace mbed
+
+#endif
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
new file mode 100644
index 0000000000..365d73413c
--- /dev/null
+++ b/drivers/QSPI.h
@@ -0,0 +1,232 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_QSPI_H
+#define MBED_QSPI_H
+
+#include "platform/platform.h"
+
+#if defined (DEVICE_QSPI) || defined(DOXYGEN_ONLY)
+
+#include "platform/PlatformMutex.h"
+#include "hal/qspi_api.h"
+#include "platform/SingletonPtr.h"
+#include "platform/NonCopyable.h"
+
+#define QSPI_DEFAULT_INST_WIDTH QSPI_CFG_BUS_SINGLE //Single bit mode for Instruction as most devices use 1-4-4 mode
+#define QSPI_DEFAULT_ADDRESS_WIDTH QSPI_CFG_BUS_QUAD //QuadSPI mode
+#define QSPI_DEFAULT_ADDRESS_SIZE QSPI_CFG_ADDR_SIZE_32
+#define QSPI_DEFAULT_ALT_WIDTH QSPI_CFG_BUS_QUAD //QuadSPI mode
+#define QSPI_DEFAULT_ALT_SIZE QSPI_CFG_ALT_SIZE_NONE
+#define QSPI_DEFAULT_DATA_WIDTH QSPI_CFG_BUS_QUAD //QuadSPI mode
+#define QSPI_DEFAULT_DUMMY_CYCLES 0
+#define _1_MHZ_ 1000000
+#define QSPI_DEFAULT_HZ _1_MHZ_
+
+namespace mbed {
+/** \addtogroup drivers */
+
+/** A QSPI Driver, used for communicating with QSPI slave devices
+ *
+ * The default format is set to Quad-SPI(4-4-4), and a clock frequency of 1MHz
+ * Most QSPI devices will also require Chip Select which is indicated by ssel.
+ *
+ * @note Synchronization level: Thread safe
+ *
+ * Example:
+ * @code
+ * // Write 4 byte array to a QSPI slave, and read the response, note that each device will have its specific read/write/alt values defined
+ *
+ * #include "mbed.h"
+ *
+ * // hardware ssel (where applicable)
+ * QSPI qspi_device(p5, p6, p7, p8, p9, p10); // io0, io1, io2, io3, sclk, ssel
+ *
+ *
+ * int main() {
+ * char tx_buf[] = { 0x11, 0x22, 0x33, 0x44 };
+ * char rx_buf[4];
+ * int buf_len = sizeof(tx_buf);
+ *
+ * int result = qspi_device.write( 0x12 , 0x100000 , 0 , tx_buf, &buf_len );
+ * if( !result ) printf("Write failed");
+ * int result = qspi_device.read( 0x13 , 0x100000 , 0 , rx_buf, &buf_len );
+ * if( !result ) printf("Read failed");
+ *
+ * }
+ * @endcode
+ * @ingroup drivers
+ */
+class QSPI : private NonCopyable {
+
+public:
+
+ /** Create a QSPI master connected to the specified pins
+ *
+ * io0-io3 is used to specify the Pins used for Quad SPI mode
+ *
+ * @param io0-io3 IO pins used for sending/receiving data during data phase of a transaction
+ * @param sclk QSPI Clock pin
+ * @param ssel QSPI chip select pin
+ */
+ QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel=NC);
+
+ /** Configure the data transmission format
+ *
+ * @param inst_width Bus width used by instruction phase(Valid values are 1,2,4)
+ * @param inst_size Size in bits used by instruction phase(Valid values are NONE,8,16,24,32)
+ * @param address_width Bus width used by address phase(Valid values are 1,2,4)
+ * @param address_size Size in bits used by address phase(Valid values are NONE,8,16,24,32)
+ * @param alt_width Bus width used by alt phase(Valid values are 1,2,4)
+ * @param alt_size Size in bits used by alt phase(Valid values are NONE,8,16,24,32)
+ * @param data_width Bus width used by data phase(Valid values are 1,2,4)
+ * @param dummy_cycles Number of dummy clock cycles to be used after alt phase
+ *
+ * @endcode
+ */
+ bool configure_format(int inst_width = QSPI_DEFAULT_INST_WIDTH,
+ int address_width = QSPI_DEFAULT_ADDRESS_WIDTH,
+ int address_size = QSPI_DEFAULT_ADDRESS_SIZE,
+ int alt_width = QSPI_DEFAULT_ALT_WIDTH,
+ int alt_size = QSPI_DEFAULT_ALT_SIZE,
+ int data_width = QSPI_DEFAULT_DATA_WIDTH,
+ int dummy_cycles = QSPI_DEFAULT_DUMMY_CYCLES,
+ int mode = 0);
+
+ /** Initialize QSPI interface
+ *
+ * This function must be called before doing any operation on the QSPI bus to initialize the interface
+ */
+ bool initialize();
+
+
+ /** Set the qspi bus clock frequency
+ *
+ * @param hz SCLK frequency in hz (default = 1MHz)
+ * @returns
+ * Returns true on successful, fails if the interface is already init-ed
+ */
+ bool set_frequency(int hz = QSPI_DEFAULT_HZ);
+
+ /** Read from QSPI peripheral with the preset read_instruction and alt_value
+ *
+ * @param address Address to be accessed in QSPI peripheral
+ * @param rx_buffer Buffer for data to be read from the peripheral
+ * @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
+ *
+ * @returns
+ * Returns 1 on successful reads and 0 on failed reads.
+ */
+ int read(unsigned int address, char *rx_buffer, size_t *rx_length);
+
+ /** Write to QSPI peripheral with the preset write_instruction and alt_value
+ *
+ * @param address Address to be accessed in QSPI peripheral
+ * @param tx_buffer Buffer containing data to be sent to peripheral
+ * @param rx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
+ *
+ * @returns
+ * Returns 1 on successful writes and 0 on failed write operation.
+ */
+ int write(unsigned int address, const char *tx_buffer, size_t *tx_length);
+
+ /** Read from QSPI peripheral using custom read instruction, alt values
+ *
+ * @param instruction Instruction value to be used in instruction phase
+ * @param address Address to be accessed in QSPI peripheral
+ * @param alt Alt value to be used in instruction phase
+ * @param rx_buffer Buffer for data to be read from the peripheral
+ * @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
+ *
+ * @returns
+ * Returns 1 on successful reads and 0 on failed reads.
+ */
+ int read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length);
+
+ /** Write to QSPI peripheral using custom write instruction, alt values
+ *
+ * @param instruction Instruction value to be used in instruction phase
+ * @param address Address to be accessed in QSPI peripheral
+ * @param alt Alt value to be used in instruction phase
+ * @param tx_buffer Buffer containing data to be sent to peripheral
+ * @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
+ *
+ * @returns
+ * Returns 1 on successful writes and 0 on failed write operation.
+ */
+ int write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length);
+
+ /** Perform a transaction to write to an address(a control register) and get the status results
+ *
+ * @param instruction Instruction value to be used in instruction phase
+ * @param address Address to be accessed in QSPI peripheral
+ * @param alt Alt value to be used in instruction phase
+ * @param tx_buffer Buffer containing data to be sent to peripheral
+ * @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
+ * @param rx_buffer Buffer for data to be read from the peripheral
+ * @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
+ *
+ * @returns
+ * Returns 1 on successful command transaction and 0 if operation failed.
+ */
+ int command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length);
+
+ /** Acquire exclusive access to this SPI bus
+ */
+ virtual void lock(void);
+
+ /** Release exclusive access to this SPI bus
+ */
+ virtual void unlock(void);
+
+public:
+ virtual ~QSPI() {
+ }
+
+protected:
+ qspi_t _qspi;
+
+ bool acquire(void);
+ static QSPI *_owner;
+ static SingletonPtr _mutex;
+ qspi_bus_width_t _inst_width; //Bus width for Instruction phase
+ qspi_bus_width_t _address_width; //Bus width for Address phase
+ qspi_address_size_t _address_size;
+ qspi_bus_width_t _alt_width; //Bus width for Alt phase
+ qspi_alt_size_t _alt_size;
+ qspi_bus_width_t _data_width; //Bus width for Data phase
+ qspi_command_t _qspi_command; //QSPI Hal command struct
+ int _num_dummy_cycles; //Number of dummy cycles to be used
+ int _hz; //Bus Frequency
+ int _mode; //SPI mode
+ PinName _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs; //IO lines, clock and chip select
+
+private:
+ /* Private acquire function without locking/unlocking
+ * Implemented in order to avoid duplicate locking and boost performance
+ */
+ bool _acquire(void);
+
+ /*
+ * This function builds the qspi command struct to be send to Hal
+ */
+ inline qspi_command_t *_build_qspi_command(int instruction, int address, int alt);
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
From 16d121c5d2f3aec769e4a71901971b6f6ce6feb7 Mon Sep 17 00:00:00 2001
From: Senthil Ramakrishnan
Date: Mon, 27 Nov 2017 16:52:32 -0600
Subject: [PATCH 10/78] Review fixes and doxygen changes
---
drivers/QSPI.cpp | 164 +++++++++---------
drivers/QSPI.h | 102 +++++++----
.../TARGET_NRF5x/TARGET_NRF52/objects.h | 2 +-
3 files changed, 151 insertions(+), 117 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index 97e91f8aea..28fe402c19 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -13,13 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#include "drivers/QSPI.h"
#include "platform/mbed_critical.h"
#if DEVICE_QSPI
-#define IS_BUS_WIDTH_VALID(width) ((width == 1) || (width == 2) || (width == 4))
-#define IS_SIZE_VALID(size) ((size == 8) || (size == 16) || (size == 24) || (size == 32))
-#define IS_ALT_SIZE_VALID(alt_size) ((alt_size == 0) || (alt_size == 8) || (alt_size == 16) || (alt_size == 24) || (alt_size == 32))
+
+#define IS_BUS_WIDTH_VALID(width) ((width == QSPI_BUS_SINGLE) || (width == QSPI_BUS_DUAL) || (width == QSPI_BUS_QUAD))
+#define IS_SIZE_VALID(size) ((size == QSPI_ADDR_SIZE_NONE) || (size == QSPI_ADDR_SIZE_8) || (size == QSPI_ADDR_SIZE_16) || (size == QSPI_ADDR_SIZE_24) || (size == QSPI_ADDR_SIZE_32))
+#define IS_ALT_SIZE_VALID(alt_size) ((alt_size == QSPI_ALT_SIZE_NONE) || (alt_size == QSPI_ALT_SIZE_8) || (alt_size == QSPI_ALT_SIZE_16) || (alt_size == QSPI_ALT_SIZE_24) || (alt_size == QSPI_ALT_SIZE_32))
namespace mbed {
@@ -27,82 +29,78 @@ QSPI* QSPI::_owner = NULL;
SingletonPtr QSPI::_mutex;
QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel) :
- _qspi(),
- _inst_width(QSPI_DEFAULT_INST_WIDTH),
- _address_width(QSPI_DEFAULT_ADDRESS_WIDTH),
- _address_size(QSPI_DEFAULT_ADDRESS_SIZE),
- _alt_width(QSPI_DEFAULT_ALT_WIDTH),
- _alt_size(QSPI_DEFAULT_ALT_SIZE),
- _data_width(QSPI_DEFAULT_DATA_WIDTH),
- _num_dummy_cycles(QSPI_DEFAULT_DUMMY_CYCLES),
- _hz(QSPI_DEFAULT_HZ) {
+ _qspi() {
// No lock needed in the constructor
_qspi_io0 = io0;
_qspi_io1 = io1;
_qspi_io2 = io2;
_qspi_io3 = io3;
_qspi_clk = sclk;
- _qspi_cs = ssel;
+ _qspi_cs = ssel;
+ _inst_width = QSPI_CFG_BUS_SINGLE;
+ _address_width = QSPI_CFG_BUS_SINGLE;
+ _address_size = QSPI_CFG_ADDR_SIZE_24;
+ _alt_width = QSPI_CFG_BUS_SINGLE;
+ _alt_size = QSPI_CFG_ALT_SIZE_NONE;
+ _data_width = QSPI_CFG_BUS_SINGLE;
+ _num_dummy_cycles = 0;
+ _mode = 0;
+ _hz = ONE_MHZ;
}
-bool QSPI::configure_format(int inst_width,
- int address_width, int address_size,
- int alt_width, int alt_size,
- int data_width,
- int dummy_cycles,
- int mode ) {
- if(!IS_BUS_WIDTH_VALID(inst_width)) return false;
- if(!IS_BUS_WIDTH_VALID(address_width)) return false;
- if(!IS_SIZE_VALID(address_size)) return false;
- if(!IS_BUS_WIDTH_VALID(alt_width)) return false;
- if(!IS_ALT_SIZE_VALID(alt_size)) return false;
- if(!IS_BUS_WIDTH_VALID(data_width)) return false;
- if(dummy_cycles < 0) return false;
- if(mode != 0 && mode != 1) return false;
+qspi_return_status_t QSPI::configure_format(qspi_config_bus_width_t inst_width, qspi_config_bus_width_t address_width, qspi_config_address_size_t address_size, qspi_config_bus_width_t alt_width, qspi_config_alt_size_t alt_size, qspi_config_bus_width_t data_width, int dummy_cycles, int mode ) {
+ if(!IS_BUS_WIDTH_VALID(inst_width)) return QSPI_INVALID_PARAMETER;
+ if(!IS_BUS_WIDTH_VALID(address_width)) return QSPI_INVALID_PARAMETER;
+ if(!IS_SIZE_VALID(address_size)) return QSPI_INVALID_PARAMETER;
+ if(!IS_BUS_WIDTH_VALID(alt_width)) return QSPI_INVALID_PARAMETER;
+ if(!IS_ALT_SIZE_VALID(alt_size)) return QSPI_INVALID_PARAMETER;
+ if(!IS_BUS_WIDTH_VALID(data_width)) return QSPI_INVALID_PARAMETER;
+ if(dummy_cycles < 0) return QSPI_INVALID_PARAMETER;
+ if(mode != 0 && mode != 1) return QSPI_INVALID_PARAMETER;
lock();
switch(inst_width) {
- case 1:_inst_width = QSPI_CFG_BUS_SINGLE; break;
- case 2:_inst_width = QSPI_CFG_BUS_DUAL; break;
- case 4:_inst_width = QSPI_CFG_BUS_QUAD; break;
+ case QSPI_BUS_SINGLE:_inst_width = QSPI_CFG_BUS_SINGLE; break;
+ case QSPI_BUS_DUAL:_inst_width = QSPI_CFG_BUS_DUAL; break;
+ case QSPI_BUS_QUAD:_inst_width = QSPI_CFG_BUS_QUAD; break;
default:_inst_width = QSPI_CFG_BUS_SINGLE;
}
switch(address_width) {
- case 1:_address_width = QSPI_CFG_BUS_SINGLE; break;
- case 2:_address_width = QSPI_CFG_BUS_DUAL; break;
- case 4:_address_width = QSPI_CFG_BUS_QUAD; break;
+ case QSPI_BUS_SINGLE:_address_width = QSPI_CFG_BUS_SINGLE; break;
+ case QSPI_BUS_DUAL:_address_width = QSPI_CFG_BUS_DUAL; break;
+ case QSPI_BUS_QUAD:_address_width = QSPI_CFG_BUS_QUAD; break;
default:_address_width = QSPI_CFG_BUS_SINGLE;
}
switch(address_size) {
- case 8:_address_size = QSPI_CFG_ADDR_SIZE_8; break;
- case 16:_address_size = QSPI_CFG_ADDR_SIZE_16; break;
- case 24:_address_size = QSPI_CFG_ADDR_SIZE_24; break;
- case 32:_address_size = QSPI_CFG_ADDR_SIZE_32; break;
+ case QSPI_ADDR_SIZE_8:_address_size = QSPI_CFG_ADDR_SIZE_8; break;
+ case QSPI_ADDR_SIZE_16:_address_size = QSPI_CFG_ADDR_SIZE_16; break;
+ case QSPI_ADDR_SIZE_24:_address_size = QSPI_CFG_ADDR_SIZE_24; break;
+ case QSPI_ADDR_SIZE_32:_address_size = QSPI_CFG_ADDR_SIZE_32; break;
default:_address_size = QSPI_CFG_ADDR_SIZE_8;
}
switch(alt_width) {
- case 1:_alt_width = QSPI_CFG_BUS_SINGLE; break;
- case 2:_alt_width = QSPI_CFG_BUS_DUAL; break;
- case 4:_alt_width = QSPI_CFG_BUS_QUAD; break;
+ case QSPI_BUS_SINGLE:_alt_width = QSPI_CFG_BUS_SINGLE; break;
+ case QSPI_BUS_DUAL:_alt_width = QSPI_CFG_BUS_DUAL; break;
+ case QSPI_BUS_QUAD:_alt_width = QSPI_CFG_BUS_QUAD; break;
default:_alt_width = QSPI_CFG_BUS_SINGLE;
}
switch(alt_size) {
- case 0:_alt_size = QSPI_CFG_ALT_SIZE_NONE; break;
- case 8:_alt_size = QSPI_CFG_ALT_SIZE_8; break;
- case 16:_alt_size = QSPI_CFG_ALT_SIZE_16; break;
- case 24:_alt_size = QSPI_CFG_ALT_SIZE_24; break;
- case 32:_alt_size = QSPI_CFG_ALT_SIZE_32; break;
+ case QSPI_ALT_SIZE_NONE:_alt_size = QSPI_CFG_ALT_SIZE_NONE; break;
+ case QSPI_ALT_SIZE_8:_alt_size = QSPI_CFG_ALT_SIZE_8; break;
+ case QSPI_ALT_SIZE_16:_alt_size = QSPI_CFG_ALT_SIZE_16; break;
+ case QSPI_ALT_SIZE_24:_alt_size = QSPI_CFG_ALT_SIZE_24; break;
+ case QSPI_ALT_SIZE_32:_alt_size = QSPI_CFG_ALT_SIZE_32; break;
default:_alt_size = QSPI_CFG_ALT_SIZE_NONE;
}
switch(data_width) {
- case 1:_data_width = QSPI_CFG_BUS_SINGLE; break;
- case 2:_data_width = QSPI_CFG_BUS_DUAL; break;
- case 4:_data_width = QSPI_CFG_BUS_QUAD; break;
+ case QSPI_BUS_SINGLE:_data_width = QSPI_CFG_BUS_SINGLE; break;
+ case QSPI_BUS_DUAL:_data_width = QSPI_CFG_BUS_DUAL; break;
+ case QSPI_BUS_QUAD:_data_width = QSPI_CFG_BUS_QUAD; break;
default:_data_width = QSPI_CFG_BUS_SINGLE;
}
@@ -110,36 +108,38 @@ bool QSPI::configure_format(int inst_width,
_mode = mode;
unlock();
- return true;
+ return QSPI_SUCCESS;
}
-bool QSPI::set_frequency(int hz) {
-
+qspi_return_status_t QSPI::set_frequency(int hz) {
+ qspi_return_status_t ret_status = QSPI_SUCCESS;
lock();
_hz = hz;
//If the same owner, just change freq.
//Otherwise we may have to change mode as well, so call _acquire
if (_owner == this) {
- qspi_frequency(&_qspi, _hz);
+ if(QSPI_STATUS_OK != qspi_frequency(&_qspi, _hz)) {
+ ret_status = QSPI_ERROR;
+ }
} else {
_acquire();
}
unlock();
- return true;
+ return ret_status;
}
-bool QSPI::initialize() {
+qspi_return_status_t QSPI::initialize() {
lock();
qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode );
unlock();
- return ( ret == QSPI_STATUS_OK )? true:false;
+ return ( ret == QSPI_STATUS_OK )? QSPI_SUCCESS:QSPI_ERROR;
}
-int QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_length) {
- int ret = 0;
+qspi_return_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_length) {
+ qspi_return_status_t ret_status = QSPI_ERROR;
if( (rx_length != NULL) && (rx_buffer != NULL) ) {
if(*rx_length != 0) {
@@ -147,18 +147,20 @@ int QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_length) {
if( true == _acquire()) {
qspi_command_t *qspi_cmd = _build_qspi_command(-1, address, -1);
if(QSPI_STATUS_OK == qspi_read(&_qspi, qspi_cmd, rx_buffer, rx_length)) {
- ret = 1;
+ ret_status = QSPI_SUCCESS;
}
}
unlock();
}
+ } else {
+ ret_status = QSPI_INVALID_PARAMETER;
}
- return ret;
+ return ret_status;
}
-int QSPI::write(unsigned int address, const char *tx_buffer, size_t *tx_length) {
- int ret = 0;
+qspi_return_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *tx_length) {
+ qspi_return_status_t ret_status = QSPI_ERROR;
if( (tx_length != NULL) && (tx_buffer != NULL) ) {
if(*tx_length != 0) {
@@ -166,18 +168,20 @@ int QSPI::write(unsigned int address, const char *tx_buffer, size_t *tx_length)
if(true == _acquire()) {
qspi_command_t *qspi_cmd = _build_qspi_command(-1, address, -1);
if(QSPI_STATUS_OK == qspi_write(&_qspi, qspi_cmd, tx_buffer, tx_length)) {
- ret = 1;
+ ret_status = QSPI_SUCCESS;
}
}
unlock();
}
+ } else {
+ ret_status = QSPI_INVALID_PARAMETER;
}
- return ret;
+ return ret_status;
}
-int QSPI::read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length) {
- int ret = 0;
+qspi_return_status_t QSPI::read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length) {
+ qspi_return_status_t ret_status = QSPI_ERROR;
if( (rx_length != NULL) && (rx_buffer != NULL) ) {
if(*rx_length != 0) {
@@ -185,18 +189,20 @@ int QSPI::read(unsigned int instruction, unsigned int address, unsigned int alt,
if( true == _acquire()) {
qspi_command_t *qspi_cmd = _build_qspi_command(instruction, address, alt);
if(QSPI_STATUS_OK == qspi_read(&_qspi, qspi_cmd, rx_buffer, rx_length)) {
- ret = 1;
+ ret_status = QSPI_SUCCESS;
}
}
unlock();
}
+ } else {
+ ret_status = QSPI_INVALID_PARAMETER;
}
- return ret;
+ return ret_status;
}
-int QSPI::write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length) {
- int ret = 0;
+qspi_return_status_t QSPI::write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length) {
+ qspi_return_status_t ret_status = QSPI_ERROR;
if( (tx_length != NULL) && (tx_buffer != NULL) ) {
if(*tx_length != 0) {
@@ -204,32 +210,32 @@ int QSPI::write(unsigned int instruction, unsigned int address, unsigned int alt
if(true == _acquire()) {
qspi_command_t *qspi_cmd = _build_qspi_command(instruction, address, alt);
if(QSPI_STATUS_OK == qspi_write(&_qspi, qspi_cmd, tx_buffer, tx_length)) {
- ret = 1;
+ ret_status = QSPI_SUCCESS;
}
}
unlock();
}
+ } else {
+ ret_status = QSPI_INVALID_PARAMETER;
}
- return ret;
+ return ret_status;
}
-int QSPI::command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length) {
- int ret = 1;
+qspi_return_status_t QSPI::command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length) {
+ qspi_return_status_t ret_status = QSPI_ERROR;
lock();
if(true == _acquire()) {
qspi_command_t *qspi_cmd = _build_qspi_command(instruction, -1, -1); //We just need the command
- if(QSPI_STATUS_OK != qspi_command_transfer(&_qspi, qspi_cmd, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
+ if(QSPI_STATUS_OK == qspi_command_transfer(&_qspi, qspi_cmd, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
//We got error status, return 0
- ret = 0;
+ ret_status = QSPI_SUCCESS;
}
- } else {
- ret = 0;
- }
+ }
unlock();
- return ret;
+ return ret_status;
}
void QSPI::lock() {
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index 365d73413c..a3b672e30b 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -20,20 +20,48 @@
#if defined (DEVICE_QSPI) || defined(DOXYGEN_ONLY)
-#include "platform/PlatformMutex.h"
#include "hal/qspi_api.h"
+#include "platform/PlatformMutex.h"
#include "platform/SingletonPtr.h"
#include "platform/NonCopyable.h"
-#define QSPI_DEFAULT_INST_WIDTH QSPI_CFG_BUS_SINGLE //Single bit mode for Instruction as most devices use 1-4-4 mode
-#define QSPI_DEFAULT_ADDRESS_WIDTH QSPI_CFG_BUS_QUAD //QuadSPI mode
-#define QSPI_DEFAULT_ADDRESS_SIZE QSPI_CFG_ADDR_SIZE_32
-#define QSPI_DEFAULT_ALT_WIDTH QSPI_CFG_BUS_QUAD //QuadSPI mode
-#define QSPI_DEFAULT_ALT_SIZE QSPI_CFG_ALT_SIZE_NONE
-#define QSPI_DEFAULT_DATA_WIDTH QSPI_CFG_BUS_QUAD //QuadSPI mode
-#define QSPI_DEFAULT_DUMMY_CYCLES 0
-#define _1_MHZ_ 1000000
-#define QSPI_DEFAULT_HZ _1_MHZ_
+#define ONE_MHZ 1000000
+
+/** QSPI Bus width Enum
+ */
+typedef enum qspi_config_bus_width {
+ QSPI_BUS_SINGLE,
+ QSPI_BUS_DUAL,
+ QSPI_BUS_QUAD,
+} qspi_config_bus_width_t;
+
+/** Address size Enum
+ */
+typedef enum qspi_config_address_size {
+ QSPI_ADDR_SIZE_NONE,
+ QSPI_ADDR_SIZE_8,
+ QSPI_ADDR_SIZE_16,
+ QSPI_ADDR_SIZE_24,
+ QSPI_ADDR_SIZE_32,
+} qspi_config_address_size_t;
+
+/** Alternative size Enum
+ */
+typedef enum qspi_config_alt_size {
+ QSPI_ALT_SIZE_NONE,
+ QSPI_ALT_SIZE_8,
+ QSPI_ALT_SIZE_16,
+ QSPI_ALT_SIZE_24,
+ QSPI_ALT_SIZE_32,
+} qspi_config_alt_size_t;
+
+/** QSPI Driver Return Status Enum
+ */
+typedef enum qspi_return_status {
+ QSPI_ERROR = -1, /**< Generic error >*/
+ QSPI_INVALID_PARAMETER = -2, /**< The parameter is invalid >*/
+ QSPI_SUCCESS = 0, /**< Function executed sucessfully >*/
+} qspi_return_status_t;
namespace mbed {
/** \addtogroup drivers */
@@ -77,7 +105,10 @@ public:
*
* io0-io3 is used to specify the Pins used for Quad SPI mode
*
- * @param io0-io3 IO pins used for sending/receiving data during data phase of a transaction
+ * @param io0 1st IO pin used for sending/receiving data during data phase of a transaction
+ * @param io1 2nd IO pin used for sending/receiving data during data phase of a transaction
+ * @param io2 3rd IO pin used for sending/receiving data during data phase of a transaction
+ * @param io3 4th IO pin used for sending/receiving data during data phase of a transaction
* @param sclk QSPI Clock pin
* @param ssel QSPI chip select pin
*/
@@ -86,39 +117,38 @@ public:
/** Configure the data transmission format
*
* @param inst_width Bus width used by instruction phase(Valid values are 1,2,4)
- * @param inst_size Size in bits used by instruction phase(Valid values are NONE,8,16,24,32)
* @param address_width Bus width used by address phase(Valid values are 1,2,4)
* @param address_size Size in bits used by address phase(Valid values are NONE,8,16,24,32)
* @param alt_width Bus width used by alt phase(Valid values are 1,2,4)
* @param alt_size Size in bits used by alt phase(Valid values are NONE,8,16,24,32)
* @param data_width Bus width used by data phase(Valid values are 1,2,4)
* @param dummy_cycles Number of dummy clock cycles to be used after alt phase
+ * @param mode Mode specifies the SPI mode(Mode=0 uses CPOL=0, CPHA=0, Mode=1 uses CPOL=1, CPHA=1)
*
- * @endcode
*/
- bool configure_format(int inst_width = QSPI_DEFAULT_INST_WIDTH,
- int address_width = QSPI_DEFAULT_ADDRESS_WIDTH,
- int address_size = QSPI_DEFAULT_ADDRESS_SIZE,
- int alt_width = QSPI_DEFAULT_ALT_WIDTH,
- int alt_size = QSPI_DEFAULT_ALT_SIZE,
- int data_width = QSPI_DEFAULT_DATA_WIDTH,
- int dummy_cycles = QSPI_DEFAULT_DUMMY_CYCLES,
- int mode = 0);
+ qspi_return_status_t configure_format(qspi_config_bus_width_t inst_width,
+ qspi_config_bus_width_t address_width,
+ qspi_config_address_size_t address_size,
+ qspi_config_bus_width_t alt_width,
+ qspi_config_alt_size_t alt_size,
+ qspi_config_bus_width_t data_width,
+ int dummy_cycles,
+ int mode);
/** Initialize QSPI interface
*
* This function must be called before doing any operation on the QSPI bus to initialize the interface
*/
- bool initialize();
+ qspi_return_status_t initialize();
/** Set the qspi bus clock frequency
*
* @param hz SCLK frequency in hz (default = 1MHz)
* @returns
- * Returns true on successful, fails if the interface is already init-ed
+ * Returns QSPI_SUCCESS on successful, fails if the interface is already init-ed
*/
- bool set_frequency(int hz = QSPI_DEFAULT_HZ);
+ qspi_return_status_t set_frequency(int hz = ONE_MHZ);
/** Read from QSPI peripheral with the preset read_instruction and alt_value
*
@@ -127,20 +157,20 @@ public:
* @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
*
* @returns
- * Returns 1 on successful reads and 0 on failed reads.
+ * Returns QSPI_SUCCESS on successful reads and QSPI_ERROR on failed reads.
*/
- int read(unsigned int address, char *rx_buffer, size_t *rx_length);
+ qspi_return_status_t read(unsigned int address, char *rx_buffer, size_t *rx_length);
/** Write to QSPI peripheral with the preset write_instruction and alt_value
*
* @param address Address to be accessed in QSPI peripheral
* @param tx_buffer Buffer containing data to be sent to peripheral
- * @param rx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
+ * @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
*
* @returns
- * Returns 1 on successful writes and 0 on failed write operation.
+ * Returns QSPI_SUCCESS on successful reads and QSPI_ERROR on failed reads.
*/
- int write(unsigned int address, const char *tx_buffer, size_t *tx_length);
+ qspi_return_status_t write(unsigned int address, const char *tx_buffer, size_t *tx_length);
/** Read from QSPI peripheral using custom read instruction, alt values
*
@@ -151,9 +181,9 @@ public:
* @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
*
* @returns
- * Returns 1 on successful reads and 0 on failed reads.
+ * Returns QSPI_SUCCESS on successful reads and QSPI_ERROR on failed reads.
*/
- int read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length);
+ qspi_return_status_t read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length);
/** Write to QSPI peripheral using custom write instruction, alt values
*
@@ -164,24 +194,22 @@ public:
* @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
*
* @returns
- * Returns 1 on successful writes and 0 on failed write operation.
+ * Returns QSPI_SUCCESS on successful reads and QSPI_ERROR on failed reads.
*/
- int write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length);
+ qspi_return_status_t write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length);
/** Perform a transaction to write to an address(a control register) and get the status results
*
* @param instruction Instruction value to be used in instruction phase
- * @param address Address to be accessed in QSPI peripheral
- * @param alt Alt value to be used in instruction phase
* @param tx_buffer Buffer containing data to be sent to peripheral
* @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
* @param rx_buffer Buffer for data to be read from the peripheral
* @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
*
* @returns
- * Returns 1 on successful command transaction and 0 if operation failed.
+ * Returns QSPI_SUCCESS on successful reads and QSPI_ERROR on failed reads.
*/
- int command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length);
+ qspi_return_status_t command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length);
/** Acquire exclusive access to this SPI bus
*/
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/objects.h b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/objects.h
index 10e19c7b50..39c4b60f67 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/objects.h
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/objects.h
@@ -148,7 +148,7 @@ struct flash_s {
struct qspi_s {
uint32_t placeholder;
- nrf_drv_qspi_config_t config;
+ //nrf_drv_qspi_config_t config;
};
#endif
From 9deecacc9bdd884d9ac7e8cd0de90f13adf5fdd0 Mon Sep 17 00:00:00 2001
From: Senthil Ramakrishnan
Date: Wed, 29 Nov 2017 14:01:04 -0600
Subject: [PATCH 11/78] Fix code style issues
---
drivers/QSPI.cpp | 132 +++++++++++++++++++++++++++++++++--------------
drivers/QSPI.h | 10 ++--
2 files changed, 100 insertions(+), 42 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index 28fe402c19..99a06ed2f1 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -26,8 +26,8 @@
namespace mbed {
QSPI* QSPI::_owner = NULL;
-SingletonPtr QSPI::_mutex;
-
+SingletonPtr QSPI::_mutex;
+
QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel) :
_qspi() {
// No lock needed in the constructor
@@ -49,59 +49,115 @@ QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, Pin
}
qspi_return_status_t QSPI::configure_format(qspi_config_bus_width_t inst_width, qspi_config_bus_width_t address_width, qspi_config_address_size_t address_size, qspi_config_bus_width_t alt_width, qspi_config_alt_size_t alt_size, qspi_config_bus_width_t data_width, int dummy_cycles, int mode ) {
- if(!IS_BUS_WIDTH_VALID(inst_width)) return QSPI_INVALID_PARAMETER;
- if(!IS_BUS_WIDTH_VALID(address_width)) return QSPI_INVALID_PARAMETER;
- if(!IS_SIZE_VALID(address_size)) return QSPI_INVALID_PARAMETER;
- if(!IS_BUS_WIDTH_VALID(alt_width)) return QSPI_INVALID_PARAMETER;
- if(!IS_ALT_SIZE_VALID(alt_size)) return QSPI_INVALID_PARAMETER;
- if(!IS_BUS_WIDTH_VALID(data_width)) return QSPI_INVALID_PARAMETER;
- if(dummy_cycles < 0) return QSPI_INVALID_PARAMETER;
- if(mode != 0 && mode != 1) return QSPI_INVALID_PARAMETER;
+ if(!IS_BUS_WIDTH_VALID(inst_width))
+ return QSPI_INVALID_PARAMETER;
+ if(!IS_BUS_WIDTH_VALID(address_width))
+ return QSPI_INVALID_PARAMETER;
+ if(!IS_SIZE_VALID(address_size))
+ return QSPI_INVALID_PARAMETER;
+ if(!IS_BUS_WIDTH_VALID(alt_width))
+ return QSPI_INVALID_PARAMETER;
+ if(!IS_ALT_SIZE_VALID(alt_size))
+ return QSPI_INVALID_PARAMETER;
+ if(!IS_BUS_WIDTH_VALID(data_width))
+ return QSPI_INVALID_PARAMETER;
+ if(dummy_cycles < 0)
+ return QSPI_INVALID_PARAMETER;
+ if(mode != 0 && mode != 1)
+ return QSPI_INVALID_PARAMETER;
lock();
switch(inst_width) {
- case QSPI_BUS_SINGLE:_inst_width = QSPI_CFG_BUS_SINGLE; break;
- case QSPI_BUS_DUAL:_inst_width = QSPI_CFG_BUS_DUAL; break;
- case QSPI_BUS_QUAD:_inst_width = QSPI_CFG_BUS_QUAD; break;
- default:_inst_width = QSPI_CFG_BUS_SINGLE;
+ case QSPI_BUS_SINGLE:
+ _inst_width = QSPI_CFG_BUS_SINGLE;
+ break;
+ case QSPI_BUS_DUAL:
+ _inst_width = QSPI_CFG_BUS_DUAL;
+ break;
+ case QSPI_BUS_QUAD:
+ _inst_width = QSPI_CFG_BUS_QUAD;
+ break;
+ default:
+ _inst_width = QSPI_CFG_BUS_SINGLE;
}
switch(address_width) {
- case QSPI_BUS_SINGLE:_address_width = QSPI_CFG_BUS_SINGLE; break;
- case QSPI_BUS_DUAL:_address_width = QSPI_CFG_BUS_DUAL; break;
- case QSPI_BUS_QUAD:_address_width = QSPI_CFG_BUS_QUAD; break;
- default:_address_width = QSPI_CFG_BUS_SINGLE;
+ case QSPI_BUS_SINGLE:
+ _address_width = QSPI_CFG_BUS_SINGLE;
+ break;
+ case QSPI_BUS_DUAL:
+ _address_width = QSPI_CFG_BUS_DUAL;
+ break;
+ case QSPI_BUS_QUAD:
+ _address_width = QSPI_CFG_BUS_QUAD;
+ break;
+ default:
+ _address_width = QSPI_CFG_BUS_SINGLE;
}
switch(address_size) {
- case QSPI_ADDR_SIZE_8:_address_size = QSPI_CFG_ADDR_SIZE_8; break;
- case QSPI_ADDR_SIZE_16:_address_size = QSPI_CFG_ADDR_SIZE_16; break;
- case QSPI_ADDR_SIZE_24:_address_size = QSPI_CFG_ADDR_SIZE_24; break;
- case QSPI_ADDR_SIZE_32:_address_size = QSPI_CFG_ADDR_SIZE_32; break;
- default:_address_size = QSPI_CFG_ADDR_SIZE_8;
+ case QSPI_ADDR_SIZE_8:
+ _address_size = QSPI_CFG_ADDR_SIZE_8;
+ break;
+ case QSPI_ADDR_SIZE_16:
+ _address_size = QSPI_CFG_ADDR_SIZE_16;
+ break;
+ case QSPI_ADDR_SIZE_24:
+ _address_size = QSPI_CFG_ADDR_SIZE_24;
+ break;
+ case QSPI_ADDR_SIZE_32:
+ _address_size = QSPI_CFG_ADDR_SIZE_32;
+ break;
+ default:
+ _address_size = QSPI_CFG_ADDR_SIZE_8;
}
switch(alt_width) {
- case QSPI_BUS_SINGLE:_alt_width = QSPI_CFG_BUS_SINGLE; break;
- case QSPI_BUS_DUAL:_alt_width = QSPI_CFG_BUS_DUAL; break;
- case QSPI_BUS_QUAD:_alt_width = QSPI_CFG_BUS_QUAD; break;
- default:_alt_width = QSPI_CFG_BUS_SINGLE;
+ case QSPI_BUS_SINGLE:
+ _alt_width = QSPI_CFG_BUS_SINGLE;
+ break;
+ case QSPI_BUS_DUAL:
+ _alt_width = QSPI_CFG_BUS_DUAL;
+ break;
+ case QSPI_BUS_QUAD:
+ _alt_width = QSPI_CFG_BUS_QUAD;
+ break;
+ default:
+ _alt_width = QSPI_CFG_BUS_SINGLE;
}
switch(alt_size) {
- case QSPI_ALT_SIZE_NONE:_alt_size = QSPI_CFG_ALT_SIZE_NONE; break;
- case QSPI_ALT_SIZE_8:_alt_size = QSPI_CFG_ALT_SIZE_8; break;
- case QSPI_ALT_SIZE_16:_alt_size = QSPI_CFG_ALT_SIZE_16; break;
- case QSPI_ALT_SIZE_24:_alt_size = QSPI_CFG_ALT_SIZE_24; break;
- case QSPI_ALT_SIZE_32:_alt_size = QSPI_CFG_ALT_SIZE_32; break;
- default:_alt_size = QSPI_CFG_ALT_SIZE_NONE;
+ case QSPI_ALT_SIZE_NONE:
+ _alt_size = QSPI_CFG_ALT_SIZE_NONE;
+ break;
+ case QSPI_ALT_SIZE_8:
+ _alt_size = QSPI_CFG_ALT_SIZE_8;
+ break;
+ case QSPI_ALT_SIZE_16:
+ _alt_size = QSPI_CFG_ALT_SIZE_16;
+ break;
+ case QSPI_ALT_SIZE_24:
+ _alt_size = QSPI_CFG_ALT_SIZE_24;
+ break;
+ case QSPI_ALT_SIZE_32:
+ _alt_size = QSPI_CFG_ALT_SIZE_32;
+ break;
+ default:
+ _alt_size = QSPI_CFG_ALT_SIZE_NONE;
}
switch(data_width) {
- case QSPI_BUS_SINGLE:_data_width = QSPI_CFG_BUS_SINGLE; break;
- case QSPI_BUS_DUAL:_data_width = QSPI_CFG_BUS_DUAL; break;
- case QSPI_BUS_QUAD:_data_width = QSPI_CFG_BUS_QUAD; break;
- default:_data_width = QSPI_CFG_BUS_SINGLE;
+ case QSPI_BUS_SINGLE:
+ _data_width = QSPI_CFG_BUS_SINGLE;
+ break;
+ case QSPI_BUS_DUAL:
+ _data_width = QSPI_CFG_BUS_DUAL;
+ break;
+ case QSPI_BUS_QUAD:
+ _data_width = QSPI_CFG_BUS_QUAD;
+ break;
+ default:
+ _data_width = QSPI_CFG_BUS_SINGLE;
}
_num_dummy_cycles = dummy_cycles;
@@ -135,7 +191,7 @@ qspi_return_status_t QSPI::initialize() {
qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode );
unlock();
- return ( ret == QSPI_STATUS_OK )? QSPI_SUCCESS:QSPI_ERROR;
+ return ( ret == QSPI_STATUS_OK )? QSPI_SUCCESS : QSPI_ERROR;
}
qspi_return_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_length) {
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index a3b672e30b..f71bd106ad 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -27,6 +27,9 @@
#define ONE_MHZ 1000000
+namespace mbed {
+
+// Config/Mode Defines
/** QSPI Bus width Enum
*/
typedef enum qspi_config_bus_width {
@@ -61,9 +64,8 @@ typedef enum qspi_return_status {
QSPI_ERROR = -1, /**< Generic error >*/
QSPI_INVALID_PARAMETER = -2, /**< The parameter is invalid >*/
QSPI_SUCCESS = 0, /**< Function executed sucessfully >*/
-} qspi_return_status_t;
-
-namespace mbed {
+} qspi_return_status_t;
+
/** \addtogroup drivers */
/** A QSPI Driver, used for communicating with QSPI slave devices
@@ -100,7 +102,7 @@ namespace mbed {
class QSPI : private NonCopyable {
public:
-
+
/** Create a QSPI master connected to the specified pins
*
* io0-io3 is used to specify the Pins used for Quad SPI mode
From 10a6fd6549f6d6969f1cf59f0fe702e4a4a4cfc5 Mon Sep 17 00:00:00 2001
From: Senthil Ramakrishnan
Date: Thu, 30 Nov 2017 11:45:44 -0600
Subject: [PATCH 12/78] Add support for 1_1_2 and 1_2_2 modes in HAL
---
targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c | 22 ++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
index 10c8e6b1fc..63f07e109b 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
@@ -100,11 +100,31 @@ qspi_status_t qspi_prepare_command(qspi_t *obj, const qspi_command_t *command, b
} else {
config.prot_if.readoc = NRF_QSPI_READOC_READ4IO;
}
+ // 1-1-2
+ } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->data.bus_width == QSPI_CFG_BUS_DUAL) {
+ // 1-1-2
+ if (write) {
+ config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP2O;
+ } else {
+ config.prot_if.readoc = NRF_QSPI_READOC_READ2O;
+ }
+ // 1-2-2
+ } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->address.bus_width == QSPI_CFG_BUS_DUAL &&
+ command->data.bus_width == QSPI_CFG_BUS_DUAL) {
+ // 1-2-2
+ if (write) {
+ //Currently NRF52840 does not define PP2IO, so use PP2O for 1-2-2 mode
+ config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP2O;
+ } else {
+ config.prot_if.readoc = NRF_QSPI_READOC_READ2IO;
+ }
}
}
qspi_status_t ret = QSPI_STATUS_OK;
-
// supporting only 24 or 32 bit address
if (command->address.size == QSPI_CFG_ADDR_SIZE_24) {
config.prot_if.addrmode = NRF_QSPI_ADDRMODE_24BIT;
From 0f7cc36f694498ac2ab25885ce15fb063f10612b Mon Sep 17 00:00:00 2001
From: Senthil Ramakrishnan
Date: Thu, 30 Nov 2017 11:46:25 -0600
Subject: [PATCH 13/78] Changing config and return definitions to adhere to HAL
defs
---
drivers/QSPI.cpp | 174 ++++++++++++-----------------------------------
drivers/QSPI.h | 75 ++++++--------------
2 files changed, 62 insertions(+), 187 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index 99a06ed2f1..451180f8cf 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -19,9 +19,9 @@
#if DEVICE_QSPI
-#define IS_BUS_WIDTH_VALID(width) ((width == QSPI_BUS_SINGLE) || (width == QSPI_BUS_DUAL) || (width == QSPI_BUS_QUAD))
-#define IS_SIZE_VALID(size) ((size == QSPI_ADDR_SIZE_NONE) || (size == QSPI_ADDR_SIZE_8) || (size == QSPI_ADDR_SIZE_16) || (size == QSPI_ADDR_SIZE_24) || (size == QSPI_ADDR_SIZE_32))
-#define IS_ALT_SIZE_VALID(alt_size) ((alt_size == QSPI_ALT_SIZE_NONE) || (alt_size == QSPI_ALT_SIZE_8) || (alt_size == QSPI_ALT_SIZE_16) || (alt_size == QSPI_ALT_SIZE_24) || (alt_size == QSPI_ALT_SIZE_32))
+#define IS_BUS_WIDTH_VALID(width) ((width == QSPI_CFG_BUS_SINGLE) || (width == QSPI_CFG_BUS_DUAL) || (width == QSPI_CFG_BUS_QUAD))
+#define IS_SIZE_VALID(size) ((size == QSPI_CFG_ADDR_SIZE_NONE) || (size == QSPI_CFG_ADDR_SIZE_8) || (size == QSPI_CFG_ADDR_SIZE_16) || (size == QSPI_CFG_ADDR_SIZE_24) || (size == QSPI_CFG_ADDR_SIZE_32))
+#define IS_ALT_SIZE_VALID(alt_size) ((alt_size == QSPI_CFG_ALT_SIZE_NONE) || (alt_size == QSPI_CFG_ALT_SIZE_8) || (alt_size == QSPI_CFG_ALT_SIZE_16) || (alt_size == QSPI_CFG_ALT_SIZE_24) || (alt_size == QSPI_CFG_ALT_SIZE_32))
namespace mbed {
@@ -30,7 +30,6 @@ SingletonPtr QSPI::_mutex;
QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel) :
_qspi() {
- // No lock needed in the constructor
_qspi_io0 = io0;
_qspi_io1 = io1;
_qspi_io2 = io2;
@@ -48,127 +47,40 @@ QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, Pin
_hz = ONE_MHZ;
}
-qspi_return_status_t QSPI::configure_format(qspi_config_bus_width_t inst_width, qspi_config_bus_width_t address_width, qspi_config_address_size_t address_size, qspi_config_bus_width_t alt_width, qspi_config_alt_size_t alt_size, qspi_config_bus_width_t data_width, int dummy_cycles, int mode ) {
+qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width_t address_width, qspi_address_size_t address_size, qspi_bus_width_t alt_width, qspi_alt_size_t alt_size, qspi_bus_width_t data_width, int dummy_cycles, int mode ) {
if(!IS_BUS_WIDTH_VALID(inst_width))
- return QSPI_INVALID_PARAMETER;
+ return QSPI_STATUS_INVALID_PARAMETER;
if(!IS_BUS_WIDTH_VALID(address_width))
- return QSPI_INVALID_PARAMETER;
+ return QSPI_STATUS_INVALID_PARAMETER;
if(!IS_SIZE_VALID(address_size))
- return QSPI_INVALID_PARAMETER;
+ return QSPI_STATUS_INVALID_PARAMETER;
if(!IS_BUS_WIDTH_VALID(alt_width))
- return QSPI_INVALID_PARAMETER;
+ return QSPI_STATUS_INVALID_PARAMETER;
if(!IS_ALT_SIZE_VALID(alt_size))
- return QSPI_INVALID_PARAMETER;
+ return QSPI_STATUS_INVALID_PARAMETER;
if(!IS_BUS_WIDTH_VALID(data_width))
- return QSPI_INVALID_PARAMETER;
+ return QSPI_STATUS_INVALID_PARAMETER;
if(dummy_cycles < 0)
- return QSPI_INVALID_PARAMETER;
+ return QSPI_STATUS_INVALID_PARAMETER;
if(mode != 0 && mode != 1)
- return QSPI_INVALID_PARAMETER;
+ return QSPI_STATUS_INVALID_PARAMETER;
lock();
- switch(inst_width) {
- case QSPI_BUS_SINGLE:
- _inst_width = QSPI_CFG_BUS_SINGLE;
- break;
- case QSPI_BUS_DUAL:
- _inst_width = QSPI_CFG_BUS_DUAL;
- break;
- case QSPI_BUS_QUAD:
- _inst_width = QSPI_CFG_BUS_QUAD;
- break;
- default:
- _inst_width = QSPI_CFG_BUS_SINGLE;
- }
-
- switch(address_width) {
- case QSPI_BUS_SINGLE:
- _address_width = QSPI_CFG_BUS_SINGLE;
- break;
- case QSPI_BUS_DUAL:
- _address_width = QSPI_CFG_BUS_DUAL;
- break;
- case QSPI_BUS_QUAD:
- _address_width = QSPI_CFG_BUS_QUAD;
- break;
- default:
- _address_width = QSPI_CFG_BUS_SINGLE;
- }
-
- switch(address_size) {
- case QSPI_ADDR_SIZE_8:
- _address_size = QSPI_CFG_ADDR_SIZE_8;
- break;
- case QSPI_ADDR_SIZE_16:
- _address_size = QSPI_CFG_ADDR_SIZE_16;
- break;
- case QSPI_ADDR_SIZE_24:
- _address_size = QSPI_CFG_ADDR_SIZE_24;
- break;
- case QSPI_ADDR_SIZE_32:
- _address_size = QSPI_CFG_ADDR_SIZE_32;
- break;
- default:
- _address_size = QSPI_CFG_ADDR_SIZE_8;
- }
-
- switch(alt_width) {
- case QSPI_BUS_SINGLE:
- _alt_width = QSPI_CFG_BUS_SINGLE;
- break;
- case QSPI_BUS_DUAL:
- _alt_width = QSPI_CFG_BUS_DUAL;
- break;
- case QSPI_BUS_QUAD:
- _alt_width = QSPI_CFG_BUS_QUAD;
- break;
- default:
- _alt_width = QSPI_CFG_BUS_SINGLE;
- }
-
- switch(alt_size) {
- case QSPI_ALT_SIZE_NONE:
- _alt_size = QSPI_CFG_ALT_SIZE_NONE;
- break;
- case QSPI_ALT_SIZE_8:
- _alt_size = QSPI_CFG_ALT_SIZE_8;
- break;
- case QSPI_ALT_SIZE_16:
- _alt_size = QSPI_CFG_ALT_SIZE_16;
- break;
- case QSPI_ALT_SIZE_24:
- _alt_size = QSPI_CFG_ALT_SIZE_24;
- break;
- case QSPI_ALT_SIZE_32:
- _alt_size = QSPI_CFG_ALT_SIZE_32;
- break;
- default:
- _alt_size = QSPI_CFG_ALT_SIZE_NONE;
- }
-
- switch(data_width) {
- case QSPI_BUS_SINGLE:
- _data_width = QSPI_CFG_BUS_SINGLE;
- break;
- case QSPI_BUS_DUAL:
- _data_width = QSPI_CFG_BUS_DUAL;
- break;
- case QSPI_BUS_QUAD:
- _data_width = QSPI_CFG_BUS_QUAD;
- break;
- default:
- _data_width = QSPI_CFG_BUS_SINGLE;
- }
-
+ _inst_width = inst_width;
+ _address_width = address_width;
+ _address_size = address_size;
+ _alt_width = alt_width;
+ _alt_size = alt_size;
+ _data_width = data_width;
_num_dummy_cycles = dummy_cycles;
_mode = mode;
unlock();
- return QSPI_SUCCESS;
+ return QSPI_STATUS_OK;
}
-qspi_return_status_t QSPI::set_frequency(int hz) {
- qspi_return_status_t ret_status = QSPI_SUCCESS;
+qspi_status_t QSPI::set_frequency(int hz) {
+ qspi_status_t ret_status = QSPI_STATUS_OK;
lock();
_hz = hz;
@@ -176,7 +88,7 @@ qspi_return_status_t QSPI::set_frequency(int hz) {
//Otherwise we may have to change mode as well, so call _acquire
if (_owner == this) {
if(QSPI_STATUS_OK != qspi_frequency(&_qspi, _hz)) {
- ret_status = QSPI_ERROR;
+ ret_status = QSPI_STATUS_ERROR;
}
} else {
_acquire();
@@ -186,16 +98,16 @@ qspi_return_status_t QSPI::set_frequency(int hz) {
return ret_status;
}
-qspi_return_status_t QSPI::initialize() {
+qspi_status_t QSPI::initialize() {
lock();
qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode );
unlock();
- return ( ret == QSPI_STATUS_OK )? QSPI_SUCCESS : QSPI_ERROR;
+ return ( ret == QSPI_STATUS_OK )? QSPI_STATUS_OK : QSPI_STATUS_ERROR;
}
-qspi_return_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_length) {
- qspi_return_status_t ret_status = QSPI_ERROR;
+qspi_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_length) {
+ qspi_status_t ret_status = QSPI_STATUS_ERROR;
if( (rx_length != NULL) && (rx_buffer != NULL) ) {
if(*rx_length != 0) {
@@ -203,20 +115,20 @@ qspi_return_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *r
if( true == _acquire()) {
qspi_command_t *qspi_cmd = _build_qspi_command(-1, address, -1);
if(QSPI_STATUS_OK == qspi_read(&_qspi, qspi_cmd, rx_buffer, rx_length)) {
- ret_status = QSPI_SUCCESS;
+ ret_status = QSPI_STATUS_OK;
}
}
unlock();
}
} else {
- ret_status = QSPI_INVALID_PARAMETER;
+ ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
return ret_status;
}
-qspi_return_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *tx_length) {
- qspi_return_status_t ret_status = QSPI_ERROR;
+qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *tx_length) {
+ qspi_status_t ret_status = QSPI_STATUS_ERROR;
if( (tx_length != NULL) && (tx_buffer != NULL) ) {
if(*tx_length != 0) {
@@ -224,20 +136,20 @@ qspi_return_status_t QSPI::write(unsigned int address, const char *tx_buffer, si
if(true == _acquire()) {
qspi_command_t *qspi_cmd = _build_qspi_command(-1, address, -1);
if(QSPI_STATUS_OK == qspi_write(&_qspi, qspi_cmd, tx_buffer, tx_length)) {
- ret_status = QSPI_SUCCESS;
+ ret_status = QSPI_STATUS_OK;
}
}
unlock();
}
} else {
- ret_status = QSPI_INVALID_PARAMETER;
+ ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
return ret_status;
}
-qspi_return_status_t QSPI::read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length) {
- qspi_return_status_t ret_status = QSPI_ERROR;
+qspi_status_t QSPI::read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length) {
+ qspi_status_t ret_status = QSPI_STATUS_ERROR;
if( (rx_length != NULL) && (rx_buffer != NULL) ) {
if(*rx_length != 0) {
@@ -245,20 +157,20 @@ qspi_return_status_t QSPI::read(unsigned int instruction, unsigned int address,
if( true == _acquire()) {
qspi_command_t *qspi_cmd = _build_qspi_command(instruction, address, alt);
if(QSPI_STATUS_OK == qspi_read(&_qspi, qspi_cmd, rx_buffer, rx_length)) {
- ret_status = QSPI_SUCCESS;
+ ret_status = QSPI_STATUS_OK;
}
}
unlock();
}
} else {
- ret_status = QSPI_INVALID_PARAMETER;
+ ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
return ret_status;
}
-qspi_return_status_t QSPI::write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length) {
- qspi_return_status_t ret_status = QSPI_ERROR;
+qspi_status_t QSPI::write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length) {
+ qspi_status_t ret_status = QSPI_STATUS_ERROR;
if( (tx_length != NULL) && (tx_buffer != NULL) ) {
if(*tx_length != 0) {
@@ -266,27 +178,27 @@ qspi_return_status_t QSPI::write(unsigned int instruction, unsigned int address,
if(true == _acquire()) {
qspi_command_t *qspi_cmd = _build_qspi_command(instruction, address, alt);
if(QSPI_STATUS_OK == qspi_write(&_qspi, qspi_cmd, tx_buffer, tx_length)) {
- ret_status = QSPI_SUCCESS;
+ ret_status = QSPI_STATUS_OK;
}
}
unlock();
}
} else {
- ret_status = QSPI_INVALID_PARAMETER;
+ ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
return ret_status;
}
-qspi_return_status_t QSPI::command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length) {
- qspi_return_status_t ret_status = QSPI_ERROR;
+qspi_status_t QSPI::command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length) {
+ qspi_status_t ret_status = QSPI_STATUS_ERROR;
lock();
if(true == _acquire()) {
qspi_command_t *qspi_cmd = _build_qspi_command(instruction, -1, -1); //We just need the command
if(QSPI_STATUS_OK == qspi_command_transfer(&_qspi, qspi_cmd, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
//We got error status, return 0
- ret_status = QSPI_SUCCESS;
+ ret_status = QSPI_STATUS_OK;
}
}
unlock();
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index f71bd106ad..7bc8f5744c 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -29,43 +29,6 @@
namespace mbed {
-// Config/Mode Defines
-/** QSPI Bus width Enum
- */
-typedef enum qspi_config_bus_width {
- QSPI_BUS_SINGLE,
- QSPI_BUS_DUAL,
- QSPI_BUS_QUAD,
-} qspi_config_bus_width_t;
-
-/** Address size Enum
- */
-typedef enum qspi_config_address_size {
- QSPI_ADDR_SIZE_NONE,
- QSPI_ADDR_SIZE_8,
- QSPI_ADDR_SIZE_16,
- QSPI_ADDR_SIZE_24,
- QSPI_ADDR_SIZE_32,
-} qspi_config_address_size_t;
-
-/** Alternative size Enum
- */
-typedef enum qspi_config_alt_size {
- QSPI_ALT_SIZE_NONE,
- QSPI_ALT_SIZE_8,
- QSPI_ALT_SIZE_16,
- QSPI_ALT_SIZE_24,
- QSPI_ALT_SIZE_32,
-} qspi_config_alt_size_t;
-
-/** QSPI Driver Return Status Enum
- */
-typedef enum qspi_return_status {
- QSPI_ERROR = -1, /**< Generic error >*/
- QSPI_INVALID_PARAMETER = -2, /**< The parameter is invalid >*/
- QSPI_SUCCESS = 0, /**< Function executed sucessfully >*/
-} qspi_return_status_t;
-
/** \addtogroup drivers */
/** A QSPI Driver, used for communicating with QSPI slave devices
@@ -128,12 +91,12 @@ public:
* @param mode Mode specifies the SPI mode(Mode=0 uses CPOL=0, CPHA=0, Mode=1 uses CPOL=1, CPHA=1)
*
*/
- qspi_return_status_t configure_format(qspi_config_bus_width_t inst_width,
- qspi_config_bus_width_t address_width,
- qspi_config_address_size_t address_size,
- qspi_config_bus_width_t alt_width,
- qspi_config_alt_size_t alt_size,
- qspi_config_bus_width_t data_width,
+ qspi_status_t configure_format(qspi_bus_width_t inst_width,
+ qspi_bus_width_t address_width,
+ qspi_address_size_t address_size,
+ qspi_bus_width_t alt_width,
+ qspi_alt_size_t alt_size,
+ qspi_bus_width_t data_width,
int dummy_cycles,
int mode);
@@ -141,16 +104,16 @@ public:
*
* This function must be called before doing any operation on the QSPI bus to initialize the interface
*/
- qspi_return_status_t initialize();
+ qspi_status_t initialize();
/** Set the qspi bus clock frequency
*
* @param hz SCLK frequency in hz (default = 1MHz)
* @returns
- * Returns QSPI_SUCCESS on successful, fails if the interface is already init-ed
+ * Returns QSPI_STATUS_SUCCESS on successful, fails if the interface is already init-ed
*/
- qspi_return_status_t set_frequency(int hz = ONE_MHZ);
+ qspi_status_t set_frequency(int hz = ONE_MHZ);
/** Read from QSPI peripheral with the preset read_instruction and alt_value
*
@@ -159,9 +122,9 @@ public:
* @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
*
* @returns
- * Returns QSPI_SUCCESS on successful reads and QSPI_ERROR on failed reads.
+ * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
- qspi_return_status_t read(unsigned int address, char *rx_buffer, size_t *rx_length);
+ qspi_status_t read(unsigned int address, char *rx_buffer, size_t *rx_length);
/** Write to QSPI peripheral with the preset write_instruction and alt_value
*
@@ -170,9 +133,9 @@ public:
* @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
*
* @returns
- * Returns QSPI_SUCCESS on successful reads and QSPI_ERROR on failed reads.
+ * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
- qspi_return_status_t write(unsigned int address, const char *tx_buffer, size_t *tx_length);
+ qspi_status_t write(unsigned int address, const char *tx_buffer, size_t *tx_length);
/** Read from QSPI peripheral using custom read instruction, alt values
*
@@ -183,9 +146,9 @@ public:
* @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
*
* @returns
- * Returns QSPI_SUCCESS on successful reads and QSPI_ERROR on failed reads.
+ * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
- qspi_return_status_t read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length);
+ qspi_status_t read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length);
/** Write to QSPI peripheral using custom write instruction, alt values
*
@@ -196,9 +159,9 @@ public:
* @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
*
* @returns
- * Returns QSPI_SUCCESS on successful reads and QSPI_ERROR on failed reads.
+ * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
- qspi_return_status_t write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length);
+ qspi_status_t write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length);
/** Perform a transaction to write to an address(a control register) and get the status results
*
@@ -209,9 +172,9 @@ public:
* @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
*
* @returns
- * Returns QSPI_SUCCESS on successful reads and QSPI_ERROR on failed reads.
+ * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
- qspi_return_status_t command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length);
+ qspi_status_t command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length);
/** Acquire exclusive access to this SPI bus
*/
From d9036865d8725e1ac3a2ffeaefbb8ee3b3f04faa Mon Sep 17 00:00:00 2001
From: Senthil Ramakrishnan
Date: Fri, 1 Dec 2017 14:32:42 -0600
Subject: [PATCH 14/78] Remove explicit initialize API and coding style fixes
---
drivers/QSPI.cpp | 252 ++++++++++++++++++++++++++---------------------
drivers/QSPI.h | 2 +
2 files changed, 141 insertions(+), 113 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index 451180f8cf..1f4b37f2ee 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -19,17 +19,13 @@
#if DEVICE_QSPI
-#define IS_BUS_WIDTH_VALID(width) ((width == QSPI_CFG_BUS_SINGLE) || (width == QSPI_CFG_BUS_DUAL) || (width == QSPI_CFG_BUS_QUAD))
-#define IS_SIZE_VALID(size) ((size == QSPI_CFG_ADDR_SIZE_NONE) || (size == QSPI_CFG_ADDR_SIZE_8) || (size == QSPI_CFG_ADDR_SIZE_16) || (size == QSPI_CFG_ADDR_SIZE_24) || (size == QSPI_CFG_ADDR_SIZE_32))
-#define IS_ALT_SIZE_VALID(alt_size) ((alt_size == QSPI_CFG_ALT_SIZE_NONE) || (alt_size == QSPI_CFG_ALT_SIZE_8) || (alt_size == QSPI_CFG_ALT_SIZE_16) || (alt_size == QSPI_CFG_ALT_SIZE_24) || (alt_size == QSPI_CFG_ALT_SIZE_32))
-
namespace mbed {
QSPI* QSPI::_owner = NULL;
SingletonPtr QSPI::_mutex;
-QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel) :
- _qspi() {
+QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel) : _qspi()
+{
_qspi_io0 = io0;
_qspi_io1 = io1;
_qspi_io2 = io2;
@@ -44,22 +40,18 @@ QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, Pin
_data_width = QSPI_CFG_BUS_SINGLE;
_num_dummy_cycles = 0;
_mode = 0;
- _hz = ONE_MHZ;
+ _hz = ONE_MHZ;
+ _initialized = false;
+
+ //Go ahead init the device here with the default config
+ _initialize();
+
}
-qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width_t address_width, qspi_address_size_t address_size, qspi_bus_width_t alt_width, qspi_alt_size_t alt_size, qspi_bus_width_t data_width, int dummy_cycles, int mode ) {
- if(!IS_BUS_WIDTH_VALID(inst_width))
- return QSPI_STATUS_INVALID_PARAMETER;
- if(!IS_BUS_WIDTH_VALID(address_width))
- return QSPI_STATUS_INVALID_PARAMETER;
- if(!IS_SIZE_VALID(address_size))
- return QSPI_STATUS_INVALID_PARAMETER;
- if(!IS_BUS_WIDTH_VALID(alt_width))
- return QSPI_STATUS_INVALID_PARAMETER;
- if(!IS_ALT_SIZE_VALID(alt_size))
- return QSPI_STATUS_INVALID_PARAMETER;
- if(!IS_BUS_WIDTH_VALID(data_width))
- return QSPI_STATUS_INVALID_PARAMETER;
+qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width_t address_width, qspi_address_size_t address_size, qspi_bus_width_t alt_width, qspi_alt_size_t alt_size, qspi_bus_width_t data_width, int dummy_cycles, int mode )
+{
+ qspi_status_t ret_status = QSPI_STATUS_OK;
+
if(dummy_cycles < 0)
return QSPI_STATUS_INVALID_PARAMETER;
if(mode != 0 && mode != 1)
@@ -74,161 +66,195 @@ qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width
_data_width = data_width;
_num_dummy_cycles = dummy_cycles;
_mode = mode;
+
+ //Re-init the device, as the mode might have changed
+ if( !_initialize() ) {
+ ret_status = QSPI_STATUS_ERROR;
+ }
unlock();
- return QSPI_STATUS_OK;
+ return ret_status;
}
-qspi_status_t QSPI::set_frequency(int hz) {
+qspi_status_t QSPI::set_frequency(int hz)
+{
qspi_status_t ret_status = QSPI_STATUS_OK;
- lock();
- _hz = hz;
- //If the same owner, just change freq.
- //Otherwise we may have to change mode as well, so call _acquire
- if (_owner == this) {
- if(QSPI_STATUS_OK != qspi_frequency(&_qspi, _hz)) {
- ret_status = QSPI_STATUS_ERROR;
- }
- } else {
- _acquire();
- }
- unlock();
-
- return ret_status;
-}
-
-qspi_status_t QSPI::initialize() {
- lock();
- qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode );
- unlock();
-
- return ( ret == QSPI_STATUS_OK )? QSPI_STATUS_OK : QSPI_STATUS_ERROR;
-}
-
-qspi_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_length) {
- qspi_status_t ret_status = QSPI_STATUS_ERROR;
-
- if( (rx_length != NULL) && (rx_buffer != NULL) ) {
- if(*rx_length != 0) {
- lock();
- if( true == _acquire()) {
- qspi_command_t *qspi_cmd = _build_qspi_command(-1, address, -1);
- if(QSPI_STATUS_OK == qspi_read(&_qspi, qspi_cmd, rx_buffer, rx_length)) {
- ret_status = QSPI_STATUS_OK;
- }
+ if(_initialized) {
+ lock();
+ _hz = hz;
+ //If the same owner, just change freq.
+ //Otherwise we may have to change mode as well, so call _acquire
+ if (_owner == this) {
+ if(QSPI_STATUS_OK != qspi_frequency(&_qspi, _hz)) {
+ ret_status = QSPI_STATUS_ERROR;
}
- unlock();
+ } else {
+ _acquire();
}
+ unlock();
} else {
- ret_status = QSPI_STATUS_INVALID_PARAMETER;
+ ret_status = QSPI_STATUS_ERROR;
}
return ret_status;
}
-qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *tx_length) {
+qspi_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_length)
+{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
- if( (tx_length != NULL) && (tx_buffer != NULL) ) {
- if(*tx_length != 0) {
- lock();
- if(true == _acquire()) {
- qspi_command_t *qspi_cmd = _build_qspi_command(-1, address, -1);
- if(QSPI_STATUS_OK == qspi_write(&_qspi, qspi_cmd, tx_buffer, tx_length)) {
- ret_status = QSPI_STATUS_OK;
+ if(_initialized) {
+ if( (rx_length != NULL) && (rx_buffer != NULL) ) {
+ if(*rx_length != 0) {
+ lock();
+ if( true == _acquire()) {
+ qspi_command_t *qspi_cmd = _build_qspi_command(-1, address, -1);
+ if(QSPI_STATUS_OK == qspi_read(&_qspi, qspi_cmd, rx_buffer, rx_length)) {
+ ret_status = QSPI_STATUS_OK;
+ }
}
+ unlock();
}
- unlock();
+ } else {
+ ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
- } else {
- ret_status = QSPI_STATUS_INVALID_PARAMETER;
- }
+ } //if(_initialized)
return ret_status;
}
-qspi_status_t QSPI::read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length) {
+qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *tx_length)
+{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
- if( (rx_length != NULL) && (rx_buffer != NULL) ) {
- if(*rx_length != 0) {
- lock();
- if( true == _acquire()) {
- qspi_command_t *qspi_cmd = _build_qspi_command(instruction, address, alt);
- if(QSPI_STATUS_OK == qspi_read(&_qspi, qspi_cmd, rx_buffer, rx_length)) {
- ret_status = QSPI_STATUS_OK;
+ if(_initialized)
+ {
+ if( (tx_length != NULL) && (tx_buffer != NULL) ) {
+ if(*tx_length != 0) {
+ lock();
+ if(true == _acquire()) {
+ qspi_command_t *qspi_cmd = _build_qspi_command(-1, address, -1);
+ if(QSPI_STATUS_OK == qspi_write(&_qspi, qspi_cmd, tx_buffer, tx_length)) {
+ ret_status = QSPI_STATUS_OK;
+ }
}
+ unlock();
}
- unlock();
+ } else {
+ ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
- } else {
- ret_status = QSPI_STATUS_INVALID_PARAMETER;
- }
+ } //if(_initialized)
return ret_status;
}
-qspi_status_t QSPI::write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length) {
+qspi_status_t QSPI::read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length)
+{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
- if( (tx_length != NULL) && (tx_buffer != NULL) ) {
- if(*tx_length != 0) {
- lock();
- if(true == _acquire()) {
- qspi_command_t *qspi_cmd = _build_qspi_command(instruction, address, alt);
- if(QSPI_STATUS_OK == qspi_write(&_qspi, qspi_cmd, tx_buffer, tx_length)) {
- ret_status = QSPI_STATUS_OK;
+ if(_initialized) {
+ if( (rx_length != NULL) && (rx_buffer != NULL) ) {
+ if(*rx_length != 0) {
+ lock();
+ if( true == _acquire()) {
+ qspi_command_t *qspi_cmd = _build_qspi_command(instruction, address, alt);
+ if(QSPI_STATUS_OK == qspi_read(&_qspi, qspi_cmd, rx_buffer, rx_length)) {
+ ret_status = QSPI_STATUS_OK;
+ }
}
+ unlock();
}
- unlock();
+ } else {
+ ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
- } else {
- ret_status = QSPI_STATUS_INVALID_PARAMETER;
- }
+ } //if(_initialized)
return ret_status;
}
-qspi_status_t QSPI::command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length) {
+qspi_status_t QSPI::write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length)
+{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
- lock();
- if(true == _acquire()) {
- qspi_command_t *qspi_cmd = _build_qspi_command(instruction, -1, -1); //We just need the command
- if(QSPI_STATUS_OK == qspi_command_transfer(&_qspi, qspi_cmd, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
- //We got error status, return 0
- ret_status = QSPI_STATUS_OK;
+ if(_initialized)
+ {
+ if( (tx_length != NULL) && (tx_buffer != NULL) ) {
+ if(*tx_length != 0) {
+ lock();
+ if(true == _acquire()) {
+ qspi_command_t *qspi_cmd = _build_qspi_command(instruction, address, alt);
+ if(QSPI_STATUS_OK == qspi_write(&_qspi, qspi_cmd, tx_buffer, tx_length)) {
+ ret_status = QSPI_STATUS_OK;
+ }
+ }
+ unlock();
+ }
+ } else {
+ ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
- }
- unlock();
+ } //if(_initialized)
return ret_status;
}
-void QSPI::lock() {
+qspi_status_t QSPI::command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length)
+{
+ qspi_status_t ret_status = QSPI_STATUS_ERROR;
+
+ if(_initialized)
+ {
+ lock();
+ if(true == _acquire()) {
+ qspi_command_t *qspi_cmd = _build_qspi_command(instruction, -1, -1); //We just need the command
+ if(QSPI_STATUS_OK == qspi_command_transfer(&_qspi, qspi_cmd, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
+ //We got error status, return 0
+ ret_status = QSPI_STATUS_OK;
+ }
+ }
+ unlock();
+ } //if(_initialized)
+
+ return ret_status;
+}
+
+void QSPI::lock()
+{
_mutex->lock();
}
-void QSPI::unlock() {
+void QSPI::unlock()
+{
_mutex->unlock();
}
-// Note: Private function with no locking
-bool QSPI::_acquire() {
- qspi_status_t ret = QSPI_STATUS_OK;
+// Note: Private helper function to initialize qspi HAL
+bool QSPI::_initialize()
+{
+ qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode );
+ if(QSPI_STATUS_OK == ret) {
+ _initialized = true;
+ } else {
+ _initialized = false;
+ }
+ return _initialized;
+}
+
+// Note: Private function with no locking
+bool QSPI::_acquire()
+{
if (_owner != this) {
//This will set freq as well
- ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode );
+ _initialize();
_owner = this;
}
- return ( ret == QSPI_STATUS_OK )? true:false;
+ return _initialized;
}
-qspi_command_t *QSPI::_build_qspi_command(int instruction, int address, int alt) {
-
+qspi_command_t *QSPI::_build_qspi_command(int instruction, int address, int alt)
+{
memset( &_qspi_command, 0, sizeof(qspi_command_t) );
//Set up instruction phase parameters
_qspi_command.instruction.bus_width = _inst_width;
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index 7bc8f5744c..4eb838a390 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -204,6 +204,7 @@ protected:
int _num_dummy_cycles; //Number of dummy cycles to be used
int _hz; //Bus Frequency
int _mode; //SPI mode
+ bool _initialized;
PinName _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs; //IO lines, clock and chip select
private:
@@ -211,6 +212,7 @@ private:
* Implemented in order to avoid duplicate locking and boost performance
*/
bool _acquire(void);
+ bool _initialize();
/*
* This function builds the qspi command struct to be send to Hal
From 04ec07c017238fbd5121b04e1f0eaf4f8a984c11 Mon Sep 17 00:00:00 2001
From: Senthil Ramakrishnan
Date: Fri, 1 Dec 2017 15:20:45 -0600
Subject: [PATCH 15/78] Fix bracket placements
---
drivers/QSPI.cpp | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index 1f4b37f2ee..816861ceac 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -128,8 +128,7 @@ qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *t
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
- if(_initialized)
- {
+ if(_initialized) {
if( (tx_length != NULL) && (tx_buffer != NULL) ) {
if(*tx_length != 0) {
lock();
@@ -177,8 +176,7 @@ qspi_status_t QSPI::write(unsigned int instruction, unsigned int address, unsign
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
- if(_initialized)
- {
+ if(_initialized) {
if( (tx_length != NULL) && (tx_buffer != NULL) ) {
if(*tx_length != 0) {
lock();
@@ -202,8 +200,7 @@ qspi_status_t QSPI::command_transfer(unsigned int instruction, const char *tx_bu
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
- if(_initialized)
- {
+ if(_initialized) {
lock();
if(true == _acquire()) {
qspi_command_t *qspi_cmd = _build_qspi_command(instruction, -1, -1); //We just need the command
From cb4308ad6476dc007e9b3c4c4a84951029ad491e Mon Sep 17 00:00:00 2001
From: Senthil Ramakrishnan
Date: Mon, 4 Dec 2017 13:05:54 -0600
Subject: [PATCH 16/78] Remove changes to Nordic SDK and modify HAL to track
qspi init
---
.../drivers_nrf/qspi/nrf_drv_qspi.c | 4 +-
targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c | 44 +++++++++++++------
2 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/qspi/nrf_drv_qspi.c b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/qspi/nrf_drv_qspi.c
index 6e8a6aae99..83287313a5 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/qspi/nrf_drv_qspi.c
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/drivers_nrf/qspi/nrf_drv_qspi.c
@@ -122,10 +122,10 @@ ret_code_t nrf_drv_qspi_init(nrf_drv_qspi_config_t const * p_config,
nrf_drv_qspi_handler_t handler,
void * p_context)
{
- /*if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED)
+ if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED)
{
return NRF_ERROR_INVALID_STATE;
- }*/
+ }
if (!qspi_pins_configure(&p_config->pins))
{
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
index 63f07e109b..849970a093 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
@@ -58,6 +58,9 @@ TODO
static nrf_drv_qspi_config_t config;
+// Private helper function to track initialization
+static ret_code_t _qspi_drv_init(void);
+
qspi_status_t qspi_prepare_command(qspi_t *obj, const qspi_command_t *command, bool write)
{
//Use custom command if provided by the caller
@@ -136,7 +139,7 @@ qspi_status_t qspi_prepare_command(qspi_t *obj, const qspi_command_t *command, b
//Configure QSPI with new command format
if(ret == QSPI_STATUS_OK) {
- ret_code_t ret_status = nrf_drv_qspi_init(&config, NULL , NULL);
+ ret_code_t ret_status = _qspi_drv_init();
if (ret_status != NRF_SUCCESS ) {
if (ret_status == NRF_ERROR_INVALID_PARAM) {
return QSPI_STATUS_INVALID_PARAMETER;
@@ -171,7 +174,8 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
config.phy_if.dpmen = false;
config.phy_if.spi_mode = mode == 0 ? NRF_QSPI_MODE_0 : NRF_QSPI_MODE_1;
- ret_code_t ret = nrf_drv_qspi_init(&config, NULL , NULL);
+ //Use _qspi_drv_init private function to initialize
+ ret_code_t ret = _qspi_drv_init();
if (ret == NRF_SUCCESS ) {
return QSPI_STATUS_OK;
} else if (ret == NRF_ERROR_INVALID_PARAM) {
@@ -191,8 +195,9 @@ qspi_status_t qspi_free(qspi_t *obj)
qspi_status_t qspi_frequency(qspi_t *obj, int hz)
{
config.phy_if.sck_freq = (nrf_qspi_frequency_t)MBED_HAL_QSPI_HZ_TO_CONFIG(hz);
+
// use sync version, no handler
- ret_code_t ret = nrf_drv_qspi_init(&config, NULL , NULL);
+ ret_code_t ret = _qspi_drv_init();
if (ret == NRF_SUCCESS ) {
return QSPI_STATUS_OK;
} else if (ret == NRF_ERROR_INVALID_PARAM) {
@@ -247,30 +252,24 @@ qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command,
qspi_cinstr_config.wipwait = false;
qspi_cinstr_config.wren = false;
- if (data_size < 9)
- {
+ if (data_size < 9) {
qspi_cinstr_config.length = (nrf_qspi_cinstr_len_t)(NRF_QSPI_CINSTR_LEN_1B + data_size);
- }
- else
- {
+ } else {
return QSPI_STATUS_ERROR;
}
// preparing data to send
- for (i = 0; i < tx_size; ++i)
- {
+ for (i = 0; i < tx_size; ++i) {
data[i] = ((uint8_t *)tx_data)[i];
}
ret_code = nrf_drv_qspi_cinstr_xfer(&qspi_cinstr_config, data, data);
- if (ret_code != NRF_SUCCESS)
- {
+ if (ret_code != NRF_SUCCESS) {
return QSPI_STATUS_ERROR;
}
// preparing received data
- for (i = 0; i < rx_size; ++i)
- {
+ for (i = 0; i < rx_size; ++i) {
// Data is sending as a normal SPI transmission so there is one buffer to send and receive data.
((uint8_t *)rx_data)[i] = data[i];
}
@@ -278,6 +277,23 @@ qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command,
return QSPI_STATUS_OK;
}
+// Private helper function to track initialization
+static ret_code_t _qspi_drv_init(void)
+{
+ static bool _initialized = false;
+ ret_code_t ret = NRF_ERROR_INVALID_STATE;
+
+ if(_initialized) {
+ //NRF implementation prevents calling init again. But we need to call init again to program the new command settings in the IFCONFIG registers.
+ //So, we have to uninit qspi first and call init again.
+ nrf_drv_qspi_uninit();
+ }
+ ret = nrf_drv_qspi_init(&config, NULL , NULL);
+ if( ret == NRF_SUCCESS )
+ _initialized = true;
+ return ret;
+}
+
#endif
From 273cf05d92223b37c7cd3ce0606da465753ae86d Mon Sep 17 00:00:00 2001
From: Senthil Ramakrishnan
Date: Mon, 4 Dec 2017 13:06:39 -0600
Subject: [PATCH 17/78] Minor optimizations and code style fixes
---
drivers/QSPI.cpp | 14 +++++---------
drivers/QSPI.h | 2 +-
2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index 816861ceac..1d31d4365d 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -52,8 +52,6 @@ qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width
{
qspi_status_t ret_status = QSPI_STATUS_OK;
- if(dummy_cycles < 0)
- return QSPI_STATUS_INVALID_PARAMETER;
if(mode != 0 && mode != 1)
return QSPI_STATUS_INVALID_PARAMETER;
@@ -119,7 +117,7 @@ qspi_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_lengt
} else {
ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
- } //if(_initialized)
+ }
return ret_status;
}
@@ -143,7 +141,7 @@ qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *t
} else {
ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
- } //if(_initialized)
+ }
return ret_status;
}
@@ -167,7 +165,7 @@ qspi_status_t QSPI::read(unsigned int instruction, unsigned int address, unsigne
} else {
ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
- } //if(_initialized)
+ }
return ret_status;
}
@@ -191,7 +189,7 @@ qspi_status_t QSPI::write(unsigned int instruction, unsigned int address, unsign
} else {
ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
- } //if(_initialized)
+ }
return ret_status;
}
@@ -205,12 +203,11 @@ qspi_status_t QSPI::command_transfer(unsigned int instruction, const char *tx_bu
if(true == _acquire()) {
qspi_command_t *qspi_cmd = _build_qspi_command(instruction, -1, -1); //We just need the command
if(QSPI_STATUS_OK == qspi_command_transfer(&_qspi, qspi_cmd, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
- //We got error status, return 0
ret_status = QSPI_STATUS_OK;
}
}
unlock();
- } //if(_initialized)
+ }
return ret_status;
}
@@ -280,7 +277,6 @@ qspi_command_t *QSPI::_build_qspi_command(int instruction, int address, int alt)
_qspi_command.alt.value = 0;
}
- //Set up dummy cycle count
_qspi_command.dummy_count = _num_dummy_cycles;
//Set up bus width for data phase
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index 4eb838a390..e4b1b18256 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -201,7 +201,7 @@ protected:
qspi_alt_size_t _alt_size;
qspi_bus_width_t _data_width; //Bus width for Data phase
qspi_command_t _qspi_command; //QSPI Hal command struct
- int _num_dummy_cycles; //Number of dummy cycles to be used
+ unsigned int _num_dummy_cycles; //Number of dummy cycles to be used
int _hz; //Bus Frequency
int _mode; //SPI mode
bool _initialized;
From 894f8bdf9f93868990b0b60ce43de3680cd1610c Mon Sep 17 00:00:00 2001
From: Senthil Ramakrishnan
Date: Mon, 4 Dec 2017 14:12:01 -0600
Subject: [PATCH 18/78] Review fixes
---
drivers/QSPI.cpp | 24 +++++++++++-------------
drivers/QSPI.h | 2 +-
2 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index 1d31d4365d..3d1eee970a 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -107,8 +107,8 @@ qspi_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_lengt
if(*rx_length != 0) {
lock();
if( true == _acquire()) {
- qspi_command_t *qspi_cmd = _build_qspi_command(-1, address, -1);
- if(QSPI_STATUS_OK == qspi_read(&_qspi, qspi_cmd, rx_buffer, rx_length)) {
+ _build_qspi_command(-1, address, -1);
+ if(QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
}
@@ -131,8 +131,8 @@ qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *t
if(*tx_length != 0) {
lock();
if(true == _acquire()) {
- qspi_command_t *qspi_cmd = _build_qspi_command(-1, address, -1);
- if(QSPI_STATUS_OK == qspi_write(&_qspi, qspi_cmd, tx_buffer, tx_length)) {
+ _build_qspi_command(-1, address, -1);
+ if(QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
ret_status = QSPI_STATUS_OK;
}
}
@@ -155,8 +155,8 @@ qspi_status_t QSPI::read(unsigned int instruction, unsigned int address, unsigne
if(*rx_length != 0) {
lock();
if( true == _acquire()) {
- qspi_command_t *qspi_cmd = _build_qspi_command(instruction, address, alt);
- if(QSPI_STATUS_OK == qspi_read(&_qspi, qspi_cmd, rx_buffer, rx_length)) {
+ _build_qspi_command(instruction, address, alt);
+ if(QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
}
@@ -179,8 +179,8 @@ qspi_status_t QSPI::write(unsigned int instruction, unsigned int address, unsign
if(*tx_length != 0) {
lock();
if(true == _acquire()) {
- qspi_command_t *qspi_cmd = _build_qspi_command(instruction, address, alt);
- if(QSPI_STATUS_OK == qspi_write(&_qspi, qspi_cmd, tx_buffer, tx_length)) {
+ _build_qspi_command(instruction, address, alt);
+ if(QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
ret_status = QSPI_STATUS_OK;
}
}
@@ -201,8 +201,8 @@ qspi_status_t QSPI::command_transfer(unsigned int instruction, const char *tx_bu
if(_initialized) {
lock();
if(true == _acquire()) {
- qspi_command_t *qspi_cmd = _build_qspi_command(instruction, -1, -1); //We just need the command
- if(QSPI_STATUS_OK == qspi_command_transfer(&_qspi, qspi_cmd, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
+ _build_qspi_command(instruction, -1, -1); //We just need the command
+ if(QSPI_STATUS_OK == qspi_command_transfer(&_qspi, &_qspi_command, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
}
@@ -247,7 +247,7 @@ bool QSPI::_acquire()
return _initialized;
}
-qspi_command_t *QSPI::_build_qspi_command(int instruction, int address, int alt)
+void QSPI::_build_qspi_command(int instruction, int address, int alt)
{
memset( &_qspi_command, 0, sizeof(qspi_command_t) );
//Set up instruction phase parameters
@@ -281,8 +281,6 @@ qspi_command_t *QSPI::_build_qspi_command(int instruction, int address, int alt)
//Set up bus width for data phase
_qspi_command.data.bus_width = _data_width;
-
- return &_qspi_command;
}
} // namespace mbed
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index e4b1b18256..5962f2ed1e 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -217,7 +217,7 @@ private:
/*
* This function builds the qspi command struct to be send to Hal
*/
- inline qspi_command_t *_build_qspi_command(int instruction, int address, int alt);
+ inline void _build_qspi_command(int instruction, int address, int alt);
};
} // namespace mbed
From 6274cd4597cfff3f44e11917ba1bf7d34abbf985 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 5 Dec 2017 14:17:29 +0000
Subject: [PATCH 19/78] QSPI: fix address size for build qspi command
if address is skipped, used size NONE
---
drivers/QSPI.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index 3d1eee970a..df4bbca2a5 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -264,7 +264,7 @@ void QSPI::_build_qspi_command(int instruction, int address, int alt)
if(address != -1) {
_qspi_command.address.value = address;
} else {
- _qspi_command.address.value = 0;
+ _qspi_command.address.size = QSPI_CFG_ADDR_SIZE_NONE;
}
//Set up alt phase parameters
From 0612ab2292fccff0c3b7edecfc6bf8db328f33ef Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 5 Dec 2017 14:18:12 +0000
Subject: [PATCH 20/78] QSPI: remove initialize method
Not used anymore, not defined. ctor default initializes the object
---
drivers/QSPI.h | 7 -------
1 file changed, 7 deletions(-)
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index 5962f2ed1e..182ec45f0e 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -100,13 +100,6 @@ public:
int dummy_cycles,
int mode);
- /** Initialize QSPI interface
- *
- * This function must be called before doing any operation on the QSPI bus to initialize the interface
- */
- qspi_status_t initialize();
-
-
/** Set the qspi bus clock frequency
*
* @param hz SCLK frequency in hz (default = 1MHz)
From 1557ce37f169c37d84ca5efc9642976b02741caa Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 5 Dec 2017 14:21:22 +0000
Subject: [PATCH 21/78] QSPI: remove spaces on empty lines
---
drivers/QSPI.cpp | 86 +++++++++++++++++++++++-------------------------
drivers/QSPI.h | 18 +++++-----
2 files changed, 51 insertions(+), 53 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index df4bbca2a5..3c5adcc587 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -22,7 +22,7 @@
namespace mbed {
QSPI* QSPI::_owner = NULL;
-SingletonPtr QSPI::_mutex;
+SingletonPtr QSPI::_mutex;
QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel) : _qspi()
{
@@ -42,42 +42,40 @@ QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, Pin
_mode = 0;
_hz = ONE_MHZ;
_initialized = false;
-
+
//Go ahead init the device here with the default config
_initialize();
-
}
-
+
qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width_t address_width, qspi_address_size_t address_size, qspi_bus_width_t alt_width, qspi_alt_size_t alt_size, qspi_bus_width_t data_width, int dummy_cycles, int mode )
-{
- qspi_status_t ret_status = QSPI_STATUS_OK;
-
+{ qspi_status_t ret_status = QSPI_STATUS_OK;
+
if(mode != 0 && mode != 1)
- return QSPI_STATUS_INVALID_PARAMETER;
-
+ return QSPI_STATUS_INVALID_PARAMETER;
+
lock();
_inst_width = inst_width;
_address_width = address_width;
_address_size = address_size;
_alt_width = alt_width;
_alt_size = alt_size;
- _data_width = data_width;
+ _data_width = data_width;
_num_dummy_cycles = dummy_cycles;
_mode = mode;
-
+
//Re-init the device, as the mode might have changed
if( !_initialize() ) {
ret_status = QSPI_STATUS_ERROR;
}
unlock();
-
+
return ret_status;
}
qspi_status_t QSPI::set_frequency(int hz)
{
- qspi_status_t ret_status = QSPI_STATUS_OK;
-
+ qspi_status_t ret_status = QSPI_STATUS_OK;
+
if(_initialized) {
lock();
_hz = hz;
@@ -92,16 +90,16 @@ qspi_status_t QSPI::set_frequency(int hz)
}
unlock();
} else {
- ret_status = QSPI_STATUS_ERROR;
+ ret_status = QSPI_STATUS_ERROR;
}
-
+
return ret_status;
}
qspi_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_length)
{
- qspi_status_t ret_status = QSPI_STATUS_ERROR;
-
+ qspi_status_t ret_status = QSPI_STATUS_ERROR;
+
if(_initialized) {
if( (rx_length != NULL) && (rx_buffer != NULL) ) {
if(*rx_length != 0) {
@@ -109,22 +107,22 @@ qspi_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_lengt
if( true == _acquire()) {
_build_qspi_command(-1, address, -1);
if(QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
- ret_status = QSPI_STATUS_OK;
+ ret_status = QSPI_STATUS_OK;
}
}
unlock();
}
} else {
- ret_status = QSPI_STATUS_INVALID_PARAMETER;
+ ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
}
-
+
return ret_status;
}
qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *tx_length)
{
- qspi_status_t ret_status = QSPI_STATUS_ERROR;
+ qspi_status_t ret_status = QSPI_STATUS_ERROR;
if(_initialized) {
if( (tx_length != NULL) && (tx_buffer != NULL) ) {
@@ -133,23 +131,23 @@ qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *t
if(true == _acquire()) {
_build_qspi_command(-1, address, -1);
if(QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
- ret_status = QSPI_STATUS_OK;
+ ret_status = QSPI_STATUS_OK;
}
}
unlock();
}
} else {
- ret_status = QSPI_STATUS_INVALID_PARAMETER;
+ ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
}
-
+
return ret_status;
}
qspi_status_t QSPI::read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length)
{
- qspi_status_t ret_status = QSPI_STATUS_ERROR;
-
+ qspi_status_t ret_status = QSPI_STATUS_ERROR;
+
if(_initialized) {
if( (rx_length != NULL) && (rx_buffer != NULL) ) {
if(*rx_length != 0) {
@@ -157,13 +155,13 @@ qspi_status_t QSPI::read(unsigned int instruction, unsigned int address, unsigne
if( true == _acquire()) {
_build_qspi_command(instruction, address, alt);
if(QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
- ret_status = QSPI_STATUS_OK;
+ ret_status = QSPI_STATUS_OK;
}
}
unlock();
}
} else {
- ret_status = QSPI_STATUS_INVALID_PARAMETER;
+ ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
}
@@ -172,7 +170,7 @@ qspi_status_t QSPI::read(unsigned int instruction, unsigned int address, unsigne
qspi_status_t QSPI::write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length)
{
- qspi_status_t ret_status = QSPI_STATUS_ERROR;
+ qspi_status_t ret_status = QSPI_STATUS_ERROR;
if(_initialized) {
if( (tx_length != NULL) && (tx_buffer != NULL) ) {
@@ -181,13 +179,13 @@ qspi_status_t QSPI::write(unsigned int instruction, unsigned int address, unsign
if(true == _acquire()) {
_build_qspi_command(instruction, address, alt);
if(QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
- ret_status = QSPI_STATUS_OK;
+ ret_status = QSPI_STATUS_OK;
}
}
unlock();
}
} else {
- ret_status = QSPI_STATUS_INVALID_PARAMETER;
+ ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
}
@@ -196,14 +194,14 @@ qspi_status_t QSPI::write(unsigned int instruction, unsigned int address, unsign
qspi_status_t QSPI::command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length)
{
- qspi_status_t ret_status = QSPI_STATUS_ERROR;
+ qspi_status_t ret_status = QSPI_STATUS_ERROR;
if(_initialized) {
lock();
if(true == _acquire()) {
_build_qspi_command(instruction, -1, -1); //We just need the command
if(QSPI_STATUS_OK == qspi_command_transfer(&_qspi, &_qspi_command, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
- ret_status = QSPI_STATUS_OK;
+ ret_status = QSPI_STATUS_OK;
}
}
unlock();
@@ -251,34 +249,34 @@ void QSPI::_build_qspi_command(int instruction, int address, int alt)
{
memset( &_qspi_command, 0, sizeof(qspi_command_t) );
//Set up instruction phase parameters
- _qspi_command.instruction.bus_width = _inst_width;
+ _qspi_command.instruction.bus_width = _inst_width;
if(instruction != -1) {
- _qspi_command.instruction.value = instruction;
+ _qspi_command.instruction.value = instruction;
} else {
- _qspi_command.instruction.value = 0;
+ _qspi_command.instruction.value = 0;
}
-
+
//Set up address phase parameters
_qspi_command.address.bus_width = _address_width;
_qspi_command.address.size = _address_size;
if(address != -1) {
- _qspi_command.address.value = address;
+ _qspi_command.address.value = address;
} else {
_qspi_command.address.size = QSPI_CFG_ADDR_SIZE_NONE;
}
-
+
//Set up alt phase parameters
- _qspi_command.alt.bus_width = _alt_width;
+ _qspi_command.alt.bus_width = _alt_width;
_qspi_command.alt.size = _alt_size;
if(alt != -1) {
- _qspi_command.alt.value = alt;
+ _qspi_command.alt.value = alt;
} else {
//In the case alt phase is absent, set the alt size to be NONE
- _qspi_command.alt.value = 0;
+ _qspi_command.alt.value = 0;
}
_qspi_command.dummy_count = _num_dummy_cycles;
-
+
//Set up bus width for data phase
_qspi_command.data.bus_width = _data_width;
}
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index 182ec45f0e..ecc2cbb8e3 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -65,7 +65,7 @@ namespace mbed {
class QSPI : private NonCopyable {
public:
-
+
/** Create a QSPI master connected to the specified pins
*
* io0-io3 is used to specify the Pins used for Quad SPI mode
@@ -96,7 +96,7 @@ public:
qspi_address_size_t address_size,
qspi_bus_width_t alt_width,
qspi_alt_size_t alt_size,
- qspi_bus_width_t data_width,
+ qspi_bus_width_t data_width,
int dummy_cycles,
int mode);
@@ -117,8 +117,8 @@ public:
* @returns
* Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
- qspi_status_t read(unsigned int address, char *rx_buffer, size_t *rx_length);
-
+ qspi_status_t read(unsigned int address, char *rx_buffer, size_t *rx_length);
+
/** Write to QSPI peripheral with the preset write_instruction and alt_value
*
* @param address Address to be accessed in QSPI peripheral
@@ -129,7 +129,7 @@ public:
* Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
qspi_status_t write(unsigned int address, const char *tx_buffer, size_t *tx_length);
-
+
/** Read from QSPI peripheral using custom read instruction, alt values
*
* @param instruction Instruction value to be used in instruction phase
@@ -142,7 +142,7 @@ public:
* Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
qspi_status_t read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length);
-
+
/** Write to QSPI peripheral using custom write instruction, alt values
*
* @param instruction Instruction value to be used in instruction phase
@@ -155,7 +155,7 @@ public:
* Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
qspi_status_t write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length);
-
+
/** Perform a transaction to write to an address(a control register) and get the status results
*
* @param instruction Instruction value to be used in instruction phase
@@ -168,7 +168,7 @@ public:
* Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
qspi_status_t command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length);
-
+
/** Acquire exclusive access to this SPI bus
*/
virtual void lock(void);
@@ -199,7 +199,7 @@ protected:
int _mode; //SPI mode
bool _initialized;
PinName _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs; //IO lines, clock and chip select
-
+
private:
/* Private acquire function without locking/unlocking
* Implemented in order to avoid duplicate locking and boost performance
From 1d234aade466ce57f756f5b0f6062994a4685b96 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 5 Dec 2017 14:47:53 +0000
Subject: [PATCH 22/78] QSPI HAL: fix alternative comment
---
hal/qspi_api.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hal/qspi_api.h b/hal/qspi_api.h
index 8982aea502..80c1ff0ceb 100644
--- a/hal/qspi_api.h
+++ b/hal/qspi_api.h
@@ -83,7 +83,7 @@ typedef struct qspi_command {
struct {
qspi_bus_width_t bus_width; /**< Bus width for alternative >*/
qspi_alt_size_t size; /**< Alternative size >*/
- uint32_t value; /**< Alternative, 0 - disabled, non-zero defined value used >*/
+ uint32_t value; /**< Alternative value >*/
} alt;
uint8_t dummy_count; /**< Dummy cycles count >*/
struct {
From 3db336482140ed39470c5be1a6342c8295b95ee0 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Wed, 6 Dec 2017 13:12:59 +0000
Subject: [PATCH 23/78] QSPI: fix arguments for write/read when alt is defined
Should be: instr, alt, address or inst, addr or just addr
---
drivers/QSPI.cpp | 4 ++--
drivers/QSPI.h | 10 +++++-----
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index 3c5adcc587..2f111e27eb 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -144,7 +144,7 @@ qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *t
return ret_status;
}
-qspi_status_t QSPI::read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length)
+qspi_status_t QSPI::read(unsigned int instruction, unsigned int alt, unsigned int address, char *rx_buffer, size_t *rx_length)
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
@@ -168,7 +168,7 @@ qspi_status_t QSPI::read(unsigned int instruction, unsigned int address, unsigne
return ret_status;
}
-qspi_status_t QSPI::write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length)
+qspi_status_t QSPI::write(unsigned int instruction, unsigned int alt, unsigned int address, const char *tx_buffer, size_t *tx_length)
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index ecc2cbb8e3..33039475fb 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -119,7 +119,7 @@ public:
*/
qspi_status_t read(unsigned int address, char *rx_buffer, size_t *rx_length);
- /** Write to QSPI peripheral with the preset write_instruction and alt_value
+ /** Write to QSPI peripheral using custom write instruction
*
* @param address Address to be accessed in QSPI peripheral
* @param tx_buffer Buffer containing data to be sent to peripheral
@@ -133,28 +133,28 @@ public:
/** Read from QSPI peripheral using custom read instruction, alt values
*
* @param instruction Instruction value to be used in instruction phase
- * @param address Address to be accessed in QSPI peripheral
* @param alt Alt value to be used in instruction phase
+ * @param address Address to be accessed in QSPI peripheral
* @param rx_buffer Buffer for data to be read from the peripheral
* @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
*
* @returns
* Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
- qspi_status_t read(unsigned int instruction, unsigned int address, unsigned int alt, char *rx_buffer, size_t *rx_length);
+ qspi_status_t read(unsigned int instruction, unsigned int alt, unsigned int address, char *rx_buffer, size_t *rx_length);
/** Write to QSPI peripheral using custom write instruction, alt values
*
* @param instruction Instruction value to be used in instruction phase
- * @param address Address to be accessed in QSPI peripheral
* @param alt Alt value to be used in instruction phase
+ * @param address Address to be accessed in QSPI peripheral
* @param tx_buffer Buffer containing data to be sent to peripheral
* @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
*
* @returns
* Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
- qspi_status_t write(unsigned int instruction, unsigned int address, unsigned int alt, const char *tx_buffer, size_t *tx_length);
+ qspi_status_t write(unsigned int instruction, unsigned int alt, unsigned int address, const char *tx_buffer, size_t *tx_length);
/** Perform a transaction to write to an address(a control register) and get the status results
*
From 910f1a8884938f9938021178be2a61f89489ea7b Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Wed, 6 Dec 2017 13:15:24 +0000
Subject: [PATCH 24/78] QSPI: fix driver style issues
---
drivers/QSPI.cpp | 67 ++++++++++++++++++++++++------------------------
1 file changed, 34 insertions(+), 33 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index 2f111e27eb..c30dea57ab 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -23,7 +23,7 @@ namespace mbed {
QSPI* QSPI::_owner = NULL;
SingletonPtr QSPI::_mutex;
-
+
QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel) : _qspi()
{
_qspi_io0 = io0;
@@ -48,9 +48,10 @@ QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, Pin
}
qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width_t address_width, qspi_address_size_t address_size, qspi_bus_width_t alt_width, qspi_alt_size_t alt_size, qspi_bus_width_t data_width, int dummy_cycles, int mode )
-{ qspi_status_t ret_status = QSPI_STATUS_OK;
+{
+ qspi_status_t ret_status = QSPI_STATUS_OK;
- if(mode != 0 && mode != 1)
+ if (mode != 0 && mode != 1)
return QSPI_STATUS_INVALID_PARAMETER;
lock();
@@ -64,7 +65,7 @@ qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width
_mode = mode;
//Re-init the device, as the mode might have changed
- if( !_initialize() ) {
+ if ( !_initialize() ) {
ret_status = QSPI_STATUS_ERROR;
}
unlock();
@@ -76,13 +77,13 @@ qspi_status_t QSPI::set_frequency(int hz)
{
qspi_status_t ret_status = QSPI_STATUS_OK;
- if(_initialized) {
+ if (_initialized) {
lock();
_hz = hz;
//If the same owner, just change freq.
//Otherwise we may have to change mode as well, so call _acquire
if (_owner == this) {
- if(QSPI_STATUS_OK != qspi_frequency(&_qspi, _hz)) {
+ if (QSPI_STATUS_OK != qspi_frequency(&_qspi, _hz)) {
ret_status = QSPI_STATUS_ERROR;
}
} else {
@@ -100,13 +101,13 @@ qspi_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_lengt
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
- if(_initialized) {
- if( (rx_length != NULL) && (rx_buffer != NULL) ) {
- if(*rx_length != 0) {
+ if (_initialized) {
+ if ((rx_length != NULL) && (rx_buffer != NULL)) {
+ if (*rx_length != 0) {
lock();
- if( true == _acquire()) {
+ if (true == _acquire()) {
_build_qspi_command(-1, address, -1);
- if(QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
+ if (QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
}
@@ -124,13 +125,13 @@ qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *t
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
- if(_initialized) {
- if( (tx_length != NULL) && (tx_buffer != NULL) ) {
- if(*tx_length != 0) {
+ if (_initialized) {
+ if ((tx_length != NULL) && (tx_buffer != NULL)) {
+ if (*tx_length != 0) {
lock();
- if(true == _acquire()) {
+ if (true == _acquire()) {
_build_qspi_command(-1, address, -1);
- if(QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
+ if (QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
ret_status = QSPI_STATUS_OK;
}
}
@@ -148,13 +149,13 @@ qspi_status_t QSPI::read(unsigned int instruction, unsigned int alt, unsigned in
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
- if(_initialized) {
- if( (rx_length != NULL) && (rx_buffer != NULL) ) {
- if(*rx_length != 0) {
+ if (_initialized) {
+ if ( (rx_length != NULL) && (rx_buffer != NULL) ) {
+ if (*rx_length != 0) {
lock();
- if( true == _acquire()) {
+ if ( true == _acquire()) {
_build_qspi_command(instruction, address, alt);
- if(QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
+ if (QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
}
@@ -172,13 +173,13 @@ qspi_status_t QSPI::write(unsigned int instruction, unsigned int alt, unsigned i
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
- if(_initialized) {
- if( (tx_length != NULL) && (tx_buffer != NULL) ) {
- if(*tx_length != 0) {
+ if (_initialized) {
+ if ( (tx_length != NULL) && (tx_buffer != NULL) ) {
+ if (*tx_length != 0) {
lock();
- if(true == _acquire()) {
+ if (true == _acquire()) {
_build_qspi_command(instruction, address, alt);
- if(QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
+ if (QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
ret_status = QSPI_STATUS_OK;
}
}
@@ -196,11 +197,11 @@ qspi_status_t QSPI::command_transfer(unsigned int instruction, const char *tx_bu
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
- if(_initialized) {
+ if (_initialized) {
lock();
- if(true == _acquire()) {
+ if (true == _acquire()) {
_build_qspi_command(instruction, -1, -1); //We just need the command
- if(QSPI_STATUS_OK == qspi_command_transfer(&_qspi, &_qspi_command, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
+ if (QSPI_STATUS_OK == qspi_command_transfer(&_qspi, &_qspi_command, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
}
@@ -224,7 +225,7 @@ void QSPI::unlock()
bool QSPI::_initialize()
{
qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode );
- if(QSPI_STATUS_OK == ret) {
+ if (QSPI_STATUS_OK == ret) {
_initialized = true;
} else {
_initialized = false;
@@ -250,7 +251,7 @@ void QSPI::_build_qspi_command(int instruction, int address, int alt)
memset( &_qspi_command, 0, sizeof(qspi_command_t) );
//Set up instruction phase parameters
_qspi_command.instruction.bus_width = _inst_width;
- if(instruction != -1) {
+ if (instruction != -1) {
_qspi_command.instruction.value = instruction;
} else {
_qspi_command.instruction.value = 0;
@@ -259,7 +260,7 @@ void QSPI::_build_qspi_command(int instruction, int address, int alt)
//Set up address phase parameters
_qspi_command.address.bus_width = _address_width;
_qspi_command.address.size = _address_size;
- if(address != -1) {
+ if (address != -1) {
_qspi_command.address.value = address;
} else {
_qspi_command.address.size = QSPI_CFG_ADDR_SIZE_NONE;
@@ -268,7 +269,7 @@ void QSPI::_build_qspi_command(int instruction, int address, int alt)
//Set up alt phase parameters
_qspi_command.alt.bus_width = _alt_width;
_qspi_command.alt.size = _alt_size;
- if(alt != -1) {
+ if (alt != -1) {
_qspi_command.alt.value = alt;
} else {
//In the case alt phase is absent, set the alt size to be NONE
From b71f2a15eaf7b8ceddca7cec609e16c846c01724 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Wed, 6 Dec 2017 13:16:09 +0000
Subject: [PATCH 25/78] QSPI: fix alt size NONE instead 0
---
drivers/QSPI.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index c30dea57ab..a4a11a1ec3 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -273,7 +273,7 @@ void QSPI::_build_qspi_command(int instruction, int address, int alt)
_qspi_command.alt.value = alt;
} else {
//In the case alt phase is absent, set the alt size to be NONE
- _qspi_command.alt.value = 0;
+ _qspi_command.alt.size = QSPI_CFG_ALT_SIZE_NONE;
}
_qspi_command.dummy_count = _num_dummy_cycles;
From 784c473f63db474add90bc02841073c8ea8fdea0 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Thu, 23 Nov 2017 09:24:31 +0000
Subject: [PATCH 26/78] QSPI HAL: add disabled flag to format phase
If phase is being skipped, set disabled to true, otherwise false.
---
drivers/QSPI.cpp | 12 +++++++-----
drivers/QSPI.h | 4 ++--
hal/qspi_api.h | 6 ++++--
3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index a4a11a1ec3..f2e19b8af8 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -36,7 +36,7 @@ QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, Pin
_address_width = QSPI_CFG_BUS_SINGLE;
_address_size = QSPI_CFG_ADDR_SIZE_24;
_alt_width = QSPI_CFG_BUS_SINGLE;
- _alt_size = QSPI_CFG_ALT_SIZE_NONE;
+ _alt_size = QSPI_CFG_ALT_SIZE_8;
_data_width = QSPI_CFG_BUS_SINGLE;
_num_dummy_cycles = 0;
_mode = 0;
@@ -253,8 +253,9 @@ void QSPI::_build_qspi_command(int instruction, int address, int alt)
_qspi_command.instruction.bus_width = _inst_width;
if (instruction != -1) {
_qspi_command.instruction.value = instruction;
+ _qspi_command.instruction.disabled = false;
} else {
- _qspi_command.instruction.value = 0;
+ _qspi_command.instruction.disabled = true;
}
//Set up address phase parameters
@@ -262,8 +263,9 @@ void QSPI::_build_qspi_command(int instruction, int address, int alt)
_qspi_command.address.size = _address_size;
if (address != -1) {
_qspi_command.address.value = address;
+ _qspi_command.address.disabled = false;
} else {
- _qspi_command.address.size = QSPI_CFG_ADDR_SIZE_NONE;
+ _qspi_command.address.disabled = true;
}
//Set up alt phase parameters
@@ -271,9 +273,9 @@ void QSPI::_build_qspi_command(int instruction, int address, int alt)
_qspi_command.alt.size = _alt_size;
if (alt != -1) {
_qspi_command.alt.value = alt;
+ _qspi_command.alt.disabled = false;
} else {
- //In the case alt phase is absent, set the alt size to be NONE
- _qspi_command.alt.size = QSPI_CFG_ALT_SIZE_NONE;
+ _qspi_command.alt.disabled = true;
}
_qspi_command.dummy_count = _num_dummy_cycles;
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index 33039475fb..817dbfc421 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -83,9 +83,9 @@ public:
*
* @param inst_width Bus width used by instruction phase(Valid values are 1,2,4)
* @param address_width Bus width used by address phase(Valid values are 1,2,4)
- * @param address_size Size in bits used by address phase(Valid values are NONE,8,16,24,32)
+ * @param address_size Size in bits used by address phase(Valid values are 8,16,24,32)
* @param alt_width Bus width used by alt phase(Valid values are 1,2,4)
- * @param alt_size Size in bits used by alt phase(Valid values are NONE,8,16,24,32)
+ * @param alt_size Size in bits used by alt phase(Valid values are 8,16,24,32)
* @param data_width Bus width used by data phase(Valid values are 1,2,4)
* @param dummy_cycles Number of dummy clock cycles to be used after alt phase
* @param mode Mode specifies the SPI mode(Mode=0 uses CPOL=0, CPHA=0, Mode=1 uses CPOL=1, CPHA=1)
diff --git a/hal/qspi_api.h b/hal/qspi_api.h
index 80c1ff0ceb..525ff43122 100644
--- a/hal/qspi_api.h
+++ b/hal/qspi_api.h
@@ -20,6 +20,7 @@
#define MBED_QSPI_API_H
#include "device.h"
+#include
#if DEVICE_QSPI
@@ -49,7 +50,6 @@ typedef enum qspi_bus_width {
/** Address size
*/
typedef enum qspi_address_size {
- QSPI_CFG_ADDR_SIZE_NONE,
QSPI_CFG_ADDR_SIZE_8,
QSPI_CFG_ADDR_SIZE_16,
QSPI_CFG_ADDR_SIZE_24,
@@ -59,7 +59,6 @@ typedef enum qspi_address_size {
/** Alternative size
*/
typedef enum qspi_alt_size {
- QSPI_CFG_ALT_SIZE_NONE,
QSPI_CFG_ALT_SIZE_8,
QSPI_CFG_ALT_SIZE_16,
QSPI_CFG_ALT_SIZE_24,
@@ -74,16 +73,19 @@ typedef struct qspi_command {
struct {
qspi_bus_width_t bus_width; /**< Bus width for the instruction >*/
uint8_t value; /**< Instruction value >*/
+ bool disabled; /**< Instruction phase skipped if disabled is set to true >*/
} instruction;
struct {
qspi_bus_width_t bus_width; /**< Bus width for the address >*/
qspi_address_size_t size; /**< Address size >*/
uint32_t value; /**< Address value >*/
+ bool disabled; /**< Address phase skipped if disabled is set to true >*/
} address;
struct {
qspi_bus_width_t bus_width; /**< Bus width for alternative >*/
qspi_alt_size_t size; /**< Alternative size >*/
uint32_t value; /**< Alternative value >*/
+ bool disabled; /**< Alternative phase skipped if disabled is set to true >*/
} alt;
uint8_t dummy_count; /**< Dummy cycles count >*/
struct {
From 7da0ac2516de07a266b9dffed5b6e6666cae6fee Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Wed, 15 Nov 2017 13:58:37 +0000
Subject: [PATCH 27/78] QSPI: add STM32 implementation
---
targets/TARGET_STM/PeripheralPins.h | 6 +
.../TARGET_DISCO_F469NI/PeripheralPins.c | 21 ++
.../TARGET_STM32F469xI/objects.h | 4 +
targets/TARGET_STM/qspi_api.c | 245 ++++++++++++++++++
targets/targets.json | 2 +-
5 files changed, 277 insertions(+), 1 deletion(-)
create mode 100644 targets/TARGET_STM/qspi_api.c
diff --git a/targets/TARGET_STM/PeripheralPins.h b/targets/TARGET_STM/PeripheralPins.h
index f96b84890b..d1d5f2ea84 100644
--- a/targets/TARGET_STM/PeripheralPins.h
+++ b/targets/TARGET_STM/PeripheralPins.h
@@ -80,4 +80,10 @@ extern const PinMap PinMap_CAN_RD[];
extern const PinMap PinMap_CAN_TD[];
#endif
+#ifdef DEVICE_QSPI
+extern const PinMap PinMap_QSPI_DATA[];
+extern const PinMap PinMap_QSPI_SCLK[];
+extern const PinMap PinMap_QSPI_SSEL[];
+#endif
+
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
index 1f3690e4d0..6b1c6bd192 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
@@ -388,3 +388,24 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PH_13, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, // Connected to D21
{NC, NC, 0}
};
+
+
+const PinMap PinMap_QSPI_DATA[] = {
+ {PF_6, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
+ {PF_7, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
+ {PF_8, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
+ {PF_9, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
+
+ {NC, NC, 0}
+};
+
+const PinMap PinMap_QSPI_SCLK[] = {
+ {PF_10, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
+ {NC, NC, 0}
+};
+
+const PinMap PinMap_QSPI_SSEL[] = {
+ {PB_6, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
+ {NC, NC, 0}
+};
+
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h
index bea7fef547..1702826fdb 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h
@@ -58,6 +58,10 @@ struct trng_s {
RNG_HandleTypeDef handle;
};
+struct qspi_s {
+ QSPI_HandleTypeDef handle;
+};
+
#include "common_objects.h"
#ifdef __cplusplus
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
new file mode 100644
index 0000000000..bbdd238554
--- /dev/null
+++ b/targets/TARGET_STM/qspi_api.c
@@ -0,0 +1,245 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2017, ARM Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if DEVICE_QSPI
+
+#include "qspi_api.h"
+#include "mbed_error.h"
+#include "cmsis.h"
+#include "pinmap.h"
+#include "PeripheralPins.h"
+
+#define QSPI_FLASH_SIZE_DEFAULT 32
+
+void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st_command)
+{
+ // TODO: shift these around to get more dynamic mapping
+ switch (command->instruction.bus_width) {
+ case QSPI_CFG_BUS_SINGLE:
+ st_command->InstructionMode = QSPI_INSTRUCTION_1_LINE;
+ break;
+ case QSPI_CFG_BUS_DUAL:
+ st_command->InstructionMode = QSPI_INSTRUCTION_2_LINES;
+ break;
+ case QSPI_CFG_BUS_QUAD:
+ st_command->InstructionMode = QSPI_INSTRUCTION_4_LINES;
+ break;
+ }
+
+ st_command->Instruction = command->instruction.value;
+ st_command->DummyCycles = command->dummy_count,
+ // these are target specific settings, use default values
+ st_command->SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
+ st_command->DdrMode = QSPI_DDR_MODE_DISABLE;
+ st_command->DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
+
+ switch (command->address.bus_width) {
+ case QSPI_CFG_BUS_SINGLE:
+ st_command->AddressMode = QSPI_ADDRESS_1_LINE;
+ break;
+ case QSPI_CFG_BUS_DUAL:
+ st_command->AddressMode = QSPI_ADDRESS_2_LINES;
+ break;
+ case QSPI_CFG_BUS_QUAD:
+ st_command->AddressMode = QSPI_ADDRESS_4_LINES;
+ break;
+ default:
+ st_command->AddressMode = QSPI_ADDRESS_1_LINE;
+ break;
+ }
+
+ if (command->address.size == QSPI_CFG_ADDR_SIZE_NONE) {
+ st_command->AddressMode = QSPI_ADDRESS_NONE;
+ }
+
+ switch (command->alt.bus_width) {
+ case QSPI_CFG_BUS_SINGLE:
+ st_command->AlternateByteMode = QSPI_ALTERNATE_BYTES_1_LINE;
+ break;
+ case QSPI_CFG_BUS_DUAL:
+ st_command->AlternateByteMode = QSPI_ALTERNATE_BYTES_2_LINES;
+ break;
+ case QSPI_CFG_BUS_QUAD:
+ st_command->AlternateByteMode = QSPI_ALTERNATE_BYTES_4_LINES;
+ break;
+ default:
+ st_command->AlternateByteMode = QSPI_ALTERNATE_BYTES_1_LINE;
+ break;
+ }
+
+ if (command->alt.size == QSPI_CFG_ALT_SIZE_NONE) {
+ st_command->AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ }
+
+ switch (command->data.bus_width) {
+ case QSPI_CFG_BUS_SINGLE:
+ st_command->DataMode = QSPI_DATA_1_LINE;
+ break;
+ case QSPI_CFG_BUS_DUAL:
+ st_command->DataMode = QSPI_DATA_2_LINES;
+ break;
+ case QSPI_CFG_BUS_QUAD:
+ st_command->DataMode = QSPI_DATA_4_LINES;
+ break;
+ default:
+ st_command->DataMode = QSPI_DATA_1_LINE;
+ break;
+ }
+}
+
+
+qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel, uint32_t hz, uint8_t mode)
+{
+ // Enable interface clock for QSPI
+ __HAL_RCC_QSPI_CLK_ENABLE();
+
+ // Reset QSPI
+ __HAL_RCC_QSPI_FORCE_RESET();
+ __HAL_RCC_QSPI_RELEASE_RESET();
+
+ // Set default QSPI handle values
+ obj->handle.Init.ClockPrescaler = 1;
+ obj->handle.Init.FifoThreshold = 4;
+ obj->handle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
+ obj->handle.Init.FlashSize = POSITION_VAL(QSPI_FLASH_SIZE_DEFAULT) - 1;
+ obj->handle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE;
+ obj->handle.Init.ClockMode = QSPI_CLOCK_MODE_0;
+ obj->handle.Init.FlashID = QSPI_FLASH_ID_1;
+ obj->handle.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
+
+ obj->handle.Init.ClockMode = mode == 0 ? QSPI_CLOCK_MODE_0 : QSPI_CLOCK_MODE_3;
+
+ obj->handle.Instance = QUADSPI;
+
+ // TODO pinmap here for pins (enable clock)
+ pinmap_pinout(io0, PinMap_QSPI_DATA);
+ pinmap_pinout(io1, PinMap_QSPI_DATA);
+ pinmap_pinout(io2, PinMap_QSPI_DATA);
+ pinmap_pinout(io3, PinMap_QSPI_DATA);
+
+ pinmap_pinout(sclk, PinMap_QSPI_SCLK);
+ pinmap_pinout(ssel, PinMap_QSPI_SSEL);
+
+ if (HAL_QSPI_Init(&obj->handle) != HAL_OK) {
+ error("Cannot initialize QSPI");
+ }
+ qspi_frequency(obj, hz);
+ return QSPI_STATUS_OK;
+}
+
+qspi_status_t qspi_free(qspi_t *obj)
+{
+ // TODO
+ return QSPI_STATUS_ERROR;
+}
+
+qspi_status_t qspi_frequency(qspi_t *obj, int hz)
+{
+ qspi_status_t status = QSPI_STATUS_OK;
+
+ // TODO calculate prescalers properly, needs some work
+
+ // HCLK drives QSPI
+ int div = HAL_RCC_GetHCLKFreq() / hz;
+ if (div > 256 || div < 1) {
+ status = QSPI_STATUS_INVALID_PARAMETER;
+ return status;
+ }
+
+ obj->handle.Init.ClockPrescaler = div - 1;
+
+ if (HAL_QSPI_Init(&obj->handle) != HAL_OK) {
+ status = QSPI_STATUS_ERROR;
+ }
+ return QSPI_STATUS_OK;
+}
+
+qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void *data, size_t *length)
+{
+ QSPI_CommandTypeDef st_command;
+ qspi_prepare_command(command, &st_command);
+
+ st_command.NbData = *length;
+ qspi_status_t status = QSPI_STATUS_OK;
+
+ if (HAL_QSPI_Command(&obj->handle, &st_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
+ status = QSPI_STATUS_ERROR;
+ return status;
+ }
+
+ if (HAL_QSPI_Transmit(&obj->handle, (uint8_t *)data, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
+ status = QSPI_STATUS_ERROR;
+ }
+
+ if (QSPI_AutoPollingMemReady(&obj->handle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
+ status = QSPI_STATUS_ERROR;
+ }
+
+ return status;
+}
+
+qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t *length)
+{
+ QSPI_CommandTypeDef st_command;
+ qspi_prepare_command(command, &st_command);
+
+ st_command.NbData = *length;
+ qspi_status_t status = QSPI_STATUS_OK;
+
+ if (HAL_QSPI_Command(&obj->handle, &st_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
+ status = QSPI_STATUS_ERROR;
+ return status;
+ }
+
+ if (HAL_QSPI_Receive(&obj->handle, data, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
+ status = QSPI_STATUS_ERROR;
+ }
+
+ if (QSPI_AutoPollingMemReady(&obj->handle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
+ status = QSPI_STATUS_ERROR;
+ }
+
+ return status;
+}
+
+qspi_status_t qspi_write_command(qspi_t *obj, const qspi_command_t *command)
+{
+
+ QSPI_CommandTypeDef st_command;
+ qspi_prepare_command(command, &st_command);
+
+ qspi_status_t status = QSPI_STATUS_OK;
+ if (HAL_QSPI_Command(&obj->handle, &st_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
+ status = QSPI_STATUS_ERROR;
+ }
+ return status;
+}
+
+#endif
+
+/** @}*/
diff --git a/targets/targets.json b/targets/targets.json
index 88c57e7871..d10280c4c6 100755
--- a/targets/targets.json
+++ b/targets/targets.json
@@ -1987,7 +1987,7 @@
},
"detect_code": ["0788"],
"macros_add": ["USB_STM_HAL", "USBHOST_OTHER"],
- "device_has_add": ["ANALOGOUT", "CAN", "SERIAL_FC", "TRNG", "FLASH"],
+ "device_has_add": ["ANALOGOUT", "CAN", "SERIAL_FC", "TRNG", "FLASH", "QSPI"],
"release_versions": ["2", "5"],
"device_name": "STM32F469NI"
},
From 5e75b39b78c2a2487888edada77c441d9e39dfcd Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Thu, 23 Nov 2017 14:08:21 +0000
Subject: [PATCH 28/78] QSPI STM32: fix ssel af selection
---
.../TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
index 6b1c6bd192..905fff5540 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
@@ -405,7 +405,7 @@ const PinMap PinMap_QSPI_SCLK[] = {
};
const PinMap PinMap_QSPI_SSEL[] = {
- {PB_6, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
+ {PB_6, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
{NC, NC, 0}
};
From 11ae100d800b268600ce6984711a7763671476ab Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Thu, 23 Nov 2017 14:34:11 +0000
Subject: [PATCH 29/78] QSPI STM32: fix return value in frequency
---
targets/TARGET_STM/qspi_api.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index bbdd238554..a412e679d6 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -176,7 +176,7 @@ qspi_status_t qspi_frequency(qspi_t *obj, int hz)
if (HAL_QSPI_Init(&obj->handle) != HAL_OK) {
status = QSPI_STATUS_ERROR;
}
- return QSPI_STATUS_OK;
+ return status;
}
qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void *data, size_t *length)
From 8da072d8af64945a4597b9831057491d36cfed23 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Thu, 23 Nov 2017 14:54:32 +0000
Subject: [PATCH 30/78] QSPI STM32: set default command values to none
---
targets/TARGET_STM/qspi_api.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index a412e679d6..37eab642c1 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -49,6 +49,9 @@ void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st
case QSPI_CFG_BUS_QUAD:
st_command->InstructionMode = QSPI_INSTRUCTION_4_LINES;
break;
+ default:
+ st_command->InstructionMode = QSPI_INSTRUCTION_NONE;
+ break;
}
st_command->Instruction = command->instruction.value;
@@ -69,7 +72,7 @@ void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st
st_command->AddressMode = QSPI_ADDRESS_4_LINES;
break;
default:
- st_command->AddressMode = QSPI_ADDRESS_1_LINE;
+ st_command->AddressMode = QSPI_ADDRESS_NONE;
break;
}
@@ -88,7 +91,7 @@ void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st
st_command->AlternateByteMode = QSPI_ALTERNATE_BYTES_4_LINES;
break;
default:
- st_command->AlternateByteMode = QSPI_ALTERNATE_BYTES_1_LINE;
+ st_command->AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
break;
}
@@ -107,7 +110,7 @@ void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st
st_command->DataMode = QSPI_DATA_4_LINES;
break;
default:
- st_command->DataMode = QSPI_DATA_1_LINE;
+ st_command->DataMode = QSPI_DATA_NONE;
break;
}
}
@@ -162,8 +165,6 @@ qspi_status_t qspi_frequency(qspi_t *obj, int hz)
{
qspi_status_t status = QSPI_STATUS_OK;
- // TODO calculate prescalers properly, needs some work
-
// HCLK drives QSPI
int div = HAL_RCC_GetHCLKFreq() / hz;
if (div > 256 || div < 1) {
From 6e5b889e523b82307f56de707e3afe36122ed069 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Fri, 24 Nov 2017 09:29:22 +0000
Subject: [PATCH 31/78] QSPI STM32: remove polling from write/read
This will be part of custom instruction transfer, the flow will be:
1. write data
2. wait for transfer to complete (poll status register from the memory device)
---
targets/TARGET_STM/qspi_api.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index 37eab642c1..1254b8213e 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -197,10 +197,6 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void
status = QSPI_STATUS_ERROR;
}
- if (QSPI_AutoPollingMemReady(&obj->handle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
- status = QSPI_STATUS_ERROR;
- }
-
return status;
}
@@ -221,10 +217,6 @@ qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data,
status = QSPI_STATUS_ERROR;
}
- if (QSPI_AutoPollingMemReady(&obj->handle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
- status = QSPI_STATUS_ERROR;
- }
-
return status;
}
From 551f044e779a68c5c1ef33b53970cbf1907a053c Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 5 Dec 2017 11:13:43 +0000
Subject: [PATCH 32/78] QSPI STM32: add qspi_command_transfer implementation
---
targets/TARGET_STM/qspi_api.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index 1254b8213e..52734859e6 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -220,15 +220,27 @@ qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data,
return status;
}
-qspi_status_t qspi_write_command(qspi_t *obj, const qspi_command_t *command)
+qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command, const void *tx_data, size_t tx_size, void *rx_data, size_t rx_size)
{
-
- QSPI_CommandTypeDef st_command;
- qspi_prepare_command(command, &st_command);
-
qspi_status_t status = QSPI_STATUS_OK;
- if (HAL_QSPI_Command(&obj->handle, &st_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
- status = QSPI_STATUS_ERROR;
+
+ if (rx_size > 4) {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ }
+
+ QSPI_CommandTypeDef st_command;
+ qspi_prepare_command(command, &st_command);
+
+ QSPI_AutoPollingTypeDef s_config;
+ s_config.Match = 0;
+ s_config.Mask = 0;
+ s_config.MatchMode = QSPI_MATCH_MODE_OR;
+ s_config.StatusBytesSize = rx_size;
+ s_config.Interval = 0x10;
+ s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; // or QSPI_AUTOMATIC_STOP_DISABLE ?
+
+ if (HAL_QSPI_AutoPolling(&obj->handle, &st_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
+ status = QSPI_STATUS_ERROR;
}
return status;
}
From 660d250e0df282874e6aebfc505d5053c0fd8085 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 5 Dec 2017 11:15:30 +0000
Subject: [PATCH 33/78] QSPI STM32: init returns error if failed to init
---
targets/TARGET_STM/qspi_api.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index 52734859e6..af82283f73 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -149,7 +149,7 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
pinmap_pinout(ssel, PinMap_QSPI_SSEL);
if (HAL_QSPI_Init(&obj->handle) != HAL_OK) {
- error("Cannot initialize QSPI");
+ return QSPI_STATUS_ERROR;
}
qspi_frequency(obj, hz);
return QSPI_STATUS_OK;
From 2766672f64c5404f845bf6dc2a4c41d1d7558711 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 5 Dec 2017 11:38:47 +0000
Subject: [PATCH 34/78] QSPI STM32: add QSPI_x support to pinnames
---
.../TARGET_DISCO_F469NI/PeripheralNames.h | 4 ++++
.../TARGET_DISCO_F469NI/PeripheralPins.c | 12 ++++++------
targets/TARGET_STM/qspi_api.c | 12 +++++++++++-
3 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralNames.h
index ce3afd5658..39455e98e6 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralNames.h
@@ -92,6 +92,10 @@ typedef enum {
CAN_2 = (int)CAN2_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
index 905fff5540..81fbb3f231 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
@@ -391,21 +391,21 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
const PinMap PinMap_QSPI_DATA[] = {
- {PF_6, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
- {PF_7, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
- {PF_8, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
- {PF_9, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
{NC, NC, 0}
};
const PinMap PinMap_QSPI_SCLK[] = {
- {PF_10, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
+ {PF_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
{NC, NC, 0}
};
const PinMap PinMap_QSPI_SSEL[] = {
- {PB_6, 0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
{NC, NC, 0}
};
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index af82283f73..76f1221824 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -137,7 +137,17 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
obj->handle.Init.ClockMode = mode == 0 ? QSPI_CLOCK_MODE_0 : QSPI_CLOCK_MODE_3;
- obj->handle.Instance = QUADSPI;
+ QSPIName qspi_data_first = (SPIName)pinmap_merge(io0, io1);
+ QSPIName qspi_data_second = (SPIName)pinmap_merge(io1, io2);
+ QSPIName qspi_data_third = (SPIName)pinmap_merge(io2, io3);
+
+ if (qspi_data_first != qspi_data_second || qspi_data_second != qspi_data_third ||
+ qspi_data_first != qspi_data_third) {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ }
+
+ // tested all combinations, take first
+ obj->handle.Instance = (QUADSPI_TypeDef *)qspi_data_first;
// TODO pinmap here for pins (enable clock)
pinmap_pinout(io0, PinMap_QSPI_DATA);
From 16ca742d87ee79af027eef8446a0a096abf1ca54 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Mon, 11 Dec 2017 13:01:13 +0000
Subject: [PATCH 35/78] QSPI STM32: fix disabled format phase
---
targets/TARGET_STM/qspi_api.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index 76f1221824..fd6b4a9319 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -76,7 +76,7 @@ void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st
break;
}
- if (command->address.size == QSPI_CFG_ADDR_SIZE_NONE) {
+ if (command->address.disabled == true) {
st_command->AddressMode = QSPI_ADDRESS_NONE;
}
@@ -95,7 +95,7 @@ void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st
break;
}
- if (command->alt.size == QSPI_CFG_ALT_SIZE_NONE) {
+ if (command->alt.disabled == true) {
st_command->AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
}
From 5038b386222db0b7e2641c74c534a4a584040ae2 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 12 Dec 2017 14:44:37 +0000
Subject: [PATCH 36/78] QSPI STM32: fix pin merging
hw name as input
---
targets/TARGET_STM/qspi_api.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index fd6b4a9319..657bfaa5e1 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -137,9 +137,16 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
obj->handle.Init.ClockMode = mode == 0 ? QSPI_CLOCK_MODE_0 : QSPI_CLOCK_MODE_3;
- QSPIName qspi_data_first = (SPIName)pinmap_merge(io0, io1);
- QSPIName qspi_data_second = (SPIName)pinmap_merge(io1, io2);
- QSPIName qspi_data_third = (SPIName)pinmap_merge(io2, io3);
+ QSPIName qspiio0name = (QSPIName)pinmap_peripheral(io0, PinMap_QSPI_DATA);
+ QSPIName qspiio1name = (QSPIName)pinmap_peripheral(io1, PinMap_QSPI_DATA);
+ QSPIName qspiio2name = (QSPIName)pinmap_peripheral(io2, PinMap_QSPI_DATA);
+ QSPIName qspiio3name = (QSPIName)pinmap_peripheral(io3, PinMap_QSPI_DATA);
+ QSPIName qspiclkname = (QSPIName)pinmap_peripheral(sclk, PinMap_QSPI_SCLK);
+ QSPIName qspisselname = (QSPIName)pinmap_peripheral(ssel, PinMap_QSPI_SSEL);
+
+ QSPIName qspi_data_first = (QSPIName)pinmap_merge(qspiio0name, qspiio1name);
+ QSPIName qspi_data_second = (QSPIName)pinmap_merge(qspiio2name, qspiio3name);
+ QSPIName qspi_data_third = (QSPIName)pinmap_merge(qspiclkname, qspisselname);
if (qspi_data_first != qspi_data_second || qspi_data_second != qspi_data_third ||
qspi_data_first != qspi_data_third) {
From fff20729bef6c61835afa26eda40492a87f50d7e Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 12 Dec 2017 16:31:38 +0000
Subject: [PATCH 37/78] QSPI STM32: fix command transfer
use write/read from STM32 driver
---
targets/TARGET_STM/qspi_api.c | 37 +++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 15 deletions(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index 657bfaa5e1..67ef6c2bc8 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -241,23 +241,30 @@ qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command,
{
qspi_status_t status = QSPI_STATUS_OK;
- if (rx_size > 4) {
- return QSPI_STATUS_INVALID_PARAMETER;
- }
+ if ((tx_data == NULL || tx_size == 0) && (rx_data == NULL || rx_size == 0)) {
+ // only command, no rx or tx
+ QSPI_CommandTypeDef st_command;
+ qspi_prepare_command(command, &st_command);
- QSPI_CommandTypeDef st_command;
- qspi_prepare_command(command, &st_command);
+ st_command.NbData = 1;
+ if (HAL_QSPI_Command(&obj->handle, &st_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
+ status = QSPI_STATUS_ERROR;
+ return status;
+ }
+ } else {
+ // often just read a register, check if we need to transmit anything prior reading
+ if (tx_data != NULL && tx_size) {
+ size_t tx_length = tx_size;
+ status = qspi_write(obj, command, tx_data, &tx_length);
+ if (status != QSPI_STATUS_OK) {
+ return status;
+ }
+ }
- QSPI_AutoPollingTypeDef s_config;
- s_config.Match = 0;
- s_config.Mask = 0;
- s_config.MatchMode = QSPI_MATCH_MODE_OR;
- s_config.StatusBytesSize = rx_size;
- s_config.Interval = 0x10;
- s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; // or QSPI_AUTOMATIC_STOP_DISABLE ?
-
- if (HAL_QSPI_AutoPolling(&obj->handle, &st_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
- status = QSPI_STATUS_ERROR;
+ if (rx_data != NULL && rx_size) {
+ size_t rx_length = rx_size;
+ status = qspi_read(obj, command, rx_data, &rx_length);
+ }
}
return status;
}
From 8783956a77fd429d434ff04a211e8099f28dbdfb Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 12 Dec 2017 16:34:55 +0000
Subject: [PATCH 38/78] QSPI STM32: fix prepare comman - alt/address
---
targets/TARGET_STM/qspi_api.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index 67ef6c2bc8..c586a2712b 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -78,6 +78,10 @@ void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st
if (command->address.disabled == true) {
st_command->AddressMode = QSPI_ADDRESS_NONE;
+ st_command->AddressSize = 0;
+ } else {
+ st_command->Address = command->address.value;
+ st_command->AddressSize = command->address.size;
}
switch (command->alt.bus_width) {
@@ -97,6 +101,10 @@ void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st
if (command->alt.disabled == true) {
st_command->AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ st_command->AlternateBytesSize = 0;
+ } else {
+ st_command->AlternateBytes = command->alt.value;
+ st_command->AlternateBytesSize = command->alt.size;
}
switch (command->data.bus_width) {
@@ -113,6 +121,8 @@ void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st
st_command->DataMode = QSPI_DATA_NONE;
break;
}
+
+ st_command->NbData = 0;
}
From c778c901843460175a635b2bef5e909ea66f2192 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 12 Dec 2017 16:38:58 +0000
Subject: [PATCH 39/78] QSPI STM32: fix default fifo and cycle
As example for DISCO F469NI defines them
---
targets/TARGET_STM/qspi_api.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index c586a2712b..a08420e577 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -137,10 +137,10 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
// Set default QSPI handle values
obj->handle.Init.ClockPrescaler = 1;
- obj->handle.Init.FifoThreshold = 4;
+ obj->handle.Init.FifoThreshold = 1;
obj->handle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
obj->handle.Init.FlashSize = POSITION_VAL(QSPI_FLASH_SIZE_DEFAULT) - 1;
- obj->handle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE;
+ obj->handle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_5_CYCLE;
obj->handle.Init.ClockMode = QSPI_CLOCK_MODE_0;
obj->handle.Init.FlashID = QSPI_FLASH_ID_1;
obj->handle.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
From 99f2107881fba6e0577b88bda6b7420ec6ff8c6d Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 9 Jan 2018 13:47:56 +0000
Subject: [PATCH 40/78] QSPI: hal doxygen fixes
Small corrections, fixing typos in the documentation
---
hal/qspi_api.h | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/hal/qspi_api.h b/hal/qspi_api.h
index 525ff43122..144f4f43d4 100644
--- a/hal/qspi_api.h
+++ b/hal/qspi_api.h
@@ -33,7 +33,7 @@ extern "C" {
* @{
*/
-/** QSPI HAL object declaration
+/** QSPI HAL object
*/
typedef struct qspi_s qspi_t;
@@ -47,7 +47,7 @@ typedef enum qspi_bus_width {
QSPI_CFG_BUS_QUAD,
} qspi_bus_width_t;
-/** Address size
+/** Address size in bits
*/
typedef enum qspi_address_size {
QSPI_CFG_ADDR_SIZE_8,
@@ -56,7 +56,7 @@ typedef enum qspi_address_size {
QSPI_CFG_ADDR_SIZE_32,
} qspi_address_size_t;
-/** Alternative size
+/** Alternative size in bits
*/
typedef enum qspi_alt_size {
QSPI_CFG_ALT_SIZE_8,
@@ -65,9 +65,9 @@ typedef enum qspi_alt_size {
QSPI_CFG_ALT_SIZE_32,
} qspi_alt_size_t;
-/** QSPI command declaration
+/** QSPI command
*
- * Defines a frame format
+ * Defines a frame format. It consists of instruction, address, alternative, dummy count and data
*/
typedef struct qspi_command {
struct {
@@ -148,35 +148,33 @@ qspi_status_t qspi_frequency(qspi_t *obj, int hz);
* @param obj QSPI object
* @param command QSPI command
* @param data TX buffer
- * @param[in,out] in - length TX buffer length in bytes, out - number of bytes written
+ * @param[in,out] length in - TX buffer length in bytes, out - number of bytes written
* @return QSPI_STATUS_OK if the data has been succesfully sent
QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
QSPI_STATUS_ERROR otherwise
*/
qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void *data, size_t *length);
-/** Send a command (and optionally data) and get the response. Can be used to send/receive device specific commands.
+/** Send a command (and optionally data) and get the response. Can be used to send/receive device specific commands
*
* @param obj QSPI object
* @param command QSPI command
* @param tx_data TX buffer
- * @param tx_length pointer to variable holding TX buffer length
- * @param rx_data TX buffer
- * @param rx_length pointer to variable holding TX buffer length
+ * @param tx_length TX buffer length in bytes
+ * @param rx_data RX buffer
+ * @param rx_length RX buffer length in bytes
* @return QSPI_STATUS_OK if the data has been succesfully sent
QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
QSPI_STATUS_ERROR otherwise
*/
-
qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command, const void *tx_data, size_t tx_size, void *rx_data, size_t rx_size);
-
/** Receive a command and block of data
*
* @param obj QSPI object
* @param command QSPI command
* @param data RX buffer
- * @param[in,out] in - length RX buffer length in bytes, out - number of bytes read
+ * @param[in,out] length in - RX buffer length in bytes, out - number of bytes read
* @return QSPI_STATUS_OK if data has been succesfully received
QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
QSPI_STATUS_ERROR otherwise
From 0f7fd757a42b15f9c9de48afb2e57cffc97f6c45 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Mon, 8 Jan 2018 15:25:05 +0000
Subject: [PATCH 41/78] QSPI: add flash pins for F469 disco board
---
.../TARGET_STM32F469xI/TARGET_DISCO_F469NI/PinNames.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PinNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PinNames.h
index 5d8187d616..58ebf4e8f6 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PinNames.h
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PinNames.h
@@ -406,6 +406,13 @@ typedef enum {
SYS_TRACED3_ALT0 = PE_6,
SYS_WKUP = PA_0,
+ QSPI_FLASH_IO0 = PF_8,
+ QSPI_FLASH_IO1 = PF_9,
+ QSPI_FLASH_IO2 = PF_7,
+ QSPI_FLASH_IO3 = PF_6,
+ QSPI_FLASH_SCK = PF_10,
+ QSPI_FLASH_CSN = PB_6,
+
// Not connected
NC = (int)0xFFFFFFFF
} PinName;
From ae7bb17eafab2938434fcba3eca92c17765e1133 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Mon, 8 Jan 2018 15:31:05 +0000
Subject: [PATCH 42/78] QSPI: add flash pins for nrf52480_dk board
---
.../TARGET_MCU_NRF52840/TARGET_NRF52840_DK/PinNames.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/TARGET_NRF52840_DK/PinNames.h b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/TARGET_NRF52840_DK/PinNames.h
index 2a5f319abd..4241cdcf47 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/TARGET_NRF52840_DK/PinNames.h
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/TARGET_NRF52840_DK/PinNames.h
@@ -227,6 +227,13 @@ typedef enum {
A4 = p30,
A5 = p31,
+ QSPI_FLASH_IO0 = P0_20,
+ QSPI_FLASH_IO1 = P0_21,
+ QSPI_FLASH_IO2 = P0_22,
+ QSPI_FLASH_IO3 = P0_23,
+ QSPI_FLASH_SCK = P0_19,
+ QSPI_FLASH_CSN = P0_17,
+
// Not connected
NC = (int)0xFFFFFFFF
} PinName;
From d282c81e86d9dcc50405f833395013eb0e342961 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Wed, 10 Jan 2018 10:13:47 +0000
Subject: [PATCH 43/78] QSPI: add STM32L4 support
Disco IoT board support for QSPI. As it does not have dual flash support in QSPI,
we need to fix qspi hal implementation.
---
.../PeripheralNames.h | 4 ++++
.../PeripheralPins.c | 24 +++++++++++++++++++
.../TARGET_STM32L475xG/objects.h | 4 ++++
targets/TARGET_STM/qspi_api.c | 2 ++
targets/targets.json | 2 +-
5 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PeripheralNames.h
index 2a66882a1c..04b09f6539 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PeripheralNames.h
@@ -83,6 +83,10 @@ typedef enum {
CAN_1 = (int)CAN1_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PeripheralPins.c
index a21e78ce22..502b176fa2 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PeripheralPins.c
@@ -340,3 +340,27 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PD_1, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, // Connected to PMOD_SPI2_SCK
{NC, NC, 0}
};
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PE_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {PE_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {PE_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {PE_15, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {PB_0, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PE_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h
index e68c4eb619..249e162543 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h
@@ -58,6 +58,10 @@ struct trng_s {
RNG_HandleTypeDef handle;
};
+struct qspi_s {
+ QSPI_HandleTypeDef handle;
+};
+
#include "common_objects.h"
#ifdef __cplusplus
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index a08420e577..26ed1d3bf0 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -142,8 +142,10 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
obj->handle.Init.FlashSize = POSITION_VAL(QSPI_FLASH_SIZE_DEFAULT) - 1;
obj->handle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_5_CYCLE;
obj->handle.Init.ClockMode = QSPI_CLOCK_MODE_0;
+#ifdef QSPI_DUALFLASH_ENABLE
obj->handle.Init.FlashID = QSPI_FLASH_ID_1;
obj->handle.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
+#endif
obj->handle.Init.ClockMode = mode == 0 ? QSPI_CLOCK_MODE_0 : QSPI_CLOCK_MODE_3;
diff --git a/targets/targets.json b/targets/targets.json
index d10280c4c6..c505f59657 100755
--- a/targets/targets.json
+++ b/targets/targets.json
@@ -2145,7 +2145,7 @@
"supported_form_factors": ["ARDUINO"],
"detect_code": ["0764"],
"macros_add": ["USBHOST_OTHER", "TWO_RAM_REGIONS"],
- "device_has_add": ["ANALOGOUT", "CAN", "SERIAL_FC", "TRNG", "FLASH"],
+ "device_has_add": ["ANALOGOUT", "CAN", "SERIAL_FC", "TRNG", "FLASH", "QSPI"],
"release_versions": ["2", "5"],
"device_name": "STM32L475VG",
"bootloader_supported": true
From 41453169a061b7fb28901c09b0752cbc4bb56878 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Fri, 16 Feb 2018 14:19:51 +0000
Subject: [PATCH 44/78] QSPI: fix memset header file missing
---
drivers/QSPI.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index f2e19b8af8..ceebcd3aa3 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -16,6 +16,7 @@
#include "drivers/QSPI.h"
#include "platform/mbed_critical.h"
+#include
#if DEVICE_QSPI
From d54bac2207b6c4b150fec3c73869dba762b62bc9 Mon Sep 17 00:00:00 2001
From: Martin Kojtal <0xc0170@gmail.com>
Date: Tue, 13 Feb 2018 16:48:02 +0000
Subject: [PATCH 45/78] QSPI: add address to command transfer
---
drivers/QSPI.cpp | 4 ++--
drivers/QSPI.h | 3 ++-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index ceebcd3aa3..1cfd372de2 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -194,14 +194,14 @@ qspi_status_t QSPI::write(unsigned int instruction, unsigned int alt, unsigned i
return ret_status;
}
-qspi_status_t QSPI::command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length)
+qspi_status_t QSPI::command_transfer(unsigned int instruction, int address, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length)
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
if (_initialized) {
lock();
if (true == _acquire()) {
- _build_qspi_command(instruction, -1, -1); //We just need the command
+ _build_qspi_command(instruction, address, -1); //We just need the command
if (QSPI_STATUS_OK == qspi_command_transfer(&_qspi, &_qspi_command, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index 817dbfc421..e499ee8047 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -159,6 +159,7 @@ public:
/** Perform a transaction to write to an address(a control register) and get the status results
*
* @param instruction Instruction value to be used in instruction phase
+ * @param address Some instruction might require address. Use -1 for ignoring the address value
* @param tx_buffer Buffer containing data to be sent to peripheral
* @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
* @param rx_buffer Buffer for data to be read from the peripheral
@@ -167,7 +168,7 @@ public:
* @returns
* Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
- qspi_status_t command_transfer(unsigned int instruction, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length);
+ qspi_status_t command_transfer(unsigned int instruction, int address, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length);
/** Acquire exclusive access to this SPI bus
*/
From 05899e9c700287738352a440f978d4ab173cd7c9 Mon Sep 17 00:00:00 2001
From: adustm
Date: Thu, 22 Mar 2018 18:19:39 +0100
Subject: [PATCH 46/78] Fix Address.Size and AlternateByes.Size by shifting
them
The ST HAL code is waiting for the correctly shifted vlue
(for a direct write into the HW register)
---
targets/TARGET_STM/qspi_api.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index 26ed1d3bf0..729a1d0f31 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -81,7 +81,8 @@ void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st
st_command->AddressSize = 0;
} else {
st_command->Address = command->address.value;
- st_command->AddressSize = command->address.size;
+ /* command->address.size needs to be shifted by QUADSPI_CCR_ADSIZE_Pos */
+ st_command->AddressSize = (command->address.size << QUADSPI_CCR_ADSIZE_Pos) & QUADSPI_CCR_ADSIZE_Msk;
}
switch (command->alt.bus_width) {
@@ -104,6 +105,8 @@ void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st
st_command->AlternateBytesSize = 0;
} else {
st_command->AlternateBytes = command->alt.value;
+ /* command->AlternateBytesSize needs to be shifted by QUADSPI_CCR_ABSIZE_Pos */
+ st_command->AlternateBytesSize = (command->alt.size << QUADSPI_CCR_ABSIZE_Pos) & QUADSPI_CCR_ABSIZE_Msk;
st_command->AlternateBytesSize = command->alt.size;
}
From 8e087402374be5673476c69182f7811691e02d6f Mon Sep 17 00:00:00 2001
From: adustm
Date: Thu, 22 Mar 2018 18:26:39 +0100
Subject: [PATCH 47/78] Fix Instruction with no data command Adding
QSPI_DATA_NONE activates the transfer of the command inside HAL_QSPI_COMMAND
function
---
targets/TARGET_STM/qspi_api.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index 729a1d0f31..7764c98b93 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -262,6 +262,7 @@ qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command,
qspi_prepare_command(command, &st_command);
st_command.NbData = 1;
+ st_command.DataMode = QSPI_DATA_NONE; /* Instruction only */
if (HAL_QSPI_Command(&obj->handle, &st_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
status = QSPI_STATUS_ERROR;
return status;
From 8d2f426d974f044b3324d0d85b51cca3bddff8fd Mon Sep 17 00:00:00 2001
From: adustm
Date: Tue, 20 Mar 2018 18:50:43 +0100
Subject: [PATCH 48/78] Dummy cycles count is not an init parameter, but a
command parameter. It can change depending on the chosen command, not only at
start. This way we avoid to launch init function and break the internal
status variables.
---
drivers/QSPI.cpp | 22 ++++++++++------------
drivers/QSPI.h | 9 +++++----
2 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index 1cfd372de2..ba9c9d1940 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -39,7 +39,6 @@ QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, Pin
_alt_width = QSPI_CFG_BUS_SINGLE;
_alt_size = QSPI_CFG_ALT_SIZE_8;
_data_width = QSPI_CFG_BUS_SINGLE;
- _num_dummy_cycles = 0;
_mode = 0;
_hz = ONE_MHZ;
_initialized = false;
@@ -62,7 +61,6 @@ qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width
_alt_width = alt_width;
_alt_size = alt_size;
_data_width = data_width;
- _num_dummy_cycles = dummy_cycles;
_mode = mode;
//Re-init the device, as the mode might have changed
@@ -107,7 +105,7 @@ qspi_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_lengt
if (*rx_length != 0) {
lock();
if (true == _acquire()) {
- _build_qspi_command(-1, address, -1);
+ _build_qspi_command(-1, address, -1, 0);
if (QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
@@ -131,7 +129,7 @@ qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *t
if (*tx_length != 0) {
lock();
if (true == _acquire()) {
- _build_qspi_command(-1, address, -1);
+ _build_qspi_command(-1, address, -1, 0);
if (QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
ret_status = QSPI_STATUS_OK;
}
@@ -146,7 +144,7 @@ qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *t
return ret_status;
}
-qspi_status_t QSPI::read(unsigned int instruction, unsigned int alt, unsigned int address, char *rx_buffer, size_t *rx_length)
+qspi_status_t QSPI::read(unsigned int instruction, unsigned int alt, unsigned int dummy_cnt, unsigned int address, char *rx_buffer, size_t *rx_length)
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
@@ -155,7 +153,7 @@ qspi_status_t QSPI::read(unsigned int instruction, unsigned int alt, unsigned in
if (*rx_length != 0) {
lock();
if ( true == _acquire()) {
- _build_qspi_command(instruction, address, alt);
+ _build_qspi_command(instruction, address, alt, dummy_cnt);
if (QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
@@ -170,7 +168,7 @@ qspi_status_t QSPI::read(unsigned int instruction, unsigned int alt, unsigned in
return ret_status;
}
-qspi_status_t QSPI::write(unsigned int instruction, unsigned int alt, unsigned int address, const char *tx_buffer, size_t *tx_length)
+qspi_status_t QSPI::write(unsigned int instruction, unsigned int alt, unsigned int dummy_cnt, unsigned int address, const char *tx_buffer, size_t *tx_length)
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
@@ -179,7 +177,7 @@ qspi_status_t QSPI::write(unsigned int instruction, unsigned int alt, unsigned i
if (*tx_length != 0) {
lock();
if (true == _acquire()) {
- _build_qspi_command(instruction, address, alt);
+ _build_qspi_command(instruction, address, alt, dummy_cnt);
if (QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
ret_status = QSPI_STATUS_OK;
}
@@ -201,7 +199,7 @@ qspi_status_t QSPI::command_transfer(unsigned int instruction, int address, cons
if (_initialized) {
lock();
if (true == _acquire()) {
- _build_qspi_command(instruction, address, -1); //We just need the command
+ _build_qspi_command(instruction, address, -1, 0); //We just need the command
if (QSPI_STATUS_OK == qspi_command_transfer(&_qspi, &_qspi_command, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
@@ -247,7 +245,7 @@ bool QSPI::_acquire()
return _initialized;
}
-void QSPI::_build_qspi_command(int instruction, int address, int alt)
+void QSPI::_build_qspi_command(int instruction, int address, int alt, int dummy_cnt)
{
memset( &_qspi_command, 0, sizeof(qspi_command_t) );
//Set up instruction phase parameters
@@ -278,8 +276,8 @@ void QSPI::_build_qspi_command(int instruction, int address, int alt)
} else {
_qspi_command.alt.disabled = true;
}
-
- _qspi_command.dummy_count = _num_dummy_cycles;
+
+ _qspi_command.dummy_count = dummy_cnt;
//Set up bus width for data phase
_qspi_command.data.bus_width = _data_width;
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index e499ee8047..2575af1c12 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -134,6 +134,7 @@ public:
*
* @param instruction Instruction value to be used in instruction phase
* @param alt Alt value to be used in instruction phase
+ * @param dummy_cnt Amount of dummy cycles to be sent after instruction phase
* @param address Address to be accessed in QSPI peripheral
* @param rx_buffer Buffer for data to be read from the peripheral
* @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
@@ -141,12 +142,13 @@ public:
* @returns
* Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
- qspi_status_t read(unsigned int instruction, unsigned int alt, unsigned int address, char *rx_buffer, size_t *rx_length);
+ qspi_status_t read(unsigned int instruction, unsigned int alt, unsigned int dummy_cnt, unsigned int address, char *rx_buffer, size_t *rx_length);
/** Write to QSPI peripheral using custom write instruction, alt values
*
* @param instruction Instruction value to be used in instruction phase
* @param alt Alt value to be used in instruction phase
+ * @param dummy_cnt Amount of dummy cycles to be sent after instruction phase
* @param address Address to be accessed in QSPI peripheral
* @param tx_buffer Buffer containing data to be sent to peripheral
* @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
@@ -154,7 +156,7 @@ public:
* @returns
* Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
- qspi_status_t write(unsigned int instruction, unsigned int alt, unsigned int address, const char *tx_buffer, size_t *tx_length);
+ qspi_status_t write(unsigned int instruction, unsigned int alt, unsigned int dummy_cnt, unsigned int address, const char *tx_buffer, size_t *tx_length);
/** Perform a transaction to write to an address(a control register) and get the status results
*
@@ -195,7 +197,6 @@ protected:
qspi_alt_size_t _alt_size;
qspi_bus_width_t _data_width; //Bus width for Data phase
qspi_command_t _qspi_command; //QSPI Hal command struct
- unsigned int _num_dummy_cycles; //Number of dummy cycles to be used
int _hz; //Bus Frequency
int _mode; //SPI mode
bool _initialized;
@@ -211,7 +212,7 @@ private:
/*
* This function builds the qspi command struct to be send to Hal
*/
- inline void _build_qspi_command(int instruction, int address, int alt);
+ inline void _build_qspi_command(int instruction, int address, int alt, int dummy_cnt);
};
} // namespace mbed
From c57a47e4b59bc551bb0047e0fce9a24799495238 Mon Sep 17 00:00:00 2001
From: adustm
Date: Mon, 19 Mar 2018 16:56:42 +0100
Subject: [PATCH 49/78] Change default FlashSize to 64Mbit = 8Mbytes = 0x800000
---
targets/TARGET_STM/qspi_api.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index 7764c98b93..1b1c6af9f9 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -34,7 +34,7 @@
#include "pinmap.h"
#include "PeripheralPins.h"
-#define QSPI_FLASH_SIZE_DEFAULT 32
+#define QSPI_FLASH_SIZE_DEFAULT 0x800000
void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st_command)
{
From 2b234c290286838f820413ad3055dc6bb321f96b Mon Sep 17 00:00:00 2001
From: adustm
Date: Fri, 30 Mar 2018 11:50:11 +0200
Subject: [PATCH 50/78] Move _mode from QSPI::configure_format to QSPI::QSPI
QSPI::configure_format shall not call initialize function. This way,
QSPI::configure_format can be called any time, only to change the format of
commands. It must contain only parameters for the commands, not for the Init
function
---
drivers/QSPI.cpp | 17 ++++++-----------
drivers/QSPI.h | 9 +++++----
2 files changed, 11 insertions(+), 15 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index ba9c9d1940..b13453ffd3 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -25,7 +25,7 @@ namespace mbed {
QSPI* QSPI::_owner = NULL;
SingletonPtr QSPI::_mutex;
-QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel) : _qspi()
+QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel, int mode) : _qspi()
{
_qspi_io0 = io0;
_qspi_io1 = io1;
@@ -39,7 +39,7 @@ QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, Pin
_alt_width = QSPI_CFG_BUS_SINGLE;
_alt_size = QSPI_CFG_ALT_SIZE_8;
_data_width = QSPI_CFG_BUS_SINGLE;
- _mode = 0;
+ _mode = mode;
_hz = ONE_MHZ;
_initialized = false;
@@ -47,13 +47,10 @@ QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, Pin
_initialize();
}
-qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width_t address_width, qspi_address_size_t address_size, qspi_bus_width_t alt_width, qspi_alt_size_t alt_size, qspi_bus_width_t data_width, int dummy_cycles, int mode )
+qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width_t address_width, qspi_address_size_t address_size, qspi_bus_width_t alt_width, qspi_alt_size_t alt_size, qspi_bus_width_t data_width, int dummy_cycles)
{
qspi_status_t ret_status = QSPI_STATUS_OK;
- if (mode != 0 && mode != 1)
- return QSPI_STATUS_INVALID_PARAMETER;
-
lock();
_inst_width = inst_width;
_address_width = address_width;
@@ -61,12 +58,7 @@ qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width
_alt_width = alt_width;
_alt_size = alt_size;
_data_width = data_width;
- _mode = mode;
- //Re-init the device, as the mode might have changed
- if ( !_initialize() ) {
- ret_status = QSPI_STATUS_ERROR;
- }
unlock();
return ret_status;
@@ -223,6 +215,9 @@ void QSPI::unlock()
// Note: Private helper function to initialize qspi HAL
bool QSPI::_initialize()
{
+ if (_mode != 0 && _mode != 1)
+ return QSPI_STATUS_INVALID_PARAMETER;
+
qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode );
if (QSPI_STATUS_OK == ret) {
_initialized = true;
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index 2575af1c12..09a7549db1 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -76,8 +76,11 @@ public:
* @param io3 4th IO pin used for sending/receiving data during data phase of a transaction
* @param sclk QSPI Clock pin
* @param ssel QSPI chip select pin
+ * @param mode Mode specifies the SPI mode(Mode=0 uses CPOL=0, CPHA=0, Mode=1 uses CPOL=1, CPHA=1)
+ * default value = 0
+ *
*/
- QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel=NC);
+ QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel=NC, int mode=0);
/** Configure the data transmission format
*
@@ -88,7 +91,6 @@ public:
* @param alt_size Size in bits used by alt phase(Valid values are 8,16,24,32)
* @param data_width Bus width used by data phase(Valid values are 1,2,4)
* @param dummy_cycles Number of dummy clock cycles to be used after alt phase
- * @param mode Mode specifies the SPI mode(Mode=0 uses CPOL=0, CPHA=0, Mode=1 uses CPOL=1, CPHA=1)
*
*/
qspi_status_t configure_format(qspi_bus_width_t inst_width,
@@ -97,8 +99,7 @@ public:
qspi_bus_width_t alt_width,
qspi_alt_size_t alt_size,
qspi_bus_width_t data_width,
- int dummy_cycles,
- int mode);
+ int dummy_cycles);
/** Set the qspi bus clock frequency
*
From 0714ac350f290b64ee77fdfbe7e6e0c7902a9936 Mon Sep 17 00:00:00 2001
From: adustm
Date: Fri, 30 Mar 2018 14:55:33 +0200
Subject: [PATCH 51/78] Revert "Dummy cycles count is not an init parameter,
but a command parameter."
This reverts commit f1ad089660ac59eb81cfe5d76d7af394d471c30d.
---
drivers/QSPI.cpp | 20 +++++++++++---------
drivers/QSPI.h | 9 ++++-----
2 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index b13453ffd3..36cad333e1 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -39,6 +39,7 @@ QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, Pin
_alt_width = QSPI_CFG_BUS_SINGLE;
_alt_size = QSPI_CFG_ALT_SIZE_8;
_data_width = QSPI_CFG_BUS_SINGLE;
+ _num_dummy_cycles = 0;
_mode = mode;
_hz = ONE_MHZ;
_initialized = false;
@@ -58,6 +59,7 @@ qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width
_alt_width = alt_width;
_alt_size = alt_size;
_data_width = data_width;
+ _num_dummy_cycles = dummy_cycles;
unlock();
@@ -97,7 +99,7 @@ qspi_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_lengt
if (*rx_length != 0) {
lock();
if (true == _acquire()) {
- _build_qspi_command(-1, address, -1, 0);
+ _build_qspi_command(-1, address, -1);
if (QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
@@ -121,7 +123,7 @@ qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *t
if (*tx_length != 0) {
lock();
if (true == _acquire()) {
- _build_qspi_command(-1, address, -1, 0);
+ _build_qspi_command(-1, address, -1);
if (QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
ret_status = QSPI_STATUS_OK;
}
@@ -136,7 +138,7 @@ qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *t
return ret_status;
}
-qspi_status_t QSPI::read(unsigned int instruction, unsigned int alt, unsigned int dummy_cnt, unsigned int address, char *rx_buffer, size_t *rx_length)
+qspi_status_t QSPI::read(unsigned int instruction, unsigned int alt, unsigned int address, char *rx_buffer, size_t *rx_length)
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
@@ -145,7 +147,7 @@ qspi_status_t QSPI::read(unsigned int instruction, unsigned int alt, unsigned in
if (*rx_length != 0) {
lock();
if ( true == _acquire()) {
- _build_qspi_command(instruction, address, alt, dummy_cnt);
+ _build_qspi_command(instruction, address, alt);
if (QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
@@ -160,7 +162,7 @@ qspi_status_t QSPI::read(unsigned int instruction, unsigned int alt, unsigned in
return ret_status;
}
-qspi_status_t QSPI::write(unsigned int instruction, unsigned int alt, unsigned int dummy_cnt, unsigned int address, const char *tx_buffer, size_t *tx_length)
+qspi_status_t QSPI::write(unsigned int instruction, unsigned int alt, unsigned int address, const char *tx_buffer, size_t *tx_length)
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
@@ -169,7 +171,7 @@ qspi_status_t QSPI::write(unsigned int instruction, unsigned int alt, unsigned i
if (*tx_length != 0) {
lock();
if (true == _acquire()) {
- _build_qspi_command(instruction, address, alt, dummy_cnt);
+ _build_qspi_command(instruction, address, alt);
if (QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
ret_status = QSPI_STATUS_OK;
}
@@ -191,7 +193,7 @@ qspi_status_t QSPI::command_transfer(unsigned int instruction, int address, cons
if (_initialized) {
lock();
if (true == _acquire()) {
- _build_qspi_command(instruction, address, -1, 0); //We just need the command
+ _build_qspi_command(instruction, address, -1); //We just need the command
if (QSPI_STATUS_OK == qspi_command_transfer(&_qspi, &_qspi_command, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
@@ -240,7 +242,7 @@ bool QSPI::_acquire()
return _initialized;
}
-void QSPI::_build_qspi_command(int instruction, int address, int alt, int dummy_cnt)
+void QSPI::_build_qspi_command(int instruction, int address, int alt)
{
memset( &_qspi_command, 0, sizeof(qspi_command_t) );
//Set up instruction phase parameters
@@ -272,7 +274,7 @@ void QSPI::_build_qspi_command(int instruction, int address, int alt, int dummy_
_qspi_command.alt.disabled = true;
}
- _qspi_command.dummy_count = dummy_cnt;
+ _qspi_command.dummy_count = _num_dummy_cycles;
//Set up bus width for data phase
_qspi_command.data.bus_width = _data_width;
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index 09a7549db1..ecf2d43e12 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -135,7 +135,6 @@ public:
*
* @param instruction Instruction value to be used in instruction phase
* @param alt Alt value to be used in instruction phase
- * @param dummy_cnt Amount of dummy cycles to be sent after instruction phase
* @param address Address to be accessed in QSPI peripheral
* @param rx_buffer Buffer for data to be read from the peripheral
* @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
@@ -143,13 +142,12 @@ public:
* @returns
* Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
- qspi_status_t read(unsigned int instruction, unsigned int alt, unsigned int dummy_cnt, unsigned int address, char *rx_buffer, size_t *rx_length);
+ qspi_status_t read(unsigned int instruction, unsigned int alt, unsigned int address, char *rx_buffer, size_t *rx_length);
/** Write to QSPI peripheral using custom write instruction, alt values
*
* @param instruction Instruction value to be used in instruction phase
* @param alt Alt value to be used in instruction phase
- * @param dummy_cnt Amount of dummy cycles to be sent after instruction phase
* @param address Address to be accessed in QSPI peripheral
* @param tx_buffer Buffer containing data to be sent to peripheral
* @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
@@ -157,7 +155,7 @@ public:
* @returns
* Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
*/
- qspi_status_t write(unsigned int instruction, unsigned int alt, unsigned int dummy_cnt, unsigned int address, const char *tx_buffer, size_t *tx_length);
+ qspi_status_t write(unsigned int instruction, unsigned int alt, unsigned int address, const char *tx_buffer, size_t *tx_length);
/** Perform a transaction to write to an address(a control register) and get the status results
*
@@ -198,6 +196,7 @@ protected:
qspi_alt_size_t _alt_size;
qspi_bus_width_t _data_width; //Bus width for Data phase
qspi_command_t _qspi_command; //QSPI Hal command struct
+ unsigned int _num_dummy_cycles; //Number of dummy cycles to be used
int _hz; //Bus Frequency
int _mode; //SPI mode
bool _initialized;
@@ -213,7 +212,7 @@ private:
/*
* This function builds the qspi command struct to be send to Hal
*/
- inline void _build_qspi_command(int instruction, int address, int alt, int dummy_cnt);
+ inline void _build_qspi_command(int instruction, int address, int alt);
};
} // namespace mbed
From 50b822594852700a4ad2a766e4233b4fa8314f95 Mon Sep 17 00:00:00 2001
From: adustm
Date: Mon, 9 Apr 2018 11:41:02 +0200
Subject: [PATCH 52/78] Enable QSPI feature for DISCO_F413ZH platform
---
.../TARGET_DISCO_F413ZH/PeripheralNames.h | 4 ++
.../TARGET_DISCO_F413ZH/PeripheralPins.c | 40 +++++++++++++++++++
.../TARGET_STM32F413xH/objects.h | 4 ++
targets/targets.json | 2 +-
4 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PeripheralNames.h
index 22ad0b3f55..3493e2cd25 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PeripheralNames.h
@@ -79,6 +79,10 @@ typedef enum {
CAN_3 = (int)CAN3_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PeripheralPins.c
index 3f5be12738..cf3b81ab5f 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PeripheralPins.c
@@ -399,3 +399,43 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PG_12, CAN_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, // Connected to WIFI_DRDY
{NC, NC, 0}
};
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO0
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO1
+ {PC_4, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO2
+ {PC_5, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO3
+ {PC_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO2
+ {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO0
+ {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO1
+ {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0
+ {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1
+ {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3, N25Q128A13EF840F
+ {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2, N25Q128A13EF840F
+ {PE_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO0
+ {PE_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO1
+ {PE_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO2
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO3
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO0, N25Q128A13EF840F
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO1, N25Q128A13EF840F
+ {PG_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO2
+ {PG_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO3
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
+ {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // N25Q128A13EF840F
+ {PD_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_NCS
+ {PG_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS, N25Q128A13EF840F
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h
index 9b3aa0b3f9..85d6d2667b 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h
@@ -44,6 +44,10 @@ struct trng_s {
RNG_HandleTypeDef handle;
};
+struct qspi_s {
+ QSPI_HandleTypeDef handle;
+};
+
#include "common_objects.h"
#ifdef __cplusplus
diff --git a/targets/targets.json b/targets/targets.json
index c505f59657..ab0f50fd42 100755
--- a/targets/targets.json
+++ b/targets/targets.json
@@ -1260,7 +1260,7 @@
},
"detect_code": ["0743"],
"macros_add": ["USB_STM_HAL", "USBHOST_OTHER"],
- "device_has_add": ["ANALOGOUT", "CAN", "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", "FLASH"],
+ "device_has_add": ["ANALOGOUT", "CAN", "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", "FLASH", "QSPI"],
"release_versions": ["2", "5"],
"device_name": "STM32F413ZH"
},
From 9b4b28fc3f88880a8c000b51de694a03d6cc0e3c Mon Sep 17 00:00:00 2001
From: adustm
Date: Mon, 9 Apr 2018 17:20:53 +0200
Subject: [PATCH 53/78] Support maximum flash size : 4Gbytes
---
targets/TARGET_STM/qspi_api.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index 1b1c6af9f9..2069e7805c 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -34,7 +34,9 @@
#include "pinmap.h"
#include "PeripheralPins.h"
-#define QSPI_FLASH_SIZE_DEFAULT 0x800000
+/* Max amount of flash size is 4Gbytes */
+/* hence 2^(31+1), then FLASH_SIZE_DEFAULT = 31<<20 */
+#define QSPI_FLASH_SIZE_DEFAULT 0x1F00000
void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st_command)
{
From 293d1bda42bc05b7f17941d9f702160b6788a3fd Mon Sep 17 00:00:00 2001
From: adustm
Date: Tue, 10 Apr 2018 11:41:49 +0200
Subject: [PATCH 54/78] Add MBED_WEAK for pins
---
.../TARGET_DISCO_F469NI/PeripheralPins.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
index 81fbb3f231..1e2970c096 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
@@ -390,21 +390,20 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
};
-const PinMap PinMap_QSPI_DATA[] = {
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
{PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
{PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
- {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
{PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
-
{NC, NC, 0}
};
-const PinMap PinMap_QSPI_SCLK[] = {
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
{PF_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
{NC, NC, 0}
};
-const PinMap PinMap_QSPI_SSEL[] = {
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
{PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
{NC, NC, 0}
};
From c00e49fcf2cc5fbbef767392c790bb0ffa07a756 Mon Sep 17 00:00:00 2001
From: adustm
Date: Tue, 10 Apr 2018 17:18:40 +0200
Subject: [PATCH 55/78] Enable QSPI for DISCO_F746NG
---
.../TARGET_DISCO_F746NG/PeripheralNames.h | 4 ++
.../TARGET_DISCO_F746NG/PeripheralPins.c | 37 +++++++++++++++++++
.../TARGET_STM32F746xG/objects.h | 4 ++
targets/targets.json | 2 +-
4 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/PeripheralNames.h
index 0c00d43bf5..771553bb53 100644
--- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/PeripheralNames.h
@@ -93,6 +93,10 @@ typedef enum {
CAN_2 = (int)CAN2_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/PeripheralPins.c
index 6c9c3bec71..e542065510 100644
--- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/PeripheralPins.c
@@ -406,3 +406,40 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PH_13, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, // Connected to DCMI_PWR_EN
{NC, NC, 0}
};
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+// {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
+// {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+// {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
+// {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
+// {PC_11, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
+ {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // IO0 connected to N25Q128
+ {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // IO1 connected to N25Q128
+ {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // IO3 connected to N25Q128
+ {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // IO2 connected to N25Q128
+// {PE_7, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+// {PE_8, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+// {PE_9, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+// {PE_10, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // IO3 connected to pin A5
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // IO2 connected to pin A4
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO0 connected to pin A3
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO1 connected to pin A2
+// {PG_9, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
+// {PG_14, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
+// {PH_2, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
+// {PH_3, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // connected to N25Q128 flash
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // connected to N25Q128 flash
+// {PC_11, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
+ {NC, NC, 0}
+};
+
diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h
index 2894691118..9ccc1c28d4 100644
--- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h
+++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h
@@ -58,6 +58,10 @@ struct trng_s {
RNG_HandleTypeDef handle;
};
+struct qspi_s {
+ QSPI_HandleTypeDef handle;
+};
+
#include "common_objects.h"
#ifdef __cplusplus
diff --git a/targets/targets.json b/targets/targets.json
index ab0f50fd42..0f9e2aa058 100755
--- a/targets/targets.json
+++ b/targets/targets.json
@@ -2081,7 +2081,7 @@
},
"detect_code": ["0815"],
"macros_add": ["USB_STM_HAL", "USBHOST_OTHER"],
- "device_has_add": ["ANALOGOUT", "CAN", "EMAC", "SERIAL_ASYNCH", "TRNG", "FLASH"],
+ "device_has_add": ["ANALOGOUT", "CAN", "EMAC", "SERIAL_ASYNCH", "TRNG", "FLASH", "QSPI"],
"release_versions": ["2", "5"],
"device_name": "STM32F746NG",
"overrides": {
From 2f06423a8964940b584135dd8623696f31252cd8 Mon Sep 17 00:00:00 2001
From: adustm
Date: Tue, 10 Apr 2018 18:42:35 +0200
Subject: [PATCH 56/78] Add support for QSPI on DISCO_L476VG
---
.../TARGET_DISCO_L476VG/PeripheralNames.h | 4 +++
.../TARGET_DISCO_L476VG/PeripheralPins.c | 26 +++++++++++++++++++
.../TARGET_STM32L476xG/objects.h | 4 +++
targets/targets.json | 2 +-
4 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/PeripheralNames.h
index bc8f43ffa8..553aab47cf 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/PeripheralNames.h
@@ -83,6 +83,10 @@ typedef enum {
CAN_1 = (int)CAN1_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/PeripheralPins.c
index 1207a19095..bafe58975e 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/PeripheralPins.c
@@ -340,3 +340,29 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PD_1, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, // Connected to MEMS_SCK [L3GD20_SCL/SPC]
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO3 not connected
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO2 not connected
+ {PB_0, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO1 not connected
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO0 not connected
+ {PE_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO0 connected to N25Q128
+ {PE_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO1 connected to N25Q128
+ {PE_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO2 connected to N25Q128
+ {PE_15, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO3 connected to N25Q128
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+// {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // connected to N25Q128
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+// {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
+ {PE_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // connected to N25Q128
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h
index ece5f1679f..95148ef88d 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h
@@ -58,6 +58,10 @@ struct trng_s {
RNG_HandleTypeDef handle;
};
+struct qspi_s {
+ QSPI_HandleTypeDef handle;
+};
+
#include "common_objects.h"
#ifdef __cplusplus
diff --git a/targets/targets.json b/targets/targets.json
index 0f9e2aa058..ce9b1705e2 100755
--- a/targets/targets.json
+++ b/targets/targets.json
@@ -2172,7 +2172,7 @@
},
"detect_code": ["0820"],
"macros_add": ["USBHOST_OTHER", "TWO_RAM_REGIONS"],
- "device_has_add": ["ANALOGOUT", "CAN", "SERIAL_FC", "TRNG", "FLASH"],
+ "device_has_add": ["ANALOGOUT", "CAN", "SERIAL_FC", "TRNG", "FLASH", "QSPI"],
"release_versions": ["2", "5"],
"device_name": "STM32L476VG",
"bootloader_supported": true
From dd4e2363403caa7c0039d9007bcc411bf8ebf033 Mon Sep 17 00:00:00 2001
From: Martin Kojtal
Date: Tue, 24 Apr 2018 12:11:43 +0100
Subject: [PATCH 57/78] QSPI: add doxygen options
---
doxyfile_options | 1 +
doxygen_options.json | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/doxyfile_options b/doxyfile_options
index fb8d1f7bca..b3d9e2bfea 100644
--- a/doxyfile_options
+++ b/doxyfile_options
@@ -2093,6 +2093,7 @@ PREDEFINED = DOXYGEN_ONLY \
DEVICE_SPI \
DEVICE_SPI_ASYNCH \
DEVICE_SPISLAVE \
+ DEVICE_QSPI \
DEVICE_STORAGE \
"MBED_DEPRECATED_SINCE(d, m)=" \
"MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M)=" \
diff --git a/doxygen_options.json b/doxygen_options.json
index 6884a64883..971748f333 100644
--- a/doxygen_options.json
+++ b/doxygen_options.json
@@ -6,7 +6,7 @@
"SEARCH_INCLUDES": "YES",
"INCLUDE_PATH": "",
"INCLUDE_FILE_PATTERNS": "",
- "PREDEFINED": "DOXYGEN_ONLY DEVICE_ANALOGIN DEVICE_ANALOGOUT DEVICE_CAN DEVICE_CRC DEVICE_ETHERNET DEVICE_EMAC DEVICE_FLASH DEVICE_I2C DEVICE_I2CSLAVE DEVICE_I2C_ASYNCH DEVICE_INTERRUPTIN DEVICE_ITM DEVICE_LPTICKER DEVICE_PORTIN DEVICE_PORTINOUT DEVICE_PORTOUT DEVICE_PWMOUT DEVICE_RTC DEVICE_TRNG DEVICE_SERIAL DEVICE_SERIAL_ASYNCH DEVICE_SERIAL_FC DEVICE_SLEEP DEVICE_SPI DEVICE_SPI_ASYNCH DEVICE_SPISLAVE DEVICE_STORAGE \"MBED_DEPRECATED_SINCE(f, g)=\" \"MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M)=\" \"MBED_DEPRECATED(s)=\"",
+ "PREDEFINED": "DOXYGEN_ONLY DEVICE_ANALOGIN DEVICE_ANALOGOUT DEVICE_CAN DEVICE_CRC DEVICE_ETHERNET DEVICE_EMAC DEVICE_FLASH DEVICE_I2C DEVICE_I2CSLAVE DEVICE_I2C_ASYNCH DEVICE_INTERRUPTIN DEVICE_ITM DEVICE_LPTICKER DEVICE_PORTIN DEVICE_PORTINOUT DEVICE_PORTOUT DEVICE_PWMOUT DEVICE_RTC DEVICE_TRNG DEVICE_SERIAL DEVICE_SERIAL_ASYNCH DEVICE_SERIAL_FC DEVICE_SLEEP DEVICE_SPI DEVICE_SPI_ASYNCH DEVICE_SPISLAVE DEVICE_QSPI DEVICE_STORAGE \"MBED_DEPRECATED_SINCE(f, g)=\" \"MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M)=\" \"MBED_DEPRECATED(s)=\"",
"EXPAND_AS_DEFINED": "",
"SKIP_FUNCTION_MACROS": "NO",
"STRIP_CODE_COMMENTS": "NO",
From d444abcc96769539badc33bd45f106e4373662df Mon Sep 17 00:00:00 2001
From: Martin Kojtal
Date: Tue, 24 Apr 2018 13:26:12 +0100
Subject: [PATCH 58/78] QSPI: fix doxy hal documentation
---
hal/qspi_api.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hal/qspi_api.h b/hal/qspi_api.h
index 144f4f43d4..10bd77130b 100644
--- a/hal/qspi_api.h
+++ b/hal/qspi_api.h
@@ -160,9 +160,9 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void
* @param obj QSPI object
* @param command QSPI command
* @param tx_data TX buffer
- * @param tx_length TX buffer length in bytes
+ * @param tx_size TX buffer length in bytes
* @param rx_data RX buffer
- * @param rx_length RX buffer length in bytes
+ * @param rx_size RX buffer length in bytes
* @return QSPI_STATUS_OK if the data has been succesfully sent
QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
QSPI_STATUS_ERROR otherwise
From 1f4cc95f253322dc72dff3a0c37184437b1acce6 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Fri, 22 Jun 2018 11:29:56 +0200
Subject: [PATCH 59/78] fix qspi command transfer for NORDIC
Add address unpacking support.
Only used in erase commands
---
targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c | 26 +++++++++++++------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
index 849970a093..317cb029df 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
@@ -241,7 +241,6 @@ qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data,
qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command, const void *tx_data, size_t tx_size, void *rx_data, size_t rx_size)
{
ret_code_t ret_code;
- uint32_t i;
uint8_t data[8];
uint32_t data_size = tx_size + rx_size;
@@ -252,24 +251,35 @@ qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command,
qspi_cinstr_config.wipwait = false;
qspi_cinstr_config.wren = false;
- if (data_size < 9) {
+ if(!command->address.disabled && data_size == 0) {
+ // erase command with address
+ if (command->address.size == QSPI_CFG_ADDR_SIZE_24) {
+ qspi_cinstr_config.length = NRF_QSPI_CINSTR_LEN_4B;
+ } else if (command->address.size == QSPI_CFG_ADDR_SIZE_32) {
+ qspi_cinstr_config.length = NRF_QSPI_CINSTR_LEN_5B;
+ } else {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ }
+ for (uint32_t i = 0; i < (uint32_t)qspi_cinstr_config.length - 1; ++i) {
+ data[i] = ((uint8_t *)&command->address.value)[i];
+ }
+ } else if (data_size < 9) {
qspi_cinstr_config.length = (nrf_qspi_cinstr_len_t)(NRF_QSPI_CINSTR_LEN_1B + data_size);
+ // preparing data to send
+ for (uint32_t i = 0; i < tx_size; ++i) {
+ data[i] = ((uint8_t *)tx_data)[i];
+ }
} else {
return QSPI_STATUS_ERROR;
}
- // preparing data to send
- for (i = 0; i < tx_size; ++i) {
- data[i] = ((uint8_t *)tx_data)[i];
- }
-
ret_code = nrf_drv_qspi_cinstr_xfer(&qspi_cinstr_config, data, data);
if (ret_code != NRF_SUCCESS) {
return QSPI_STATUS_ERROR;
}
// preparing received data
- for (i = 0; i < rx_size; ++i) {
+ for (uint32_t i = 0; i < rx_size; ++i) {
// Data is sending as a normal SPI transmission so there is one buffer to send and receive data.
((uint8_t *)rx_data)[i] = data[i];
}
From 42935bbdc081f610e415db30750a72aa6bd05285 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Mon, 25 Jun 2018 11:19:18 +0200
Subject: [PATCH 60/78] STM qspi: temporary fix for qspi_free return value
---
targets/TARGET_STM/qspi_api.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index 2069e7805c..3f8d6037cf 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -192,7 +192,8 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
qspi_status_t qspi_free(qspi_t *obj)
{
// TODO
- return QSPI_STATUS_ERROR;
+ //return QSPI_STATUS_ERROR;
+ return QSPI_STATUS_OK;
}
qspi_status_t qspi_frequency(qspi_t *obj, int hz)
From 67798d6eb2f755b584dcb9262e5c878724a3b105 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Mon, 25 Jun 2018 11:21:26 +0200
Subject: [PATCH 61/78] STM: add qspi pin names for DISCO_L475VG_IOT01A
---
.../TARGET_DISCO_L475VG_IOT01A/PinNames.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PinNames.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PinNames.h
index 6bc541ec78..7b69f7ea21 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PinNames.h
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PinNames.h
@@ -240,6 +240,14 @@ typedef enum {
SPI_SCK = D13,
SPI_CS = D10,
PWM_OUT = D9,
+#ifdef DEVICE_QSPI
+ QSPI_PIN_IO0 = PE_12,
+ QSPI_PIN_IO1 = PE_13,
+ QSPI_PIN_IO2 = PE_14,
+ QSPI_PIN_IO3 = PE_15,
+ QSPI_PIN_SCK = PE_10,
+ QSPI_PIN_CSN = PE_11,
+#endif
/**** USB pins ****/
USB_OTG_FS_DM = PA_11,
From c2cc559aa789f2bec1ce9bafcdc583a855021bd1 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Mon, 25 Jun 2018 11:50:42 +0200
Subject: [PATCH 62/78] NRF5: fix qspi custom command sending
---
targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
index 317cb029df..34d4e5c555 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
@@ -246,8 +246,8 @@ qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command,
nrf_qspi_cinstr_conf_t qspi_cinstr_config;
qspi_cinstr_config.opcode = command->instruction.value;
- qspi_cinstr_config.io2_level = false;
- qspi_cinstr_config.io3_level = false;
+ qspi_cinstr_config.io2_level = true;
+ qspi_cinstr_config.io3_level = true;
qspi_cinstr_config.wipwait = false;
qspi_cinstr_config.wren = false;
From 8b36d6b39ae39f36ecdfdec17f4b6e19b4b1cd72 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Mon, 25 Jun 2018 11:53:18 +0200
Subject: [PATCH 63/78] NRF5: fix qspi R/W opcodes mapping
---
targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c | 176 +++++++++++-------
1 file changed, 107 insertions(+), 69 deletions(-)
diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
index 34d4e5c555..39e25df550 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
+++ b/targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c
@@ -56,6 +56,18 @@ TODO
#define MBED_HAL_QSPI_HZ_TO_CONFIG(hz) ((32000000/(hz))-1)
#define MBED_HAL_QSPI_MAX_FREQ 32000000UL
+// NRF supported R/W opcodes
+#define FAST_READ_opcode 0x0B
+#define READ2O_opcode 0x3B
+#define READ2IO_opcode 0xBB
+#define READ4O_opcode 0x6B
+#define READ4IO_opcode 0xEB
+
+#define PP_opcode 0x02
+#define PP2O_opcode 0xA2
+#define PP4O_opcode 0x32
+#define PP4IO_opcode 0x38
+
static nrf_drv_qspi_config_t config;
// Private helper function to track initialization
@@ -63,93 +75,119 @@ static ret_code_t _qspi_drv_init(void);
qspi_status_t qspi_prepare_command(qspi_t *obj, const qspi_command_t *command, bool write)
{
- //Use custom command if provided by the caller
- if(command->instruction.value != 0) {
- //Use custom command if provided
+ // we need to remap opcodes to NRF ID's
+ // most commmon are 1-1-1, 1-1-4, 1-4-4
+
+ // 1-1-1
+ if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->data.bus_width == QSPI_CFG_BUS_SINGLE) {
if (write) {
- config.prot_if.writeoc = (nrf_qspi_writeoc_t)command->instruction.value;
- } else {
- config.prot_if.readoc = (nrf_qspi_readoc_t)command->instruction.value;
- }
- } else {
- // we need to remap to command-address-data - x_x_x
- // most commmon are 1-1-1, 1-1-4, 1-4-4
- // 1-1-1
- if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
- command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
- command->data.bus_width == QSPI_CFG_BUS_SINGLE) {
- if (write) {
+ if (command->instruction.value == PP_opcode) {
config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP;
} else {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ }
+ } else {
+ if (command->instruction.value == FAST_READ_opcode) {
config.prot_if.readoc = NRF_QSPI_READOC_FASTREAD;
- }
- // 1-1-4
- } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
- command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
- command->data.bus_width == QSPI_CFG_BUS_QUAD) {
- // 1_1_4
- if (write) {
- config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4O;
} else {
- config.prot_if.readoc = NRF_QSPI_READOC_READ4O;
- }
- // 1-4-4
- } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
- command->address.bus_width == QSPI_CFG_BUS_QUAD &&
- command->data.bus_width == QSPI_CFG_BUS_QUAD) {
- // 1_4_4
- if (write) {
- config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4IO;
- } else {
- config.prot_if.readoc = NRF_QSPI_READOC_READ4IO;
- }
- // 1-1-2
- } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
- command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
- command->data.bus_width == QSPI_CFG_BUS_DUAL) {
- // 1-1-2
- if (write) {
- config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP2O;
- } else {
- config.prot_if.readoc = NRF_QSPI_READOC_READ2O;
- }
- // 1-2-2
- } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
- command->address.bus_width == QSPI_CFG_BUS_DUAL &&
- command->data.bus_width == QSPI_CFG_BUS_DUAL) {
- // 1-2-2
- if (write) {
- //Currently NRF52840 does not define PP2IO, so use PP2O for 1-2-2 mode
- config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP2O;
- } else {
- config.prot_if.readoc = NRF_QSPI_READOC_READ2IO;
+ return QSPI_STATUS_INVALID_PARAMETER;
}
}
- }
+ // 1-1-4
+ } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->data.bus_width == QSPI_CFG_BUS_QUAD) {
+ // 1_1_4
+ if (write) {
+ if (command->instruction.value == PP4O_opcode) {
+ config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4O;
+ } else {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ }
+ } else {
+ if (command->instruction.value == READ4O_opcode) {
+ config.prot_if.readoc = NRF_QSPI_READOC_READ4O;
+ } else {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ }
+ }
+ // 1-4-4
+ } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->address.bus_width == QSPI_CFG_BUS_QUAD &&
+ command->data.bus_width == QSPI_CFG_BUS_QUAD) {
+ // 1_4_4
+ if (write) {
+ if (command->instruction.value == PP4IO_opcode) {
+ config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4IO;
+ } else {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ }
+ } else {
+ if (command->instruction.value == READ4IO_opcode) {
+ config.prot_if.readoc = NRF_QSPI_READOC_READ4IO;
+ } else {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ }
+ }
+ // 1-1-2
+ } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->data.bus_width == QSPI_CFG_BUS_DUAL) {
+ // 1-1-2
+ if (write) {
+ if (command->instruction.value == PP2O_opcode) {
+ config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP2O;
+ } else {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ }
+ } else {
+ if (command->instruction.value == READ2O_opcode) {
+ config.prot_if.readoc = NRF_QSPI_READOC_READ2O;
+ } else {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ }
+ }
+ // 1-2-2
+ } else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
+ command->address.bus_width == QSPI_CFG_BUS_DUAL &&
+ command->data.bus_width == QSPI_CFG_BUS_DUAL) {
+ // 1-2-2
+ if (write) {
+ // 1-2-2 write is not supported
+ return QSPI_STATUS_INVALID_PARAMETER;
+ } else {
+ if (command->instruction.value == READ2IO_opcode) {
+ config.prot_if.readoc = NRF_QSPI_READOC_READ2IO;
+ } else {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ }
+ }
+ } else {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ }
- qspi_status_t ret = QSPI_STATUS_OK;
// supporting only 24 or 32 bit address
if (command->address.size == QSPI_CFG_ADDR_SIZE_24) {
config.prot_if.addrmode = NRF_QSPI_ADDRMODE_24BIT;
} else if (command->address.size == QSPI_CFG_ADDR_SIZE_32) {
config.prot_if.addrmode = NRF_QSPI_ADDRMODE_32BIT;
} else {
- ret = QSPI_STATUS_INVALID_PARAMETER;
+ return QSPI_STATUS_INVALID_PARAMETER;
}
//Configure QSPI with new command format
- if(ret == QSPI_STATUS_OK) {
- ret_code_t ret_status = _qspi_drv_init();
- if (ret_status != NRF_SUCCESS ) {
- if (ret_status == NRF_ERROR_INVALID_PARAM) {
- return QSPI_STATUS_INVALID_PARAMETER;
- } else {
- return QSPI_STATUS_ERROR;
- }
+ ret_code_t ret_status = _qspi_drv_init();
+ if (ret_status != NRF_SUCCESS ) {
+ if (ret_status == NRF_ERROR_INVALID_PARAM) {
+ return QSPI_STATUS_INVALID_PARAMETER;
+ } else {
+ return QSPI_STATUS_ERROR;
}
}
- return ret;
+ return QSPI_STATUS_OK;
}
qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel, uint32_t hz, uint8_t mode)
@@ -169,8 +207,8 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
config.pins.io3_pin = (uint32_t)io3;
config.irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY;
- config.phy_if.sck_freq = (nrf_qspi_frequency_t)MBED_HAL_QSPI_HZ_TO_CONFIG(hz),
- config.phy_if.sck_delay = 0x05,
+ config.phy_if.sck_freq = (nrf_qspi_frequency_t)MBED_HAL_QSPI_HZ_TO_CONFIG(hz);
+ config.phy_if.sck_delay = 0x05;
config.phy_if.dpmen = false;
config.phy_if.spi_mode = mode == 0 ? NRF_QSPI_MODE_0 : NRF_QSPI_MODE_1;
From 443273785f4e4b204b6a304c0b612dcf0775b863 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Tue, 26 Jun 2018 09:03:25 +0200
Subject: [PATCH 64/78] add hal-qspi test
---
.../qspi/flash_configs/MX25R6435F_config.h | 109 +++++
.../NORDIC/NRF52840_DK/flash_config.h | 33 ++
.../STM/DISCO_L475VG_IOT01A/flash_config.h | 26 ++
.../qspi/flash_configs/flash_configs.h | 26 ++
TESTS/mbed_hal/qspi/main.cpp | 409 ++++++++++++++++++
TESTS/mbed_hal/qspi/qspi_test.h | 98 +++++
TESTS/mbed_hal/qspi/qspi_test_utils.cpp | 232 ++++++++++
TESTS/mbed_hal/qspi/qspi_test_utils.h | 117 +++++
8 files changed, 1050 insertions(+)
create mode 100644 TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h
create mode 100644 TESTS/mbed_hal/qspi/flash_configs/NORDIC/NRF52840_DK/flash_config.h
create mode 100644 TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_L475VG_IOT01A/flash_config.h
create mode 100644 TESTS/mbed_hal/qspi/flash_configs/flash_configs.h
create mode 100644 TESTS/mbed_hal/qspi/main.cpp
create mode 100644 TESTS/mbed_hal/qspi/qspi_test.h
create mode 100644 TESTS/mbed_hal/qspi/qspi_test_utils.cpp
create mode 100644 TESTS/mbed_hal/qspi/qspi_test_utils.h
diff --git a/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h b/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h
new file mode 100644
index 0000000000..80e68f007b
--- /dev/null
+++ b/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h
@@ -0,0 +1,109 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_QSPI_FLASH_MX25R6435F_H
+#define MBED_QSPI_FLASH_MX25R6435F_H
+
+
+#define QSPI_FLASH_CHIP_STRING "MX25R6435F"
+
+// Command for reading status register
+#define QSPI_CMD_RDSR 0x05
+// Command for reading configuration register
+#define QSPI_CMD_RDCR 0x15
+// Command for writing status/configuration register
+#define QSPI_CMD_WRSR 0x01
+// Command for reading security register
+#define QSPI_CMD_RDSCUR 0x2B
+
+// Command for setting Reset Enable
+#define QSPI_CMD_RSTEN 0x66
+// Command for setting Reset
+#define QSPI_CMD_RST 0x99
+
+// Command for setting write enable
+#define QSPI_CMD_WREN 0x06
+// Command for setting write disable
+#define QSPI_CMD_WRDI 0x04
+
+// WRSR operations max time [us] (datasheet max time + 15%)
+#define QSPI_WRSR_MAX_TIME 34500 // 30ms
+// general wait max time [us]
+#define QSPI_WAIT_MAX_TIME 10000 // 100ms
+
+
+// Commands for writing (page programming)
+#define QSPI_CMD_WRITE_1IO 0x02 // 1-1-1 mode
+#define QSPI_CMD_WRITE_4IO 0x38 // 1-4-4 mode
+
+// write operations max time [us] (datasheet max time + 15%)
+#define QSPI_PAGE_PROG_MAX_TIME 11500 // 10ms
+
+#define QSPI_PAGE_SIZE 256 // 256B
+
+// Commands for reading
+#define QSPI_CMD_READ_1IO_FAST 0x0B // 1-1-1 mode
+#define QSPI_CMD_READ_1IO 0x03 // 1-1-1 mode
+#define QSPI_CMD_READ_2IO 0xBB // 1-2-2 mode
+#define QSPI_CMD_READ_1I2O 0x3B // 1-1-2 mode
+#define QSPI_CMD_READ_4IO 0xEB // 1-4-4 mode
+#define QSPI_CMD_READ_1I4O 0x6B // 1-1-4 mode
+
+#define QSPI_READ_1IO_DUMMY_CYCLE 0
+#define QSPI_READ_FAST_DUMMY_CYCLE 8
+#define QSPI_READ_2IO_DUMMY_CYCLE 4
+#define QSPI_READ_1I2O_DUMMY_CYCLE 8
+#define QSPI_READ_4IO_DUMMY_CYCLE 6
+#define QSPI_READ_1I4O_DUMMY_CYCLE 8
+
+// Commands for erasing
+#define QSPI_CMD_ERASE_SECTOR 0x20 // 4kB
+#define QSPI_CMD_ERASE_BLOCK_32 0x52 // 32kB
+#define QSPI_CMD_ERASE_BLOCK_64 0xD8 // 64kB
+#define QSPI_CMD_ERASE_CHIP 0x60 // or 0xC7
+
+// erase operations max time [us] (datasheet max time + 15%)
+#define QSPI_ERASE_SECTOR_MAX_TIME 276000 // 240 ms
+#define QSPI_ERASE_BLOCK_32_MAX_TIME 3000000 // 3s
+#define QSPI_ERASE_BLOCK_64_MAX_TIME 3500000 // 3.5s
+
+// max frequency for basic rw operation
+#define QSPI_COMMON_MAX_FREQUENCY 32000000
+
+#define QSPI_STATUS_REGISTER_SIZE 1
+#define QSPI_CONFIGURATION_REGISTER_SIZE 2
+#define QSPI_SECURITY_REGISTER_SIZE 1
+
+// status register
+#define STATUS_BIT_WIP (1 << 0) // write in progress bit
+#define STATUS_BIT_WEL (1 << 1) // write enable latch
+#define STATUS_BIT_BP0 (1 << 2) //
+#define STATUS_BIT_BP1 (1 << 3) //
+#define STATUS_BIT_BP2 (1 << 4) //
+#define STATUS_BIT_BP3 (1 << 5) //
+#define STATUS_BIT_QE (1 << 6) // Quad Enable
+#define STATUS_BIT_SRWD (1 << 7) // status register write protect
+
+// configuration register 0
+// bit 0, 1, 2, 4, 5, 7 reserved
+#define CONFIG0_BIT_TB (1 << 3) // Top/Bottom area protect
+#define CONFIG0_BIT_DC (1 << 6) // Dummy Cycle
+
+// configuration register 1
+// bit 0, 2, 3, 4, 5, 6, 7 reserved
+#define CONFIG1_BIT_LH (1 << 1) // 0 = Ultra Low power mode, 1 = High performance mode
+
+
+#endif // MBED_QSPI_FLASH_MX25R6435F_H
diff --git a/TESTS/mbed_hal/qspi/flash_configs/NORDIC/NRF52840_DK/flash_config.h b/TESTS/mbed_hal/qspi/flash_configs/NORDIC/NRF52840_DK/flash_config.h
new file mode 100644
index 0000000000..ed288ba50a
--- /dev/null
+++ b/TESTS/mbed_hal/qspi/flash_configs/NORDIC/NRF52840_DK/flash_config.h
@@ -0,0 +1,33 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_QSPI_FLASH_CONFIG_H
+#define MBED_QSPI_FLASH_CONFIG_H
+
+#include "../../MX25R6435F_config.h"
+
+// NRF doesn't uses read/write opcodes, instead it uses commands id's.
+// Before sending it to H/W opcodes are mapped to id's in Mbed hal qspi implementation
+//
+// for more details see:
+// targets\TARGET_NORDIC\TARGET_NRF5x\TARGET_SDK_14_2\device\nrf52840_bitfields.h
+// targets\TARGET_NORDIC\TARGET_NRF5x\qspi_api.c
+
+// NRF doesn't support read 1IO (opcode 0x03)
+#undef QSPI_CMD_READ_1IO
+#define QSPI_CMD_READ_1IO QSPI_CMD_READ_1IO_FAST
+
+
+#endif // MBED_QSPI_FLASH_CONFIG_H
diff --git a/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_L475VG_IOT01A/flash_config.h b/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_L475VG_IOT01A/flash_config.h
new file mode 100644
index 0000000000..69392426c4
--- /dev/null
+++ b/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_L475VG_IOT01A/flash_config.h
@@ -0,0 +1,26 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_QSPI_FLASH_CONFIG_H
+#define MBED_QSPI_FLASH_CONFIG_H
+
+#include "../../MX25R6435F_config.h"
+
+// TODO: remove when fixed
+// when perform 4IO write, when memory indicates write finish (changing WIP bit in status register)
+// but actually write is still in progress and we have to wait a bit more before reading
+#define STM_DISCO_L475VG_IOT01A_WRITE_4IO_BUG_WORKAROUND
+
+#endif // MBED_QSPI_FLASH_CONFIG_H
diff --git a/TESTS/mbed_hal/qspi/flash_configs/flash_configs.h b/TESTS/mbed_hal/qspi/flash_configs/flash_configs.h
new file mode 100644
index 0000000000..9f2ca0ef55
--- /dev/null
+++ b/TESTS/mbed_hal/qspi/flash_configs/flash_configs.h
@@ -0,0 +1,26 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBED_FLASH_CONFIGS_H
+#define MBED_FLASH_CONFIGS_H
+
+#if defined(TARGET_DISCO_L475VG_IOT01A)
+#include "STM/DISCO_L475VG_IOT01A/flash_config.h"
+#elif defined(TARGET_NRF52840)
+#include "NORDIC/NRF52840_DK/flash_config.h"
+#endif
+
+#endif // MBED_FLASH_CONFIGS_H
diff --git a/TESTS/mbed_hal/qspi/main.cpp b/TESTS/mbed_hal/qspi/main.cpp
new file mode 100644
index 0000000000..62b029d971
--- /dev/null
+++ b/TESTS/mbed_hal/qspi/main.cpp
@@ -0,0 +1,409 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if !DEVICE_QSPI
+#error [NOT_SUPPORTED] test not supported
+#endif
+
+#include "utest/utest.h"
+#include "unity/unity.h"
+#include "greentea-client/test_env.h"
+#include "qspi_test.h"
+#include "qspi_test_utils.h"
+
+#include "mbed.h"
+#include "qspi_api.h"
+
+
+using namespace utest::v1;
+
+// uncomment to enable verbose mode
+//#define QSPI_TEST_LOG_DATA
+//#define QSPI_TEST_LOG_FLASH_TIME
+//#define QSPI_TEST_LOG_FLASH_STATUS
+
+
+// max write size is usually page size
+#define DATA_SIZE_256 (QSPI_PAGE_SIZE)
+#define DATA_SIZE_1024 (QSPI_PAGE_SIZE * 4)
+
+uint8_t tx_buf[DATA_SIZE_1024];
+uint8_t rx_buf[DATA_SIZE_1024];
+
+
+// write address should be page aligned
+#define TEST_FLASH_ADDRESS 0x0
+
+#define TEST_REPEAT_SINGLE 1
+#define TEST_REPEAT_MULTIPLE 16
+
+// write block of data in single write operation
+#define WRITE_SINGLE 1
+// write block of data in adjacent locations in multiple write operations
+#define WRITE_MULTIPLE 4
+
+// read block of data in single read operation
+#define READ_SINGLE 1
+// read block of data in adjacent locations in multiple read operations
+#define READ_MULTIPLE 4
+
+
+// some target defines QSPI pins as integers thus conversion needed
+#define QPIN_0 static_cast(QSPI_PIN_IO0)
+#define QPIN_1 static_cast(QSPI_PIN_IO1)
+#define QPIN_2 static_cast(QSPI_PIN_IO2)
+#define QPIN_3 static_cast(QSPI_PIN_IO3)
+#define QSCK static_cast(QSPI_PIN_SCK)
+#define QCSN static_cast(QSPI_PIN_CSN)
+
+
+static void log_data(const char *str, uint8_t *data, uint32_t size)
+{
+ printf("%s: ", str);
+ for (uint32_t j = 0; j < size; j++) {
+ printf("%02X ", data[j]);
+ }
+ printf("\r\n");
+}
+
+
+static void _qspi_write_read_test(Qspi &qspi, qspi_bus_width_t write_inst_width, qspi_bus_width_t write_addr_width,
+ qspi_bus_width_t write_data_width, qspi_bus_width_t write_alt_width, uint32_t write_cmd,
+ qspi_address_size_t write_addr_size, qspi_alt_size_t write_alt_size, int write_frequency,
+ uint32_t write_count, qspi_bus_width_t read_inst_width, qspi_bus_width_t read_addr_width,
+ qspi_bus_width_t read_data_width, qspi_bus_width_t read_alt_width, uint32_t read_cmd,
+ int read_dummy_cycles, qspi_address_size_t read_addr_size, qspi_alt_size_t read_alt_size,
+ int read_frequency, uint32_t read_count, uint32_t test_count, uint32_t data_size,
+ uint32_t flash_addr)
+{
+ qspi_status_t ret = QSPI_STATUS_OK;
+
+ Timer timer;
+ int erase_time, write_time, read_time;
+ size_t buf_len = data_size;
+
+ for (uint32_t tc = 0; tc < test_count; tc++)
+ {
+ qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
+
+ srand (ticker_read(get_us_ticker_data()));
+ for(uint32_t i = 0; i < data_size; i++) {
+ tx_buf[i] = (uint8_t)(rand() & 0xFF);
+ }
+
+ ret = write_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+
+ timer.reset();
+ timer.start();
+
+ ret = erase(SECTOR_ERASE, flash_addr, qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(SECTOR_ERASE_MAX_TIME, qspi);
+
+ timer.stop();
+ erase_time = timer.read_us();
+
+ if (write_frequency != QSPI_NONE) {
+ qspi_frequency(&qspi.handle, write_frequency);
+ WAIT_FOR(WAIT_MAX_TIME, qspi);
+ }
+
+ const uint32_t write_size = data_size / write_count;
+ qspi.cmd.configure(write_inst_width, write_addr_width, write_data_width, write_alt_width, write_addr_size, write_alt_size);
+ for (uint32_t wc = 0, write_start = flash_addr; wc < write_count; wc++, write_start += write_size)
+ {
+ ret = write_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+
+ timer.reset();
+ timer.start();
+
+ buf_len = write_size;
+ qspi.cmd.build(write_cmd, write_start);
+ ret = qspi_write(&qspi.handle, qspi.cmd.get(), tx_buf + wc * write_size, &buf_len);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ TEST_ASSERT_EQUAL(write_size, buf_len);
+ WAIT_FOR(PAGE_PROG_MAX_TIME, qspi);
+
+ timer.stop();
+ write_time = timer.read_us();
+#ifdef STM_DISCO_L475VG_IOT01A_WRITE_4IO_BUG_WORKAROUND
+ if (write_cmd == QSPI_CMD_WRITE_4IO) {
+ wait_us(2000);
+ }
+#endif
+ }
+
+ if (read_frequency != QSPI_NONE) {
+ qspi_frequency(&qspi.handle, read_frequency);
+ WAIT_FOR(WAIT_MAX_TIME, qspi);
+ }
+
+ memset(rx_buf, 0, sizeof(rx_buf));
+ const uint32_t read_size = data_size / read_count;
+ qspi.cmd.configure(read_inst_width, read_addr_width, read_data_width, read_alt_width, read_addr_size, read_alt_size, read_dummy_cycles);
+ for (uint32_t rc = 0, read_start = flash_addr; rc < read_count; rc++, read_start += read_size)
+ {
+ timer.reset();
+ timer.start();
+
+ buf_len = read_size;
+ qspi.cmd.build(read_cmd, read_start);
+ ret = qspi_read(&qspi.handle, qspi.cmd.get(), rx_buf + rc * read_size, &buf_len);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ TEST_ASSERT_EQUAL(read_size, buf_len);
+
+ timer.stop();
+ read_time = timer.read_us();
+ }
+
+ for (uint32_t i = 0; i < data_size; i++) {
+ if (tx_buf[i] != rx_buf[i]) {
+ log_data("tx data", tx_buf, data_size);
+ log_data("rx data", rx_buf, data_size);
+ printf("erase/write/read time: %d/%d/%d [us]\r\n", erase_time, write_time, read_time);
+ TEST_ASSERT_EQUAL(tx_buf[i], rx_buf[i]);
+ }
+ }
+
+#ifdef QSPI_TEST_LOG_FLASH_TIME
+ printf("erase/write/read time: %d/%d/%d [us]\r\n", erase_time, write_time, read_time);
+#endif
+
+#ifdef QSPI_TEST_LOG_DATA
+ log_data("tx data", tx_buf, data_size);
+ log_data("rx data", rx_buf, data_size);
+ printf("rx/tx data match\r\n");
+#endif
+ }
+}
+
+
+template < qspi_bus_width_t write_inst_width,
+ qspi_bus_width_t write_addr_width,
+ qspi_bus_width_t write_data_width,
+ qspi_bus_width_t write_alt_width,
+ unsigned int write_cmd,
+ qspi_address_size_t write_addr_size,
+ qspi_alt_size_t write_alt_size,
+ int write_frequency,
+ uint32_t write_count,
+ qspi_bus_width_t read_inst_width,
+ qspi_bus_width_t read_addr_width,
+ qspi_bus_width_t read_data_width,
+ qspi_bus_width_t read_alt_width,
+ unsigned int read_cmd,
+ int read_dummy_cycles,
+ qspi_address_size_t read_addr_size,
+ qspi_alt_size_t read_alt_size,
+ int read_frequency,
+ uint32_t read_count,
+ uint32_t test_count,
+ uint32_t data_size,
+ uint32_t flash_addr>
+void qspi_write_read_test(void)
+{
+ qspi_status_t ret;
+ Qspi qspi;
+ qspi_init(&qspi.handle, QPIN_0, QPIN_1, QPIN_2, QPIN_3, QSCK, QCSN, QSPI_COMMON_MAX_FREQUENCY, 0);
+
+ qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
+ flash_init(qspi);
+
+ ret = write_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+ ret = dual_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+
+ ret = write_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+ ret = quad_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+
+ ret = write_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+ ret = fast_mode_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+
+#ifdef QSPI_TEST_LOG_FLASH_STATUS
+ log_status_register(qspi);
+ log_config_register(qspi);
+#endif
+
+ _qspi_write_read_test(qspi, write_inst_width, write_addr_width, write_data_width, write_alt_width, write_cmd,
+ write_addr_size, write_alt_size, write_frequency, write_count, read_inst_width,
+ read_addr_width, read_data_width, read_alt_width, read_cmd, read_dummy_cycles,
+ read_addr_size, read_alt_size, read_frequency, read_count, test_count,
+ data_size, flash_addr);
+
+ qspi_free(&qspi.handle);
+}
+
+
+
+
+
+void qspi_init_free_test(void)
+{
+ Qspi qspi;
+ qspi_status_t ret;
+
+ ret = qspi_init(&qspi.handle, QPIN_0, QPIN_1, QPIN_2, QPIN_3, QSCK, QCSN, QSPI_COMMON_MAX_FREQUENCY, 0);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ ret = qspi_free(&qspi.handle);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+
+
+ ret = qspi_init(&qspi.handle, QPIN_0, QPIN_1, QPIN_2, QPIN_3, QSCK, QCSN, QSPI_COMMON_MAX_FREQUENCY, 0);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ ret = qspi_free(&qspi.handle);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+
+
+ ret = qspi_init(&qspi.handle, QPIN_0, QPIN_1, QPIN_2, QPIN_3, QSCK, QCSN, QSPI_COMMON_MAX_FREQUENCY, 0);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ ret = qspi_free(&qspi.handle);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+
+
+ ret = qspi_init(&qspi.handle, QPIN_0, QPIN_1, QPIN_2, QPIN_3, QSCK, QCSN, QSPI_COMMON_MAX_FREQUENCY, 0);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+
+ // check if the memory is working properly
+ qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
+ flash_init(qspi);
+ _qspi_write_read_test(qspi, WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE, READ_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE, TEST_REPEAT_SINGLE, DATA_SIZE_256, TEST_FLASH_ADDRESS);
+ qspi_free(&qspi.handle);
+}
+
+
+void qspi_frequency_test(void)
+{
+ Qspi qspi;
+ qspi_status_t ret;
+
+ ret = qspi_init(&qspi.handle, QPIN_0, QPIN_1, QPIN_2, QPIN_3, QSCK, QCSN, QSPI_COMMON_MAX_FREQUENCY, 0);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+
+ ret = qspi_frequency(&qspi.handle, QSPI_COMMON_MAX_FREQUENCY);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ // check if the memory is working properly
+ qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
+ flash_init(qspi);
+ _qspi_write_read_test(qspi, WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, WRITE_SINGLE, READ_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, READ_SINGLE, TEST_REPEAT_SINGLE, DATA_SIZE_256, TEST_FLASH_ADDRESS);
+
+ ret = qspi_frequency(&qspi.handle, QSPI_COMMON_MAX_FREQUENCY/2);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ // check if the memory is working properly
+ qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
+ flash_init(qspi);
+ _qspi_write_read_test(qspi, WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, WRITE_SINGLE, READ_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, READ_SINGLE, TEST_REPEAT_SINGLE, DATA_SIZE_256, TEST_FLASH_ADDRESS);
+
+ ret = qspi_frequency(&qspi.handle, QSPI_COMMON_MAX_FREQUENCY/4);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ // check if the memory is working properly
+ qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
+ flash_init(qspi);
+ _qspi_write_read_test(qspi, WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, WRITE_SINGLE, READ_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, READ_SINGLE, TEST_REPEAT_SINGLE, DATA_SIZE_256, TEST_FLASH_ADDRESS);
+
+ ret = qspi_frequency(&qspi.handle, QSPI_COMMON_MAX_FREQUENCY/8);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ // check if the memory is working properly
+ qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
+ flash_init(qspi);
+ _qspi_write_read_test(qspi, WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, WRITE_SINGLE, READ_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, READ_SINGLE, TEST_REPEAT_SINGLE, DATA_SIZE_256, TEST_FLASH_ADDRESS);
+
+ qspi_free(&qspi.handle);
+}
+
+
+void qspi_memory_id_test()
+{
+ printf("*** %s memory config loaded ***\r\n", QSPI_FLASH_CHIP_STRING);
+}
+
+
+Case cases[] = {
+ Case("qspi memory id test", qspi_memory_id_test),
+ Case("qspi init/free test", qspi_init_free_test),
+ Case("qspi frequency setting test", qspi_frequency_test),
+ // read/x1 write/x1 - read/write block of data in single write/read operation
+ // read/x4 write/x4 - read/write block of data in adjacent locations in multiple write/read operations
+ // repeat/xN - test repeat count (new data pattern each time)
+ Case("qspi write(1-1-1)/x1 read(1-1-1)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x4 read(1-1-1)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-1-1)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-1-1)/x1 repeat/x16 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-1-2)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x4 read(1-1-2)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-1-2)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-1-2)/x1 repeat/x16 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-2-2)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x4 read(1-2-2)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-2-2)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-2-2)/x1 repeat/x16 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-1-4)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x4 read(1-1-4)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-1-4)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-1-4)/x1 repeat/x16 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-4-4)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x4 read(1-4-4)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-4-4)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-1-1)/x1 read(1-4-4)/x1 repeat/x16 test", qspi_write_read_test),
+#ifdef QSPI_CMD_WRITE_4IO
+ Case("qspi write(1-4-4)/x1 read(1-1-1)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x4 read(1-1-1)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-1-1)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-1-1)/x1 repeat/x16 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-1-2)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x4 read(1-1-2)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-1-2)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-1-2)/x1 repeat/x16 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-2-2)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x4 read(1-2-2)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-2-2)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-2-2)/x1 repeat/x16 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-1-4)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x4 read(1-1-4)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-1-4)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-1-4)/x1 repeat/x16 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-4-4)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x4 read(1-4-4)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-4-4)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-4-4)/x1 read(1-4-4)/x1 repeat/x16 test", qspi_write_read_test),
+#endif
+};
+
+utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
+{
+ GREENTEA_SETUP(120, "default_auto");
+ return greentea_test_setup_handler(number_of_cases);
+}
+
+Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
+
+int main()
+{
+ Harness::run(specification);
+}
+
diff --git a/TESTS/mbed_hal/qspi/qspi_test.h b/TESTS/mbed_hal/qspi/qspi_test.h
new file mode 100644
index 0000000000..9ab3076d74
--- /dev/null
+++ b/TESTS/mbed_hal/qspi/qspi_test.h
@@ -0,0 +1,98 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** \addtogroup hal_qspi_tests
+ * @{
+ */
+#ifndef MBED_QSPI_TEST_H
+#define MBED_QSPI_TEST_H
+
+#include "qspi_api.h"
+#include "qspi_test_utils.h"
+
+
+#if DEVICE_QSPI
+
+/** Test that qspi_init/qspi_free can be called multiple times.
+ *
+ * Given board provides QSPI.
+ * When qspi_init/qspi_free is called multiple times.
+ * Then qspi_init/qspi_free are successfully performed (no exception is generated).
+ *
+ */
+void qspi_init_free_test(void);
+
+/** Test qspi frequency setting.
+ *
+ * Given board provides QSPI, with QSPI already initialized.
+ * When set QSPI frequency.
+ * Then freguency setting is successfully performed (no exception is generated).
+ *
+ */
+void qspi_frequency_test(void);
+
+/** Template for write/read tests
+ *
+ * Test single write/read operation of a block of data to/from the specific memory address
+ * Given board provides QSPI, with QSPI already initialized.
+ * When perform write and then read operations.
+ * Then data is successfully written and then read (no exception is generated) and the read data is valid.
+ *
+ * Test multiple write/read operation of a block of data to/from the same specific memory address
+ * Given board provides QSPI, with QSPI already initialized.
+ * When perform write and then read operations.
+ * Then data is successfully written and then read (no exception is generated) and the read data is valid.
+ *
+ * Test multiple adjacent write and single read operation of a block of data to/from the specific memory address
+ * Given board provides QSPI, with QSPI already initialized.
+ * When perform write and then read operations.
+ * Then data is successfully written and then read (no exception is generated) and the read data is valid.
+ *
+ * Test single write and multiple adjacent read operation of a block of data to/from the specific memory address
+ * Given board provides QSPI, with QSPI already initialized.
+ * When perform write and then read operations.
+ * Then data is successfully written and then read (no exception is generated) and the read data is valid.
+ *
+ */
+template < qspi_bus_width_t write_inst_width,
+ qspi_bus_width_t write_addr_width,
+ qspi_bus_width_t write_data_width,
+ qspi_bus_width_t write_alt_width,
+ unsigned int write_cmd,
+ qspi_address_size_t write_addr_size,
+ qspi_alt_size_t write_alt_size,
+ int write_frequency,
+ uint32_t write_count,
+ qspi_bus_width_t read_inst_width,
+ qspi_bus_width_t read_addr_width,
+ qspi_bus_width_t read_data_width,
+ qspi_bus_width_t read_alt_width,
+ unsigned int read_cmd,
+ int read_dummy_cycles,
+ qspi_address_size_t read_addr_size,
+ qspi_alt_size_t read_alt_size,
+ int read_frequency,
+ uint32_t read_count,
+ uint32_t test_count,
+ uint32_t data_size,
+ uint32_t flash_addr>
+void qspi_write_read_test(void);
+
+#endif
+
+#endif
+
+/** @}*/
diff --git a/TESTS/mbed_hal/qspi/qspi_test_utils.cpp b/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
new file mode 100644
index 0000000000..83991b3a5f
--- /dev/null
+++ b/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
@@ -0,0 +1,232 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "hal/qspi_api.h"
+#include "qspi_test_utils.h"
+
+#include "unity/unity.h"
+
+#include // for memset
+
+#include "flash_configs/flash_configs.h"
+#include "mbed.h" // for WEAK
+
+//====================================================================================
+// all WEAK functions can be overridden, to fit board or memory chip specific features
+// override in flash_configs/vendor/target/qspi_test_utils_specific.cpp
+//====================================================================================
+
+
+void QspiCommand::configure(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width,
+ qspi_bus_width_t data_width, qspi_bus_width_t alt_width,
+ qspi_address_size_t addr_size, qspi_alt_size_t alt_size,
+ int dummy_cycles)
+{
+ memset(&cmd, 0, sizeof(qspi_command_t) );
+ cmd.instruction.disabled = cmd.address.disabled = cmd.alt.disabled = true;
+
+ cmd.instruction.bus_width = inst_width;
+ cmd.address.bus_width = addr_width;
+ cmd.address.size = addr_size;
+ cmd.alt.bus_width = alt_width;
+ cmd.alt.size = alt_size;
+ cmd.data.bus_width = data_width;
+ cmd.dummy_count = dummy_cycles;
+}
+
+void QspiCommand::build(int instruction, int address, int alt)
+{
+ cmd.instruction.disabled = (instruction == QSPI_NONE);
+ if (!cmd.instruction.disabled) {
+ cmd.instruction.value = instruction;
+ }
+
+ cmd.address.disabled = (address == QSPI_NONE);
+ if (!cmd.address.disabled) {
+ cmd.address.value = address;
+ }
+
+ cmd.alt.disabled = (alt == QSPI_NONE);
+ if (!cmd.alt.disabled) {
+ cmd.alt.value = alt;
+ }
+}
+
+qspi_command_t* QspiCommand::get()
+{
+ return &cmd;
+}
+
+
+qspi_status_t read_register(uint32_t cmd, uint8_t *buf, uint32_t size, Qspi &q)
+{
+ q.cmd.build(cmd);
+ return qspi_command_transfer(&q.handle, q.cmd.get(), NULL, 0, buf, size);
+}
+
+
+bool flash_wait_for(uint32_t time_us, Qspi &qspi)
+{
+ uint8_t reg[QSPI_STATUS_REGISTER_SIZE];
+ qspi_status_t ret;
+ reg[0] = STATUS_BIT_WIP;
+
+ const ticker_data_t *const ticker = get_us_ticker_data();
+ const uint32_t start = ticker_read(ticker);
+
+ do {
+ ret = read_register(STATUS_REG, reg, QSPI_STATUS_REGISTER_SIZE, qspi);
+ } while (((reg[0] & STATUS_BIT_WIP) != 0) && ((ticker_read(ticker) - start) < (uint32_t)time_us));
+
+ return (((reg[0] & STATUS_BIT_WIP) == 0) && (ret == QSPI_STATUS_OK));
+}
+
+void flash_init(Qspi &qspi)
+{
+ uint8_t status[2] = { 0 };
+ qspi_status_t ret;
+
+ qspi.cmd.build(QSPI_CMD_RDSR);
+ ret = qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, status, 1);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+
+ qspi.cmd.build(QSPI_CMD_RSTEN);
+ ret = qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+
+ qspi.cmd.build(QSPI_CMD_RST);
+ ret = qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+
+ WAIT_FOR(WAIT_MAX_TIME, qspi);
+}
+
+
+qspi_status_t write_enable(Qspi &qspi)
+{
+ uint8_t reg[QSPI_STATUS_REGISTER_SIZE];
+ qspi.cmd.build(QSPI_CMD_WREN);
+
+ if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+
+ memset(reg, 0, QSPI_STATUS_REGISTER_SIZE);
+ if (read_register(STATUS_REG, reg, QSPI_STATUS_REGISTER_SIZE, qspi) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ return ((reg[0] & STATUS_BIT_WEL) != 0 ? QSPI_STATUS_OK : QSPI_STATUS_ERROR);
+}
+
+qspi_status_t write_disable(Qspi &qspi)
+{
+ uint8_t reg[QSPI_STATUS_REGISTER_SIZE];
+ qspi.cmd.build(QSPI_CMD_WRDI);
+
+ if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+
+ memset(reg, 0, QSPI_STATUS_REGISTER_SIZE);
+ if (read_register(STATUS_REG, reg, QSPI_STATUS_REGISTER_SIZE, qspi) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ return ((reg[0] & STATUS_BIT_WEL) == 0 ? QSPI_STATUS_OK : QSPI_STATUS_ERROR);
+}
+
+WEAK qspi_status_t dual_enable(Qspi &qspi)
+{
+ return QSPI_STATUS_OK;
+}
+
+WEAK qspi_status_t dual_disable(Qspi &qspi)
+{
+ return QSPI_STATUS_OK;
+}
+
+WEAK qspi_status_t quad_enable(Qspi &qspi)
+{
+ uint8_t reg_data[QSPI_STATUS_REGISTER_SIZE];
+
+ reg_data[0] = STATUS_BIT_QE;
+ qspi.cmd.build(QSPI_CMD_WRSR);
+
+ if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), reg_data, QSPI_STATUS_REGISTER_SIZE, NULL, 0) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+
+ memset(reg_data, 0, QSPI_STATUS_REGISTER_SIZE);
+ if (read_register(STATUS_REG, reg_data, QSPI_STATUS_REGISTER_SIZE, qspi) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ return ((reg_data[0] & STATUS_BIT_QE) != 0 ? QSPI_STATUS_OK : QSPI_STATUS_ERROR);
+}
+
+WEAK qspi_status_t quad_disable(Qspi &qspi)
+{
+ uint8_t reg_data[QSPI_STATUS_REGISTER_SIZE];
+
+ reg_data[0] = 0;
+ qspi.cmd.build(QSPI_CMD_WRSR);
+
+ if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), reg_data, QSPI_STATUS_REGISTER_SIZE, NULL, 0) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+
+ reg_data[0] = 0;
+ if (read_register(STATUS_REG, reg_data, QSPI_STATUS_REGISTER_SIZE, qspi) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ return ((reg_data[0] & STATUS_BIT_QE) == 0 ? QSPI_STATUS_OK : QSPI_STATUS_ERROR);
+}
+
+WEAK qspi_status_t fast_mode_enable(Qspi &qspi)
+{
+ qspi_status_t ret;
+ const int32_t reg_size = QSPI_STATUS_REGISTER_SIZE + QSPI_CONFIGURATION_REGISTER_SIZE;
+ uint8_t reg_data[reg_size];
+
+ if (read_register(STATUS_REG, reg_data, QSPI_STATUS_REGISTER_SIZE, qspi) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+ if (read_register(CONFIG_REG, reg_data + QSPI_STATUS_REGISTER_SIZE, QSPI_CONFIGURATION_REGISTER_SIZE, qspi) != QSPI_STATUS_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ reg_data[2] |= CONFIG1_BIT_LH;
+ qspi.cmd.build(QSPI_CMD_WRSR);
+
+ return qspi_command_transfer(&qspi.handle, qspi.cmd.get(), reg_data, reg_size, NULL, 0);
+}
+
+qspi_status_t erase(uint32_t erase_cmd, uint32_t flash_addr, Qspi &qspi)
+{
+ qspi.cmd.build(erase_cmd, flash_addr);
+ return qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0);
+}
diff --git a/TESTS/mbed_hal/qspi/qspi_test_utils.h b/TESTS/mbed_hal/qspi/qspi_test_utils.h
new file mode 100644
index 0000000000..bd08c53d64
--- /dev/null
+++ b/TESTS/mbed_hal/qspi/qspi_test_utils.h
@@ -0,0 +1,117 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_QSPI_TEST_UTILS_H
+#define MBED_QSPI_TEST_UTILS_H
+
+#include "flash_configs/flash_configs.h"
+#include "unity/unity.h"
+
+#define QSPI_NONE (-1)
+
+struct QspiCommand {
+
+ void configure(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width,
+ qspi_bus_width_t alt_width, qspi_address_size_t addr_size, qspi_alt_size_t alt_size,
+ int dummy_cycles = 0);
+
+ void build(int instruction, int address = QSPI_NONE, int alt = QSPI_NONE);
+
+ qspi_command_t * get();
+
+ qspi_command_t cmd;
+};
+
+struct Qspi {
+ qspi_t handle;
+ QspiCommand cmd;
+};
+
+// MODE_Command_Address_Data_Alt
+#define MODE_1_1_1 QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE
+#define MODE_1_1_2 QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_DUAL
+#define MODE_1_2_2 QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_DUAL
+#define MODE_1_1_4 QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_QUAD, QSPI_CFG_BUS_SINGLE
+#define MODE_1_4_4 QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_QUAD, QSPI_CFG_BUS_QUAD, QSPI_CFG_BUS_QUAD
+
+#define WRITE_1_1_1 MODE_1_1_1, QSPI_CMD_WRITE_1IO
+#ifdef QSPI_CMD_WRITE_4IO
+#define WRITE_1_4_4 MODE_1_4_4, QSPI_CMD_WRITE_4IO
+#endif
+
+
+#define READ_1_1_1 MODE_1_1_1, QSPI_CMD_READ_1IO, QSPI_READ_1IO_DUMMY_CYCLE
+#define READ_1_1_2 MODE_1_1_2, QSPI_CMD_READ_1I2O, QSPI_READ_1I2O_DUMMY_CYCLE
+#define READ_1_2_2 MODE_1_2_2, QSPI_CMD_READ_2IO, QSPI_READ_2IO_DUMMY_CYCLE
+#define READ_1_1_4 MODE_1_1_4, QSPI_CMD_READ_1I4O, QSPI_READ_1I4O_DUMMY_CYCLE
+#define READ_1_4_4 MODE_1_4_4, QSPI_CMD_READ_4IO, QSPI_READ_4IO_DUMMY_CYCLE
+
+
+#define ADDR_SIZE_8 QSPI_CFG_ADDR_SIZE_8
+#define ADDR_SIZE_16 QSPI_CFG_ADDR_SIZE_16
+#define ADDR_SIZE_24 QSPI_CFG_ADDR_SIZE_24
+#define ADDR_SIZE_32 QSPI_CFG_ADDR_SIZE_32
+
+#define ALT_SIZE_8 QSPI_CFG_ALT_SIZE_8
+#define ALT_SIZE_16 QSPI_CFG_ALT_SIZE_16
+#define ALT_SIZE_24 QSPI_CFG_ALT_SIZE_24
+#define ALT_SIZE_32 QSPI_CFG_ALT_SIZE_32
+
+#define STATUS_REG QSPI_CMD_RDSR
+#define CONFIG_REG QSPI_CMD_RDCR
+#define SECURITY_REG QSPI_CMD_RDSCUR
+
+
+#define SECTOR_ERASE QSPI_CMD_ERASE_SECTOR
+#define BLOCK_ERASE QSPI_CMD_ERASE_BLOCK_64
+
+
+#define SECTOR_ERASE_MAX_TIME QSPI_ERASE_SECTOR_MAX_TIME
+#define BLOCK32_ERASE_MAX_TIME QSPI_ERASE_BLOCK_32_MAX_TIME
+#define BLOCK64_ERASE_MAX_TIME QSPI_ERASE_BLOCK_64_MAX_TIME
+#define PAGE_PROG_MAX_TIME QSPI_PAGE_PROG_MAX_TIME
+#define WRSR_MAX_TIME QSPI_WRSR_MAX_TIME
+#define WAIT_MAX_TIME QSPI_WAIT_MAX_TIME
+
+
+
+qspi_status_t read_register(uint32_t cmd, uint8_t *buf, uint32_t size, Qspi &q);
+
+bool flash_wait_for(uint32_t time_us, Qspi &qspi);
+
+void flash_init(Qspi &qspi);
+
+qspi_status_t write_enable(Qspi &qspi);
+
+qspi_status_t write_disable(Qspi &qspi);
+
+qspi_status_t dual_enable(Qspi &qspi);
+
+qspi_status_t dual_disable(Qspi &qspi);
+
+qspi_status_t quad_enable(Qspi &qspi);
+
+qspi_status_t quad_disable(Qspi &qspi);
+
+qspi_status_t fast_mode_enable(Qspi &qspi);
+
+qspi_status_t erase(uint32_t erase_cmd, uint32_t flash_addr, Qspi &qspi);
+
+#define WAIT_FOR(timeout, q) \
+ if(!flash_wait_for(timeout, q)) { \
+ TEST_ASSERT_MESSAGE(false, "flash_wait_for failed!!!"); \
+ }
+
+#endif // MBED_QSPI_TEST_UTILS_H
From de46a547faee31418270ce6fda43e1d8cac61051 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Wed, 4 Jul 2018 18:38:02 +0200
Subject: [PATCH 65/78] hal-qspi test refactoring
Main idea of introduced changes is to ease adding support for new flash chips
Major changes:
- move implementation of all memory chip specific functions to memory config file (no weak functions)
- add support for 1-2-2 write
---
.../qspi/flash_configs/MX25R6435F_config.h | 87 +++++++++-
.../STM/DISCO_L475VG_IOT01A/flash_config.h | 2 +-
TESTS/mbed_hal/qspi/main.cpp | 100 +++++++++--
TESTS/mbed_hal/qspi/qspi_test_utils.cpp | 164 +++++++++---------
TESTS/mbed_hal/qspi/qspi_test_utils.h | 33 +++-
5 files changed, 269 insertions(+), 117 deletions(-)
diff --git a/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h b/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h
index 80e68f007b..adcfc32205 100644
--- a/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h
+++ b/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h
@@ -22,7 +22,7 @@
// Command for reading status register
#define QSPI_CMD_RDSR 0x05
// Command for reading configuration register
-#define QSPI_CMD_RDCR 0x15
+#define QSPI_CMD_RDCR0 0x15
// Command for writing status/configuration register
#define QSPI_CMD_WRSR 0x01
// Command for reading security register
@@ -41,7 +41,7 @@
// WRSR operations max time [us] (datasheet max time + 15%)
#define QSPI_WRSR_MAX_TIME 34500 // 30ms
// general wait max time [us]
-#define QSPI_WAIT_MAX_TIME 10000 // 100ms
+#define QSPI_WAIT_MAX_TIME 100000 // 100ms
// Commands for writing (page programming)
@@ -76,15 +76,16 @@
// erase operations max time [us] (datasheet max time + 15%)
#define QSPI_ERASE_SECTOR_MAX_TIME 276000 // 240 ms
-#define QSPI_ERASE_BLOCK_32_MAX_TIME 3000000 // 3s
-#define QSPI_ERASE_BLOCK_64_MAX_TIME 3500000 // 3.5s
+#define QSPI_ERASE_BLOCK_32_MAX_TIME 3450000 // 3s
+#define QSPI_ERASE_BLOCK_64_MAX_TIME 4025000 // 3.5s
// max frequency for basic rw operation
#define QSPI_COMMON_MAX_FREQUENCY 32000000
-#define QSPI_STATUS_REGISTER_SIZE 1
-#define QSPI_CONFIGURATION_REGISTER_SIZE 2
-#define QSPI_SECURITY_REGISTER_SIZE 1
+#define QSPI_STATUS_REG_SIZE 1
+#define QSPI_CONFIG_REG_0_SIZE 2
+#define QSPI_SECURITY_REG_SIZE 1
+#define QSPI_MAX_REG_SIZE 2
// status register
#define STATUS_BIT_WIP (1 << 0) // write in progress bit
@@ -106,4 +107,76 @@
#define CONFIG1_BIT_LH (1 << 1) // 0 = Ultra Low power mode, 1 = High performance mode
+// single quad enable flag for both dual and quad mode
+#define QUAD_ENABLE_IMPLEMENTATION() \
+ \
+ uint8_t reg_data[QSPI_STATUS_REG_SIZE]; \
+ \
+ reg_data[0] = STATUS_BIT_QE; \
+ qspi.cmd.build(QSPI_CMD_WRSR); \
+ \
+ if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), \
+ reg_data, QSPI_STATUS_REG_SIZE, NULL, 0) != QSPI_STATUS_OK) { \
+ return QSPI_STATUS_ERROR; \
+ } \
+ WAIT_FOR(WRSR_MAX_TIME, qspi); \
+ \
+ memset(reg_data, 0, QSPI_STATUS_REG_SIZE); \
+ if (read_register(STATUS_REG, reg_data, \
+ QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
+ return QSPI_STATUS_ERROR; \
+ } \
+ \
+ return ((reg_data[0] & STATUS_BIT_QE) != 0 ? \
+ QSPI_STATUS_OK : QSPI_STATUS_ERROR)
+
+
+
+#define QUAD_DISABLE_IMPLEMENTATION() \
+ \
+ uint8_t reg_data[QSPI_STATUS_REG_SIZE]; \
+ \
+ reg_data[0] = 0; \
+ qspi.cmd.build(QSPI_CMD_WRSR); \
+ \
+ if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), \
+ reg_data, QSPI_STATUS_REG_SIZE, NULL, 0) != QSPI_STATUS_OK) { \
+ return QSPI_STATUS_ERROR; \
+ } \
+ WAIT_FOR(WRSR_MAX_TIME, qspi); \
+ \
+ reg_data[0] = 0; \
+ if (read_register(STATUS_REG, reg_data, \
+ QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
+ return QSPI_STATUS_ERROR; \
+ } \
+ \
+ return ((reg_data[0] & STATUS_BIT_QE) == 0 ? \
+ QSPI_STATUS_OK : QSPI_STATUS_ERROR)
+
+
+
+#define FAST_MODE_ENABLE_IMPLEMENTATION() \
+ \
+ qspi_status_t ret; \
+ const int32_t reg_size = QSPI_STATUS_REG_SIZE + QSPI_CONFIG_REG_0_SIZE; \
+ uint8_t reg_data[reg_size]; \
+ \
+ if (read_register(STATUS_REG, reg_data, \
+ QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
+ return QSPI_STATUS_ERROR; \
+ } \
+ if (read_register(CONFIG_REG0, reg_data + QSPI_STATUS_REG_SIZE, \
+ QSPI_CONFIG_REG_0_SIZE, qspi) != QSPI_STATUS_OK) { \
+ return QSPI_STATUS_ERROR; \
+ } \
+ \
+ reg_data[2] |= CONFIG1_BIT_LH; \
+ qspi.cmd.build(QSPI_CMD_WRSR); \
+ \
+ return qspi_command_transfer(&qspi.handle, qspi.cmd.get(), \
+ reg_data, reg_size, NULL, 0)
+
+
+
#endif // MBED_QSPI_FLASH_MX25R6435F_H
diff --git a/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_L475VG_IOT01A/flash_config.h b/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_L475VG_IOT01A/flash_config.h
index 69392426c4..93e1c2855c 100644
--- a/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_L475VG_IOT01A/flash_config.h
+++ b/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_L475VG_IOT01A/flash_config.h
@@ -21,6 +21,6 @@
// TODO: remove when fixed
// when perform 4IO write, when memory indicates write finish (changing WIP bit in status register)
// but actually write is still in progress and we have to wait a bit more before reading
-#define STM_DISCO_L475VG_IOT01A_WRITE_4IO_BUG_WORKAROUND
+#define STM_WRITE_4IO_BUG_WORKAROUND
#endif // MBED_QSPI_FLASH_CONFIG_H
diff --git a/TESTS/mbed_hal/qspi/main.cpp b/TESTS/mbed_hal/qspi/main.cpp
index 62b029d971..3496660516 100644
--- a/TESTS/mbed_hal/qspi/main.cpp
+++ b/TESTS/mbed_hal/qspi/main.cpp
@@ -92,7 +92,7 @@ static void _qspi_write_read_test(Qspi &qspi, qspi_bus_width_t write_inst_width,
qspi_status_t ret = QSPI_STATUS_OK;
Timer timer;
- int erase_time, write_time, read_time;
+ int erase_time = 0, write_time = 0, read_time = 0;
size_t buf_len = data_size;
for (uint32_t tc = 0; tc < test_count; tc++)
@@ -123,7 +123,6 @@ static void _qspi_write_read_test(Qspi &qspi, qspi_bus_width_t write_inst_width,
}
const uint32_t write_size = data_size / write_count;
- qspi.cmd.configure(write_inst_width, write_addr_width, write_data_width, write_alt_width, write_addr_size, write_alt_size);
for (uint32_t wc = 0, write_start = flash_addr; wc < write_count; wc++, write_start += write_size)
{
ret = write_enable(qspi);
@@ -133,15 +132,18 @@ static void _qspi_write_read_test(Qspi &qspi, qspi_bus_width_t write_inst_width,
timer.start();
buf_len = write_size;
+ qspi.cmd.configure(write_inst_width, write_addr_width, write_data_width, write_alt_width, write_addr_size, write_alt_size);
qspi.cmd.build(write_cmd, write_start);
ret = qspi_write(&qspi.handle, qspi.cmd.get(), tx_buf + wc * write_size, &buf_len);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
TEST_ASSERT_EQUAL(write_size, buf_len);
+
+ qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
WAIT_FOR(PAGE_PROG_MAX_TIME, qspi);
timer.stop();
write_time = timer.read_us();
-#ifdef STM_DISCO_L475VG_IOT01A_WRITE_4IO_BUG_WORKAROUND
+#ifdef STM_WRITE_4IO_BUG_WORKAROUND
if (write_cmd == QSPI_CMD_WRITE_4IO) {
wait_us(2000);
}
@@ -224,19 +226,25 @@ void qspi_write_read_test(void)
qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
flash_init(qspi);
- ret = write_enable(qspi);
- TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
- WAIT_FOR(WRSR_MAX_TIME, qspi);
- ret = dual_enable(qspi);
- TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
- WAIT_FOR(WRSR_MAX_TIME, qspi);
+ if (is_dual_cmd(write_inst_width, write_addr_width, write_data_width) ||
+ is_dual_cmd(read_inst_width, read_addr_width, read_data_width)) {
+ ret = write_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+ ret = dual_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+ }
- ret = write_enable(qspi);
- TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
- WAIT_FOR(WRSR_MAX_TIME, qspi);
- ret = quad_enable(qspi);
- TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
- WAIT_FOR(WRSR_MAX_TIME, qspi);
+ if (is_quad_cmd(write_inst_width, write_addr_width, write_data_width) ||
+ is_quad_cmd(read_inst_width, read_addr_width, read_data_width)) {
+ ret = write_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+ ret = quad_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+ }
ret = write_enable(qspi);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
@@ -246,8 +254,11 @@ void qspi_write_read_test(void)
WAIT_FOR(WRSR_MAX_TIME, qspi);
#ifdef QSPI_TEST_LOG_FLASH_STATUS
- log_status_register(qspi);
- log_config_register(qspi);
+ printf("Status "); log_register(STATUS_REG, QSPI_STATUS_REG_SIZE, qspi);
+ printf("Config 0 "); log_register(CONFIG_REG0, QSPI_CONFIG_REG_0_SIZE, qspi);
+#ifdef CONFIG_REG1
+ printf("Config 1 "); log_register(CONFIG_REG1, QSPI_CONFIG_REG_1_SIZE, qspi);
+#endif
#endif
_qspi_write_read_test(qspi, write_inst_width, write_addr_width, write_data_width, write_alt_width, write_cmd,
@@ -256,6 +267,28 @@ void qspi_write_read_test(void)
read_addr_size, read_alt_size, read_frequency, read_count, test_count,
data_size, flash_addr);
+ qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
+
+ if (is_dual_cmd(write_inst_width, write_addr_width, write_data_width) ||
+ is_dual_cmd(read_inst_width, read_addr_width, read_data_width)) {
+ ret = write_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+ ret = dual_disable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+ }
+
+ if (is_quad_cmd(write_inst_width, write_addr_width, write_data_width) ||
+ is_quad_cmd(read_inst_width, read_addr_width, read_data_width)) {
+ ret = write_enable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+ ret = quad_disable(qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+ WAIT_FOR(WRSR_MAX_TIME, qspi);
+ }
+
qspi_free(&qspi.handle);
}
@@ -292,6 +325,15 @@ void qspi_init_free_test(void)
// check if the memory is working properly
qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
flash_init(qspi);
+
+#ifdef QSPI_TEST_LOG_FLASH_STATUS
+ printf("Status "); log_register(STATUS_REG, QSPI_STATUS_REG_SIZE, qspi);
+ printf("Config 0 "); log_register(CONFIG_REG0, QSPI_CONFIG_REG_0_SIZE, qspi);
+#ifdef CONFIG_REG1
+ printf("Config 1 "); log_register(CONFIG_REG1, QSPI_CONFIG_REG_1_SIZE, qspi);
+#endif
+#endif
+
_qspi_write_read_test(qspi, WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE, READ_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE, TEST_REPEAT_SINGLE, DATA_SIZE_256, TEST_FLASH_ADDRESS);
qspi_free(&qspi.handle);
}
@@ -370,6 +412,28 @@ Case cases[] = {
Case("qspi write(1-1-1)/x4 read(1-4-4)/x1 repeat/x1 test", qspi_write_read_test),
Case("qspi write(1-1-1)/x1 read(1-4-4)/x4 repeat/x1 test", qspi_write_read_test),
Case("qspi write(1-1-1)/x1 read(1-4-4)/x1 repeat/x16 test", qspi_write_read_test),
+#ifdef QSPI_CMD_WRITE_2IO
+ Case("qspi write(1-2-2)/x1 read(1-1-1)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x4 read(1-1-1)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-1-1)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-1-1)/x1 repeat/x16 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-1-2)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x4 read(1-1-2)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-1-2)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-1-2)/x1 repeat/x16 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-2-2)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x4 read(1-2-2)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-2-2)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-2-2)/x1 repeat/x16 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-1-4)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x4 read(1-1-4)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-1-4)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-1-4)/x1 repeat/x16 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-4-4)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x4 read(1-4-4)/x1 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-4-4)/x4 repeat/x1 test", qspi_write_read_test),
+ Case("qspi write(1-2-2)/x1 read(1-4-4)/x1 repeat/x16 test", qspi_write_read_test),
+#endif
#ifdef QSPI_CMD_WRITE_4IO
Case("qspi write(1-4-4)/x1 read(1-1-1)/x1 repeat/x1 test", qspi_write_read_test),
Case("qspi write(1-4-4)/x4 read(1-1-1)/x1 repeat/x1 test", qspi_write_read_test),
@@ -396,7 +460,7 @@ Case cases[] = {
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
{
- GREENTEA_SETUP(120, "default_auto");
+ GREENTEA_SETUP(180, "default_auto");
return greentea_test_setup_handler(number_of_cases);
}
diff --git a/TESTS/mbed_hal/qspi/qspi_test_utils.cpp b/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
index 83991b3a5f..8339d38edb 100644
--- a/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
+++ b/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
@@ -23,12 +23,7 @@
#include // for memset
#include "flash_configs/flash_configs.h"
-#include "mbed.h" // for WEAK
-
-//====================================================================================
-// all WEAK functions can be overridden, to fit board or memory chip specific features
-// override in flash_configs/vendor/target/qspi_test_utils_specific.cpp
-//====================================================================================
+#include "mbed.h"
void QspiCommand::configure(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width,
@@ -79,33 +74,40 @@ qspi_status_t read_register(uint32_t cmd, uint8_t *buf, uint32_t size, Qspi &q)
}
-bool flash_wait_for(uint32_t time_us, Qspi &qspi)
+QspiStatus flash_wait_for(uint32_t time_us, Qspi &qspi)
{
- uint8_t reg[QSPI_STATUS_REGISTER_SIZE];
+ uint8_t reg[QSPI_STATUS_REG_SIZE];
qspi_status_t ret;
- reg[0] = STATUS_BIT_WIP;
+ uint32_t curr_time;
const ticker_data_t *const ticker = get_us_ticker_data();
const uint32_t start = ticker_read(ticker);
+ memset(reg, 255, QSPI_STATUS_REG_SIZE);
do {
- ret = read_register(STATUS_REG, reg, QSPI_STATUS_REGISTER_SIZE, qspi);
- } while (((reg[0] & STATUS_BIT_WIP) != 0) && ((ticker_read(ticker) - start) < (uint32_t)time_us));
+ ret = read_register(STATUS_REG, reg, QSPI_STATUS_REG_SIZE, qspi);
+ curr_time = ticker_read(ticker);
+ } while (((reg[0] & STATUS_BIT_WIP) != 0) && ((curr_time - start) < time_us));
- return (((reg[0] & STATUS_BIT_WIP) == 0) && (ret == QSPI_STATUS_OK));
+ if (((reg[0] & STATUS_BIT_WIP) == 0) && (ret == QSPI_STATUS_OK)) {
+ return sOK;
+ } else if (ret != QSPI_STATUS_OK) {
+ return sError;
+ } else if ((curr_time - start) >= time_us) {
+ return sTimeout;
+ }
+ return sUnknown;
}
void flash_init(Qspi &qspi)
{
- uint8_t status[2] = { 0 };
+ uint8_t status[QSPI_STATUS_REG_SIZE];
qspi_status_t ret;
qspi.cmd.build(QSPI_CMD_RDSR);
- ret = qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, status, 1);
+ ret = qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, status, QSPI_STATUS_REG_SIZE);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
- WAIT_FOR(WRSR_MAX_TIME, qspi);
-
qspi.cmd.build(QSPI_CMD_RSTEN);
ret = qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
@@ -122,7 +124,7 @@ void flash_init(Qspi &qspi)
qspi_status_t write_enable(Qspi &qspi)
{
- uint8_t reg[QSPI_STATUS_REGISTER_SIZE];
+ uint8_t reg[QSPI_STATUS_REG_SIZE];
qspi.cmd.build(QSPI_CMD_WREN);
if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0) != QSPI_STATUS_OK) {
@@ -130,8 +132,8 @@ qspi_status_t write_enable(Qspi &qspi)
}
WAIT_FOR(WRSR_MAX_TIME, qspi);
- memset(reg, 0, QSPI_STATUS_REGISTER_SIZE);
- if (read_register(STATUS_REG, reg, QSPI_STATUS_REGISTER_SIZE, qspi) != QSPI_STATUS_OK) {
+ memset(reg, 0, QSPI_STATUS_REG_SIZE);
+ if (read_register(STATUS_REG, reg, QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) {
return QSPI_STATUS_ERROR;
}
@@ -140,7 +142,7 @@ qspi_status_t write_enable(Qspi &qspi)
qspi_status_t write_disable(Qspi &qspi)
{
- uint8_t reg[QSPI_STATUS_REGISTER_SIZE];
+ uint8_t reg[QSPI_STATUS_REG_SIZE];
qspi.cmd.build(QSPI_CMD_WRDI);
if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0) != QSPI_STATUS_OK) {
@@ -148,81 +150,29 @@ qspi_status_t write_disable(Qspi &qspi)
}
WAIT_FOR(WRSR_MAX_TIME, qspi);
- memset(reg, 0, QSPI_STATUS_REGISTER_SIZE);
- if (read_register(STATUS_REG, reg, QSPI_STATUS_REGISTER_SIZE, qspi) != QSPI_STATUS_OK) {
+ memset(reg, 0, QSPI_STATUS_REG_SIZE);
+ if (read_register(STATUS_REG, reg, QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) {
return QSPI_STATUS_ERROR;
}
return ((reg[0] & STATUS_BIT_WEL) == 0 ? QSPI_STATUS_OK : QSPI_STATUS_ERROR);
}
-WEAK qspi_status_t dual_enable(Qspi &qspi)
-{
- return QSPI_STATUS_OK;
-}
-
-WEAK qspi_status_t dual_disable(Qspi &qspi)
-{
- return QSPI_STATUS_OK;
-}
-
-WEAK qspi_status_t quad_enable(Qspi &qspi)
-{
- uint8_t reg_data[QSPI_STATUS_REGISTER_SIZE];
-
- reg_data[0] = STATUS_BIT_QE;
- qspi.cmd.build(QSPI_CMD_WRSR);
-
- if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), reg_data, QSPI_STATUS_REGISTER_SIZE, NULL, 0) != QSPI_STATUS_OK) {
- return QSPI_STATUS_ERROR;
- }
- WAIT_FOR(WRSR_MAX_TIME, qspi);
-
- memset(reg_data, 0, QSPI_STATUS_REGISTER_SIZE);
- if (read_register(STATUS_REG, reg_data, QSPI_STATUS_REGISTER_SIZE, qspi) != QSPI_STATUS_OK) {
- return QSPI_STATUS_ERROR;
- }
-
- return ((reg_data[0] & STATUS_BIT_QE) != 0 ? QSPI_STATUS_OK : QSPI_STATUS_ERROR);
-}
-
-WEAK qspi_status_t quad_disable(Qspi &qspi)
-{
- uint8_t reg_data[QSPI_STATUS_REGISTER_SIZE];
-
- reg_data[0] = 0;
- qspi.cmd.build(QSPI_CMD_WRSR);
-
- if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), reg_data, QSPI_STATUS_REGISTER_SIZE, NULL, 0) != QSPI_STATUS_OK) {
- return QSPI_STATUS_ERROR;
- }
- WAIT_FOR(WRSR_MAX_TIME, qspi);
-
- reg_data[0] = 0;
- if (read_register(STATUS_REG, reg_data, QSPI_STATUS_REGISTER_SIZE, qspi) != QSPI_STATUS_OK) {
- return QSPI_STATUS_ERROR;
- }
-
- return ((reg_data[0] & STATUS_BIT_QE) == 0 ? QSPI_STATUS_OK : QSPI_STATUS_ERROR);
-}
-
-WEAK qspi_status_t fast_mode_enable(Qspi &qspi)
+void log_register(uint32_t cmd, uint32_t reg_size, Qspi &qspi)
{
qspi_status_t ret;
- const int32_t reg_size = QSPI_STATUS_REGISTER_SIZE + QSPI_CONFIGURATION_REGISTER_SIZE;
- uint8_t reg_data[reg_size];
+ static uint8_t reg[QSPI_MAX_REG_SIZE];
- if (read_register(STATUS_REG, reg_data, QSPI_STATUS_REGISTER_SIZE, qspi) != QSPI_STATUS_OK) {
- return QSPI_STATUS_ERROR;
+ ret = read_register(cmd, reg, reg_size, qspi);
+ TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
+
+ for (int j = 0; j < reg_size; j++) {
+ printf("register byte %d data: ", j);
+ for(int i = 0; i < 8; i++) {
+ printf("%s ", ((reg[j] & (1 << i)) & 0xFF) == 0 ? "0" : "1");
+ }
+ printf("\r\n");
}
- if (read_register(CONFIG_REG, reg_data + QSPI_STATUS_REGISTER_SIZE, QSPI_CONFIGURATION_REGISTER_SIZE, qspi) != QSPI_STATUS_OK) {
- return QSPI_STATUS_ERROR;
- }
-
- reg_data[2] |= CONFIG1_BIT_LH;
- qspi.cmd.build(QSPI_CMD_WRSR);
-
- return qspi_command_transfer(&qspi.handle, qspi.cmd.get(), reg_data, reg_size, NULL, 0);
}
qspi_status_t erase(uint32_t erase_cmd, uint32_t flash_addr, Qspi &qspi)
@@ -230,3 +180,47 @@ qspi_status_t erase(uint32_t erase_cmd, uint32_t flash_addr, Qspi &qspi)
qspi.cmd.build(erase_cmd, flash_addr);
return qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0);
}
+
+qspi_status_t dual_enable(Qspi &qspi)
+{
+#ifdef DUAL_ENABLE_IMPLEMENTATION
+ DUAL_ENABLE_IMPLEMENTATION();
+#else
+ QUAD_ENABLE_IMPLEMENTATION();
+#endif
+}
+
+qspi_status_t dual_disable(Qspi &qspi)
+{
+#ifdef DUAL_DISABLE_IMPLEMENTATION
+ DUAL_DISABLE_IMPLEMENTATION();
+#else
+ QUAD_DISABLE_IMPLEMENTATION();
+#endif
+
+}
+
+qspi_status_t quad_enable(Qspi &qspi)
+{
+ QUAD_ENABLE_IMPLEMENTATION();
+}
+
+qspi_status_t quad_disable(Qspi &qspi)
+{
+ QUAD_DISABLE_IMPLEMENTATION();
+}
+
+qspi_status_t fast_mode_enable(Qspi &qspi)
+{
+ FAST_MODE_ENABLE_IMPLEMENTATION();
+}
+
+bool is_dual_cmd(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width)
+{
+ return (inst_width == QSPI_CFG_BUS_DUAL) || (addr_width == QSPI_CFG_BUS_DUAL) || (data_width == QSPI_CFG_BUS_DUAL);
+}
+
+bool is_quad_cmd(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width)
+{
+ return (inst_width == QSPI_CFG_BUS_QUAD) || (addr_width == QSPI_CFG_BUS_QUAD) || (data_width == QSPI_CFG_BUS_QUAD);
+}
diff --git a/TESTS/mbed_hal/qspi/qspi_test_utils.h b/TESTS/mbed_hal/qspi/qspi_test_utils.h
index bd08c53d64..ed92237a40 100644
--- a/TESTS/mbed_hal/qspi/qspi_test_utils.h
+++ b/TESTS/mbed_hal/qspi/qspi_test_utils.h
@@ -21,6 +21,13 @@
#define QSPI_NONE (-1)
+enum QspiStatus {
+ sOK,
+ sError,
+ sTimeout,
+ sUnknown
+};
+
struct QspiCommand {
void configure(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width,
@@ -47,6 +54,9 @@ struct Qspi {
#define MODE_1_4_4 QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_QUAD, QSPI_CFG_BUS_QUAD, QSPI_CFG_BUS_QUAD
#define WRITE_1_1_1 MODE_1_1_1, QSPI_CMD_WRITE_1IO
+#ifdef QSPI_CMD_WRITE_2IO
+#define WRITE_1_2_2 MODE_1_2_2, QSPI_CMD_WRITE_2IO
+#endif
#ifdef QSPI_CMD_WRITE_4IO
#define WRITE_1_4_4 MODE_1_4_4, QSPI_CMD_WRITE_4IO
#endif
@@ -70,9 +80,16 @@ struct Qspi {
#define ALT_SIZE_32 QSPI_CFG_ALT_SIZE_32
#define STATUS_REG QSPI_CMD_RDSR
-#define CONFIG_REG QSPI_CMD_RDCR
+#define CONFIG_REG0 QSPI_CMD_RDCR0
+#ifdef QSPI_CMD_RDCR1
+#define CONFIG_REG1 QSPI_CMD_RDCR1
+#endif
#define SECURITY_REG QSPI_CMD_RDSCUR
+#ifndef QSPI_CONFIG_REG_1_SIZE
+#define QSPI_CONFIG_REG_1_SIZE 0
+#endif
+
#define SECTOR_ERASE QSPI_CMD_ERASE_SECTOR
#define BLOCK_ERASE QSPI_CMD_ERASE_BLOCK_64
@@ -89,7 +106,7 @@ struct Qspi {
qspi_status_t read_register(uint32_t cmd, uint8_t *buf, uint32_t size, Qspi &q);
-bool flash_wait_for(uint32_t time_us, Qspi &qspi);
+QspiStatus flash_wait_for(uint32_t time_us, Qspi &qspi);
void flash_init(Qspi &qspi);
@@ -97,6 +114,8 @@ qspi_status_t write_enable(Qspi &qspi);
qspi_status_t write_disable(Qspi &qspi);
+void log_register(uint32_t cmd, uint32_t reg_size, Qspi &qspi);
+
qspi_status_t dual_enable(Qspi &qspi);
qspi_status_t dual_disable(Qspi &qspi);
@@ -109,9 +128,11 @@ qspi_status_t fast_mode_enable(Qspi &qspi);
qspi_status_t erase(uint32_t erase_cmd, uint32_t flash_addr, Qspi &qspi);
-#define WAIT_FOR(timeout, q) \
- if(!flash_wait_for(timeout, q)) { \
- TEST_ASSERT_MESSAGE(false, "flash_wait_for failed!!!"); \
- }
+bool is_dual_cmd(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width);
+
+bool is_quad_cmd(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width);
+
+#define WAIT_FOR(timeout, q) TEST_ASSERT_EQUAL_MESSAGE(sOK, flash_wait_for(timeout, q), "flash_wait_for failed!!!")
+
#endif // MBED_QSPI_TEST_UTILS_H
From e5e05df66cbfe97bf63585211ff4b1a77049525c Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Fri, 6 Jul 2018 07:27:40 +0200
Subject: [PATCH 66/78] hal-qspi test: fix QSPI preprocessor guard
---
TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h | 2 +-
TESTS/mbed_hal/qspi/main.cpp | 9 ++++-----
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h b/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h
index adcfc32205..ce426064c8 100644
--- a/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h
+++ b/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h
@@ -17,7 +17,7 @@
#define MBED_QSPI_FLASH_MX25R6435F_H
-#define QSPI_FLASH_CHIP_STRING "MX25R6435F"
+#define QSPI_FLASH_CHIP_STRING "macronix MX25R6435F"
// Command for reading status register
#define QSPI_CMD_RDSR 0x05
diff --git a/TESTS/mbed_hal/qspi/main.cpp b/TESTS/mbed_hal/qspi/main.cpp
index 3496660516..b05fe91153 100644
--- a/TESTS/mbed_hal/qspi/main.cpp
+++ b/TESTS/mbed_hal/qspi/main.cpp
@@ -13,11 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-#if !DEVICE_QSPI
-#error [NOT_SUPPORTED] test not supported
-#endif
-
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
@@ -28,6 +23,10 @@
#include "qspi_api.h"
+#if !DEVICE_QSPI || !defined(QSPI_FLASH_CHIP_STRING)
+#error [NOT_SUPPORTED] QSPI not supported for this target
+#endif
+
using namespace utest::v1;
// uncomment to enable verbose mode
From 1534426b7ed5fe8c9e56b55617450d0824623486 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Tue, 17 Jul 2018 22:50:11 +0200
Subject: [PATCH 67/78] nrf52x: fix QSPI enable flag
QSPI feature was mistakenly moved form target nrf52840 to nrf52832
while rebasing. This change fixes it
---
targets/targets.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/targets/targets.json b/targets/targets.json
index ce9b1705e2..aee085e1b1 100755
--- a/targets/targets.json
+++ b/targets/targets.json
@@ -3873,8 +3873,7 @@
"SPI_ASYNCH",
"STCLK_OFF_DURING_SLEEP",
"TRNG",
- "USTICKER",
- "QSPI"
+ "USTICKER"
],
"extra_labels": [
"NORDIC",
@@ -3979,7 +3978,8 @@
"SPI_ASYNCH",
"STCLK_OFF_DURING_SLEEP",
"TRNG",
- "USTICKER"
+ "USTICKER",
+ "QSPI"
],
"extra_labels": [
"NORDIC",
From 43258a8ff47ca7ebb1343c344509f1f3f8f3f887 Mon Sep 17 00:00:00 2001
From: jeromecoutant
Date: Fri, 20 Jul 2018 10:18:13 +0200
Subject: [PATCH 68/78] STM32 : add all QSPI pins in available targets
---
.../TARGET_NUCLEO_F412ZG/PeripheralNames.h | 4 ++
.../TARGET_NUCLEO_F412ZG/PeripheralPins.c | 45 +++++++++++++
.../TARGET_DISCO_F413ZH/PeripheralPins.c | 67 ++++++++++---------
.../TARGET_NUCLEO_F413ZH/PeripheralNames.h | 4 ++
.../TARGET_NUCLEO_F413ZH/PeripheralPins.c | 45 +++++++++++++
.../TARGET_NUCLEO_F446RE/PeripheralNames.h | 4 ++
.../TARGET_NUCLEO_F446RE/PeripheralPins.c | 22 ++++++
.../TARGET_NUCLEO_F446ZE/PeripheralNames.h | 4 ++
.../TARGET_NUCLEO_F446ZE/PeripheralPins.c | 39 +++++++++++
.../TARGET_DISCO_F469NI/PeripheralPins.c | 41 +++++++++---
.../TARGET_DISCO_F746NG/PeripheralPins.c | 51 +++++++-------
.../TARGET_NUCLEO_F746ZG/PeripheralNames.h | 4 ++
.../TARGET_NUCLEO_F746ZG/PeripheralPins.c | 36 ++++++++++
.../TARGET_NUCLEO_F756ZG/PeripheralNames.h | 4 ++
.../TARGET_NUCLEO_F756ZG/PeripheralPins.c | 36 ++++++++++
.../TARGET_NUCLEO_F767ZI/PeripheralNames.h | 4 ++
.../TARGET_NUCLEO_F767ZI/PeripheralPins.c | 39 +++++++++++
.../TARGET_DISCO_F769NI/PeripheralNames.h | 4 ++
.../TARGET_DISCO_F769NI/PeripheralPins.c | 41 ++++++++++++
.../TARGET_NUCLEO_L432KC/PeripheralNames.h | 4 ++
.../TARGET_NUCLEO_L432KC/PeripheralPins.c | 21 ++++++
.../TARGET_NUCLEO_L433RC_P/PeripheralNames.h | 4 ++
.../TARGET_NUCLEO_L433RC_P/PeripheralPins.c | 24 +++++++
.../PeripheralPins.c | 32 ++++-----
.../TARGET_DISCO_L476VG/PeripheralPins.c | 24 +++----
.../TARGET_NUCLEO_L476RG/PeripheralNames.h | 4 ++
.../TARGET_NUCLEO_L476RG/PeripheralPins.c | 20 ++++++
.../TARGET_NUCLEO_L486RG/PeripheralNames.h | 4 ++
.../TARGET_NUCLEO_L486RG/PeripheralPins.c | 20 ++++++
.../TARGET_DISCO_L496AG/PeripheralPins.c | 46 +++++++++++++
.../TARGET_NUCLEO_L496ZG/PeripheralNames.h | 4 ++
.../TARGET_NUCLEO_L496ZG/PeripheralPins.c | 49 ++++++++++++++
tools/targets/STM32_gen_PeripheralPins.py | 24 +++----
33 files changed, 665 insertions(+), 109 deletions(-)
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/PeripheralNames.h
index c85180daf4..fd90f158b8 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/PeripheralNames.h
@@ -68,6 +68,10 @@ typedef enum {
CAN_2 = (int)CAN2_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/PeripheralPins.c
index e930f1049d..60b2bb5ce8 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/TARGET_NUCLEO_F412ZG/PeripheralPins.c
@@ -347,3 +347,48 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PG_12, CAN_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)},
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO0
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO1
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS
+ {PC_4, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO2
+ {PC_5, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO3
+ {PC_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2
+ {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0
+ {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_NCS
+ {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0
+ {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1
+ {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
+ {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2
+ {PE_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO0
+ {PE_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO1
+ {PE_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO2
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO3
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO0
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO1
+ {PG_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS // Connected to USB_PowerSwitchOn [STMPS2151STR_EN]
+ {PG_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO2
+ {PG_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO3
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK
+ {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK
+ {PD_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_NCS
+ {PG_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS // Connected to USB_PowerSwitchOn [STMPS2151STR_EN]
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PeripheralPins.c
index cf3b81ab5f..1f1b0edb2b 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PeripheralPins.c
@@ -400,42 +400,47 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{NC, NC, 0}
};
+//*** QUADSPI ***
+
MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
- {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
- {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO0
- {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO1
- {PC_4, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO2
- {PC_5, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO3
- {PC_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO2
- {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO0
- {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO1
- {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0
- {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1
- {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3, N25Q128A13EF840F
- {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2, N25Q128A13EF840F
- {PE_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO0
- {PE_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO1
- {PE_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO2
- {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO3
- {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
- {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2
- {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO0, N25Q128A13EF840F
- {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO1, N25Q128A13EF840F
- {PG_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO2
- {PG_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO3
- {NC, NC, 0}
+ {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3 // Connected to ARD_A1
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO0 // Connected to SD_CMD
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO1 // Connected to DFSDM2_DATIN1
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS // Connected to ARD_D4
+ {PC_4, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO2 // Connected to ARD_A5
+ {PC_5, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO3 // Connected to LED2_GREEN
+ {PC_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2 // Connected to SD_D0
+ {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0 // Connected to SD_D1
+ {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1 // Connected to SD_D2
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_NCS // Connected to SD_D3
+ {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0 // Connected to PSRAM_A16 [IS66WV51216EBLL_A16]
+ {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1 // Connected to PSRAM_A17 [IS66WV51216EBLL_A17]
+ {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3 // Connected to QSPI_BK1_IO3 [N25Q128A13EF840F_DQ3]
+ {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2 // Connected to QSPI_BK1_IO2 [N25Q128A13EF840F_DQ2]
+ {PE_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO0 // Connected to LCD_PSRAM_D4
+ {PE_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO1 // Connected to LCD_PSRAM_D5
+ {PE_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO2 // Connected to LCD_PSRAM_D6
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO3 // Connected to LCD_PSRAM_D7
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3 // Connected to ARD_D0
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2 // Connected to ARD_D1
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO0 // Connected to QSPI_BK1_IO0 [N25Q128A13EF840F_DQ0]
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO1 // Connected to QSPI_BK1_IO1 [N25Q128A13EF840F_DQ1]
+ {PG_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS // Connected to QSPI_BK1_NCS [N25Q128A13EF840F_S]
+// {PG_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO2 // Connected to STDIO_UART_RX
+// {PG_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO3 // Connected to STDIO_UART_TX
+ {NC, NC, 0}
};
MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
- {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
- {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // N25Q128A13EF840F
- {PD_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
- {NC, NC, 0}
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK // Connected to ARD_A4
+ {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK // Connected to QSPI_CLK [N25Q128A13EF840F_C]
+ {PD_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK // Connected to CODEC_CK [WM8994ECS_BCLK1]
+ {NC, NC, 0}
};
MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
- {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS
- {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_NCS
- {PG_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS, N25Q128A13EF840F
- {NC, NC, 0}
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS // Connected to ARD_D4
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_NCS // Connected to SD_D3
+ {PG_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS // Connected to QSPI_BK1_NCS [N25Q128A13EF840F_S]
+ {NC, NC, 0}
};
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_NUCLEO_F413ZH/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_NUCLEO_F413ZH/PeripheralNames.h
index 22ad0b3f55..3493e2cd25 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_NUCLEO_F413ZH/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_NUCLEO_F413ZH/PeripheralNames.h
@@ -79,6 +79,10 @@ typedef enum {
CAN_3 = (int)CAN3_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_NUCLEO_F413ZH/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_NUCLEO_F413ZH/PeripheralPins.c
index 7849e9a665..c36385da88 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_NUCLEO_F413ZH/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_NUCLEO_F413ZH/PeripheralPins.c
@@ -399,3 +399,48 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PG_12, CAN_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)},
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO0
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO1
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS
+ {PC_4, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO2
+ {PC_5, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO3
+ {PC_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2
+ {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0
+ {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_NCS
+ {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0
+ {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1
+ {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
+ {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2
+ {PE_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO0
+ {PE_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO1
+ {PE_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO2
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO3
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO0
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO1
+ {PG_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS // Connected to USB_PowerSwitchOn [STMPS2151STR_EN]
+ {PG_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO2
+ {PG_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO3
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK
+ {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK
+ {PD_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_NCS
+ {PG_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS // Connected to USB_PowerSwitchOn [STMPS2151STR_EN]
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/PeripheralNames.h
index 0382c324ea..baa8cfb032 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/PeripheralNames.h
@@ -89,6 +89,10 @@ typedef enum {
CAN_2 = (int)CAN2_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/PeripheralPins.c
index 5c950eaba3..bfb40065cf 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/PeripheralPins.c
@@ -309,3 +309,25 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PB_13, CAN_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)},
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS
+ {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0
+ {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_NCS
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_NCS
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/PeripheralNames.h
index 0382c324ea..baa8cfb032 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/PeripheralNames.h
@@ -89,6 +89,10 @@ typedef enum {
CAN_2 = (int)CAN2_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/PeripheralPins.c
index cf27af8c35..91dee64454 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446ZE/PeripheralPins.c
@@ -380,3 +380,42 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PD_1, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS
+ {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0
+ {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_NCS
+ {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0
+ {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1
+ {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
+ {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2
+ {PE_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO0
+ {PE_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO1
+ {PE_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO2
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO3
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO0
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO1
+ {PG_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS // Connected to USB_PowerSwitchOn [STMPS2151STR_EN]
+ {PG_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO2
+ {PG_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO3
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK
+ {PD_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_NCS
+ {PG_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS // Connected to USB_PowerSwitchOn [STMPS2151STR_EN]
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
index 1e2970c096..8d2e24426d 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_DISCO_F469NI/PeripheralPins.c
@@ -389,22 +389,43 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{NC, NC, 0}
};
+//*** QUADSPI ***
MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
- {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
- {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
- {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
- {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
- {NC, NC, 0}
+ {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS // Connected to QSPI_BK1_NCS [N25Q128A13EF840F_S]
+// {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_NCS // Connected to STDIO_UART_TX
+ {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0 // Connected to uSD_D1
+ {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1 // Connected to uSD_D2
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_NCS // Connected to uSD_D3
+ {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO0
+ {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO1
+ {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3 // Connected to MIC_CK [MP34DT01TR_CLK]
+ {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2 // Connected to AUDIO_RST [CS43L22_RESET]
+ {PE_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO0 // Connected to D4
+ {PE_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO1 // Connected to D5
+ {PE_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO2 // Connected to D6
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK2_IO3 // Connected to D7
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO3 // Connected to QSPI_BK1_IO3 [N25Q128A13EF840F_DQ3]
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_IO2 // Connected to QSPI_BK1_IO2 [N25Q128A13EF840F_DQ2]
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO0 // Connected to QSPI_BK1_IO0 [N25Q128A13EF840F_DQ0]
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_IO1 // Connected to QSPI_BK1_IO1 [N25Q128A13EF840F_DQ1]
+ {PG_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO2 // Connected to USART6_RX
+ {PG_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO3 // Connected to ARDUINO USART6_TX
+ {PH_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO0 // Connected to SDCKE0 [MT48LC4M32B2B5-6A_CKE]
+ {PH_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_IO1 // Connected to SDNE0 [MT48LC4M32B2B5-6A_CS]
+ {NC, NC, 0}
};
MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
- {PF_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)},
- {NC, NC, 0}
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_CLK
+ {PF_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_CLK // Connected to QSPI_CLK [N25Q128A13EF840F_C]
+ {NC, NC, 0}
};
MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
- {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)},
- {NC, NC, 0}
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QSPI)}, // QUADSPI_BK1_NCS // Connected to QSPI_BK1_NCS [N25Q128A13EF840F_S]
+// {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK1_NCS // Connected to STDIO_UART_TX
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QSPI)}, // QUADSPI_BK2_NCS // Connected to uSD_D3
+ {NC, NC, 0}
};
-
diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/PeripheralPins.c
index e542065510..9781b7dd46 100644
--- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_DISCO_F746NG/PeripheralPins.c
@@ -407,39 +407,40 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{NC, NC, 0}
};
+//*** QUADSPI ***
+
MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
-// {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
-// {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
-// {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
-// {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
-// {PC_11, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
- {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // IO0 connected to N25Q128
- {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // IO1 connected to N25Q128
- {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // IO3 connected to N25Q128
- {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // IO2 connected to N25Q128
-// {PE_7, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
-// {PE_8, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
-// {PE_9, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
-// {PE_10, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // IO3 connected to pin A5
- {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // IO2 connected to pin A4
- {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO0 connected to pin A3
- {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO1 connected to pin A2
-// {PG_9, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
-// {PG_14, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
-// {PH_2, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
-// {PH_3, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
+ {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to RMII_REF_CLK [LAN8742A-CZ-TR_REFCLK0]
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to QSPI_NCS [N25Q128A13EF840E_S]
+ {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO0 // Connected to SDMMC1_D1
+ {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO1 // Connected to SDMMC_D2
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_NCS // Connected to SDMMC_D3
+ {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO0 // Connected to QSPI_D0 [N25Q128A13EF840E_DQ0]
+ {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO1 // Connected to QSPI_D1 [N25Q128A13EF840E_DQ1]
+ {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to QSPI_D3 [N25Q128A13EF840E_DQ3]
+ {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO2 // Connected to QSPI_D2 [N25Q128A13EF840E_DQ2]
+ {PE_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO0 // Connected to FMC_D4 [MT48LC4M32B2B5-6A_DQ4]
+ {PE_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO1 // Connected to FMC_D5 [MT48LC4M32B2B5-6A_DQ5]
+ {PE_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO2 // Connected to FMC_D6 [MT48LC4M32B2B5-6A_DQ6]
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO3 // Connected to FMC_D7 [MT48LC4M32B2B5-6A_DQ7]
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to ARDUINO A5
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO2 // Connected to ARDUINO A4
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0 // Connected to ARDUINO A3
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1 // Connected to ARDUINO A2
+ {PG_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO2 // Connected to DCMI_VSYNC
+ {PG_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO3 // Connected to RMII_TXD1 [LAN8742A-CZ-TR_TXD1]
+ {PH_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO0 // Connected to NC2
+ {PH_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO1 // Connected to FMC_SDNE0 [MT48LC4M32B2B5-6A_CS]
{NC, NC, 0}
};
MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
- {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // connected to N25Q128 flash
+ {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_CLK // Connected to QUADSPI_CLK
{NC, NC, 0}
};
MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
- {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // connected to N25Q128 flash
-// {PC_11, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)},
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to QSPI_NCS [N25Q128A13EF840E_S]
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_NCS // Connected to SDMMC_D3
{NC, NC, 0}
};
-
diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/PeripheralNames.h
index 66fc3645d5..1665800aa2 100644
--- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/PeripheralNames.h
@@ -93,6 +93,10 @@ typedef enum {
CAN_2 = (int)CAN2_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/PeripheralPins.c
index b532122f88..3d8218d176 100644
--- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/TARGET_NUCLEO_F746ZG/PeripheralPins.c
@@ -378,3 +378,39 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PD_1, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to RMII_REF_CLK [LAN8742A-CZ-TR_REFCLK0]
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS
+ {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO0
+ {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_NCS
+ {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO0
+ {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3
+ {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO2
+ {PE_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO0
+ {PE_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO1
+ {PE_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO2
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO3
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO2
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PG_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO2
+ {PG_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO3
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_CLK
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_NCS
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/PeripheralNames.h
index 66fc3645d5..1665800aa2 100644
--- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/PeripheralNames.h
@@ -93,6 +93,10 @@ typedef enum {
CAN_2 = (int)CAN2_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/PeripheralPins.c
index b532122f88..3d8218d176 100644
--- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/TARGET_NUCLEO_F756ZG/PeripheralPins.c
@@ -378,3 +378,39 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PD_1, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to RMII_REF_CLK [LAN8742A-CZ-TR_REFCLK0]
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS
+ {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO0
+ {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_NCS
+ {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO0
+ {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3
+ {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO2
+ {PE_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO0
+ {PE_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO1
+ {PE_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO2
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO3
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO2
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PG_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO2
+ {PG_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO3
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_CLK
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_NCS
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/PeripheralNames.h
index 2383be6c21..f0584fe465 100644
--- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/PeripheralNames.h
@@ -94,6 +94,10 @@ typedef enum {
CAN_3 = (int)CAN3_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/PeripheralPins.c
index 5e12d2c985..c11e39acbd 100644
--- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/TARGET_NUCLEO_F767ZI/PeripheralPins.c
@@ -418,3 +418,42 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PD_1, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to RMII_REF_CLK [LAN8742A-CZ-TR_REFCLK0]
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS
+ {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_NCS
+ {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO0
+ {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_NCS
+ {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO0
+ {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3
+ {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO2
+ {PE_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO0
+ {PE_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO1
+ {PE_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO2
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO3
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO2
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PG_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO2
+ {PG_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO3
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_CLK
+ {PF_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_CLK
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS
+ {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_NCS
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_NCS
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/PeripheralNames.h
index 2383be6c21..f0584fe465 100644
--- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/PeripheralNames.h
@@ -94,6 +94,10 @@ typedef enum {
CAN_3 = (int)CAN3_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/PeripheralPins.c
index 1920db8a2c..6c2ac77d70 100644
--- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/TARGET_DISCO_F769NI/PeripheralPins.c
@@ -450,3 +450,44 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PH_13, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, // Connected to D21
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PA_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to RMII_REF_CLK [LAN8742A-CZ-TR_REFCLK0]
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to QSPI_NCS [N25Q128A13EF840E_S]
+ {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to ULPI_D3 [USB3320C-EZK_D3]
+ {PC_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO0 // Connected to QSPI_D0 [N25Q128A13EF840E_DQ0]
+ {PC_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO1 // Connected to QSPI_D1 [MT25QL512ABB1EW9_DQ1]
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_NCS // Connected to DFSDM_DATIN5 [TP5]
+ {PD_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO0 // Connected to SPDIF_TX [TP20]
+ {PD_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO1 // Connected to AUDIO_SCL [WM8994ECS/R_SCLK]
+ {PD_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to QSPI_D3 [N25Q128A13EF840E_DQ3]
+ {PE_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO2 // Connected to QSPI_D2 [N25Q128A13EF840E_DQ2]
+ {PE_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO0 // Connected to FMC_D4 [MT48LC4M32B2B5-6A_DQ4]
+ {PE_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO1 // Connected to FMC_D5 [MT48LC4M32B2B5-6A_DQ5]
+ {PE_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO2 // Connected to FMC_D6 [MT48LC4M32B2B5-6A_DQ6]
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO3 // Connected to FMC_D7 [MT48LC4M32B2B5-6A_DQ7]
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to ARD_D3/PWM
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO2 // Connected to ARD_D6/PWM
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0 // Connected to ARDUINO A3
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1 // Connected to ARDUINO A2
+ {PG_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO2 // Connected to uSD_D0
+ {PG_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO3 // Connected to RMII_TXD1 [LAN8742A-CZ-TR_TXD1]
+ {PH_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO0 // Connected to FMC_SDCKE0 [MT48LC4M32B2B5-6A_CKE]
+ {PH_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_IO1 // Connected to FMC_SDNE0 [MT48LC4M32B2B5-6A_CS]
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PB_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_CLK // Connected to QSPI_CLK
+ {PF_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_CLK // Connected to ARDUINO A1
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PB_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to QSPI_NCS [N25Q128A13EF840E_S]
+ {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to ULPI_D3 [USB3320C-EZK_D3]
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK2_NCS // Connected to DFSDM_DATIN5 [TP5]
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/PeripheralNames.h
index 4c8d454ccc..045a699cb4 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/PeripheralNames.h
@@ -71,6 +71,10 @@ typedef enum {
CAN_1 = (int)CAN1_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/PeripheralPins.c
index cb5bbaff5b..175a8747bf 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/PeripheralPins.c
@@ -204,3 +204,24 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PA_12, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+// {PA_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to STDIO_UART_TX
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO3
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO2
+ {PB_0, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PA_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+// {PA_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to STDIO_UART_TX
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/TARGET_NUCLEO_L433RC_P/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/TARGET_NUCLEO_L433RC_P/PeripheralNames.h
index bc71becee7..049b2f31f5 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/TARGET_NUCLEO_L433RC_P/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/TARGET_NUCLEO_L433RC_P/PeripheralNames.h
@@ -76,6 +76,10 @@ typedef enum {
CAN_1 = (int)CAN1_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_R_BASE,
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/TARGET_NUCLEO_L433RC_P/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/TARGET_NUCLEO_L433RC_P/PeripheralPins.c
index 405e6778ad..6dddb43f74 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/TARGET_NUCLEO_L433RC_P/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/TARGET_NUCLEO_L433RC_P/PeripheralPins.c
@@ -259,3 +259,27 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PB_9, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+// {PA_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to STDIO_UART_TX
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to SMPS_PG [ADP5301ACBZ_OUTOK]
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO2 // Connected to SMPS_SW [TS3A44159PWR_IN1_2]
+ {PB_0, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0
+ {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+// {PA_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK // Connected to STDIO_UART_RX
+ {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+// {PA_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to STDIO_UART_TX
+ {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PeripheralPins.c
index 502b176fa2..3861e7a9d5 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/TARGET_DISCO_L475VG_IOT01A/PeripheralPins.c
@@ -341,26 +341,28 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{NC, NC, 0}
};
+//*** QUADSPI ***
+
MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
- {PE_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {PE_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {PE_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {PE_15, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {PB_0, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {NC, NC, 0}
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to ARD_D12 [SPI1_MISO]
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO2 // Connected to ARD_D11 [SPI1_MOSI]
+ {PB_0, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1 // Connected to ARD_D3 [INT_EXT10]
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0 // Connected to ARD_D6 [ADC1_IN6]
+ {PE_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0 // Connected to OQUADSPI_BK1_IO0 [MX25R6435F_IO0]
+ {PE_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1 // Connected to QUADSPI_BK1_IO1 [MX25R6435F_IO1]
+ {PE_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO2 // Connected to QUAD_SPI_BK1_IO2 [MX25R6435F_IO2]
+ {PE_15, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to QUAD_SPI_BK1_IO3 [MX25R6435F_IO3]
+ {NC, NC, 0}
};
MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
- {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {NC, NC, 0}
+ {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK // Connected to INTERNAL_I2C2_SCL [VL53L0X_SCL]
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK // Connected to QUADSPI_CLK [MX25R6435F_SCLK]
+ {NC, NC, 0}
};
MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
- {PE_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {NC, NC, 0}
+ {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_NCS // Connected to INTERNAL_I2C2_SDA [VL53L0X_SDA]
+ {PE_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_NCS // Connected to QUADSPI_NCS [MX25R6435F_SCLK]
+ {NC, NC, 0}
};
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/PeripheralPins.c
index bafe58975e..58bb3cbe88 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_DISCO_L476VG/PeripheralPins.c
@@ -344,25 +344,25 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
//*** QUADSPI ***
MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
- {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO3 not connected
- {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO2 not connected
- {PB_0, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO1 not connected
- {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO0 not connected
- {PE_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO0 connected to N25Q128
- {PE_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO1 connected to N25Q128
- {PE_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO2 connected to N25Q128
- {PE_15, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // IO3 connected to N25Q128
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to SEG23 [GH08172T_SEG23]
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO2 // Connected to SEG0 [GH08172T_SEG0]
+ {PB_0, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1 // Connected to SEG21 [GH08172T_SEG21]
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0 // Connected to SEG2 [GH08172T_SEG2]
+ {PE_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0 // Connected to QSPI_D0 [N25Q128A13EF840E_DQ0]
+ {PE_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1 // Connected to QSPI_D1 [N25Q128A13EF840E_DQ1]
+ {PE_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO2 // Connected to QSPI_D2 [N25Q128A13EF840E_DQ2]
+ {PE_15, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to QSPI_D3 [N25Q128A13EF840E_DQ3]
{NC, NC, 0}
};
MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
-// {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // connected to N25Q128
+ {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK // Connected to MFX_I2C_SLC [MFX_V2_I2C_SCL]
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK // Connected to QSPI_CLK [N25Q128A13EF840E_C]
{NC, NC, 0}
};
MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
-// {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)},
- {PE_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // connected to N25Q128
+ {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_NCS // Connected to MFX_I2C_SDA [MFX_V2_I2C_SDA]
+ {PE_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_NCS // Connected to QSPI_CS [N25Q128A13EF840E_S\#]
{NC, NC, 0}
};
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/PeripheralNames.h
index bc8f43ffa8..2300627c5b 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/PeripheralNames.h
@@ -83,6 +83,10 @@ typedef enum {
CAN_1 = (int)CAN1_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_BASE
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/PeripheralPins.c
index 008265a2ac..76ec6e2d10 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/TARGET_NUCLEO_L476RG/PeripheralPins.c
@@ -305,3 +305,23 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PB_9, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO3
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO2
+ {PB_0, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_NCS
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/PeripheralNames.h
index bc8f43ffa8..2300627c5b 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/PeripheralNames.h
@@ -83,6 +83,10 @@ typedef enum {
CAN_1 = (int)CAN1_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_BASE
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/PeripheralPins.c
index 008265a2ac..76ec6e2d10 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/TARGET_NUCLEO_L486RG/PeripheralPins.c
@@ -305,3 +305,23 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PB_9, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO3
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO2
+ {PB_0, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_NCS
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_DISCO_L496AG/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_DISCO_L496AG/PeripheralPins.c
index a8254ebd4d..6b99293215 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_DISCO_L496AG/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_DISCO_L496AG/PeripheralPins.c
@@ -421,3 +421,49 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PH_13, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, // Connected to ARD_D9
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+// {PA_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to STDIO_UART_TX
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to QSPI_BK1_IO3 [MX25R6435FM2IL0_SIO3]
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO2 // Connected to QSPI_BK1_IO2 [MX25R6435FM2IL0_SIO2]
+ {PB_0, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1 // Connected to QSPI_BK1_IO1 [MX25R6435FM2IL0_SIO1]
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0 // Connected to QSPI_BK1_IO0 [MX25R6435FM2IL0_SIO0]
+ {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to QSPI_BK1_NCS [MX25R6435FM2IL0_CS]
+ {PC_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO0 // Connected to ADCx_IN2
+ {PC_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO1 // Connected to DF_CKOUT
+ {PC_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO2 // Connected to ARD_A2
+ {PC_4, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO3 // Connected to ARD_A0
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_QUADSPI)}, // QUADSPI_BK2_NCS // Connected to uSD_D3
+ {PD_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_NCS
+ {PD_4, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO0 // Connected to OE [OE_IS66WV51216EBLL]
+ {PD_5, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO1 // Connected to WE [WE_IS66WV51216EBLL]
+// {PD_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_QUADSPI)}, // QUADSPI_BK2_IO1 // Connected to STDIO_UART_RX
+// {PD_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO2 // Connected to STDIO_UART_RX
+ {PD_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO3 // Connected to LCD_NE
+ {PE_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to D8 [D8_IS66WV51216EBLL]
+ {PE_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0 // Connected to D9 [D9_IS66WV51216EBLL]
+ {PE_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1 // Connected to D10 [D10_IS66WV51216EBLL]
+ {PE_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO2 // Connected to D11 [D11_IS66WV51216EBLL]
+ {PE_15, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO3 // Connected to D12 [D12_IS66WV51216EBLL]
+ {PH_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_QUADSPI)}, // QUADSPI_BK2_IO0 // Connected to STMOD_INT
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PA_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK // Connected to QSPI_CLK [MX25R6435FM2IL0_SCLK]
+ {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK // Connected to SAI1_SCK_A
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK // Connected to D7 [D7_IS66WV51216EBLL]
+ {PF_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_QUADSPI)}, // QUADSPI_CLK // Connected to ARD_A3
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+// {PA_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to STDIO_UART_TX
+ {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to QSPI_BK1_NCS [MX25R6435FM2IL0_CS]
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_QUADSPI)}, // QUADSPI_BK2_NCS // Connected to uSD_D3
+ {PD_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_NCS
+ {PE_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Connected to D8 [D8_IS66WV51216EBLL]
+ {NC, NC, 0}
+};
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_NUCLEO_L496ZG/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_NUCLEO_L496ZG/PeripheralNames.h
index b3a010be10..73046c23d4 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_NUCLEO_L496ZG/PeripheralNames.h
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_NUCLEO_L496ZG/PeripheralNames.h
@@ -85,6 +85,10 @@ typedef enum {
CAN_2 = (int)CAN2_BASE
} CANName;
+typedef enum {
+ QSPI_1 = (int)QSPI_BASE
+} QSPIName;
+
#ifdef __cplusplus
}
#endif
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_NUCLEO_L496ZG/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_NUCLEO_L496ZG/PeripheralPins.c
index c1d0424246..0c36de6fe9 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_NUCLEO_L496ZG/PeripheralPins.c
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/TARGET_NUCLEO_L496ZG/PeripheralPins.c
@@ -409,3 +409,52 @@ MBED_WEAK const PinMap PinMap_CAN_TD[] = {
{PD_1, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
{NC, NC, 0}
};
+
+//*** QUADSPI ***
+
+MBED_WEAK const PinMap PinMap_QSPI_DATA[] = {
+ {PA_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS
+ {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO3
+ {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO2
+ {PB_0, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0
+ {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Only STM32L496ZG, not STM32L496ZG-P
+ {PC_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO0
+ {PC_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO1
+ {PC_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO2
+ {PC_4, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO3
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_QUADSPI)}, // QUADSPI_BK2_NCS
+ {PD_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_NCS
+ {PD_4, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO0
+ {PD_5, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO1
+ {PD_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_QUADSPI)}, // QUADSPI_BK2_IO1
+ {PD_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO2
+ {PD_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_IO3
+ {PE_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS
+ {PE_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0
+ {PE_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1
+ {PE_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO2
+ {PE_15, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO3
+ {PF_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO3
+ {PF_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO2
+ {PF_8, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0
+ {PF_9, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
+ {PA_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK
+ {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK
+ {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_CLK
+ {PF_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_QUADSPI)}, // QUADSPI_CLK
+ {NC, NC, 0}
+};
+
+MBED_WEAK const PinMap PinMap_QSPI_SSEL[] = {
+ {PA_2, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS
+ {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS // Only STM32L496ZG, not STM32L496ZG-P
+ {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_QUADSPI)}, // QUADSPI_BK2_NCS
+ {PD_3, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK2_NCS
+ {PE_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_NCS
+ {NC, NC, 0}
+};
diff --git a/tools/targets/STM32_gen_PeripheralPins.py b/tools/targets/STM32_gen_PeripheralPins.py
index 6ec8a0b0d2..5fddb018d3 100644
--- a/tools/targets/STM32_gen_PeripheralPins.py
+++ b/tools/targets/STM32_gen_PeripheralPins.py
@@ -26,10 +26,10 @@ import textwrap
from xml.dom.minidom import parse, Node
from argparse import RawTextHelpFormatter
-GENPINMAP_VERSION = "1.2"
+GENPINMAP_VERSION = "1.3"
ADD_DEVICE_IFDEF = 0
-ADD_QSPI_FEATURE = 0
+ADD_QSPI_FEATURE = 1
mcu_file=""
mcu_list = [] #'name'
@@ -779,7 +779,6 @@ def print_can(l):
out_c_file.write( "#endif\n" )
def print_qspi(l):
- prev_s = ''
for p in l:
result = get_gpio_af_num(p[1], p[2])
if result != 'NOTFOUND':
@@ -789,21 +788,12 @@ def print_qspi(l):
CommentedLine = "//"
if "RCC_OSC" in PinLabel[p[1]]:
CommentedLine = "//"
- s1 = "%-17s" % (CommentedLine + " {" + p[0] + ',')
+ s1 = "%-16s" % (CommentedLine + " {" + p[0] + ',')
# p[2] : QUADSPI_BK1_IO3 / QUADSPI_CLK / QUADSPI_NCS
- instance = p[2].split('_')[1].replace("BK", "")
- instance = instance.replace("CLK", "1")
- instance = instance.replace("NCS", "1")
- s1 += "%-7s" % ('QSPI_' + instance + ',')
+ s1 += "%-8s" % ('QSPI_1,')
+ result = result.replace("GPIO_AF10_OTG_FS", "GPIO_AF10_QSPI")
s1 += 'STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, ' + result +')},'
- #check duplicated lines, only signal differs
- if (prev_s == s1):
- s1 = '|' + p[2]
- else:
- if len(prev_s)>0:
- out_c_file.write('\n')
- prev_s = s1
- s1 += ' // ' + p[2]
+ s1 += ' // ' + p[2]
if p[1] in PinLabel.keys():
s1 += ' // Connected to ' + PinLabel[p[1]]
s1 += '\n'
@@ -980,6 +970,7 @@ def parse_BoardFile(fileName):
PinLabel[EachPin] = PinData[EachPin]["GPIO_Label"]
if "STLK_RX" in PinLabel[EachPin] or "STLK_TX" in PinLabel[EachPin]:
+ # Patch waiting for CubeMX correction
if "RX" in PinData[EachPin]["Signal"]:
PinLabel[EachPin] = "STDIO_UART_RX"
else:
@@ -1001,6 +992,7 @@ def parse_BoardFile(fileName):
elif "USART2_TX" in PinLabel[EachPin]:
PinLabel[EachPin] = "STDIO_UART_TX"
elif "STLINK_RX" in PinLabel[EachPin] or "STLINK_TX" in PinLabel[EachPin]:
+ # Patch waiting for CubeMX correction
if "RX" in PinData[EachPin]["Signal"]:
PinLabel[EachPin] = "STDIO_UART_RX"
else:
From 5c26e15cd337dd6b9e2102d6ec013ed5e9279ecb Mon Sep 17 00:00:00 2001
From: adustm
Date: Thu, 19 Jul 2018 16:29:13 +0200
Subject: [PATCH 69/78] Fix support of max flash size
---
targets/TARGET_STM/qspi_api.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index 3f8d6037cf..cae46fe06a 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -35,8 +35,8 @@
#include "PeripheralPins.h"
/* Max amount of flash size is 4Gbytes */
-/* hence 2^(31+1), then FLASH_SIZE_DEFAULT = 31<<20 */
-#define QSPI_FLASH_SIZE_DEFAULT 0x1F00000
+/* hence 2^(31+1), then FLASH_SIZE_DEFAULT = 1<<31 */
+#define QSPI_FLASH_SIZE_DEFAULT 0x80000000
void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st_command)
{
From 893cf2a5f5906b32f18dfb634a9be3759fc590b5 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Mon, 23 Jul 2018 12:00:25 +0200
Subject: [PATCH 70/78] hal-qspi_test: remove STM workaround
after feature-qspi branch rebase, everything works fine and workaround is not needed anymore
---
.../flash_configs/STM/DISCO_L475VG_IOT01A/flash_config.h | 4 ----
TESTS/mbed_hal/qspi/main.cpp | 5 -----
2 files changed, 9 deletions(-)
diff --git a/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_L475VG_IOT01A/flash_config.h b/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_L475VG_IOT01A/flash_config.h
index 93e1c2855c..76cb739bb5 100644
--- a/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_L475VG_IOT01A/flash_config.h
+++ b/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_L475VG_IOT01A/flash_config.h
@@ -18,9 +18,5 @@
#include "../../MX25R6435F_config.h"
-// TODO: remove when fixed
-// when perform 4IO write, when memory indicates write finish (changing WIP bit in status register)
-// but actually write is still in progress and we have to wait a bit more before reading
-#define STM_WRITE_4IO_BUG_WORKAROUND
#endif // MBED_QSPI_FLASH_CONFIG_H
diff --git a/TESTS/mbed_hal/qspi/main.cpp b/TESTS/mbed_hal/qspi/main.cpp
index b05fe91153..0ef44ee797 100644
--- a/TESTS/mbed_hal/qspi/main.cpp
+++ b/TESTS/mbed_hal/qspi/main.cpp
@@ -142,11 +142,6 @@ static void _qspi_write_read_test(Qspi &qspi, qspi_bus_width_t write_inst_width,
timer.stop();
write_time = timer.read_us();
-#ifdef STM_WRITE_4IO_BUG_WORKAROUND
- if (write_cmd == QSPI_CMD_WRITE_4IO) {
- wait_us(2000);
- }
-#endif
}
if (read_frequency != QSPI_NONE) {
From 7dda4e4fc6ca9d1701555165ac29a26c0ed2169e Mon Sep 17 00:00:00 2001
From: adustm
Date: Thu, 19 Jul 2018 10:41:09 +0200
Subject: [PATCH 71/78] Implement qspi_free function
---
.../TARGET_STM32F413xH/objects.h | 6 ++++
.../TARGET_STM32F469xI/objects.h | 6 ++++
.../TARGET_STM32F746xG/objects.h | 6 ++++
.../TARGET_STM32L475xG/objects.h | 6 ++++
.../TARGET_STM32L476xG/objects.h | 6 ++++
targets/TARGET_STM/qspi_api.c | 30 +++++++++++++++++--
6 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h
index 85d6d2667b..0c132e93fd 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h
@@ -46,6 +46,12 @@ struct trng_s {
struct qspi_s {
QSPI_HandleTypeDef handle;
+ PinName io0;
+ PinName io1;
+ PinName io2;
+ PinName io3;
+ PinName sclk;
+ PinName ssel;
};
#include "common_objects.h"
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h
index 1702826fdb..106be4c446 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h
@@ -60,6 +60,12 @@ struct trng_s {
struct qspi_s {
QSPI_HandleTypeDef handle;
+ PinName io0;
+ PinName io1;
+ PinName io2;
+ PinName io3;
+ PinName sclk;
+ PinName ssel;
};
#include "common_objects.h"
diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h
index 9ccc1c28d4..2e538dcf5b 100644
--- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h
+++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h
@@ -60,6 +60,12 @@ struct trng_s {
struct qspi_s {
QSPI_HandleTypeDef handle;
+ PinName io0;
+ PinName io1;
+ PinName io2;
+ PinName io3;
+ PinName sclk;
+ PinName ssel;
};
#include "common_objects.h"
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h
index 249e162543..61c29a5fba 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h
@@ -60,6 +60,12 @@ struct trng_s {
struct qspi_s {
QSPI_HandleTypeDef handle;
+ PinName io0;
+ PinName io1;
+ PinName io2;
+ PinName io3;
+ PinName sclk;
+ PinName ssel;
};
#include "common_objects.h"
diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h
index 95148ef88d..cd0f1a783c 100644
--- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h
+++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h
@@ -60,6 +60,12 @@ struct trng_s {
struct qspi_s {
QSPI_HandleTypeDef handle;
+ PinName io0;
+ PinName io1;
+ PinName io2;
+ PinName io3;
+ PinName sclk;
+ PinName ssel;
};
#include "common_objects.h"
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index cae46fe06a..92b427d54b 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -173,13 +173,19 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
// tested all combinations, take first
obj->handle.Instance = (QUADSPI_TypeDef *)qspi_data_first;
- // TODO pinmap here for pins (enable clock)
+ // pinmap for pins (enable clock)
+ obj->io0 = io0;
pinmap_pinout(io0, PinMap_QSPI_DATA);
+ obj->io1 = io1;
pinmap_pinout(io1, PinMap_QSPI_DATA);
+ obj->io2 = io2;
pinmap_pinout(io2, PinMap_QSPI_DATA);
+ obj->io3 = io3;
pinmap_pinout(io3, PinMap_QSPI_DATA);
+ obj->sclk = sclk;
pinmap_pinout(sclk, PinMap_QSPI_SCLK);
+ obj->ssel = ssel;
pinmap_pinout(ssel, PinMap_QSPI_SSEL);
if (HAL_QSPI_Init(&obj->handle) != HAL_OK) {
@@ -191,8 +197,26 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
qspi_status_t qspi_free(qspi_t *obj)
{
- // TODO
- //return QSPI_STATUS_ERROR;
+ if(HAL_QSPI_DeInit(&obj->handle) != HAL_OK) {
+ return QSPI_STATUS_ERROR;
+ }
+
+ // Reset QSPI
+ __HAL_RCC_QSPI_FORCE_RESET();
+ __HAL_RCC_QSPI_RELEASE_RESET();
+
+ // Disable interface clock for QSPI
+ __HAL_RCC_QSPI_CLK_DISABLE();
+
+ // Configure GPIOs
+ pin_function(obj->io0, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
+ pin_function(obj->io1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
+ pin_function(obj->io2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
+ pin_function(obj->io3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
+ pin_function(obj->sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
+ pin_function(obj->ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
+
+ (void)(obj);
return QSPI_STATUS_OK;
}
From 6095ccf1b4e108b9ba40ad5367b67afd35f7b8d8 Mon Sep 17 00:00:00 2001
From: adustm
Date: Tue, 24 Jul 2018 14:32:31 +0200
Subject: [PATCH 72/78] Add reset internal state before call to HAL_QspiInit
function
---
targets/TARGET_STM/qspi_api.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c
index 92b427d54b..da8570c026 100644
--- a/targets/TARGET_STM/qspi_api.c
+++ b/targets/TARGET_STM/qspi_api.c
@@ -140,6 +140,10 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
__HAL_RCC_QSPI_FORCE_RESET();
__HAL_RCC_QSPI_RELEASE_RESET();
+ // Reset handle internal state
+ obj->handle.State = HAL_QSPI_STATE_RESET;
+ obj->handle.Lock = HAL_UNLOCKED;
+
// Set default QSPI handle values
obj->handle.Init.ClockPrescaler = 1;
obj->handle.Init.FifoThreshold = 1;
From 948d1a301356f541ce45d8a468e198c9ccd694f3 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Fri, 3 Aug 2018 09:54:47 +0200
Subject: [PATCH 73/78] hal-qspi test: code refactoring
---
.../qspi/flash_configs/MX25R6435F_config.h | 16 +++++--
TESTS/mbed_hal/qspi/main.cpp | 44 ++++++++-----------
TESTS/mbed_hal/qspi/qspi_test_utils.cpp | 27 ++++++------
3 files changed, 46 insertions(+), 41 deletions(-)
diff --git a/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h b/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h
index ce426064c8..6cd588d487 100644
--- a/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h
+++ b/TESTS/mbed_hal/qspi/flash_configs/MX25R6435F_config.h
@@ -108,10 +108,15 @@
// single quad enable flag for both dual and quad mode
-#define QUAD_ENABLE_IMPLEMENTATION() \
+#define QUAD_ENABLE() \
\
uint8_t reg_data[QSPI_STATUS_REG_SIZE]; \
\
+ if (write_enable(qspi) != QSPI_STATUS_OK) { \
+ return QSPI_STATUS_ERROR; \
+ } \
+ WAIT_FOR(WRSR_MAX_TIME, qspi); \
+ \
reg_data[0] = STATUS_BIT_QE; \
qspi.cmd.build(QSPI_CMD_WRSR); \
\
@@ -132,10 +137,15 @@
-#define QUAD_DISABLE_IMPLEMENTATION() \
+#define QUAD_DISABLE() \
\
uint8_t reg_data[QSPI_STATUS_REG_SIZE]; \
\
+ if (write_enable(qspi) != QSPI_STATUS_OK) { \
+ return QSPI_STATUS_ERROR; \
+ } \
+ WAIT_FOR(WRSR_MAX_TIME, qspi); \
+ \
reg_data[0] = 0; \
qspi.cmd.build(QSPI_CMD_WRSR); \
\
@@ -156,7 +166,7 @@
-#define FAST_MODE_ENABLE_IMPLEMENTATION() \
+#define FAST_MODE_ENABLE() \
\
qspi_status_t ret; \
const int32_t reg_size = QSPI_STATUS_REG_SIZE + QSPI_CONFIG_REG_0_SIZE; \
diff --git a/TESTS/mbed_hal/qspi/main.cpp b/TESTS/mbed_hal/qspi/main.cpp
index 0ef44ee797..cdcfd34899 100644
--- a/TESTS/mbed_hal/qspi/main.cpp
+++ b/TESTS/mbed_hal/qspi/main.cpp
@@ -71,11 +71,11 @@ uint8_t rx_buf[DATA_SIZE_1024];
static void log_data(const char *str, uint8_t *data, uint32_t size)
{
- printf("%s: ", str);
+ utest_printf("%s: ", str);
for (uint32_t j = 0; j < size; j++) {
- printf("%02X ", data[j]);
+ utest_printf("%02X ", data[j]);
}
- printf("\r\n");
+ utest_printf("\r\n");
}
@@ -171,19 +171,19 @@ static void _qspi_write_read_test(Qspi &qspi, qspi_bus_width_t write_inst_width,
if (tx_buf[i] != rx_buf[i]) {
log_data("tx data", tx_buf, data_size);
log_data("rx data", rx_buf, data_size);
- printf("erase/write/read time: %d/%d/%d [us]\r\n", erase_time, write_time, read_time);
+ utest_printf("erase/write/read time: %d/%d/%d [us]\r\n", erase_time, write_time, read_time);
TEST_ASSERT_EQUAL(tx_buf[i], rx_buf[i]);
}
}
#ifdef QSPI_TEST_LOG_FLASH_TIME
- printf("erase/write/read time: %d/%d/%d [us]\r\n", erase_time, write_time, read_time);
+ utest_printf("erase/write/read time: %d/%d/%d [us]\r\n", erase_time, write_time, read_time);
#endif
#ifdef QSPI_TEST_LOG_DATA
log_data("tx data", tx_buf, data_size);
log_data("rx data", rx_buf, data_size);
- printf("rx/tx data match\r\n");
+ utest_printf("rx/tx data match\r\n");
#endif
}
}
@@ -222,9 +222,6 @@ void qspi_write_read_test(void)
if (is_dual_cmd(write_inst_width, write_addr_width, write_data_width) ||
is_dual_cmd(read_inst_width, read_addr_width, read_data_width)) {
- ret = write_enable(qspi);
- TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
- WAIT_FOR(WRSR_MAX_TIME, qspi);
ret = dual_enable(qspi);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
WAIT_FOR(WRSR_MAX_TIME, qspi);
@@ -232,9 +229,6 @@ void qspi_write_read_test(void)
if (is_quad_cmd(write_inst_width, write_addr_width, write_data_width) ||
is_quad_cmd(read_inst_width, read_addr_width, read_data_width)) {
- ret = write_enable(qspi);
- TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
- WAIT_FOR(WRSR_MAX_TIME, qspi);
ret = quad_enable(qspi);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
WAIT_FOR(WRSR_MAX_TIME, qspi);
@@ -248,10 +242,13 @@ void qspi_write_read_test(void)
WAIT_FOR(WRSR_MAX_TIME, qspi);
#ifdef QSPI_TEST_LOG_FLASH_STATUS
- printf("Status "); log_register(STATUS_REG, QSPI_STATUS_REG_SIZE, qspi);
- printf("Config 0 "); log_register(CONFIG_REG0, QSPI_CONFIG_REG_0_SIZE, qspi);
+ utest_printf("Status\r\n"); log_register(STATUS_REG, QSPI_STATUS_REG_SIZE, qspi);
+ utest_printf("Config 0\r\n"); log_register(CONFIG_REG0, QSPI_CONFIG_REG_0_SIZE, qspi);
#ifdef CONFIG_REG1
- printf("Config 1 "); log_register(CONFIG_REG1, QSPI_CONFIG_REG_1_SIZE, qspi);
+ utest_printf("Config 1\r\n"); log_register(CONFIG_REG1, QSPI_CONFIG_REG_1_SIZE, qspi);
+#endif
+#ifdef CONFIG_REG2
+ utest_printf("Config 2\r\n"); log_register(CONFIG_REG2, QSPI_CONFIG_REG_2_SIZE, qspi);
#endif
#endif
@@ -265,9 +262,6 @@ void qspi_write_read_test(void)
if (is_dual_cmd(write_inst_width, write_addr_width, write_data_width) ||
is_dual_cmd(read_inst_width, read_addr_width, read_data_width)) {
- ret = write_enable(qspi);
- TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
- WAIT_FOR(WRSR_MAX_TIME, qspi);
ret = dual_disable(qspi);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
WAIT_FOR(WRSR_MAX_TIME, qspi);
@@ -275,9 +269,6 @@ void qspi_write_read_test(void)
if (is_quad_cmd(write_inst_width, write_addr_width, write_data_width) ||
is_quad_cmd(read_inst_width, read_addr_width, read_data_width)) {
- ret = write_enable(qspi);
- TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
- WAIT_FOR(WRSR_MAX_TIME, qspi);
ret = quad_disable(qspi);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
WAIT_FOR(WRSR_MAX_TIME, qspi);
@@ -321,10 +312,13 @@ void qspi_init_free_test(void)
flash_init(qspi);
#ifdef QSPI_TEST_LOG_FLASH_STATUS
- printf("Status "); log_register(STATUS_REG, QSPI_STATUS_REG_SIZE, qspi);
- printf("Config 0 "); log_register(CONFIG_REG0, QSPI_CONFIG_REG_0_SIZE, qspi);
+ utest_printf("Status\r\n"); log_register(STATUS_REG, QSPI_STATUS_REG_SIZE, qspi);
+ utest_printf("Config 0\r\n"); log_register(CONFIG_REG0, QSPI_CONFIG_REG_0_SIZE, qspi);
#ifdef CONFIG_REG1
- printf("Config 1 "); log_register(CONFIG_REG1, QSPI_CONFIG_REG_1_SIZE, qspi);
+ utest_printf("Config 1\r\n"); log_register(CONFIG_REG1, QSPI_CONFIG_REG_1_SIZE, qspi);
+#endif
+#ifdef CONFIG_REG2
+ utest_printf("Config 2\r\n"); log_register(CONFIG_REG2, QSPI_CONFIG_REG_2_SIZE, qspi);
#endif
#endif
@@ -375,7 +369,7 @@ void qspi_frequency_test(void)
void qspi_memory_id_test()
{
- printf("*** %s memory config loaded ***\r\n", QSPI_FLASH_CHIP_STRING);
+ utest_printf("*** %s memory config loaded ***\r\n", QSPI_FLASH_CHIP_STRING);
}
diff --git a/TESTS/mbed_hal/qspi/qspi_test_utils.cpp b/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
index 8339d38edb..76d7a9fd48 100644
--- a/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
+++ b/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "utest/utest.h"
#include "hal/qspi_api.h"
#include "qspi_test_utils.h"
@@ -166,12 +167,12 @@ void log_register(uint32_t cmd, uint32_t reg_size, Qspi &qspi)
ret = read_register(cmd, reg, reg_size, qspi);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
- for (int j = 0; j < reg_size; j++) {
- printf("register byte %d data: ", j);
+ for (uint32_t j = 0; j < reg_size; j++) {
+ utest_printf("register byte %u data: ", j);
for(int i = 0; i < 8; i++) {
- printf("%s ", ((reg[j] & (1 << i)) & 0xFF) == 0 ? "0" : "1");
+ utest_printf("%s ", ((reg[j] & (1 << i)) & 0xFF) == 0 ? "0" : "1");
}
- printf("\r\n");
+ utest_printf("\r\n");
}
}
@@ -183,36 +184,36 @@ qspi_status_t erase(uint32_t erase_cmd, uint32_t flash_addr, Qspi &qspi)
qspi_status_t dual_enable(Qspi &qspi)
{
-#ifdef DUAL_ENABLE_IMPLEMENTATION
- DUAL_ENABLE_IMPLEMENTATION();
+#ifdef DUAL_ENABLE
+ DUAL_ENABLE();
#else
- QUAD_ENABLE_IMPLEMENTATION();
+ QUAD_ENABLE();
#endif
}
qspi_status_t dual_disable(Qspi &qspi)
{
-#ifdef DUAL_DISABLE_IMPLEMENTATION
- DUAL_DISABLE_IMPLEMENTATION();
+#ifdef DUAL_DISABLE
+ DUAL_DISABLE();
#else
- QUAD_DISABLE_IMPLEMENTATION();
+ QUAD_DISABLE();
#endif
}
qspi_status_t quad_enable(Qspi &qspi)
{
- QUAD_ENABLE_IMPLEMENTATION();
+ QUAD_ENABLE();
}
qspi_status_t quad_disable(Qspi &qspi)
{
- QUAD_DISABLE_IMPLEMENTATION();
+ QUAD_DISABLE();
}
qspi_status_t fast_mode_enable(Qspi &qspi)
{
- FAST_MODE_ENABLE_IMPLEMENTATION();
+ FAST_MODE_ENABLE();
}
bool is_dual_cmd(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width)
From e6923342efd49be50479ac637536f7a196b61066 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Fri, 3 Aug 2018 10:21:12 +0200
Subject: [PATCH 74/78] hal-qspi test: add F413ZH support
---
.../qspi/flash_configs/N25Q128A_config.h | 182 ++++++++++++++++++
.../STM/DISCO_F413ZH/flash_config.h | 22 +++
.../qspi/flash_configs/flash_configs.h | 2 +
TESTS/mbed_hal/qspi/main.cpp | 12 +-
TESTS/mbed_hal/qspi/qspi_test_utils.cpp | 6 +
TESTS/mbed_hal/qspi/qspi_test_utils.h | 8 +
6 files changed, 227 insertions(+), 5 deletions(-)
create mode 100644 TESTS/mbed_hal/qspi/flash_configs/N25Q128A_config.h
create mode 100644 TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_F413ZH/flash_config.h
diff --git a/TESTS/mbed_hal/qspi/flash_configs/N25Q128A_config.h b/TESTS/mbed_hal/qspi/flash_configs/N25Q128A_config.h
new file mode 100644
index 0000000000..138844abe6
--- /dev/null
+++ b/TESTS/mbed_hal/qspi/flash_configs/N25Q128A_config.h
@@ -0,0 +1,182 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_QSPI_FLASH_N25Q128A_H
+#define MBED_QSPI_FLASH_N25Q128A_H
+
+
+#define QSPI_FLASH_CHIP_STRING "Micron N25Q128A"
+
+// Command for reading status register
+#define QSPI_CMD_RDSR 0x05
+// Command for reading configuration register 0 (NONVOLATILE CONFIGURATION REGISTER)
+#define QSPI_CMD_RDCR0 0xB5
+// Command for reading configuration register 1 (VOLATILE CONFIGURATION REGISTER)
+#define QSPI_CMD_RDCR1 0x85
+// Command for reading configuration register 2 (ENHANCED VOLATILE CONFIGURATION REGISTER)
+#define QSPI_CMD_RDCR2 0x65
+// Command for writing status
+#define QSPI_CMD_WRSR 0x01
+// Command for writing configuration register 0 (NONVOLATILE CONFIGURATION REGISTER)
+#define QSPI_CMD_WRCR0 0xB1
+// Command for writing configuration register 1 (VOLATILE CONFIGURATION REGISTER)
+#define QSPI_CMD_WRCR1 0x81
+// Command for writing configuration register 2 (ENHANCED VOLATILE CONFIGURATION REGISTER)
+#define QSPI_CMD_WRCR2 0x61
+// Command for reading security register
+#define QSPI_CMD_RDSCUR 0x2B
+
+// Command for setting Reset Enable
+#define QSPI_CMD_RSTEN 0x66
+// Command for setting Reset
+#define QSPI_CMD_RST 0x99
+
+// Command for setting write enable
+#define QSPI_CMD_WREN 0x06
+// Command for setting write disable
+#define QSPI_CMD_WRDI 0x04
+
+// WRSR operations max time [us] (datasheet max time + 15%)
+#define QSPI_WRSR_MAX_TIME 9200 // 8ms
+// general wait max time [us]
+#define QSPI_WAIT_MAX_TIME 100000 // 100ms
+
+
+// Commands for writing (page programming)
+#define QSPI_CMD_WRITE_1IO 0x02 // 1-1-1 mode
+#define QSPI_CMD_WRITE_2IO 0xD2 // 1-2-2 mode
+#define QSPI_CMD_WRITE_4IO 0x12 // 1-4-4 mode
+
+// write operations max time [us] (datasheet max time + 15%)
+#define QSPI_PAGE_PROG_MAX_TIME 5750 // 5ms
+
+#define QSPI_PAGE_SIZE 256 // 256B
+
+// Commands for reading
+#define QSPI_CMD_READ_1IO_FAST 0x0B // 1-1-1 mode
+#define QSPI_CMD_READ_1IO 0x03 // 1-1-1 mode
+#define QSPI_CMD_READ_2IO 0xBB // 1-2-2 mode
+#define QSPI_CMD_READ_1I2O 0x3B // 1-1-2 mode
+#define QSPI_CMD_READ_4IO 0xEB // 1-4-4 mode
+#define QSPI_CMD_READ_1I4O 0x6B // 1-1-4 mode
+
+
+#define QSPI_READ_1IO_DUMMY_CYCLE 0
+#define QSPI_READ_FAST_DUMMY_CYCLE 8
+// 8 dummy (10 dummy when quad SPI protocol is enabled)
+#define QSPI_READ_2IO_DUMMY_CYCLE 8
+#define QSPI_READ_1I2O_DUMMY_CYCLE 8
+#define QSPI_READ_4IO_DUMMY_CYCLE 10
+#define QSPI_READ_1I4O_DUMMY_CYCLE 8
+
+// Commands for erasing
+#define QSPI_CMD_ERASE_SECTOR 0x20 // 4kB
+#define QSPI_CMD_ERASE_BLOCK_32 0x52 // 32kB
+#define QSPI_CMD_ERASE_BLOCK_64 0xD8 // 64kB
+#define QSPI_CMD_ERASE_CHIP 0x60 // or 0xC7
+
+// erase operations max time [us] (datasheet max time + 15%)
+#define QSPI_ERASE_SECTOR_MAX_TIME 276000 // 240 ms
+#define QSPI_ERASE_BLOCK_32_MAX_TIME 3000000 // 3s
+#define QSPI_ERASE_BLOCK_64_MAX_TIME 3500000 // 3.5s
+
+// max frequency for basic rw operation
+#define QSPI_COMMON_MAX_FREQUENCY 50000000
+
+#define QSPI_STATUS_REG_SIZE 1
+#define QSPI_CONFIG_REG_0_SIZE 2
+#define QSPI_CONFIG_REG_1_SIZE 1
+#define QSPI_CONFIG_REG_2_SIZE 1
+#define QSPI_MAX_REG_SIZE 2
+
+// status register
+#define STATUS_BIT_WIP (1 << 0) // write in progress bit
+#define STATUS_BIT_WEL (1 << 1) // write enable latch
+#define STATUS_BIT_BP0 (1 << 2) // block
+#define STATUS_BIT_BP1 (1 << 3) //
+#define STATUS_BIT_BP2 (1 << 4) //
+#define STATUS_BIT_BP_TB (1 << 5) // Block protect top/bottom
+#define STATUS_BIT_BP3 (1 << 6) //
+#define STATUS_BIT_SRWD (1 << 7) // status register write protect
+
+// configuration register 0 (Nonvolatile Configuration Register)
+// bit 1, 5, reserved
+#define CONFIG0_BIT_LOCK (1 << 0) // Lock nonvolatile configuration register
+#define CONFIG0_BIT_DE (1 << 2) // Dual Enable 0 = Enabled / 1 = Disabled
+#define CONFIG0_BIT_QE (1 << 3) // Quad Enable 0 = Enabled / 1 = Disabled
+#define CONFIG0_BIT_RH (1 << 4) // Reset/hold
+#define CONFIG0_BIT_ODS0 (1 << 6) // Output driver strength
+#define CONFIG0_BIT_ODS1 (1 << 7) // Output driver strength
+#define CONFIG0_BIT_ODS2 (1 << 8) // Output driver strength
+#define CONFIG0_BIT_XIP_MODE0 (1 << 9) // XIP mode at power-on reset
+#define CONFIG0_BIT_XIP_MODE1 (1 << 10) // XIP mode at power-on reset
+#define CONFIG0_BIT_XIP_MODE2 (1 << 11) // XIP mode at power-on reset
+#define CONFIG0_BIT_DCYCLE0 (1 << 12) // Dummy Cycle
+#define CONFIG0_BIT_DCYCLE1 (1 << 13) // Dummy Cycle
+#define CONFIG0_BIT_DCYCLE2 (1 << 14) // Dummy Cycle
+#define CONFIG0_BIT_DCYCLE3 (1 << 15) // Dummy Cycle
+#define CONFIG0_BITS_DEFAULT 0xFFFF // reg default state
+
+
+// configuration register 1 (Volatile Configuration Register)
+// bit 2, reserved
+#define CONFIG1_BIT_WRAP0 (1 << 0) // Output data wrap
+#define CONFIG1_BIT_WRAP1 (1 << 1) // Output data wrap
+#define CONFIG1_BIT_XIP (1 << 3) // 0 = Enable / 1 = Disable (default)
+#define CONFIG1_BIT_DCYCLE0 (1 << 4) // Number of dummy clock cycles
+#define CONFIG1_BIT_DCYCLE1 (1 << 5) // Number of dummy clock cycles
+#define CONFIG1_BIT_DCYCLE2 (1 << 6) // Number of dummy clock cycles
+#define CONFIG1_BIT_DCYCLE3 (1 << 7) // Number of dummy clock cycles
+#define CONFIG1_BITS_DEFAULT 0xB // reg default state
+
+
+// configuration register 2 (Enhanced Volatile Configuration Register)
+// bit 5, reserved
+#define CONFIG2_BIT_ODS0 (1 << 0) // Output driver strength 111 = 30 Ohms (Default)
+#define CONFIG2_BIT_ODS1 (1 << 1) // Output driver strength
+#define CONFIG2_BIT_ODS2 (1 << 2) // Output driver strength
+#define CONFIG2_BIT_VPP (1 << 3) // VPP accelerator 1 = Disabled (Default)
+#define CONFIG2_BIT_RH (1 << 4) // Reset/hold
+#define CONFIG2_BIT_DE (1 << 6) // Dual I/O protocol 0 = Enabled / 1 = Disabled (Default, extended SPI protocol)
+#define CONFIG2_BIT_QE (1 << 7) // Quad I/O protocol 0 = Enabled / 1 = Disabled (Default, extended SPI protocol)
+#define CONFIG2_BITS_DEFAULT 0xDF // reg default state
+
+
+#define DUAL_ENABLE() \
+ /* TODO: add implementation */ \
+ return QSPI_STATUS_OK
+
+
+#define DUAL_DISABLE() \
+ /* TODO: add implementation */ \
+ return QSPI_STATUS_OK
+
+
+#define QUAD_ENABLE() \
+ /* TODO: add implementation */ \
+ return QSPI_STATUS_OK
+
+
+#define QUAD_DISABLE() \
+ /* TODO: add implementation */ \
+ return QSPI_STATUS_OK
+
+
+#define FAST_MODE_ENABLE() \
+ /* TODO: add implementation */ \
+ return QSPI_STATUS_OK
+
+
+#endif // MBED_QSPI_FLASH_N25Q128A_H
diff --git a/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_F413ZH/flash_config.h b/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_F413ZH/flash_config.h
new file mode 100644
index 0000000000..67d8c317d6
--- /dev/null
+++ b/TESTS/mbed_hal/qspi/flash_configs/STM/DISCO_F413ZH/flash_config.h
@@ -0,0 +1,22 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018-2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_QSPI_FLASH_CONFIG_H
+#define MBED_QSPI_FLASH_CONFIG_H
+
+#include "../../N25Q128A_config.h"
+
+
+#endif // MBED_QSPI_FLASH_CONFIG_H
diff --git a/TESTS/mbed_hal/qspi/flash_configs/flash_configs.h b/TESTS/mbed_hal/qspi/flash_configs/flash_configs.h
index 9f2ca0ef55..deced43d7f 100644
--- a/TESTS/mbed_hal/qspi/flash_configs/flash_configs.h
+++ b/TESTS/mbed_hal/qspi/flash_configs/flash_configs.h
@@ -21,6 +21,8 @@
#include "STM/DISCO_L475VG_IOT01A/flash_config.h"
#elif defined(TARGET_NRF52840)
#include "NORDIC/NRF52840_DK/flash_config.h"
+#elif defined(TARGET_DISCO_F413ZH)
+#include "STM/DISCO_F413ZH/flash_config.h"
#endif
#endif // MBED_FLASH_CONFIGS_H
diff --git a/TESTS/mbed_hal/qspi/main.cpp b/TESTS/mbed_hal/qspi/main.cpp
index cdcfd34899..167e081f19 100644
--- a/TESTS/mbed_hal/qspi/main.cpp
+++ b/TESTS/mbed_hal/qspi/main.cpp
@@ -13,6 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+#if !DEVICE_QSPI
+#error [NOT_SUPPORTED] QSPI not supported for this target
+#endif
+
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
@@ -23,8 +28,8 @@
#include "qspi_api.h"
-#if !DEVICE_QSPI || !defined(QSPI_FLASH_CHIP_STRING)
-#error [NOT_SUPPORTED] QSPI not supported for this target
+#if !defined(QSPI_FLASH_CHIP_STRING)
+#error [NOT_SUPPORTED] QSPI test not supported for this target
#endif
using namespace utest::v1;
@@ -278,9 +283,6 @@ void qspi_write_read_test(void)
}
-
-
-
void qspi_init_free_test(void)
{
Qspi qspi;
diff --git a/TESTS/mbed_hal/qspi/qspi_test_utils.cpp b/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
index 76d7a9fd48..b7d386fd9d 100644
--- a/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
+++ b/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
@@ -74,6 +74,12 @@ qspi_status_t read_register(uint32_t cmd, uint8_t *buf, uint32_t size, Qspi &q)
return qspi_command_transfer(&q.handle, q.cmd.get(), NULL, 0, buf, size);
}
+qspi_status_t write_register(uint32_t cmd, uint8_t *buf, uint32_t size, Qspi &q)
+{
+ q.cmd.build(cmd);
+ return qspi_command_transfer(&q.handle, q.cmd.get(), buf, size, NULL, 0);
+}
+
QspiStatus flash_wait_for(uint32_t time_us, Qspi &qspi)
{
diff --git a/TESTS/mbed_hal/qspi/qspi_test_utils.h b/TESTS/mbed_hal/qspi/qspi_test_utils.h
index ed92237a40..e26b039071 100644
--- a/TESTS/mbed_hal/qspi/qspi_test_utils.h
+++ b/TESTS/mbed_hal/qspi/qspi_test_utils.h
@@ -84,12 +84,19 @@ struct Qspi {
#ifdef QSPI_CMD_RDCR1
#define CONFIG_REG1 QSPI_CMD_RDCR1
#endif
+#ifdef QSPI_CMD_RDCR2
+#define CONFIG_REG2 QSPI_CMD_RDCR2
+#endif
#define SECURITY_REG QSPI_CMD_RDSCUR
#ifndef QSPI_CONFIG_REG_1_SIZE
#define QSPI_CONFIG_REG_1_SIZE 0
#endif
+#ifndef QSPI_CONFIG_REG_2_SIZE
+#define QSPI_CONFIG_REG_2_SIZE 0
+#endif
+
#define SECTOR_ERASE QSPI_CMD_ERASE_SECTOR
#define BLOCK_ERASE QSPI_CMD_ERASE_BLOCK_64
@@ -105,6 +112,7 @@ struct Qspi {
qspi_status_t read_register(uint32_t cmd, uint8_t *buf, uint32_t size, Qspi &q);
+qspi_status_t write_register(uint32_t cmd, uint8_t *buf, uint32_t size, Qspi &q);
QspiStatus flash_wait_for(uint32_t time_us, Qspi &qspi);
From 3bf9df7b56a54278fbaa8bf7c356421804a3ddf4 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Fri, 3 Aug 2018 14:12:29 +0200
Subject: [PATCH 75/78] target DISCO_F413ZH: add QSPI flash pin names
---
.../TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PinNames.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PinNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PinNames.h
index c207cc1b8c..1d8185833f 100644
--- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PinNames.h
+++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/TARGET_DISCO_F413ZH/PinNames.h
@@ -303,6 +303,14 @@ typedef enum {
SYS_WKUP2 = PC_0,
SYS_WKUP3 = PC_1,
+ /**** QSPI FLASH pins ****/
+ QSPI_PIN_IO0 = PF_8,
+ QSPI_PIN_IO1 = PF_9,
+ QSPI_PIN_IO2 = PE_2,
+ QSPI_PIN_IO3 = PD_13,
+ QSPI_PIN_SCK = PB_2,
+ QSPI_PIN_CSN = PG_6,
+
// Not connected
NC = (int)0xFFFFFFFF
} PinName;
From c94f22c7ad040e749c39a2748ae52906267129c1 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Mon, 20 Aug 2018 14:09:01 +0200
Subject: [PATCH 76/78] mbed_hal-qspi test code refactoring after PR 7783
review
- refactoring of status/config register logging code,
- make QspiCommand a class,
---
TESTS/mbed_hal/qspi/main.cpp | 24 +++++++++-----
TESTS/mbed_hal/qspi/qspi_test_utils.cpp | 44 ++++++++++++-------------
TESTS/mbed_hal/qspi/qspi_test_utils.h | 9 ++---
3 files changed, 43 insertions(+), 34 deletions(-)
diff --git a/TESTS/mbed_hal/qspi/main.cpp b/TESTS/mbed_hal/qspi/main.cpp
index 167e081f19..c783ce967f 100644
--- a/TESTS/mbed_hal/qspi/main.cpp
+++ b/TESTS/mbed_hal/qspi/main.cpp
@@ -247,13 +247,17 @@ void qspi_write_read_test(void)
WAIT_FOR(WRSR_MAX_TIME, qspi);
#ifdef QSPI_TEST_LOG_FLASH_STATUS
- utest_printf("Status\r\n"); log_register(STATUS_REG, QSPI_STATUS_REG_SIZE, qspi);
- utest_printf("Config 0\r\n"); log_register(CONFIG_REG0, QSPI_CONFIG_REG_0_SIZE, qspi);
+ //utest_printf("Status register:\r\n");
+ log_register(STATUS_REG, QSPI_STATUS_REG_SIZE, qspi, "Status register");
+ //utest_printf("Config register 0:\r\n");
+ log_register(CONFIG_REG0, QSPI_CONFIG_REG_0_SIZE, qspi, "Config register 0");
#ifdef CONFIG_REG1
- utest_printf("Config 1\r\n"); log_register(CONFIG_REG1, QSPI_CONFIG_REG_1_SIZE, qspi);
+ //utest_printf("Config register 1:\r\n");
+ log_register(CONFIG_REG1, QSPI_CONFIG_REG_1_SIZE, qspi, "Config register 1");
#endif
#ifdef CONFIG_REG2
- utest_printf("Config 2\r\n"); log_register(CONFIG_REG2, QSPI_CONFIG_REG_2_SIZE, qspi);
+ //utest_printf("Config register 2:\r\n");
+ log_register(CONFIG_REG2, QSPI_CONFIG_REG_2_SIZE, qspi, "Config register 2");
#endif
#endif
@@ -314,13 +318,17 @@ void qspi_init_free_test(void)
flash_init(qspi);
#ifdef QSPI_TEST_LOG_FLASH_STATUS
- utest_printf("Status\r\n"); log_register(STATUS_REG, QSPI_STATUS_REG_SIZE, qspi);
- utest_printf("Config 0\r\n"); log_register(CONFIG_REG0, QSPI_CONFIG_REG_0_SIZE, qspi);
+ //utest_printf("Status register:\r\n");
+ log_register(STATUS_REG, QSPI_STATUS_REG_SIZE, qspi, "Status register");
+ //utest_printf("Config register 0:\r\n");
+ log_register(CONFIG_REG0, QSPI_CONFIG_REG_0_SIZE, qspi, "Config register 0");
#ifdef CONFIG_REG1
- utest_printf("Config 1\r\n"); log_register(CONFIG_REG1, QSPI_CONFIG_REG_1_SIZE, qspi);
+ //utest_printf("Config register 1:\r\n");
+ log_register(CONFIG_REG1, QSPI_CONFIG_REG_1_SIZE, qspi, "Config register 1");
#endif
#ifdef CONFIG_REG2
- utest_printf("Config 2\r\n"); log_register(CONFIG_REG2, QSPI_CONFIG_REG_2_SIZE, qspi);
+ //utest_printf("Config register 2:\r\n");
+ log_register(CONFIG_REG2, QSPI_CONFIG_REG_2_SIZE, qspi, "Config register 2");
#endif
#endif
diff --git a/TESTS/mbed_hal/qspi/qspi_test_utils.cpp b/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
index b7d386fd9d..51a9963882 100644
--- a/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
+++ b/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
@@ -32,39 +32,39 @@ void QspiCommand::configure(qspi_bus_width_t inst_width, qspi_bus_width_t addr_w
qspi_address_size_t addr_size, qspi_alt_size_t alt_size,
int dummy_cycles)
{
- memset(&cmd, 0, sizeof(qspi_command_t) );
- cmd.instruction.disabled = cmd.address.disabled = cmd.alt.disabled = true;
+ memset(&_cmd, 0, sizeof(qspi_command_t) );
+ _cmd.instruction.disabled = _cmd.address.disabled = _cmd.alt.disabled = true;
- cmd.instruction.bus_width = inst_width;
- cmd.address.bus_width = addr_width;
- cmd.address.size = addr_size;
- cmd.alt.bus_width = alt_width;
- cmd.alt.size = alt_size;
- cmd.data.bus_width = data_width;
- cmd.dummy_count = dummy_cycles;
+ _cmd.instruction.bus_width = inst_width;
+ _cmd.address.bus_width = addr_width;
+ _cmd.address.size = addr_size;
+ _cmd.alt.bus_width = alt_width;
+ _cmd.alt.size = alt_size;
+ _cmd.data.bus_width = data_width;
+ _cmd.dummy_count = dummy_cycles;
}
void QspiCommand::build(int instruction, int address, int alt)
{
- cmd.instruction.disabled = (instruction == QSPI_NONE);
- if (!cmd.instruction.disabled) {
- cmd.instruction.value = instruction;
+ _cmd.instruction.disabled = (instruction == QSPI_NONE);
+ if (!_cmd.instruction.disabled) {
+ _cmd.instruction.value = instruction;
}
- cmd.address.disabled = (address == QSPI_NONE);
- if (!cmd.address.disabled) {
- cmd.address.value = address;
+ _cmd.address.disabled = (address == QSPI_NONE);
+ if (!_cmd.address.disabled) {
+ _cmd.address.value = address;
}
- cmd.alt.disabled = (alt == QSPI_NONE);
- if (!cmd.alt.disabled) {
- cmd.alt.value = alt;
+ _cmd.alt.disabled = (alt == QSPI_NONE);
+ if (!_cmd.alt.disabled) {
+ _cmd.alt.value = alt;
}
}
qspi_command_t* QspiCommand::get()
{
- return &cmd;
+ return &_cmd;
}
@@ -165,7 +165,7 @@ qspi_status_t write_disable(Qspi &qspi)
return ((reg[0] & STATUS_BIT_WEL) == 0 ? QSPI_STATUS_OK : QSPI_STATUS_ERROR);
}
-void log_register(uint32_t cmd, uint32_t reg_size, Qspi &qspi)
+void log_register(uint32_t cmd, uint32_t reg_size, Qspi &qspi, const char *str)
{
qspi_status_t ret;
static uint8_t reg[QSPI_MAX_REG_SIZE];
@@ -174,9 +174,9 @@ void log_register(uint32_t cmd, uint32_t reg_size, Qspi &qspi)
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
for (uint32_t j = 0; j < reg_size; j++) {
- utest_printf("register byte %u data: ", j);
+ utest_printf("%s byte %u (MSB first): ", str != NULL ? str : "", j);
for(int i = 0; i < 8; i++) {
- utest_printf("%s ", ((reg[j] & (1 << i)) & 0xFF) == 0 ? "0" : "1");
+ utest_printf("%s ", ((reg[j] & (1 << (7 - i))) & 0xFF) == 0 ? "0" : "1");
}
utest_printf("\r\n");
}
diff --git a/TESTS/mbed_hal/qspi/qspi_test_utils.h b/TESTS/mbed_hal/qspi/qspi_test_utils.h
index e26b039071..2a177657cf 100644
--- a/TESTS/mbed_hal/qspi/qspi_test_utils.h
+++ b/TESTS/mbed_hal/qspi/qspi_test_utils.h
@@ -28,8 +28,8 @@ enum QspiStatus {
sUnknown
};
-struct QspiCommand {
-
+class QspiCommand {
+public:
void configure(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width,
qspi_bus_width_t alt_width, qspi_address_size_t addr_size, qspi_alt_size_t alt_size,
int dummy_cycles = 0);
@@ -38,7 +38,8 @@ struct QspiCommand {
qspi_command_t * get();
- qspi_command_t cmd;
+private:
+ qspi_command_t _cmd;
};
struct Qspi {
@@ -122,7 +123,7 @@ qspi_status_t write_enable(Qspi &qspi);
qspi_status_t write_disable(Qspi &qspi);
-void log_register(uint32_t cmd, uint32_t reg_size, Qspi &qspi);
+void log_register(uint32_t cmd, uint32_t reg_size, Qspi &qspi, const char *str = NULL);
qspi_status_t dual_enable(Qspi &qspi);
From ad493888887cf3ccd13d415617160bf4791f1930 Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Tue, 21 Aug 2018 10:05:08 +0200
Subject: [PATCH 77/78] QSPI driver: fixes after PR 7783 review
- make QSPI::lock and QSPI::unlock protected
- fix QSPI::_initialize return value
- add assert on QSPI::_initialize failure
- minor comments fixes
---
drivers/QSPI.cpp | 11 +++++++----
drivers/QSPI.h | 19 ++++++++++---------
2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index 36cad333e1..e1d0abdd69 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -1,5 +1,5 @@
/* mbed Microcontroller Library
- * Copyright (c) 2006-2013 ARM Limited
+ * Copyright (c) 2006-2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,7 +45,8 @@ QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, Pin
_initialized = false;
//Go ahead init the device here with the default config
- _initialize();
+ bool success = _initialize();
+ MBED_ASSERT(success);
}
qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width_t address_width, qspi_address_size_t address_size, qspi_bus_width_t alt_width, qspi_alt_size_t alt_size, qspi_bus_width_t data_width, int dummy_cycles)
@@ -217,8 +218,10 @@ void QSPI::unlock()
// Note: Private helper function to initialize qspi HAL
bool QSPI::_initialize()
{
- if (_mode != 0 && _mode != 1)
- return QSPI_STATUS_INVALID_PARAMETER;
+ if (_mode != 0 && _mode != 1) {
+ _initialized = false;
+ return _initialized;
+ }
qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode );
if (QSPI_STATUS_OK == ret) {
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index ecf2d43e12..70fa88596e 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -1,5 +1,5 @@
/* mbed Microcontroller Library
- * Copyright (c) 2006-2015 ARM Limited
+ * Copyright (c) 2006-2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ namespace mbed {
/** A QSPI Driver, used for communicating with QSPI slave devices
*
- * The default format is set to Quad-SPI(4-4-4), and a clock frequency of 1MHz
+ * The default format is set to Quad-SPI(1-1-1), and a clock frequency of 1MHz
* Most QSPI devices will also require Chip Select which is indicated by ssel.
*
* @note Synchronization level: Thread safe
@@ -45,7 +45,7 @@ namespace mbed {
* #include "mbed.h"
*
* // hardware ssel (where applicable)
- * QSPI qspi_device(p5, p6, p7, p8, p9, p10); // io0, io1, io2, io3, sclk, ssel
+ * QSPI qspi_device(QSPI_PIN_IO0, QSPI_PIN_IO1, QSPI_PIN_IO2, QSPI_PIN_IO3, QSPI_PIN_SCK, QSPI_PIN_CSN); // io0, io1, io2, io3, sclk, ssel
*
*
* int main() {
@@ -84,12 +84,12 @@ public:
/** Configure the data transmission format
*
- * @param inst_width Bus width used by instruction phase(Valid values are 1,2,4)
- * @param address_width Bus width used by address phase(Valid values are 1,2,4)
- * @param address_size Size in bits used by address phase(Valid values are 8,16,24,32)
- * @param alt_width Bus width used by alt phase(Valid values are 1,2,4)
- * @param alt_size Size in bits used by alt phase(Valid values are 8,16,24,32)
- * @param data_width Bus width used by data phase(Valid values are 1,2,4)
+ * @param inst_width Bus width used by instruction phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD)
+ * @param address_width Bus width used by address phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD)
+ * @param address_size Size in bits used by address phase(Valid values are QSPI_CFG_ADDR_SIZE_8, QSPI_CFG_ADDR_SIZE_16, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_ADDR_SIZE_32)
+ * @param alt_width Bus width used by alt phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD)
+ * @param alt_size Size in bits used by alt phase(Valid values are QSPI_CFG_ADDR_SIZE_8, QSPI_CFG_ADDR_SIZE_16, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_ADDR_SIZE_32)
+ * @param data_width Bus width used by data phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD)
* @param dummy_cycles Number of dummy clock cycles to be used after alt phase
*
*/
@@ -171,6 +171,7 @@ public:
*/
qspi_status_t command_transfer(unsigned int instruction, int address, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length);
+protected:
/** Acquire exclusive access to this SPI bus
*/
virtual void lock(void);
From 883ea2f1d1c119ffa896dcb2181af606a7e15eda Mon Sep 17 00:00:00 2001
From: Maciej Bocianski
Date: Tue, 21 Aug 2018 10:39:05 +0200
Subject: [PATCH 78/78] astyle fixes on QSPI API/driver/tests
---
TESTS/mbed_hal/qspi/main.cpp | 27 ++++++------
TESTS/mbed_hal/qspi/qspi_test_utils.cpp | 6 +--
TESTS/mbed_hal/qspi/qspi_test_utils.h | 2 +-
drivers/QSPI.cpp | 56 ++++++++++++-------------
drivers/QSPI.h | 45 ++++++++++----------
hal/qspi_api.h | 10 ++---
6 files changed, 72 insertions(+), 74 deletions(-)
diff --git a/TESTS/mbed_hal/qspi/main.cpp b/TESTS/mbed_hal/qspi/main.cpp
index c783ce967f..0d1db1db35 100644
--- a/TESTS/mbed_hal/qspi/main.cpp
+++ b/TESTS/mbed_hal/qspi/main.cpp
@@ -99,12 +99,11 @@ static void _qspi_write_read_test(Qspi &qspi, qspi_bus_width_t write_inst_width,
int erase_time = 0, write_time = 0, read_time = 0;
size_t buf_len = data_size;
- for (uint32_t tc = 0; tc < test_count; tc++)
- {
+ for (uint32_t tc = 0; tc < test_count; tc++) {
qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
- srand (ticker_read(get_us_ticker_data()));
- for(uint32_t i = 0; i < data_size; i++) {
+ srand(ticker_read(get_us_ticker_data()));
+ for (uint32_t i = 0; i < data_size; i++) {
tx_buf[i] = (uint8_t)(rand() & 0xFF);
}
@@ -127,8 +126,7 @@ static void _qspi_write_read_test(Qspi &qspi, qspi_bus_width_t write_inst_width,
}
const uint32_t write_size = data_size / write_count;
- for (uint32_t wc = 0, write_start = flash_addr; wc < write_count; wc++, write_start += write_size)
- {
+ for (uint32_t wc = 0, write_start = flash_addr; wc < write_count; wc++, write_start += write_size) {
ret = write_enable(qspi);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
@@ -157,8 +155,7 @@ static void _qspi_write_read_test(Qspi &qspi, qspi_bus_width_t write_inst_width,
memset(rx_buf, 0, sizeof(rx_buf));
const uint32_t read_size = data_size / read_count;
qspi.cmd.configure(read_inst_width, read_addr_width, read_data_width, read_alt_width, read_addr_size, read_alt_size, read_dummy_cycles);
- for (uint32_t rc = 0, read_start = flash_addr; rc < read_count; rc++, read_start += read_size)
- {
+ for (uint32_t rc = 0, read_start = flash_addr; rc < read_count; rc++, read_start += read_size) {
timer.reset();
timer.start();
@@ -226,14 +223,14 @@ void qspi_write_read_test(void)
flash_init(qspi);
if (is_dual_cmd(write_inst_width, write_addr_width, write_data_width) ||
- is_dual_cmd(read_inst_width, read_addr_width, read_data_width)) {
+ is_dual_cmd(read_inst_width, read_addr_width, read_data_width)) {
ret = dual_enable(qspi);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
WAIT_FOR(WRSR_MAX_TIME, qspi);
}
if (is_quad_cmd(write_inst_width, write_addr_width, write_data_width) ||
- is_quad_cmd(read_inst_width, read_addr_width, read_data_width)) {
+ is_quad_cmd(read_inst_width, read_addr_width, read_data_width)) {
ret = quad_enable(qspi);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
WAIT_FOR(WRSR_MAX_TIME, qspi);
@@ -270,14 +267,14 @@ void qspi_write_read_test(void)
qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
if (is_dual_cmd(write_inst_width, write_addr_width, write_data_width) ||
- is_dual_cmd(read_inst_width, read_addr_width, read_data_width)) {
+ is_dual_cmd(read_inst_width, read_addr_width, read_data_width)) {
ret = dual_disable(qspi);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
WAIT_FOR(WRSR_MAX_TIME, qspi);
}
if (is_quad_cmd(write_inst_width, write_addr_width, write_data_width) ||
- is_quad_cmd(read_inst_width, read_addr_width, read_data_width)) {
+ is_quad_cmd(read_inst_width, read_addr_width, read_data_width)) {
ret = quad_disable(qspi);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
WAIT_FOR(WRSR_MAX_TIME, qspi);
@@ -352,21 +349,21 @@ void qspi_frequency_test(void)
flash_init(qspi);
_qspi_write_read_test(qspi, WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, WRITE_SINGLE, READ_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, READ_SINGLE, TEST_REPEAT_SINGLE, DATA_SIZE_256, TEST_FLASH_ADDRESS);
- ret = qspi_frequency(&qspi.handle, QSPI_COMMON_MAX_FREQUENCY/2);
+ ret = qspi_frequency(&qspi.handle, QSPI_COMMON_MAX_FREQUENCY / 2);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
// check if the memory is working properly
qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
flash_init(qspi);
_qspi_write_read_test(qspi, WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, WRITE_SINGLE, READ_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, READ_SINGLE, TEST_REPEAT_SINGLE, DATA_SIZE_256, TEST_FLASH_ADDRESS);
- ret = qspi_frequency(&qspi.handle, QSPI_COMMON_MAX_FREQUENCY/4);
+ ret = qspi_frequency(&qspi.handle, QSPI_COMMON_MAX_FREQUENCY / 4);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
// check if the memory is working properly
qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
flash_init(qspi);
_qspi_write_read_test(qspi, WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, WRITE_SINGLE, READ_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_NONE, READ_SINGLE, TEST_REPEAT_SINGLE, DATA_SIZE_256, TEST_FLASH_ADDRESS);
- ret = qspi_frequency(&qspi.handle, QSPI_COMMON_MAX_FREQUENCY/8);
+ ret = qspi_frequency(&qspi.handle, QSPI_COMMON_MAX_FREQUENCY / 8);
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
// check if the memory is working properly
qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
diff --git a/TESTS/mbed_hal/qspi/qspi_test_utils.cpp b/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
index 51a9963882..8ee85f7ffc 100644
--- a/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
+++ b/TESTS/mbed_hal/qspi/qspi_test_utils.cpp
@@ -32,7 +32,7 @@ void QspiCommand::configure(qspi_bus_width_t inst_width, qspi_bus_width_t addr_w
qspi_address_size_t addr_size, qspi_alt_size_t alt_size,
int dummy_cycles)
{
- memset(&_cmd, 0, sizeof(qspi_command_t) );
+ memset(&_cmd, 0, sizeof(qspi_command_t));
_cmd.instruction.disabled = _cmd.address.disabled = _cmd.alt.disabled = true;
_cmd.instruction.bus_width = inst_width;
@@ -62,7 +62,7 @@ void QspiCommand::build(int instruction, int address, int alt)
}
}
-qspi_command_t* QspiCommand::get()
+qspi_command_t *QspiCommand::get()
{
return &_cmd;
}
@@ -175,7 +175,7 @@ void log_register(uint32_t cmd, uint32_t reg_size, Qspi &qspi, const char *str)
for (uint32_t j = 0; j < reg_size; j++) {
utest_printf("%s byte %u (MSB first): ", str != NULL ? str : "", j);
- for(int i = 0; i < 8; i++) {
+ for (int i = 0; i < 8; i++) {
utest_printf("%s ", ((reg[j] & (1 << (7 - i))) & 0xFF) == 0 ? "0" : "1");
}
utest_printf("\r\n");
diff --git a/TESTS/mbed_hal/qspi/qspi_test_utils.h b/TESTS/mbed_hal/qspi/qspi_test_utils.h
index 2a177657cf..7f54a439f4 100644
--- a/TESTS/mbed_hal/qspi/qspi_test_utils.h
+++ b/TESTS/mbed_hal/qspi/qspi_test_utils.h
@@ -36,7 +36,7 @@ public:
void build(int instruction, int address = QSPI_NONE, int alt = QSPI_NONE);
- qspi_command_t * get();
+ qspi_command_t *get();
private:
qspi_command_t _cmd;
diff --git a/drivers/QSPI.cpp b/drivers/QSPI.cpp
index e1d0abdd69..e0cb3b62d1 100644
--- a/drivers/QSPI.cpp
+++ b/drivers/QSPI.cpp
@@ -22,10 +22,10 @@
namespace mbed {
-QSPI* QSPI::_owner = NULL;
+QSPI *QSPI::_owner = NULL;
SingletonPtr QSPI::_mutex;
-QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel, int mode) : _qspi()
+QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel, int mode) : _qspi()
{
_qspi_io0 = io0;
_qspi_io1 = io1;
@@ -67,7 +67,7 @@ qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width
return ret_status;
}
-qspi_status_t QSPI::set_frequency(int hz)
+qspi_status_t QSPI::set_frequency(int hz)
{
qspi_status_t ret_status = QSPI_STATUS_OK;
@@ -91,7 +91,7 @@ qspi_status_t QSPI::set_frequency(int hz)
return ret_status;
}
-qspi_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_length)
+qspi_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_length)
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
@@ -115,10 +115,10 @@ qspi_status_t QSPI::read(unsigned int address, char *rx_buffer, size_t *rx_lengt
return ret_status;
}
-qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *tx_length)
+qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *tx_length)
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
-
+
if (_initialized) {
if ((tx_length != NULL) && (tx_buffer != NULL)) {
if (*tx_length != 0) {
@@ -139,15 +139,15 @@ qspi_status_t QSPI::write(unsigned int address, const char *tx_buffer, size_t *t
return ret_status;
}
-qspi_status_t QSPI::read(unsigned int instruction, unsigned int alt, unsigned int address, char *rx_buffer, size_t *rx_length)
+qspi_status_t QSPI::read(unsigned int instruction, unsigned int alt, unsigned int address, char *rx_buffer, size_t *rx_length)
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
if (_initialized) {
- if ( (rx_length != NULL) && (rx_buffer != NULL) ) {
+ if ((rx_length != NULL) && (rx_buffer != NULL)) {
if (*rx_length != 0) {
lock();
- if ( true == _acquire()) {
+ if (true == _acquire()) {
_build_qspi_command(instruction, address, alt);
if (QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
@@ -159,16 +159,16 @@ qspi_status_t QSPI::read(unsigned int instruction, unsigned int alt, unsigned in
ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
}
-
+
return ret_status;
}
-qspi_status_t QSPI::write(unsigned int instruction, unsigned int alt, unsigned int address, const char *tx_buffer, size_t *tx_length)
+qspi_status_t QSPI::write(unsigned int instruction, unsigned int alt, unsigned int address, const char *tx_buffer, size_t *tx_length)
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
-
+
if (_initialized) {
- if ( (tx_length != NULL) && (tx_buffer != NULL) ) {
+ if ((tx_length != NULL) && (tx_buffer != NULL)) {
if (*tx_length != 0) {
lock();
if (true == _acquire()) {
@@ -183,14 +183,14 @@ qspi_status_t QSPI::write(unsigned int instruction, unsigned int alt, unsigned i
ret_status = QSPI_STATUS_INVALID_PARAMETER;
}
}
-
+
return ret_status;
}
-qspi_status_t QSPI::command_transfer(unsigned int instruction, int address, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length)
+qspi_status_t QSPI::command_transfer(unsigned int instruction, int address, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length)
{
qspi_status_t ret_status = QSPI_STATUS_ERROR;
-
+
if (_initialized) {
lock();
if (true == _acquire()) {
@@ -198,56 +198,56 @@ qspi_status_t QSPI::command_transfer(unsigned int instruction, int address, cons
if (QSPI_STATUS_OK == qspi_command_transfer(&_qspi, &_qspi_command, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
ret_status = QSPI_STATUS_OK;
}
- }
+ }
unlock();
}
-
+
return ret_status;
}
-void QSPI::lock()
+void QSPI::lock()
{
_mutex->lock();
}
-void QSPI::unlock()
+void QSPI::unlock()
{
_mutex->unlock();
}
// Note: Private helper function to initialize qspi HAL
-bool QSPI::_initialize()
+bool QSPI::_initialize()
{
if (_mode != 0 && _mode != 1) {
_initialized = false;
return _initialized;
}
- qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode );
+ qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode);
if (QSPI_STATUS_OK == ret) {
_initialized = true;
} else {
_initialized = false;
}
-
+
return _initialized;
}
// Note: Private function with no locking
-bool QSPI::_acquire()
+bool QSPI::_acquire()
{
if (_owner != this) {
//This will set freq as well
_initialize();
_owner = this;
}
-
+
return _initialized;
}
-void QSPI::_build_qspi_command(int instruction, int address, int alt)
+void QSPI::_build_qspi_command(int instruction, int address, int alt)
{
- memset( &_qspi_command, 0, sizeof(qspi_command_t) );
+ memset(&_qspi_command, 0, sizeof(qspi_command_t));
//Set up instruction phase parameters
_qspi_command.instruction.bus_width = _inst_width;
if (instruction != -1) {
@@ -271,7 +271,7 @@ void QSPI::_build_qspi_command(int instruction, int address, int alt)
_qspi_command.alt.bus_width = _alt_width;
_qspi_command.alt.size = _alt_size;
if (alt != -1) {
- _qspi_command.alt.value = alt;
+ _qspi_command.alt.value = alt;
_qspi_command.alt.disabled = false;
} else {
_qspi_command.alt.disabled = true;
diff --git a/drivers/QSPI.h b/drivers/QSPI.h
index 70fa88596e..c166e4bc55 100644
--- a/drivers/QSPI.h
+++ b/drivers/QSPI.h
@@ -28,13 +28,13 @@
#define ONE_MHZ 1000000
namespace mbed {
-
+
/** \addtogroup drivers */
/** A QSPI Driver, used for communicating with QSPI slave devices
*
* The default format is set to Quad-SPI(1-1-1), and a clock frequency of 1MHz
- * Most QSPI devices will also require Chip Select which is indicated by ssel.
+ * Most QSPI devices will also require Chip Select which is indicated by ssel.
*
* @note Synchronization level: Thread safe
*
@@ -49,10 +49,10 @@ namespace mbed {
*
*
* int main() {
- * char tx_buf[] = { 0x11, 0x22, 0x33, 0x44 };
- * char rx_buf[4];
- * int buf_len = sizeof(tx_buf);
- *
+ * char tx_buf[] = { 0x11, 0x22, 0x33, 0x44 };
+ * char rx_buf[4];
+ * int buf_len = sizeof(tx_buf);
+ *
* int result = qspi_device.write( 0x12 , 0x100000 , 0 , tx_buf, &buf_len );
* if( !result ) printf("Write failed");
* int result = qspi_device.read( 0x13 , 0x100000 , 0 , rx_buf, &buf_len );
@@ -80,7 +80,7 @@ public:
* default value = 0
*
*/
- QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel=NC, int mode=0);
+ QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel = NC, int mode = 0);
/** Configure the data transmission format
*
@@ -93,13 +93,13 @@ public:
* @param dummy_cycles Number of dummy clock cycles to be used after alt phase
*
*/
- qspi_status_t configure_format(qspi_bus_width_t inst_width,
- qspi_bus_width_t address_width,
- qspi_address_size_t address_size,
- qspi_bus_width_t alt_width,
- qspi_alt_size_t alt_size,
- qspi_bus_width_t data_width,
- int dummy_cycles);
+ qspi_status_t configure_format(qspi_bus_width_t inst_width,
+ qspi_bus_width_t address_width,
+ qspi_address_size_t address_size,
+ qspi_bus_width_t alt_width,
+ qspi_alt_size_t alt_size,
+ qspi_bus_width_t data_width,
+ int dummy_cycles);
/** Set the qspi bus clock frequency
*
@@ -112,7 +112,7 @@ public:
/** Read from QSPI peripheral with the preset read_instruction and alt_value
*
* @param address Address to be accessed in QSPI peripheral
- * @param rx_buffer Buffer for data to be read from the peripheral
+ * @param rx_buffer Buffer for data to be read from the peripheral
* @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
*
* @returns
@@ -123,7 +123,7 @@ public:
/** Write to QSPI peripheral using custom write instruction
*
* @param address Address to be accessed in QSPI peripheral
- * @param tx_buffer Buffer containing data to be sent to peripheral
+ * @param tx_buffer Buffer containing data to be sent to peripheral
* @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
*
* @returns
@@ -136,7 +136,7 @@ public:
* @param instruction Instruction value to be used in instruction phase
* @param alt Alt value to be used in instruction phase
* @param address Address to be accessed in QSPI peripheral
- * @param rx_buffer Buffer for data to be read from the peripheral
+ * @param rx_buffer Buffer for data to be read from the peripheral
* @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
*
* @returns
@@ -149,7 +149,7 @@ public:
* @param instruction Instruction value to be used in instruction phase
* @param alt Alt value to be used in instruction phase
* @param address Address to be accessed in QSPI peripheral
- * @param tx_buffer Buffer containing data to be sent to peripheral
+ * @param tx_buffer Buffer containing data to be sent to peripheral
* @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
*
* @returns
@@ -161,9 +161,9 @@ public:
*
* @param instruction Instruction value to be used in instruction phase
* @param address Some instruction might require address. Use -1 for ignoring the address value
- * @param tx_buffer Buffer containing data to be sent to peripheral
+ * @param tx_buffer Buffer containing data to be sent to peripheral
* @param tx_length Pointer to a variable containing the length of data to be transmitted, and on return this variable will be updated with the actual number of bytes written
- * @param rx_buffer Buffer for data to be read from the peripheral
+ * @param rx_buffer Buffer for data to be read from the peripheral
* @param rx_length Pointer to a variable containing the length of rx_buffer, and on return this variable will be updated with the actual number of bytes read
*
* @returns
@@ -181,7 +181,8 @@ protected:
virtual void unlock(void);
public:
- virtual ~QSPI() {
+ virtual ~QSPI()
+ {
}
protected:
@@ -210,7 +211,7 @@ private:
bool _acquire(void);
bool _initialize();
- /*
+ /*
* This function builds the qspi command struct to be send to Hal
*/
inline void _build_qspi_command(int instruction, int address, int alt);
diff --git a/hal/qspi_api.h b/hal/qspi_api.h
index 10bd77130b..24ba473545 100644
--- a/hal/qspi_api.h
+++ b/hal/qspi_api.h
@@ -38,8 +38,8 @@ extern "C" {
typedef struct qspi_s qspi_t;
/** QSPI Bus width
- *
- * Some parts of commands provide variable bus width
+ *
+ * Some parts of commands provide variable bus width
*/
typedef enum qspi_bus_width {
QSPI_CFG_BUS_SINGLE,
@@ -101,10 +101,10 @@ typedef enum qspi_status {
QSPI_STATUS_OK = 0, /**< Function executed sucessfully >*/
} qspi_status_t;
-/** Initialize QSPI peripheral.
+/** Initialize QSPI peripheral.
*
* It should initialize QSPI pins (io0-io3, sclk and ssel), set frequency, clock polarity and phase mode. The clock for the peripheral should be enabled
- *
+ *
* @param obj QSPI object
* @param io0 Data pin 0
* @param io1 Data pin 1
@@ -167,7 +167,7 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void
QSPI_STATUS_INVALID_PARAMETER if invalid parameter found
QSPI_STATUS_ERROR otherwise
*/
-qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command, const void *tx_data, size_t tx_size, void *rx_data, size_t rx_size);
+qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command, const void *tx_data, size_t tx_size, void *rx_data, size_t rx_size);
/** Receive a command and block of data
*