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 *