diff --git a/TESTS/mbed_hal/qspi/flash_configs/MX25LM51245G_config.h b/TESTS/mbed_hal/qspi/flash_configs/MX25LM51245G_config.h new file mode 100644 index 00000000000..f3243a4eb60 --- /dev/null +++ b/TESTS/mbed_hal/qspi/flash_configs/MX25LM51245G_config.h @@ -0,0 +1,101 @@ +/* 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_MX25LM51245G_H +#define MBED_QSPI_FLASH_MX25LM51245G_H + + +#define QSPI_FLASH_CHIP_STRING "macronix MX25LM51245G" + +// Command for reading status register +#define QSPI_CMD_RDSR 0x05 +// Command for reading configuration register +#define QSPI_CMD_RDCR0 0x15 +#define QSPI_CMD_RDCR1 0x71 +// 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 100000 // 100ms + + +// Commands for writing (page programming) +// Only single/octal mode supported with this memory +// So only single 1-1-1 mode in this QSPI config +#define QSPI_CMD_WRITE_1IO 0x02 // 1-1-1 mode +// write operations max time [us] (datasheet max time + 15%) +#define QSPI_PAGE_PROG_MAX_TIME 11500 // 10ms + +#define QSPI_PAGE_SIZE 256 // 256B +#define QSPI_SECTOR_SIZE 4096 // 4kB +#define QSPI_SECTOR_COUNT 2048 + +// Commands for reading +// Only single/octal mode supported with this memory +// So only single 1-1-1 mode in this QSPI config +#define QSPI_CMD_READ_1IO_FAST 0x0B // 1-1-1 mode +#define QSPI_CMD_READ_1IO 0x03 // 1-1-1 mode + +#define QSPI_READ_1IO_DUMMY_CYCLE 0 +#define QSPI_READ_FAST_DUMMY_CYCLE 8 + +// Commands for erasing +#define QSPI_CMD_ERASE_SECTOR 0x20 // 4kB +//#define QSPI_CMD_ERASE_BLOCK_32 // not supported, only ersae block 64 +#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 480000 // 400 ms +#define QSPI_ERASE_BLOCK_64_MAX_TIME 2400000 // 2s + +// max frequency for basic rw operation (for fast mode) +#define QSPI_COMMON_MAX_FREQUENCY 1000000 + +#define QSPI_STATUS_REG_SIZE 1 //2 ?? +#define QSPI_CONFIG_REG_0_SIZE 1 +#define QSPI_CONFIG_REG_1_SIZE 1 +#define QSPI_SECURITY_REG_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) // +#define STATUS_BIT_BP1 (1 << 3) // +#define STATUS_BIT_BP2 (1 << 4) // +#define STATUS_BIT_BP3 (1 << 5) // +//#define STATUS_BIT_QE (1 << 6) // Not supported +//#define STATUS_BIT_SRWD (1 << 7) // Not supported + +// configuration register 0 +// bit 0, 1, 2, 4, 5, 7 reserved +#define CONFIG0_BIT_TB (1 << 3) // Top/Bottom area protect + +#endif // MBED_QSPI_FLASH_MX25LM51245G_H diff --git a/TESTS/mbed_hal/qspi/flash_configs/flash_configs.h b/TESTS/mbed_hal/qspi/flash_configs/flash_configs.h index 03e85a66dd8..90c61e98bfa 100644 --- a/TESTS/mbed_hal/qspi/flash_configs/flash_configs.h +++ b/TESTS/mbed_hal/qspi/flash_configs/flash_configs.h @@ -32,6 +32,9 @@ #elif defined(TARGET_DISCO_F769NI) #include "MX25L51245G_config.h" // MX25L51245G +#elif defined(TARGET_DISCO_L4R9I) +#include "MX25LM51245G_config.h" // MX25LM51245G + #elif defined(TARGET_DISCO_L476VG) #include "N25Q128A_config.h" // N25Q128A13EF840E /* See STM32L476 Errata Sheet, it is not possible to use Dual-/Quad-mode for the command phase */ diff --git a/TESTS/mbed_hal/qspi/main.cpp b/TESTS/mbed_hal/qspi/main.cpp index 883cf48b46f..c24036a610d 100644 --- a/TESTS/mbed_hal/qspi/main.cpp +++ b/TESTS/mbed_hal/qspi/main.cpp @@ -385,28 +385,36 @@ Case cases[] = { 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/x4 test", qspi_write_read_test), +#ifdef READ_1_1_2 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/x4 test", qspi_write_read_test), +#endif +#ifdef READ_1_2_2 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/x4 test", qspi_write_read_test), +#endif #ifdef READ_2_2_2 Case("qspi write(1-1-1)/x1 read(2-2-2)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(1-1-1)/x4 read(2-2-2)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(1-1-1)/x1 read(2-2-2)/x4 repeat/x1 test", qspi_write_read_test), Case("qspi write(1-1-1)/x1 read(2-2-2)/x1 repeat/x4 test", qspi_write_read_test), #endif +#ifdef READ_1_1_4 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/x4 test", qspi_write_read_test), +#endif +#ifdef READ_1_4_4 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/x4 test", qspi_write_read_test), +#endif #ifdef READ_4_4_4 Case("qspi write(1-1-1)/x1 read(4-4-4)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(1-1-1)/x4 read(4-4-4)/x1 repeat/x1 test", qspi_write_read_test), @@ -433,10 +441,12 @@ Case cases[] = { Case("qspi write(1-2-2)/x1 read(2-2-2)/x4 repeat/x1 test", qspi_write_read_test), Case("qspi write(1-2-2)/x1 read(2-2-2)/x1 repeat/x4 test", qspi_write_read_test), #endif +#ifdef READ_1_1_4 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/x4 test", qspi_write_read_test), +#endif 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), @@ -468,10 +478,12 @@ Case cases[] = { Case("qspi write(2-2-2)/x1 read(2-2-2)/x4 repeat/x1 test", qspi_write_read_test), Case("qspi write(2-2-2)/x1 read(2-2-2)/x1 repeat/x4 test", qspi_write_read_test), #endif +#ifdef READ_1_1_4 Case("qspi write(2-2-2)/x1 read(1-1-4)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(2-2-2)/x4 read(1-1-4)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(2-2-2)/x1 read(1-1-4)/x4 repeat/x1 test", qspi_write_read_test), Case("qspi write(2-2-2)/x1 read(1-1-4)/x1 repeat/x4 test", qspi_write_read_test), +#endif Case("qspi write(2-2-2)/x1 read(1-4-4)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(2-2-2)/x4 read(1-4-4)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(2-2-2)/x1 read(1-4-4)/x4 repeat/x1 test", qspi_write_read_test), @@ -503,10 +515,12 @@ Case cases[] = { Case("qspi write(1-1-4)/x1 read(2-2-2)/x4 repeat/x1 test", qspi_write_read_test), Case("qspi write(1-1-4)/x1 read(2-2-2)/x1 repeat/x4 test", qspi_write_read_test), #endif +#ifdef READ_1_1_4 Case("qspi write(1-1-4)/x1 read(1-1-4)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(1-1-4)/x4 read(1-1-4)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(1-1-4)/x1 read(1-1-4)/x4 repeat/x1 test", qspi_write_read_test), Case("qspi write(1-1-4)/x1 read(1-1-4)/x1 repeat/x4 test", qspi_write_read_test), +#endif Case("qspi write(1-1-4)/x1 read(1-4-4)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(1-1-4)/x4 read(1-4-4)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(1-1-4)/x1 read(1-4-4)/x4 repeat/x1 test", qspi_write_read_test), @@ -538,10 +552,12 @@ Case cases[] = { Case("qspi write(1-4-4)/x1 read(2-2-2)/x4 repeat/x1 test", qspi_write_read_test), Case("qspi write(1-4-4)/x1 read(2-2-2)/x1 repeat/x4 test", qspi_write_read_test), #endif +#ifdef READ_1_1_4 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/x4 test", qspi_write_read_test), +#endif 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), @@ -573,10 +589,12 @@ Case cases[] = { Case("qspi write(4-4-4)/x1 read(2-2-2)/x4 repeat/x1 test", qspi_write_read_test), Case("qspi write(4-4-4)/x1 read(2-2-2)/x1 repeat/x4 test", qspi_write_read_test), #endif +#ifdef READ_1_1_4 Case("qspi write(4-4-4)/x1 read(1-1-4)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(4-4-4)/x4 read(1-1-4)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(4-4-4)/x1 read(1-1-4)/x4 repeat/x1 test", qspi_write_read_test), Case("qspi write(4-4-4)/x1 read(1-1-4)/x1 repeat/x4 test", qspi_write_read_test), +#endif Case("qspi write(4-4-4)/x1 read(1-4-4)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(4-4-4)/x4 read(1-4-4)/x1 repeat/x1 test", qspi_write_read_test), Case("qspi write(4-4-4)/x1 read(1-4-4)/x4 repeat/x1 test", qspi_write_read_test), diff --git a/TESTS/mbed_hal/qspi/qspi_test_utils.h b/TESTS/mbed_hal/qspi/qspi_test_utils.h index 0ed73b55cf5..08f16f42c9f 100644 --- a/TESTS/mbed_hal/qspi/qspi_test_utils.h +++ b/TESTS/mbed_hal/qspi/qspi_test_utils.h @@ -77,10 +77,19 @@ struct Qspi { #define READ_1_1_1 MODE_1_1_1, QSPI_CMD_READ_1IO, QSPI_READ_1IO_DUMMY_CYCLE +#ifdef QSPI_CMD_READ_1I2O #define READ_1_1_2 MODE_1_1_2, QSPI_CMD_READ_1I2O, QSPI_READ_1I2O_DUMMY_CYCLE +#endif +#ifdef QSPI_CMD_READ_2IO #define READ_1_2_2 MODE_1_2_2, QSPI_CMD_READ_2IO, QSPI_READ_2IO_DUMMY_CYCLE +#endif +#ifdef QSPI_CMD_READ_1I4O #define READ_1_1_4 MODE_1_1_4, QSPI_CMD_READ_1I4O, QSPI_READ_1I4O_DUMMY_CYCLE +#endif +#ifdef QSPI_CMD_READ_4IO #define READ_1_4_4 MODE_1_4_4, QSPI_CMD_READ_4IO, QSPI_READ_4IO_DUMMY_CYCLE +#endif + #ifdef QSPI_CMD_READ_DPI #define READ_2_2_2 MODE_2_2_2, QSPI_CMD_READ_DPI, QSPI_READ_2IO_DUMMY_CYCLE #endif diff --git a/features/cellular/framework/AT/ATHandler.cpp b/features/cellular/framework/AT/ATHandler.cpp index 621b444fddc..cfc86ec54ae 100644 --- a/features/cellular/framework/AT/ATHandler.cpp +++ b/features/cellular/framework/AT/ATHandler.cpp @@ -722,7 +722,19 @@ int32_t ATHandler::read_int() return -1; } - return std::strtol(buff, NULL, 10); + errno = 0; + char *endptr; + long result = std::strtol(buff, &endptr, 10); + if ((result == LONG_MIN || result == LONG_MAX) && errno == ERANGE) { + return -1; // overflow/underflow + } + if (result < 0) { + return -1; // negative values are unsupported + } + if (*buff == '\0') { + return -1; // empty string + } + return (int32_t) result; } void ATHandler::set_delimiter(char delimiter) diff --git a/features/cellular/framework/AT/ATHandler.h b/features/cellular/framework/AT/ATHandler.h index 19c9c3daae9..ce763de93a6 100644 --- a/features/cellular/framework/AT/ATHandler.h +++ b/features/cellular/framework/AT/ATHandler.h @@ -416,9 +416,9 @@ class ATHandler { */ ssize_t read_hex_string(char *str, size_t size); - /** Reads as string and converts result to integer. Supports only positive integers. + /** Reads as string and converts result to integer. Supports only non-negative integers. * - * @return the positive integer or -1 in case of error. + * @return the non-negative integer or -1 in case of error. */ int32_t read_int(); diff --git a/features/storage/kvstore/tdbstore/TDBStore.cpp b/features/storage/kvstore/tdbstore/TDBStore.cpp index 59c33651cd7..2f25e1c4d32 100644 --- a/features/storage/kvstore/tdbstore/TDBStore.cpp +++ b/features/storage/kvstore/tdbstore/TDBStore.cpp @@ -1414,7 +1414,7 @@ int TDBStore::do_reserved_data_get(void *reserved_data, size_t reserved_data_buf while (actual_size) { uint32_t chunk = std::min(work_buf_size, (uint32_t) actual_size); - ret = read_area(_active_area, offset, chunk, buf); + ret = read_area(_active_area, offset, chunk, buf + offset); if (ret) { return ret; } diff --git a/rtos/source/Mutex.cpp b/rtos/source/Mutex.cpp index 7752f6670cd..57e69f7c9eb 100644 --- a/rtos/source/Mutex.cpp +++ b/rtos/source/Mutex.cpp @@ -97,6 +97,7 @@ bool Mutex::trylock_for(uint32_t millisec) { osStatus status = osMutexAcquire(_id, millisec); if (status == osOK) { + _count++; return true; } diff --git a/targets/TARGET_STM/TARGET_STM32F0/device/stm32f0xx_hal_i2c.c b/targets/TARGET_STM/TARGET_STM32F0/device/stm32f0xx_hal_i2c.c index 225b519bdb8..610fcf34018 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/device/stm32f0xx_hal_i2c.c +++ b/targets/TARGET_STM/TARGET_STM32F0/device/stm32f0xx_hal_i2c.c @@ -2592,7 +2592,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; - hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); + hi2c->XferOptions = XferOptions; hi2c->XferISR = I2C_Master_ISR_IT; /* If size > MAX_NBYTE_SIZE, use reload mode */ @@ -2658,7 +2658,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; - hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); + hi2c->XferOptions = XferOptions; hi2c->XferISR = I2C_Master_ISR_IT; /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ diff --git a/targets/TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_i2c.c b/targets/TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_i2c.c index 66afaed8cc9..c721823a7e9 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_i2c.c +++ b/targets/TARGET_STM/TARGET_STM32F3/device/stm32f3xx_hal_i2c.c @@ -2592,7 +2592,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; - hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED patch + hi2c->XferOptions = XferOptions; hi2c->XferISR = I2C_Master_ISR_IT; /* If size > MAX_NBYTE_SIZE, use reload mode */ @@ -2666,7 +2666,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; - hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED patch + hi2c->XferOptions = XferOptions; hi2c->XferISR = I2C_Master_ISR_IT; /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h index 0c132e93fd3..9b3aa0b3f9a 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h @@ -44,16 +44,6 @@ struct trng_s { RNG_HandleTypeDef handle; }; -struct qspi_s { - QSPI_HandleTypeDef handle; - PinName io0; - PinName io1; - PinName io2; - PinName io3; - PinName sclk; - PinName ssel; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_SDP_K1/PinNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_SDP_K1/PinNames.h index ec97bd96cf9..f7070074f0b 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_SDP_K1/PinNames.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/TARGET_SDP_K1/PinNames.h @@ -284,12 +284,12 @@ typedef enum { D7 = PG_10, D8 = PG_11, D9 = PB_15, - D10 = PA_15, - D11 = PA_7, - D12 = PB_4, - D13 = PB_3, - D14 = PB_7, - D15 = PB_8, + D10 = PA_15, // SPI CS + D11 = PA_7, // SPI MOSI + D12 = PB_4, // SPI MISO + D13 = PB_3, // SPI SCK + D14 = PB_7, // I2C SDA + D15 = PB_8, // I2C SCL // STDIO for console print #ifdef MBED_CONF_TARGET_STDIO_UART_TX @@ -310,43 +310,35 @@ typedef enum { LED2 = PK_6, // Orange LED LED3 = PK_5, // Green LED LED4 = PK_4, - LED_RED = LED1, - LED_ORANGE = LED2, - LED_GREEN = LED3, SERIAL_TX = STDIO_UART_TX, SERIAL_RX = STDIO_UART_RX, USBTX = STDIO_UART_TX, USBRX = STDIO_UART_RX, - // Adding these signals for the SDP connector - SDP_SPI_MOSI = PF_9, // SDP Connector for SPI lines - SDP_SPI_MISO = PF_8, + SDP_SPI_MOSI = PF_9, // SDP Connector for SPI lines + SDP_SPI_MISO = PF_8, SDP_SPI_SCK = PH_6, SDP_SPI_CS_A = PB_9, SDP_SPI_CS_B = PC_6, SDP_SPI_CS_C = PC_7, - SDP_I2C_SDA = PC_9, // SDP Connector I2C lines + SDP_I2C_SDA = PC_9, // SDP Connector I2C lines SDP_I2C_SCL = PH_7, - SDP_GPIO_0 = PJ_0, // SDP connector GPIO 0-7 + SDP_GPIO_0 = PJ_0, // SDP connector GPIO 0-7 SDP_GPIO_1 = PJ_1, SDP_GPIO_2 = PJ_3, SDP_GPIO_3 = PJ_4, SDP_GPIO_4 = PJ_5, SDP_GPIO_5 = PJ_12, SDP_GPIO_6 = PJ_13, - SDP_GPIO_7 = PJ_14, - SDP_UART_TX = PD_5, // SDP connector UART + SDP_GPIO_7 = PJ_14, + SDP_UART_TX = PD_5, // SDP connector UART SDP_UART_RX = PD_6, - SDP_TMR_A = PB_14, // SDP connector TMR A, B & D + SDP_TMR_A = PB_14, // SDP connector TMR A, B & D SDP_TMR_B = PE_6, SDP_TMR_D = PC_8, - /**** USB pins ****/ - USB_OTG_HS_DM = PB_14, - USB_OTG_HS_DP = PB_15, - USB_OTG_HS_ID = PB_12, - USB_OTG_HS_SOF = PA_4, + /**** USB pins ****/ USB_OTG_HS_ULPI_CK = PA_5, USB_OTG_HS_ULPI_D0 = PA_3, USB_OTG_HS_ULPI_D1 = PB_0, @@ -356,12 +348,9 @@ typedef enum { USB_OTG_HS_ULPI_D5 = PB_12, USB_OTG_HS_ULPI_D6 = PB_13, USB_OTG_HS_ULPI_D7 = PB_5, - USB_OTG_HS_ULPI_DIR = PI_11, - USB_OTG_HS_ULPI_DIR_ALT0 = PC_2, - USB_OTG_HS_ULPI_NXT = PH_4, - USB_OTG_HS_ULPI_NXT_ALT0 = PC_3, + USB_OTG_HS_ULPI_DIR = PC_2, + USB_OTG_HS_ULPI_NXT = PC_3, USB_OTG_HS_ULPI_STP = PC_0, - USB_OTG_HS_VBUS = PB_13, /**** OSCILLATOR pins ****/ RCC_OSC32_IN = PC_14, diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h index 106be4c4466..bea7fef5477 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h @@ -58,16 +58,6 @@ struct trng_s { RNG_HandleTypeDef handle; }; -struct qspi_s { - QSPI_HandleTypeDef handle; - PinName io0; - PinName io1; - PinName io2; - PinName io3; - PinName sclk; - PinName ssel; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F4/common_objects.h b/targets/TARGET_STM/TARGET_STM32F4/common_objects.h index 963e9133535..00129513d57 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/common_objects.h @@ -143,6 +143,23 @@ struct can_s { }; #endif +#if DEVICE_QSPI +struct qspi_s { +#if defined(OCTOSPI1) + OSPI_HandleTypeDef handle; +#else + QSPI_HandleTypeDef handle; +#endif + QSPIName qspi; + PinName io0; + PinName io1; + PinName io2; + PinName io3; + PinName sclk; + PinName ssel; +}; +#endif + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h index 2e538dcf5bc..28946911189 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h @@ -58,16 +58,6 @@ struct trng_s { RNG_HandleTypeDef handle; }; -struct qspi_s { - QSPI_HandleTypeDef handle; - PinName io0; - PinName io1; - PinName io2; - PinName io3; - PinName sclk; - PinName ssel; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/objects.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/objects.h index 2e538dcf5bc..28946911189 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/objects.h @@ -58,16 +58,6 @@ struct trng_s { RNG_HandleTypeDef handle; }; -struct qspi_s { - QSPI_HandleTypeDef handle; - PinName io0; - PinName io1; - PinName io2; - PinName io3; - PinName sclk; - PinName ssel; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/objects.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/objects.h index 2e538dcf5bc..28946911189 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/objects.h @@ -58,16 +58,6 @@ struct trng_s { RNG_HandleTypeDef handle; }; -struct qspi_s { - QSPI_HandleTypeDef handle; - PinName io0; - PinName io1; - PinName io2; - PinName io3; - PinName sclk; - PinName ssel; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F7/common_objects.h b/targets/TARGET_STM/TARGET_STM32F7/common_objects.h index 972bd60ee93..8a048a3de1a 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/common_objects.h @@ -142,6 +142,23 @@ struct can_s { }; #endif +#if DEVICE_QSPI +struct qspi_s { +#if defined(OCTOSPI1) + OSPI_HandleTypeDef handle; +#else + QSPI_HandleTypeDef handle; +#endif + QSPIName qspi; + PinName io0; + PinName io1; + PinName io2; + PinName io3; + PinName sclk; + PinName ssel; +}; +#endif + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_i2c.c b/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_i2c.c index f79ec0aa566..ebfb11125a0 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_i2c.c +++ b/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_i2c.c @@ -2598,7 +2598,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; - hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED: changed + hi2c->XferOptions = XferOptions; hi2c->XferISR = I2C_Master_ISR_IT; /* If size > MAX_NBYTE_SIZE, use reload mode */ @@ -2672,7 +2672,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; - hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED: changed + hi2c->XferOptions = XferOptions; hi2c->XferISR = I2C_Master_ISR_IT; /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ diff --git a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.c b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.c index d99695721c3..0f6f34f1dcb 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.c +++ b/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_i2c.c @@ -2592,7 +2592,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; - hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED commit 23926a2418 + hi2c->XferOptions = XferOptions; hi2c->XferISR = I2C_Master_ISR_IT; /* If size > MAX_NBYTE_SIZE, use reload mode */ @@ -2666,7 +2666,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; - hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); // MBED commit 23926a2418 + hi2c->XferOptions = XferOptions; hi2c->XferISR = I2C_Master_ISR_IT; /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h index 61c29a5fba4..e68c4eb6194 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h @@ -58,16 +58,6 @@ struct trng_s { RNG_HandleTypeDef handle; }; -struct qspi_s { - QSPI_HandleTypeDef handle; - PinName io0; - PinName io1; - PinName io2; - PinName io3; - PinName sclk; - PinName ssel; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h index cd0f1a783c1..ece5f1679fa 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h @@ -58,16 +58,6 @@ struct trng_s { RNG_HandleTypeDef handle; }; -struct qspi_s { - QSPI_HandleTypeDef handle; - PinName io0; - PinName io1; - PinName io2; - PinName io3; - PinName sclk; - PinName ssel; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/objects.h index cd0f1a783c1..ece5f1679fa 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/objects.h @@ -58,16 +58,6 @@ struct trng_s { RNG_HandleTypeDef handle; }; -struct qspi_s { - QSPI_HandleTypeDef handle; - PinName io0; - PinName io1; - PinName io2; - PinName io3; - PinName sclk; - PinName ssel; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/objects.h index cd0f1a783c1..ece5f1679fa 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L496xG/objects.h @@ -58,16 +58,6 @@ struct trng_s { RNG_HandleTypeDef handle; }; -struct qspi_s { - QSPI_HandleTypeDef handle; - PinName io0; - PinName io1; - PinName io2; - PinName io3; - PinName sclk; - PinName ssel; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/TARGET_DISCO_L4R9I/PeripheralNames.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/TARGET_DISCO_L4R9I/PeripheralNames.h index 0393c8ffb39..ca8b3a0961a 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/TARGET_DISCO_L4R9I/PeripheralNames.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/TARGET_DISCO_L4R9I/PeripheralNames.h @@ -83,6 +83,11 @@ typedef enum { CAN_1 = (int)CAN1_BASE } CANName; +typedef enum { + QSPI_1 = (int)OCTOSPI1_R_BASE, + QSPI_2 = (int)OCTOSPI2_R_BASE +} QSPIName; + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/TARGET_DISCO_L4R9I/PeripheralPins.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/TARGET_DISCO_L4R9I/PeripheralPins.c index ae6697e28ef..a0db3f7922f 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/TARGET_DISCO_L4R9I/PeripheralPins.c +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/TARGET_DISCO_L4R9I/PeripheralPins.c @@ -390,3 +390,59 @@ 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_DATA0[] = { + {PB_1, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OCTOSPIM_P1)}, // OCTOSPIM_P1_IO0 + {PE_12, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OCTOSPIM_P1)}, // OCTOSPIM_P1_IO0 // Connected to D9 + {PF_0, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_OCTOSPIM_P2)}, // OCTOSPIM_P2_IO0 // Connected to PSRAM_A0 + {PI_11, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_OCTOSPIM_P2)}, // OCTOSPIM_P2_IO0 // Connected to OCTOSPIM_P2_IO0 + {NC, NC, 0} +}; + +MBED_WEAK const PinMap PinMap_QSPI_DATA1[] = { + {PB_0, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OCTOSPIM_P1)}, // OCTOSPIM_P1_IO1 // Connected to ARD_A3 + {PE_13, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OCTOSPIM_P1)}, // OCTOSPIM_P1_IO1 // Connected to D10 + {PF_1, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_OCTOSPIM_P2)}, // OCTOSPIM_P2_IO1 // Connected to PSRAM_A1 + {PI_10, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_OCTOSPIM_P2)}, // OCTOSPIM_P2_IO1 // Connected to OCTOSPIM_P2_IO1 + {NC, NC, 0} +}; + +MBED_WEAK const PinMap PinMap_QSPI_DATA2[] = { + {PA_7, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OCTOSPIM_P1)}, // OCTOSPIM_P1_IO2 // Connected to ARD_A0 + {PE_14, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OCTOSPIM_P1)}, // OCTOSPIM_P1_IO2 // Connected to D11 + {PF_2, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_OCTOSPIM_P2)}, // OCTOSPIM_P2_IO2 // Connected to PSRAM_A2 + {PI_9, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_OCTOSPIM_P2)}, // OCTOSPIM_P2_IO2 // Connected to OCTOSPIM_P2_IO2 + {NC, NC, 0} +}; + +MBED_WEAK const PinMap PinMap_QSPI_DATA3[] = { + {PA_6, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OCTOSPIM_P1)}, // OCTOSPIM_P1_IO3 // Connected to SPI2_CS + {PE_15, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OCTOSPIM_P1)}, // OCTOSPIM_P1_IO3 // Connected to D12 + {PF_3, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_OCTOSPIM_P2)}, // OCTOSPIM_P2_IO3 // Connected to PSRAM_A3 + {PH_8, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_OCTOSPIM_P2)}, // OCTOSPIM_P2_IO3 // Connected to OCTOSPI_P2_IO3 + {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_OCTOSPIM_P1)}, // OCTOSPIM_P1_CLK // Connected to STDIO_UART_RX + {PB_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OCTOSPIM_P1)}, // OCTOSPIM_P1_CLK // Connected to USART3_TX + {PE_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OCTOSPIM_P1)}, // OCTOSPIM_P1_CLK // Connected to D7 + {PF_4, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_OCTOSPIM_P2)}, // OCTOSPIM_P2_CLK // Connected to PSRAM_A4 + {PF_10, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_OCTOSPIM_P1)}, // OCTOSPIM_P1_CLK + {PI_6, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_OCTOSPIM_P2)}, // OCTOSPIM_P2_CLK // Connected to OCTOSPIM_P2_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_OCTOSPIM_P1)}, // OCTOSPIM_P1_NCS // Connected to STDIO_UART_TX + {PA_4, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_OCTOSPIM_P1)}, // OCTOSPIM_P1_NCS // Connected to DCMI_HSYNC + {PB_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OCTOSPIM_P1)}, // OCTOSPIM_P1_NCS // Connected to USART3_RX + {PC_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_OCTOSPIM_P1)}, // OCTOSPIM_P1_NCS // Connected to uSD_D3 + {PD_3, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OCTOSPIM_P2)}, // OCTOSPIM_P2_NCS // Connected to PSRAM_CLK + {PE_11, QSPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OCTOSPIM_P1)}, // OCTOSPIM_P1_NCS // Connected to D8 + {PG_12, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_OCTOSPIM_P2)}, // OCTOSPIM_P2_NCS // Connected to OCTOSPIM_P2_CS + {PI_5, QSPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_OCTOSPIM_P2)}, // OCTOSPIM_P2_NCS // Connected to DCMI_VSYNC + {NC, NC, 0} +}; diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/TARGET_DISCO_L4R9I/PinNames.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/TARGET_DISCO_L4R9I/PinNames.h index 12ad25ca981..f8c96d01f2c 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/TARGET_DISCO_L4R9I/PinNames.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/TARGET_DISCO_L4R9I/PinNames.h @@ -352,6 +352,14 @@ typedef enum { SYS_WKUP3 = PE_6, SYS_WKUP4 = PA_2, + /**** QSPI FLASH pins ****/ + QSPI_FLASH1_IO0 = PI_11, + QSPI_FLASH1_IO1 = PI_10, + QSPI_FLASH1_IO2 = PI_9, + QSPI_FLASH1_IO3 = PH_8, + QSPI_FLASH1_SCK = PI_6, + QSPI_FLASH1_CSN = PG_12, + /**** STMOD+ pins ****/ STMOD_1 = PA_6, STMOD_2 = PB_15, diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/device/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/device/objects.h deleted file mode 100644 index 8eefb96ea17..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/device/objects.h +++ /dev/null @@ -1,53 +0,0 @@ -/* mbed Microcontroller Library - * 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. - * 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_OBJECTS_H -#define MBED_OBJECTS_H - -#include "cmsis.h" -#include "PortNames.h" -#include "PeripheralNames.h" -#include "PinNames.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct gpio_irq_s { - IRQn_Type irq_n; - uint32_t irq_index; - uint32_t event; - PinName pin; -}; - -struct port_s { - PortName port; - uint32_t mask; - PinDirection direction; - __IO uint32_t *reg_in; - __IO uint32_t *reg_out; -}; - -struct trng_s { - RNG_HandleTypeDef handle; -}; - -#include "common_objects.h" - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/objects.h new file mode 100644 index 00000000000..69fe798e2d4 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4R9xI/objects.h @@ -0,0 +1,67 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2019, STMicroelectronics + * 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. + ******************************************************************************* + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + IRQn_Type irq_n; + uint32_t irq_index; + uint32_t event; + PinName pin; +}; + +struct port_s { + PortName port; + uint32_t mask; + PinDirection direction; + __IO uint32_t *reg_in; + __IO uint32_t *reg_out; +}; + +struct trng_s { + RNG_HandleTypeDef handle; +}; + +#include "common_objects.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/common_objects.h b/targets/TARGET_STM/TARGET_STM32L4/common_objects.h index a8116038067..be251d8349e 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/common_objects.h @@ -148,4 +148,21 @@ struct can_s { }; #endif +#if DEVICE_QSPI +struct qspi_s { +#if defined(OCTOSPI1) + OSPI_HandleTypeDef handle; +#else + QSPI_HandleTypeDef handle; +#endif + QSPIName qspi; + PinName io0; + PinName io1; + PinName io2; + PinName io3; + PinName sclk; + PinName ssel; +}; +#endif + #endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_i2c.c b/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_i2c.c index a070a6545e7..f296d5e57cc 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_i2c.c +++ b/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_i2c.c @@ -3173,8 +3173,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16 /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; - // Added for MBED PR #3324 - hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); + hi2c->XferOptions = XferOptions; hi2c->XferISR = I2C_Master_ISR_IT; /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ @@ -3420,8 +3419,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_ /* Prepare transfer parameters */ hi2c->pBuffPtr = pData; hi2c->XferCount = Size; - // Added for MBED PR #3324 - hi2c->XferOptions = (XferOptions & (~I2C_RELOAD_MODE)); + hi2c->XferOptions = XferOptions; hi2c->XferISR = I2C_Master_ISR_IT; /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ diff --git a/targets/TARGET_STM/i2c_api.c b/targets/TARGET_STM/i2c_api.c index 142e01b52a1..995bda07cbf 100644 --- a/targets/TARGET_STM/i2c_api.c +++ b/targets/TARGET_STM/i2c_api.c @@ -40,6 +40,7 @@ #include "pinmap.h" #include "PeripheralPins.h" #include "i2c_device.h" // family specific defines +#include "mbed_error.h" #ifndef DEBUG_STDIO # define DEBUG_STDIO 0 @@ -597,8 +598,6 @@ int i2c_stop(i2c_t *obj) return 0; } #endif - // Disable reload mode - handle->Instance->CR2 &= (uint32_t)~I2C_CR2_RELOAD; // Ensure the transmission is started before sending a stop if ((handle->Instance->CR2 & (uint32_t)I2C_CR2_RD_WRN) == 0) { @@ -611,7 +610,7 @@ int i2c_stop(i2c_t *obj) } // Generate the STOP condition - handle->Instance->CR2 |= I2C_CR2_STOP; + handle->Instance->CR2 = I2C_CR2_STOP; timeout = FLAG_TIMEOUT; while (!__HAL_I2C_GET_FLAG(handle, I2C_FLAG_STOPF)) { @@ -664,9 +663,16 @@ int i2c_byte_read(i2c_t *obj, int last) } } - /* Enable reload mode as we don't know how many bytes will be sent */ - /* and set transfer size to 1 */ - tmpreg |= I2C_CR2_RELOAD | (I2C_CR2_NBYTES & (1 << 16)); + if (last) { + /* Disable Address Acknowledge */ + tmpreg = tmpreg & (~I2C_CR2_RELOAD); + tmpreg |= I2C_CR2_NACK | (I2C_CR2_NBYTES & (1 << 16)); + } else { + /* Enable reload mode as we don't know how many bytes will be sent */ + /* and set transfer size to 1 */ + tmpreg |= I2C_CR2_RELOAD | (I2C_CR2_NBYTES & (1 << 16)); + } + /* Set the prepared configuration */ handle->Instance->CR2 = tmpreg; @@ -680,11 +686,6 @@ int i2c_byte_read(i2c_t *obj, int last) /* Then Get Byte */ data = handle->Instance->RXDR; - if (last) { - /* Disable Address Acknowledge */ - handle->Instance->CR2 |= I2C_CR2_NACK; - } - return data; } @@ -760,7 +761,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) I2C_HandleTypeDef *handle = &(obj_s->handle); int count = I2C_ERROR_BUS_BUSY, ret = 0; uint32_t timeout = 0; - +#if defined(I2C_IP_VERSION_V1) // Trick to remove compiler warning "left and right operands are identical" in some cases uint32_t op1 = I2C_FIRST_AND_LAST_FRAME; uint32_t op2 = I2C_LAST_FRAME; @@ -778,6 +779,18 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) obj_s->XferOperation = I2C_NEXT_FRAME; } } +#elif defined(I2C_IP_VERSION_V2) + if ((obj_s->XferOperation == I2C_FIRST_FRAME) || (obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) || (obj_s->XferOperation == I2C_LAST_FRAME)) { + if (stop) { + obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME; + } else { + obj_s->XferOperation = I2C_FIRST_FRAME; + } + } else { + // should not happend + error("I2C: abnormal case should not happend"); + } +#endif obj_s->event = 0; @@ -818,6 +831,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) int count = I2C_ERROR_BUS_BUSY, ret = 0; uint32_t timeout = 0; +#if defined(I2C_IP_VERSION_V1) // Trick to remove compiler warning "left and right operands are identical" in some cases uint32_t op1 = I2C_FIRST_AND_LAST_FRAME; uint32_t op2 = I2C_LAST_FRAME; @@ -835,6 +849,18 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) obj_s->XferOperation = I2C_NEXT_FRAME; } } +#elif defined(I2C_IP_VERSION_V2) + if ((obj_s->XferOperation == I2C_FIRST_FRAME) || (obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) || (obj_s->XferOperation == I2C_LAST_FRAME)) { + if (stop) { + obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME; + } else { + obj_s->XferOperation = I2C_FIRST_FRAME; + } + } else { + // should not happend + error("I2C: abnormal case should not happend"); + } +#endif obj_s->event = 0; @@ -874,11 +900,19 @@ void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) #if DEVICE_I2C_ASYNCH /* Handle potential Tx/Rx use case */ if ((obj->tx_buff.length) && (obj->rx_buff.length)) { +#if defined(I2C_IP_VERSION_V1) if (obj_s->stop) { obj_s->XferOperation = I2C_LAST_FRAME; } else { obj_s->XferOperation = I2C_NEXT_FRAME; } +#elif defined(I2C_IP_VERSION_V2) + if (obj_s->stop) { + obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME; + } else { + obj_s->XferOperation = I2C_FIRST_FRAME; + } +#endif HAL_I2C_Master_Sequential_Receive_IT(hi2c, obj_s->address, (uint8_t *)obj->rx_buff.buffer, obj->rx_buff.length, obj_s->XferOperation); } else @@ -1143,6 +1177,7 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, /* Set operation step depending if stop sending required or not */ if ((tx_length && !rx_length) || (!tx_length && rx_length)) { +#if defined(I2C_IP_VERSION_V1) // Trick to remove compiler warning "left and right operands are identical" in some cases uint32_t op1 = I2C_FIRST_AND_LAST_FRAME; uint32_t op2 = I2C_LAST_FRAME; @@ -1160,7 +1195,18 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, obj_s->XferOperation = I2C_NEXT_FRAME; } } - +#elif defined(I2C_IP_VERSION_V2) + if ((obj_s->XferOperation == I2C_FIRST_FRAME) || (obj_s->XferOperation == I2C_FIRST_AND_LAST_FRAME) || (obj_s->XferOperation == I2C_LAST_FRAME)) { + if (stop) { + obj_s->XferOperation = I2C_FIRST_AND_LAST_FRAME; + } else { + obj_s->XferOperation = I2C_FIRST_FRAME; + } + } else { + // should not happend + error("I2C: abnormal case should not happend"); + } +#endif if (tx_length > 0) { HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *)tx, tx_length, obj_s->XferOperation); } @@ -1169,6 +1215,7 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, } } else if (tx_length && rx_length) { /* Two steps operation, don't modify XferOperation, keep it for next step */ +#if defined(I2C_IP_VERSION_V1) // Trick to remove compiler warning "left and right operands are identical" in some cases uint32_t op1 = I2C_FIRST_AND_LAST_FRAME; uint32_t op2 = I2C_LAST_FRAME; @@ -1178,6 +1225,9 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, (obj_s->XferOperation == I2C_NEXT_FRAME)) { HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *)tx, tx_length, I2C_NEXT_FRAME); } +#elif defined(I2C_IP_VERSION_V2) + HAL_I2C_Master_Sequential_Transmit_IT(handle, address, (uint8_t *)tx, tx_length, I2C_FIRST_FRAME); +#endif } } diff --git a/targets/TARGET_STM/qspi_api.c b/targets/TARGET_STM/qspi_api.c index 67401fd79ad..bb71108b3d9 100644 --- a/targets/TARGET_STM/qspi_api.c +++ b/targets/TARGET_STM/qspi_api.c @@ -30,16 +30,154 @@ #include "qspi_api.h" #include "mbed_error.h" +#include "mbed_debug.h" #include "cmsis.h" #include "pinmap.h" #include "PeripheralPins.h" +// activate / de-activate debug +#define qspi_api_c_debug 0 + /* Max amount of flash size is 4Gbytes */ /* hence 2^(31+1), then FLASH_SIZE_DEFAULT = 1<<31 */ #define QSPI_FLASH_SIZE_DEFAULT 0x80000000 +#if defined(OCTOSPI1) +void qspi_prepare_command(const qspi_command_t *command, OSPI_RegularCmdTypeDef *st_command) +{ + debug_if(qspi_api_c_debug, "qspi_prepare_command In: instruction.value %x dummy_count %x address.bus_width %x address.disabled %x address.value %x address.size %x\n", + command->instruction.value, command->dummy_count, command->address.bus_width, command->address.disabled, command->address.value, command->address.size); + + st_command->FlashId = HAL_OSPI_FLASH_ID_1; + + switch (command->instruction.bus_width) { + case QSPI_CFG_BUS_SINGLE: + st_command->InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + break; + case QSPI_CFG_BUS_DUAL: + st_command->InstructionMode = HAL_OSPI_INSTRUCTION_2_LINES; + break; + case QSPI_CFG_BUS_QUAD: + st_command->InstructionMode = HAL_OSPI_INSTRUCTION_4_LINES; + break; + default: + st_command->InstructionMode = HAL_OSPI_INSTRUCTION_NONE; + break; + } + + st_command->InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + st_command->InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + st_command->Instruction = command->instruction.value; + st_command->DummyCycles = command->dummy_count; + // these are target specific settings, use default values + st_command->SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + st_command->DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + st_command->AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; + st_command->AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE; + st_command->DQSMode = HAL_OSPI_DQS_DISABLE; + + st_command->OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + if (command->address.disabled == true) { + st_command->AddressMode = HAL_OSPI_ADDRESS_NONE; + st_command->AddressSize = 0; + } else { + st_command->Address = command->address.value; + switch (command->address.bus_width) { + case QSPI_CFG_BUS_SINGLE: + st_command->AddressMode = HAL_OSPI_ADDRESS_1_LINE; + break; + case QSPI_CFG_BUS_DUAL: + st_command->AddressMode = HAL_OSPI_ADDRESS_2_LINES; + break; + case QSPI_CFG_BUS_QUAD: + st_command->AddressMode = HAL_OSPI_ADDRESS_4_LINES; + break; + default: + st_command->AddressMode = HAL_OSPI_ADDRESS_NONE; + break; + } + switch(command->address.size) { + case QSPI_CFG_ADDR_SIZE_8: + st_command->AddressSize = HAL_OSPI_ADDRESS_8_BITS; + break; + case QSPI_CFG_ADDR_SIZE_16: + st_command->AddressSize = HAL_OSPI_ADDRESS_16_BITS; + break; + case QSPI_CFG_ADDR_SIZE_24: + st_command->AddressSize = HAL_OSPI_ADDRESS_24_BITS; + break; + case QSPI_CFG_ADDR_SIZE_32: + st_command->AddressSize = HAL_OSPI_ADDRESS_32_BITS; + break; + default: + printf("Command param error: wrong address size\n"); + break; + } + } + + if (command->alt.disabled == true) { + st_command->AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + st_command->AlternateBytesSize = 0; + } else { + st_command->AlternateBytes = command->alt.value; + switch (command->alt.bus_width) { + case QSPI_CFG_BUS_SINGLE: + st_command->AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_1_LINE; + break; + case QSPI_CFG_BUS_DUAL: + st_command->AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_2_LINES; + break; + case QSPI_CFG_BUS_QUAD: + st_command->AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_4_LINES; + break; + default: + st_command->AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + break; + } + switch(command->alt.size) { + case QSPI_CFG_ALT_SIZE_8: + st_command->AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_8_BITS; + break; + case QSPI_CFG_ALT_SIZE_16: + st_command->AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_16_BITS; + break; + case QSPI_CFG_ALT_SIZE_24: + st_command->AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_24_BITS; + break; + case QSPI_CFG_ALT_SIZE_32: + st_command->AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_32_BITS; + break; + default: + st_command->AlternateBytesSize = 0; + printf("Command param error: wrong address size\n"); + break; + } + } + + switch (command->data.bus_width) { + case QSPI_CFG_BUS_SINGLE: + st_command->DataMode = HAL_OSPI_DATA_1_LINE; + break; + case QSPI_CFG_BUS_DUAL: + st_command->DataMode = HAL_OSPI_DATA_2_LINES; + break; + case QSPI_CFG_BUS_QUAD: + st_command->DataMode = HAL_OSPI_DATA_4_LINES; + break; + default: + st_command->DataMode = HAL_OSPI_DATA_NONE; + break; + } + + debug_if(qspi_api_c_debug, "qspi_prepare_command Out: InstructionMode %x Instruction %x AddressMode %x AddressSize %x Address %x DataMode %x\n", + st_command->InstructionMode, st_command->Instruction, st_command->AddressMode, st_command->AddressSize, st_command->Address, st_command->DataMode); +} +#else /* OCTOSPI */ void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st_command) { + debug_if(qspi_api_c_debug, "qspi_prepare_command In: instruction.value %x dummy_count %x address.bus_width %x address.disabled %x address.value %x address.size %x\n", + command->instruction.value, command->dummy_count, command->address.bus_width, command->address.disabled, command->address.value, command->address.size); + // TODO: shift these around to get more dynamic mapping switch (command->instruction.bus_width) { case QSPI_CFG_BUS_SINGLE: @@ -128,11 +266,115 @@ void qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTypeDef *st } st_command->NbData = 0; + debug_if(qspi_api_c_debug, "qspi_prepare_command Out: InstructionMode %x Instruction %x AddressMode %x AddressSize %x Address %x DataMode %x\n", + st_command->InstructionMode, st_command->Instruction, st_command->AddressMode, st_command->AddressSize, st_command->Address, st_command->DataMode); } +#endif /* OCTOSPI */ +#if defined(OCTOSPI1) 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) { + OSPIM_CfgTypeDef OSPIM_Cfg_Struct = {0}; + debug_if(qspi_api_c_debug, "qspi_init mode %u\n", mode); + + // Reset handle internal state + obj->handle.State = HAL_OSPI_STATE_RESET; + + // Set default OCTOSPI handle values + obj->handle.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE; + obj->handle.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON; + obj->handle.Init.ClockPrescaler = 4; + obj->handle.Init.FifoThreshold = 4; + obj->handle.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE; + obj->handle.Init.DeviceSize = POSITION_VAL(QSPI_FLASH_SIZE_DEFAULT) - 1; + obj->handle.Init.ChipSelectHighTime = 3; + obj->handle.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE; + obj->handle.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED; + obj->handle.Init.ClockMode = mode == 0 ? HAL_OSPI_CLOCK_MODE_0 : HAL_OSPI_CLOCK_MODE_3; + obj->handle.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE; + obj->handle.Init.ChipSelectBoundary = 0; + + QSPIName qspiio0name = (QSPIName)pinmap_peripheral(io0, PinMap_QSPI_DATA0); + QSPIName qspiio1name = (QSPIName)pinmap_peripheral(io1, PinMap_QSPI_DATA1); + QSPIName qspiio2name = (QSPIName)pinmap_peripheral(io2, PinMap_QSPI_DATA2); + QSPIName qspiio3name = (QSPIName)pinmap_peripheral(io3, PinMap_QSPI_DATA3); + 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) { + debug_if(qspi_api_c_debug, "QSPI_STATUS_INVALID_PARAMETER error\n"); + return QSPI_STATUS_INVALID_PARAMETER; + } + + // tested all combinations, take first + obj->qspi = qspi_data_third; + +#if defined(OCTOSPI1) + if(obj->qspi == QSPI_1) { + obj->handle.Instance = OCTOSPI1; + } +#endif +#if defined(OCTOSPI2) + if(obj->qspi == QSPI_2) { + obj->handle.Instance = OCTOSPI2; + } +#endif + +#if defined(OCTOSPI1) + if(obj->qspi == QSPI_1) { + __HAL_RCC_OSPI1_CLK_ENABLE(); + __HAL_RCC_OSPIM_CLK_ENABLE(); + __HAL_RCC_OSPI1_FORCE_RESET(); + __HAL_RCC_OSPI1_RELEASE_RESET(); + } +#endif +#if defined(OCTOSPI2) + if(obj->qspi == QSPI_2) { + __HAL_RCC_OSPI2_CLK_ENABLE(); + __HAL_RCC_OSPIM_CLK_ENABLE(); + __HAL_RCC_OSPI2_FORCE_RESET(); + __HAL_RCC_OSPI2_RELEASE_RESET(); + } +#endif + + // pinmap for pins (enable clock) + obj->io0 = io0; + pinmap_pinout(io0, PinMap_QSPI_DATA0); + obj->io1 = io1; + pinmap_pinout(io1, PinMap_QSPI_DATA1); + obj->io2 = io2; + pinmap_pinout(io2, PinMap_QSPI_DATA2); + obj->io3 = io3; + pinmap_pinout(io3, PinMap_QSPI_DATA3); + + obj->sclk = sclk; + pinmap_pinout(sclk, PinMap_QSPI_SCLK); + obj->ssel = ssel; + pinmap_pinout(ssel, PinMap_QSPI_SSEL); + + OSPIM_Cfg_Struct.ClkPort = 2; + OSPIM_Cfg_Struct.DQSPort = 2; + OSPIM_Cfg_Struct.NCSPort = 2; + OSPIM_Cfg_Struct.IOLowPort = HAL_OSPIM_IOPORT_2_LOW; + OSPIM_Cfg_Struct.IOHighPort = HAL_OSPIM_IOPORT_2_HIGH; + if (HAL_OSPIM_Config(&obj->handle, &OSPIM_Cfg_Struct, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + debug_if(qspi_api_c_debug, "HAL_OSPIM_Config error\n"); + return QSPI_STATUS_ERROR; + } + + return qspi_frequency(obj, hz); +} +#else /* OCTOSPI */ +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) +{ + debug_if(qspi_api_c_debug, "qspi_init mode %u\n", mode); // Enable interface clock for QSPI __HAL_RCC_QSPI_CLK_ENABLE(); @@ -194,7 +436,42 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN return qspi_frequency(obj, hz); } +#endif /* OCTOSPI */ + + +#if defined(OCTOSPI1) +qspi_status_t qspi_free(qspi_t *obj) +{ + debug_if(qspi_api_c_debug, "qspi_free\n"); + if (HAL_OSPI_DeInit(&obj->handle) != HAL_OK) { + return QSPI_STATUS_ERROR; + } + +#if defined(OCTOSPI1) + if(obj->qspi == QSPI_1) { + __HAL_RCC_OSPI1_FORCE_RESET(); + __HAL_RCC_OSPI1_CLK_DISABLE(); + } +#endif +#if defined(OCTOSPI2) + if(obj->qspi == QSPI_2) { + __HAL_RCC_OSPI2_FORCE_RESET(); + __HAL_RCC_OSPI2_CLK_DISABLE(); + } +#endif + + // 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; +} +#else /* OCTOSPI */ qspi_status_t qspi_free(qspi_t *obj) { if (HAL_QSPI_DeInit(&obj->handle) != HAL_OK) { @@ -219,9 +496,44 @@ qspi_status_t qspi_free(qspi_t *obj) (void)(obj); return QSPI_STATUS_OK; } +#endif /* OCTOSPI */ + +#if defined(OCTOSPI1) qspi_status_t qspi_frequency(qspi_t *obj, int hz) { + debug_if(qspi_api_c_debug, "qspi_frequency hz %d\n", hz); + qspi_status_t status = QSPI_STATUS_OK; + + /* HCLK drives QSPI. QSPI clock depends on prescaler value: + * 0: Freq = HCLK + * 1: Freq = HCLK/2 + * ... + * 255: Freq = HCLK/256 (minimum value) + */ + + int div = HAL_RCC_GetHCLKFreq() / hz; + if (div > 255) { + div = 255; + } else { + if ((HAL_RCC_GetHCLKFreq() % hz) == 0) { + div = div - 1; + } + } + + obj->handle.Init.ClockPrescaler = div; + + if (HAL_OSPI_Init(&obj->handle) != HAL_OK) { + debug_if(qspi_api_c_debug, "HAL_OSPI_Init error\n"); + status = QSPI_STATUS_ERROR; + } + + return status; +} +#else /* OCTOSPI */ +qspi_status_t qspi_frequency(qspi_t *obj, int hz) +{ + debug_if(qspi_api_c_debug, "qspi_frequency hz %d\n", hz); qspi_status_t status = QSPI_STATUS_OK; /* HCLK drives QSPI. QSPI clock depends on prescaler value: @@ -248,7 +560,33 @@ qspi_status_t qspi_frequency(qspi_t *obj, int hz) return status; } +#endif /* OCTOSPI */ + +#if defined(OCTOSPI1) +qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void *data, size_t *length) +{ + debug_if(qspi_api_c_debug, "qspi_write size %u\n", *length); + + OSPI_RegularCmdTypeDef st_command; + qspi_prepare_command(command, &st_command); + + st_command.NbData = *length; + qspi_status_t status = QSPI_STATUS_OK; + + if (HAL_OSPI_Command(&obj->handle, &st_command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + debug_if(qspi_api_c_debug, "HAL_OSPI_Command error\n"); + status = QSPI_STATUS_ERROR; + } else { + if (HAL_OSPI_Transmit(&obj->handle, (uint8_t *)data, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + debug_if(qspi_api_c_debug, "HAL_OSPI_Transmit error\n"); + status = QSPI_STATUS_ERROR; + } + } + + return status; +} +#else /* OCTOSPI */ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void *data, size_t *length) { QSPI_CommandTypeDef st_command; @@ -265,9 +603,37 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void } } + debug_if(qspi_api_c_debug, "qspi_write size %u\n", *length); + return status; } +#endif /* OCTOSPI */ + +#if defined(OCTOSPI1) +qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t *length) +{ + OSPI_RegularCmdTypeDef st_command; + qspi_prepare_command(command, &st_command); + + st_command.NbData = *length; + qspi_status_t status = QSPI_STATUS_OK; + + if (HAL_OSPI_Command(&obj->handle, &st_command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + debug_if(qspi_api_c_debug, "HAL_OSPI_Command error\n"); + status = QSPI_STATUS_ERROR; + } else { + if (HAL_OSPI_Receive(&obj->handle, data, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + debug_if(qspi_api_c_debug, "HAL_OSPI_Receive error\n"); + status = QSPI_STATUS_ERROR; + } + } + + debug_if(qspi_api_c_debug, "qspi_read size %u\n", *length); + + return status; +} +#else /* OCTOSPI */ qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t *length) { QSPI_CommandTypeDef st_command; @@ -284,11 +650,54 @@ qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, } } + debug_if(qspi_api_c_debug, "qspi_read size %u\n", *length); + return status; } +#endif /* OCTOSPI */ + + +#if defined(OCTOSPI1) +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) +{ + debug_if(qspi_api_c_debug, "qspi_command_transfer tx %u rx %u command %x\n", tx_size, rx_size, command->instruction.value); + qspi_status_t status = QSPI_STATUS_OK; + if ((tx_data == NULL || tx_size == 0) && (rx_data == NULL || rx_size == 0)) { + // only command, no rx or tx + OSPI_RegularCmdTypeDef st_command; + qspi_prepare_command(command, &st_command); + + st_command.NbData = 1; + st_command.DataMode = HAL_OSPI_DATA_NONE; /* Instruction only */ + if (HAL_OSPI_Command(&obj->handle, &st_command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + status = QSPI_STATUS_ERROR; + debug_if(qspi_api_c_debug, "HAL_OSPI_Command error\n"); + 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) { + debug_if(qspi_api_c_debug, "qspi_write error\n"); + return status; + } + } + + if (rx_data != NULL && rx_size) { + size_t rx_length = rx_size; + status = qspi_read(obj, command, rx_data, &rx_length); + // debug_if(qspi_api_c_debug, "qspi_read %d\n", status); + } + } + return status; +} +#else /* OCTOSPI */ 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) { + debug_if(qspi_api_c_debug, "qspi_command_transfer tx %u rx %u command %x\n", tx_size, rx_size, command->instruction.value); qspi_status_t status = QSPI_STATUS_OK; if ((tx_data == NULL || tx_size == 0) && (rx_data == NULL || rx_size == 0)) { @@ -319,6 +728,8 @@ qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command, } return status; } +#endif /* OCTOSPI */ + const PinMap *qspi_master_sclk_pinmap() { diff --git a/targets/targets.json b/targets/targets.json index 7183da0a76e..1e4f52ffd26 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -8052,6 +8052,9 @@ "value": 1 } }, + "components_add": [ + "FLASHIAP" + ], "macros_add": [ "STM32L4R9xx", "MBED_TICKLESS", @@ -8066,6 +8069,7 @@ "SERIAL_ASYNCH", "TRNG", "FLASH", + "QSPI", "MPU" ], "release_versions": ["2", "5"],