mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Merge pull request #7783 from maciejbocianski/feature-qspi_merging
merge QSPI feature branchpull/7880/head
						commit
						812c6d5c88
					
				| 
						 | 
					@ -0,0 +1,192 @@
 | 
				
			||||||
 | 
					/* 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 "macronix MX25R6435F"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Command for reading status register
 | 
				
			||||||
 | 
					#define QSPI_CMD_RDSR                           0x05
 | 
				
			||||||
 | 
					// Command for reading configuration register
 | 
				
			||||||
 | 
					#define QSPI_CMD_RDCR0                          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                      100000  // 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            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_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
 | 
				
			||||||
 | 
					#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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// single quad enable flag for both dual and quad mode
 | 
				
			||||||
 | 
					#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);                                          \
 | 
				
			||||||
 | 
					                                                                            \
 | 
				
			||||||
 | 
					    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()                                                      \
 | 
				
			||||||
 | 
					                                                                            \
 | 
				
			||||||
 | 
					    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);                                          \
 | 
				
			||||||
 | 
					                                                                            \
 | 
				
			||||||
 | 
					    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()                                                  \
 | 
				
			||||||
 | 
					                                                                            \
 | 
				
			||||||
 | 
					    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
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					@ -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 "../../MX25R6435F_config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // MBED_QSPI_FLASH_CONFIG_H
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					/* 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"
 | 
				
			||||||
 | 
					#elif defined(TARGET_DISCO_F413ZH)
 | 
				
			||||||
 | 
					#include "STM/DISCO_F413ZH/flash_config.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // MBED_FLASH_CONFIGS_H
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,468 @@
 | 
				
			||||||
 | 
					/* 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] QSPI not supported for this target
 | 
				
			||||||
 | 
					#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"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(QSPI_FLASH_CHIP_STRING)
 | 
				
			||||||
 | 
					#error [NOT_SUPPORTED] QSPI test not supported for this target
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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<PinName>(QSPI_PIN_IO0)
 | 
				
			||||||
 | 
					#define QPIN_1 static_cast<PinName>(QSPI_PIN_IO1)
 | 
				
			||||||
 | 
					#define QPIN_2 static_cast<PinName>(QSPI_PIN_IO2)
 | 
				
			||||||
 | 
					#define QPIN_3 static_cast<PinName>(QSPI_PIN_IO3)
 | 
				
			||||||
 | 
					#define QSCK   static_cast<PinName>(QSPI_PIN_SCK)
 | 
				
			||||||
 | 
					#define QCSN   static_cast<PinName>(QSPI_PIN_CSN)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void log_data(const char *str, uint8_t *data, uint32_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    utest_printf("%s: ", str);
 | 
				
			||||||
 | 
					    for (uint32_t j = 0; j < size; j++) {
 | 
				
			||||||
 | 
					        utest_printf("%02X ", data[j]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    utest_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 = 0, write_time = 0, read_time = 0;
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
 | 
					        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.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();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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);
 | 
				
			||||||
 | 
					                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
 | 
				
			||||||
 | 
					        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);
 | 
				
			||||||
 | 
					        utest_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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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 = 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)) {
 | 
				
			||||||
 | 
					        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
 | 
				
			||||||
 | 
					    //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 register 1:\r\n");
 | 
				
			||||||
 | 
					    log_register(CONFIG_REG1, QSPI_CONFIG_REG_1_SIZE, qspi, "Config register 1");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef CONFIG_REG2
 | 
				
			||||||
 | 
					    //utest_printf("Config register 2:\r\n");
 | 
				
			||||||
 | 
					    log_register(CONFIG_REG2, QSPI_CONFIG_REG_2_SIZE, qspi, "Config register 2");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#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.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 = 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 = quad_disable(qspi);
 | 
				
			||||||
 | 
					        TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
 | 
				
			||||||
 | 
					        WAIT_FOR(WRSR_MAX_TIME, qspi);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef QSPI_TEST_LOG_FLASH_STATUS
 | 
				
			||||||
 | 
					    //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 register 1:\r\n");
 | 
				
			||||||
 | 
					    log_register(CONFIG_REG1, QSPI_CONFIG_REG_1_SIZE, qspi, "Config register 1");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef CONFIG_REG2
 | 
				
			||||||
 | 
					    //utest_printf("Config register 2:\r\n");
 | 
				
			||||||
 | 
					    log_register(CONFIG_REG2, QSPI_CONFIG_REG_2_SIZE, qspi, "Config register 2");
 | 
				
			||||||
 | 
					#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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    utest_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<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>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x4  read(1-1-1)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-1-1)/x4  repeat/x1  test", qspi_write_read_test<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_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-1-1)/x1  repeat/x16 test", qspi_write_read_test<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_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-1-2)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x4  read(1-1-2)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_1_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-1-2)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-1-2)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-2-2)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x4  read(1-2-2)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-2-2)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-2-2)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-1-4)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x4  read(1-1-4)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_1_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-1-4)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-1-4)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-4-4)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x4  read(1-4-4)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-4-4)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-1-1)/x1  read(1-4-4)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					#ifdef QSPI_CMD_WRITE_2IO
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-1-1)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, 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>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x4  read(1-1-1)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-1-1)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, 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_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-1-1)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_2_2, 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_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-1-2)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x4  read(1-1-2)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_1_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-1-2)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-1-2)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-2-2)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x4  read(1-2-2)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-2-2)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-2-2)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-1-4)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x4  read(1-1-4)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_1_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-1-4)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-1-4)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-4-4)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x4  read(1-4-4)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-4-4)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-2-2)/x1  read(1-4-4)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					#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<WRITE_1_4_4, 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>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x4  read(1-1-1)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_1_1, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-1-1)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, 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_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-1-1)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_4_4, 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_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-1-2)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x4  read(1-1-2)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_1_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-1-2)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-1-2)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-2-2)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x4  read(1-2-2)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-2-2)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-2-2)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_2_2, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-1-4)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x4  read(1-1-4)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_1_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-1-4)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-1-4)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_1_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-4-4)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x4  read(1-4-4)/x1  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_MULTIPLE, READ_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_SINGLE,   DATA_SIZE_1024, TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-4-4)/x4  repeat/x1  test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_MULTIPLE, TEST_REPEAT_SINGLE,   DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					    Case("qspi write(1-4-4)/x1  read(1-4-4)/x1  repeat/x16 test", qspi_write_read_test<WRITE_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, WRITE_SINGLE,   READ_1_4_4, ADDR_SIZE_24, ALT_SIZE_8, QSPI_COMMON_MAX_FREQUENCY, READ_SINGLE,   TEST_REPEAT_MULTIPLE, DATA_SIZE_256,  TEST_FLASH_ADDRESS>),
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GREENTEA_SETUP(180, "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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** @}*/
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,233 @@
 | 
				
			||||||
 | 
					/* 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 "utest/utest.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "hal/qspi_api.h"
 | 
				
			||||||
 | 
					#include "qspi_test_utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "unity/unity.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h> // for memset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "flash_configs/flash_configs.h"
 | 
				
			||||||
 | 
					#include "mbed.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t reg[QSPI_STATUS_REG_SIZE];
 | 
				
			||||||
 | 
					    qspi_status_t ret;
 | 
				
			||||||
 | 
					    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_REG_SIZE, qspi);
 | 
				
			||||||
 | 
					        curr_time = ticker_read(ticker);
 | 
				
			||||||
 | 
					    } while (((reg[0] & STATUS_BIT_WIP) != 0) && ((curr_time - start) < time_us));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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[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, QSPI_STATUS_REG_SIZE);
 | 
				
			||||||
 | 
					    TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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_REG_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_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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qspi_status_t write_disable(Qspi &qspi)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    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) {
 | 
				
			||||||
 | 
					        return QSPI_STATUS_ERROR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    WAIT_FOR(WRSR_MAX_TIME, qspi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = read_register(cmd, reg, reg_size, qspi);
 | 
				
			||||||
 | 
					    TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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++) {
 | 
				
			||||||
 | 
					            utest_printf("%s ", ((reg[j] & (1 << (7 - i))) & 0xFF) == 0 ? "0" : "1");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        utest_printf("\r\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					    DUAL_ENABLE();
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    QUAD_ENABLE();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qspi_status_t dual_disable(Qspi &qspi)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef DUAL_DISABLE
 | 
				
			||||||
 | 
					    DUAL_DISABLE();
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    QUAD_DISABLE();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qspi_status_t quad_enable(Qspi &qspi)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    QUAD_ENABLE();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qspi_status_t quad_disable(Qspi &qspi)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    QUAD_DISABLE();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qspi_status_t fast_mode_enable(Qspi &qspi)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    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)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,147 @@
 | 
				
			||||||
 | 
					/* 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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum QspiStatus {
 | 
				
			||||||
 | 
					    sOK,
 | 
				
			||||||
 | 
					    sError,
 | 
				
			||||||
 | 
					    sTimeout,
 | 
				
			||||||
 | 
					    sUnknown
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void build(int instruction, int address = QSPI_NONE, int alt = QSPI_NONE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qspi_command_t *get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    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_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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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_REG0      QSPI_CMD_RDCR0
 | 
				
			||||||
 | 
					#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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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);
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void flash_init(Qspi &qspi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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, const char *str = NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
| 
						 | 
					@ -2093,6 +2093,7 @@ PREDEFINED             = DOXYGEN_ONLY            \
 | 
				
			||||||
                         DEVICE_SPI              \
 | 
					                         DEVICE_SPI              \
 | 
				
			||||||
                         DEVICE_SPI_ASYNCH       \
 | 
					                         DEVICE_SPI_ASYNCH       \
 | 
				
			||||||
                         DEVICE_SPISLAVE         \
 | 
					                         DEVICE_SPISLAVE         \
 | 
				
			||||||
 | 
					                         DEVICE_QSPI             \
 | 
				
			||||||
                         DEVICE_STORAGE          \
 | 
					                         DEVICE_STORAGE          \
 | 
				
			||||||
                         "MBED_DEPRECATED_SINCE(d, m)=" \
 | 
					                         "MBED_DEPRECATED_SINCE(d, m)=" \
 | 
				
			||||||
                         "MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M)=" \
 | 
					                         "MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M)=" \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@
 | 
				
			||||||
    "SEARCH_INCLUDES": "YES",
 | 
					    "SEARCH_INCLUDES": "YES",
 | 
				
			||||||
    "INCLUDE_PATH": "",
 | 
					    "INCLUDE_PATH": "",
 | 
				
			||||||
    "INCLUDE_FILE_PATTERNS": "",
 | 
					    "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": "",
 | 
					    "EXPAND_AS_DEFINED": "",
 | 
				
			||||||
    "SKIP_FUNCTION_MACROS": "NO",
 | 
					    "SKIP_FUNCTION_MACROS": "NO",
 | 
				
			||||||
    "STRIP_CODE_COMMENTS": "NO",
 | 
					    "STRIP_CODE_COMMENTS": "NO",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,288 @@
 | 
				
			||||||
 | 
					/* 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "drivers/QSPI.h"
 | 
				
			||||||
 | 
					#include "platform/mbed_critical.h"
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DEVICE_QSPI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace mbed {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QSPI *QSPI::_owner = NULL;
 | 
				
			||||||
 | 
					SingletonPtr<PlatformMutex> QSPI::_mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel, int mode) : _qspi()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _qspi_io0 = io0;
 | 
				
			||||||
 | 
					    _qspi_io1 = io1;
 | 
				
			||||||
 | 
					    _qspi_io2 = io2;
 | 
				
			||||||
 | 
					    _qspi_io3 = io3;
 | 
				
			||||||
 | 
					    _qspi_clk = sclk;
 | 
				
			||||||
 | 
					    _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_8;
 | 
				
			||||||
 | 
					    _data_width = QSPI_CFG_BUS_SINGLE;
 | 
				
			||||||
 | 
					    _num_dummy_cycles = 0;
 | 
				
			||||||
 | 
					    _mode = mode;
 | 
				
			||||||
 | 
					    _hz = ONE_MHZ;
 | 
				
			||||||
 | 
					    _initialized = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //Go ahead init the device here with the default config
 | 
				
			||||||
 | 
					    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)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    qspi_status_t ret_status = QSPI_STATUS_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
 | 
					    _num_dummy_cycles = dummy_cycles;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret_status;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qspi_status_t QSPI::set_frequency(int hz)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    qspi_status_t 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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            _acquire();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        unlock();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_initialized) {
 | 
				
			||||||
 | 
					        if ((rx_length != NULL) && (rx_buffer != NULL)) {
 | 
				
			||||||
 | 
					            if (*rx_length != 0) {
 | 
				
			||||||
 | 
					                lock();
 | 
				
			||||||
 | 
					                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;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                unlock();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_initialized) {
 | 
				
			||||||
 | 
					        if ((tx_length != NULL) && (tx_buffer != NULL)) {
 | 
				
			||||||
 | 
					            if (*tx_length != 0) {
 | 
				
			||||||
 | 
					                lock();
 | 
				
			||||||
 | 
					                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;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                unlock();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            ret_status = QSPI_STATUS_INVALID_PARAMETER;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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 ret_status = QSPI_STATUS_ERROR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_initialized) {
 | 
				
			||||||
 | 
					        if ((rx_length != NULL) && (rx_buffer != NULL)) {
 | 
				
			||||||
 | 
					            if (*rx_length != 0) {
 | 
				
			||||||
 | 
					                lock();
 | 
				
			||||||
 | 
					                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;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                unlock();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            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 ret_status = QSPI_STATUS_ERROR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_initialized) {
 | 
				
			||||||
 | 
					        if ((tx_length != NULL) && (tx_buffer != NULL)) {
 | 
				
			||||||
 | 
					            if (*tx_length != 0) {
 | 
				
			||||||
 | 
					                lock();
 | 
				
			||||||
 | 
					                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;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                unlock();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            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 ret_status = QSPI_STATUS_ERROR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_initialized) {
 | 
				
			||||||
 | 
					        lock();
 | 
				
			||||||
 | 
					        if (true == _acquire()) {
 | 
				
			||||||
 | 
					            _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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        unlock();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret_status;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void QSPI::lock()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _mutex->lock();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void QSPI::unlock()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _mutex->unlock();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Note: Private helper function to initialize qspi HAL
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					    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
 | 
				
			||||||
 | 
					        _initialize();
 | 
				
			||||||
 | 
					        _owner = this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return _initialized;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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) {
 | 
				
			||||||
 | 
					        _qspi_command.instruction.value = instruction;
 | 
				
			||||||
 | 
					        _qspi_command.instruction.disabled = false;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        _qspi_command.instruction.disabled = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //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.disabled = false;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        _qspi_command.address.disabled = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //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;
 | 
				
			||||||
 | 
					        _qspi_command.alt.disabled = false;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        _qspi_command.alt.disabled = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _qspi_command.dummy_count = _num_dummy_cycles;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //Set up bus width for data phase
 | 
				
			||||||
 | 
					    _qspi_command.data.bus_width = _data_width;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace mbed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,224 @@
 | 
				
			||||||
 | 
					/* 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_QSPI_H
 | 
				
			||||||
 | 
					#define MBED_QSPI_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "platform/platform.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined (DEVICE_QSPI) || defined(DOXYGEN_ONLY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "hal/qspi_api.h"
 | 
				
			||||||
 | 
					#include "platform/PlatformMutex.h"
 | 
				
			||||||
 | 
					#include "platform/SingletonPtr.h"
 | 
				
			||||||
 | 
					#include "platform/NonCopyable.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @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(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() {
 | 
				
			||||||
 | 
					 *     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<QSPI> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 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
 | 
				
			||||||
 | 
					     *  @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, int mode = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** Configure the data transmission format
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *  @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
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    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
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *  @param hz SCLK frequency in hz (default = 1MHz)
 | 
				
			||||||
 | 
					     *  @returns
 | 
				
			||||||
 | 
					     *    Returns QSPI_STATUS_SUCCESS on successful, fails if the interface is already init-ed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    qspi_status_t set_frequency(int hz = ONE_MHZ);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** 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 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** 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_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 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 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 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 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 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
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *  @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
 | 
				
			||||||
 | 
					     *  @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 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** 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<PlatformMutex> _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
 | 
				
			||||||
 | 
					    unsigned 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:
 | 
				
			||||||
 | 
					    /* Private acquire function without locking/unlocking
 | 
				
			||||||
 | 
					     * 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
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    inline void _build_qspi_command(int instruction, int address, int alt);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace mbed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,194 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** \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"
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DEVICE_QSPI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \defgroup hal_qspi QSPI HAL
 | 
				
			||||||
 | 
					 * @{
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** QSPI HAL object
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					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 in bits
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					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 in bits
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Defines a frame format. It consists of instruction, address, alternative, dummy count and data
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					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 {
 | 
				
			||||||
 | 
					        qspi_bus_width_t bus_width; /**< Bus width for data >*/
 | 
				
			||||||
 | 
					    } 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, 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
 | 
				
			||||||
 | 
					 * @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 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
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					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 a command and block of data
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param obj QSPI object
 | 
				
			||||||
 | 
					 * @param command QSPI command
 | 
				
			||||||
 | 
					 * @param data TX buffer
 | 
				
			||||||
 | 
					 * @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
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param obj QSPI object
 | 
				
			||||||
 | 
					 * @param command QSPI command
 | 
				
			||||||
 | 
					 * @param tx_data TX buffer
 | 
				
			||||||
 | 
					 * @param tx_size TX buffer length in bytes
 | 
				
			||||||
 | 
					 * @param rx_data RX buffer
 | 
				
			||||||
 | 
					 * @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
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					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] 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
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t *length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**@}*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** @}*/
 | 
				
			||||||
| 
						 | 
					@ -227,6 +227,13 @@ typedef enum {
 | 
				
			||||||
    A4 = p30,
 | 
					    A4 = p30,
 | 
				
			||||||
    A5 = p31,
 | 
					    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
 | 
					    // Not connected
 | 
				
			||||||
    NC = (int)0xFFFFFFFF
 | 
					    NC = (int)0xFFFFFFFF
 | 
				
			||||||
} PinName;
 | 
					} PinName;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2748,6 +2748,136 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// </e>
 | 
					// </e>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <e> QSPI_ENABLED - nrf_drv_qspi - QSPI peripheral driver.
 | 
				
			||||||
 | 
					//==========================================================
 | 
				
			||||||
 | 
					#ifndef QSPI_ENABLED
 | 
				
			||||||
 | 
					#define QSPI_ENABLED 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if  QSPI_ENABLED
 | 
				
			||||||
 | 
					// <o> 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <o> 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <o> 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <o> QSPI_CONFIG_ADDRMODE  - Addressing mode.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <0=> 24bit
 | 
				
			||||||
 | 
					// <1=> 32bit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef QSPI_CONFIG_ADDRMODE
 | 
				
			||||||
 | 
					#define QSPI_CONFIG_ADDRMODE 0
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <o> QSPI_CONFIG_MODE  - SPI mode.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <0=> Mode 0
 | 
				
			||||||
 | 
					// <1=> Mode 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef QSPI_CONFIG_MODE
 | 
				
			||||||
 | 
					#define QSPI_CONFIG_MODE 0
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <o> 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <s> QSPI_PIN_SCK - SCK pin value.
 | 
				
			||||||
 | 
					#ifndef QSPI_PIN_SCK
 | 
				
			||||||
 | 
					#define QSPI_PIN_SCK NRF_QSPI_PIN_NOT_CONNECTED
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <s> QSPI_PIN_CSN - CSN pin value.
 | 
				
			||||||
 | 
					#ifndef QSPI_PIN_CSN
 | 
				
			||||||
 | 
					#define QSPI_PIN_CSN NRF_QSPI_PIN_NOT_CONNECTED
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <s> QSPI_PIN_IO0 - IO0 pin value.
 | 
				
			||||||
 | 
					#ifndef QSPI_PIN_IO0
 | 
				
			||||||
 | 
					#define QSPI_PIN_IO0 NRF_QSPI_PIN_NOT_CONNECTED
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <s> QSPI_PIN_IO1 - IO1 pin value.
 | 
				
			||||||
 | 
					#ifndef QSPI_PIN_IO1
 | 
				
			||||||
 | 
					#define QSPI_PIN_IO1 NRF_QSPI_PIN_NOT_CONNECTED
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <s> QSPI_PIN_IO2 - IO2 pin value.
 | 
				
			||||||
 | 
					#ifndef QSPI_PIN_IO2
 | 
				
			||||||
 | 
					#define QSPI_PIN_IO2 NRF_QSPI_PIN_NOT_CONNECTED
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <s> QSPI_PIN_IO3 - IO3 pin value.
 | 
				
			||||||
 | 
					#ifndef QSPI_PIN_IO3
 | 
				
			||||||
 | 
					#define QSPI_PIN_IO3 NRF_QSPI_PIN_NOT_CONNECTED
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <o> QSPI_CONFIG_IRQ_PRIORITY  - Interrupt priority
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <i> 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// </e>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// </e>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// <e> TIMER_ENABLED - nrf_drv_timer - TIMER periperal driver
 | 
					// <e> TIMER_ENABLED - nrf_drv_timer - TIMER periperal driver
 | 
				
			||||||
//==========================================================
 | 
					//==========================================================
 | 
				
			||||||
#ifndef TIMER_ENABLED
 | 
					#ifndef TIMER_ENABLED
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,6 +142,17 @@ struct flash_s {
 | 
				
			||||||
    uint32_t placeholder;
 | 
					    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"
 | 
					#include "gpio_object.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,348 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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
 | 
				
			||||||
 | 
					static ret_code_t _qspi_drv_init(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qspi_status_t qspi_prepare_command(qspi_t *obj, const qspi_command_t *command, bool write) 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // 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) {
 | 
				
			||||||
 | 
					            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;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // 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 {
 | 
				
			||||||
 | 
					        return QSPI_STATUS_INVALID_PARAMETER;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    //Configure QSPI with new command format
 | 
				
			||||||
 | 
					    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 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)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    (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 = (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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //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) {
 | 
				
			||||||
 | 
					        return QSPI_STATUS_INVALID_PARAMETER;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return QSPI_STATUS_ERROR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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  = (nrf_qspi_frequency_t)MBED_HAL_QSPI_HZ_TO_CONFIG(hz);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // use sync version, no handler
 | 
				
			||||||
 | 
					    ret_code_t ret = _qspi_drv_init();
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					    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 = true;
 | 
				
			||||||
 | 
					    qspi_cinstr_config.io3_level = true;
 | 
				
			||||||
 | 
					    qspi_cinstr_config.wipwait   = false;
 | 
				
			||||||
 | 
					    qspi_cinstr_config.wren      = false;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    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 (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];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** @}*/
 | 
				
			||||||
| 
						 | 
					@ -80,4 +80,10 @@ extern const PinMap PinMap_CAN_RD[];
 | 
				
			||||||
extern const PinMap PinMap_CAN_TD[];
 | 
					extern const PinMap PinMap_CAN_TD[];
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEVICE_QSPI
 | 
				
			||||||
 | 
					extern const PinMap PinMap_QSPI_DATA[];
 | 
				
			||||||
 | 
					extern const PinMap PinMap_QSPI_SCLK[];
 | 
				
			||||||
 | 
					extern const PinMap PinMap_QSPI_SSEL[];
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,6 +68,10 @@ typedef enum {
 | 
				
			||||||
    CAN_2 = (int)CAN2_BASE
 | 
					    CAN_2 = (int)CAN2_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)},
 | 
					    {PG_12,      CAN_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)},
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,6 +79,10 @@ typedef enum {
 | 
				
			||||||
    CAN_3 = (int)CAN3_BASE
 | 
					    CAN_3 = (int)CAN3_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)}, // Connected to WIFI_DRDY
 | 
					    {PG_12,      CAN_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)}, // Connected to WIFI_DRDY
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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 // 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)},  // 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 // 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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -303,6 +303,14 @@ typedef enum {
 | 
				
			||||||
    SYS_WKUP2 = PC_0,
 | 
					    SYS_WKUP2 = PC_0,
 | 
				
			||||||
    SYS_WKUP3 = PC_1,
 | 
					    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
 | 
					    // Not connected
 | 
				
			||||||
    NC = (int)0xFFFFFFFF
 | 
					    NC = (int)0xFFFFFFFF
 | 
				
			||||||
} PinName;
 | 
					} PinName;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,6 +79,10 @@ typedef enum {
 | 
				
			||||||
    CAN_3 = (int)CAN3_BASE
 | 
					    CAN_3 = (int)CAN3_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)},
 | 
					    {PG_12,      CAN_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)},
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,16 @@ struct trng_s {
 | 
				
			||||||
    RNG_HandleTypeDef handle;
 | 
					    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"
 | 
					#include "common_objects.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,6 +89,10 @@ typedef enum {
 | 
				
			||||||
    CAN_2 = (int)CAN2_BASE
 | 
					    CAN_2 = (int)CAN2_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)},
 | 
					    {PB_13,      CAN_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)},
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,6 +89,10 @@ typedef enum {
 | 
				
			||||||
    CAN_2 = (int)CAN2_BASE
 | 
					    CAN_2 = (int)CAN2_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)},
 | 
					    {PD_1,       CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,6 +92,10 @@ typedef enum {
 | 
				
			||||||
    CAN_2 = (int)CAN2_BASE
 | 
					    CAN_2 = (int)CAN2_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -388,3 +388,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
 | 
					    {PH_13,      CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, // Connected to D21
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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 // 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[] = {
 | 
				
			||||||
 | 
					    {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)},  // 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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -406,6 +406,13 @@ typedef enum {
 | 
				
			||||||
    SYS_TRACED3_ALT0 = PE_6,
 | 
					    SYS_TRACED3_ALT0 = PE_6,
 | 
				
			||||||
    SYS_WKUP = PA_0,
 | 
					    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
 | 
					    // Not connected
 | 
				
			||||||
    NC = (int)0xFFFFFFFF
 | 
					    NC = (int)0xFFFFFFFF
 | 
				
			||||||
} PinName;
 | 
					} PinName;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,16 @@ struct trng_s {
 | 
				
			||||||
    RNG_HandleTypeDef handle;
 | 
					    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"
 | 
					#include "common_objects.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,6 +93,10 @@ typedef enum {
 | 
				
			||||||
    CAN_2 = (int)CAN2_BASE
 | 
					    CAN_2 = (int)CAN2_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -406,3 +406,41 @@ 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
 | 
					    {PH_13,      CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, // Connected to DCMI_PWR_EN
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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]
 | 
				
			||||||
 | 
					    {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)},  // 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)},  // 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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,6 +93,10 @@ typedef enum {
 | 
				
			||||||
    CAN_2 = (int)CAN2_BASE
 | 
					    CAN_2 = (int)CAN2_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)},
 | 
					    {PD_1,       CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,16 @@ struct trng_s {
 | 
				
			||||||
    RNG_HandleTypeDef handle;
 | 
					    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"
 | 
					#include "common_objects.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,6 +93,10 @@ typedef enum {
 | 
				
			||||||
    CAN_2 = (int)CAN2_BASE
 | 
					    CAN_2 = (int)CAN2_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)},
 | 
					    {PD_1,       CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,6 +94,10 @@ typedef enum {
 | 
				
			||||||
    CAN_3 = (int)CAN3_BASE
 | 
					    CAN_3 = (int)CAN3_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)},
 | 
					    {PD_1,       CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,6 +94,10 @@ typedef enum {
 | 
				
			||||||
    CAN_3 = (int)CAN3_BASE
 | 
					    CAN_3 = (int)CAN3_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
					    {PH_13,      CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, // Connected to D21
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,6 +71,10 @@ typedef enum {
 | 
				
			||||||
    CAN_1 = (int)CAN1_BASE
 | 
					    CAN_1 = (int)CAN1_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)},
 | 
					    {PA_12,      CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -76,6 +76,10 @@ typedef enum {
 | 
				
			||||||
    CAN_1 = (int)CAN1_BASE
 | 
					    CAN_1 = (int)CAN1_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)},
 | 
					    {PB_9,       CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,6 +83,10 @@ typedef enum {
 | 
				
			||||||
    CAN_1 = (int)CAN1_BASE
 | 
					    CAN_1 = (int)CAN1_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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 PMOD_SPI2_SCK
 | 
					    {PD_1,       CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, // Connected to PMOD_SPI2_SCK
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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 // 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[] = {
 | 
				
			||||||
 | 
					    {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[] = {
 | 
				
			||||||
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -240,6 +240,14 @@ typedef enum {
 | 
				
			||||||
    SPI_SCK     = D13,
 | 
					    SPI_SCK     = D13,
 | 
				
			||||||
    SPI_CS      = D10,
 | 
					    SPI_CS      = D10,
 | 
				
			||||||
    PWM_OUT     = D9,
 | 
					    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 pins ****/
 | 
				
			||||||
    USB_OTG_FS_DM = PA_11,
 | 
					    USB_OTG_FS_DM = PA_11,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,16 @@ struct trng_s {
 | 
				
			||||||
    RNG_HandleTypeDef handle;
 | 
					    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"
 | 
					#include "common_objects.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,6 +83,10 @@ typedef enum {
 | 
				
			||||||
    CAN_1 = (int)CAN1_BASE
 | 
					    CAN_1 = (int)CAN1_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_R_BASE,
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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]
 | 
					    {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}
 | 
					    {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 // 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)},  // 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)},  // 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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,6 +83,10 @@ typedef enum {
 | 
				
			||||||
    CAN_1 = (int)CAN1_BASE
 | 
					    CAN_1 = (int)CAN1_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_BASE
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)},
 | 
					    {PB_9,       CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,16 @@ struct trng_s {
 | 
				
			||||||
    RNG_HandleTypeDef handle;
 | 
					    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"
 | 
					#include "common_objects.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,6 +83,10 @@ typedef enum {
 | 
				
			||||||
    CAN_1 = (int)CAN1_BASE
 | 
					    CAN_1 = (int)CAN1_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_BASE
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)},
 | 
					    {PB_9,       CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
					    {PH_13,      CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)}, // Connected to ARD_D9
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,6 +85,10 @@ typedef enum {
 | 
				
			||||||
    CAN_2 = (int)CAN2_BASE
 | 
					    CAN_2 = (int)CAN2_BASE
 | 
				
			||||||
} CANName;
 | 
					} CANName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    QSPI_1 = (int)QSPI_BASE
 | 
				
			||||||
 | 
					} QSPIName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)},
 | 
					    {PD_1,       CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
 | 
				
			||||||
    {NC, NC, 0}
 | 
					    {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}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,321 @@
 | 
				
			||||||
 | 
					/* 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"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Max amount of flash size is 4Gbytes */
 | 
				
			||||||
 | 
					/* 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) 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // 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;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            st_command->InstructionMode = QSPI_INSTRUCTION_NONE;
 | 
				
			||||||
 | 
					            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_NONE;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (command->address.disabled == true) {
 | 
				
			||||||
 | 
					        st_command->AddressMode = QSPI_ADDRESS_NONE;
 | 
				
			||||||
 | 
					        st_command->AddressSize = 0;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        st_command->Address = command->address.value;
 | 
				
			||||||
 | 
					        /* 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) {
 | 
				
			||||||
 | 
					        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_NONE;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (command->alt.disabled == true) {
 | 
				
			||||||
 | 
					        st_command->AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
 | 
				
			||||||
 | 
					        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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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_NONE;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    st_command->NbData = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 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;
 | 
				
			||||||
 | 
					    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_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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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) {
 | 
				
			||||||
 | 
					        return QSPI_STATUS_INVALID_PARAMETER;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // tested all combinations, take first
 | 
				
			||||||
 | 
					    obj->handle.Instance = (QUADSPI_TypeDef *)qspi_data_first;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 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) {
 | 
				
			||||||
 | 
					        return QSPI_STATUS_ERROR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    qspi_frequency(obj, hz);
 | 
				
			||||||
 | 
					    return QSPI_STATUS_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qspi_status_t qspi_free(qspi_t *obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qspi_status_t qspi_frequency(qspi_t *obj, int hz)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    qspi_status_t status = QSPI_STATUS_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 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 status;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return status;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 status = QSPI_STATUS_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } 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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (rx_data != NULL && rx_size) {
 | 
				
			||||||
 | 
					            size_t rx_length = rx_size;
 | 
				
			||||||
 | 
					            status = qspi_read(obj, command, rx_data, &rx_length);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return status;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** @}*/
 | 
				
			||||||
| 
						 | 
					@ -1260,7 +1260,7 @@
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "detect_code": ["0743"],
 | 
					        "detect_code": ["0743"],
 | 
				
			||||||
        "macros_add": ["USB_STM_HAL", "USBHOST_OTHER"],
 | 
					        "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"],
 | 
					        "release_versions": ["2", "5"],
 | 
				
			||||||
        "device_name": "STM32F413ZH"
 | 
					        "device_name": "STM32F413ZH"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
| 
						 | 
					@ -1987,7 +1987,7 @@
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "detect_code": ["0788"],
 | 
					        "detect_code": ["0788"],
 | 
				
			||||||
        "macros_add": ["USB_STM_HAL", "USBHOST_OTHER"],
 | 
					        "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"],
 | 
					        "release_versions": ["2", "5"],
 | 
				
			||||||
        "device_name": "STM32F469NI"
 | 
					        "device_name": "STM32F469NI"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
| 
						 | 
					@ -2081,7 +2081,7 @@
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "detect_code": ["0815"],
 | 
					        "detect_code": ["0815"],
 | 
				
			||||||
        "macros_add": ["USB_STM_HAL", "USBHOST_OTHER"],
 | 
					        "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"],
 | 
					        "release_versions": ["2", "5"],
 | 
				
			||||||
        "device_name": "STM32F746NG",
 | 
					        "device_name": "STM32F746NG",
 | 
				
			||||||
        "overrides": {
 | 
					        "overrides": {
 | 
				
			||||||
| 
						 | 
					@ -2145,7 +2145,7 @@
 | 
				
			||||||
        "supported_form_factors": ["ARDUINO"],
 | 
					        "supported_form_factors": ["ARDUINO"],
 | 
				
			||||||
        "detect_code": ["0764"],
 | 
					        "detect_code": ["0764"],
 | 
				
			||||||
        "macros_add": ["USBHOST_OTHER", "TWO_RAM_REGIONS"],
 | 
					        "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"],
 | 
					        "release_versions": ["2", "5"],
 | 
				
			||||||
        "device_name": "STM32L475VG",
 | 
					        "device_name": "STM32L475VG",
 | 
				
			||||||
        "bootloader_supported": true
 | 
					        "bootloader_supported": true
 | 
				
			||||||
| 
						 | 
					@ -2172,7 +2172,7 @@
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "detect_code": ["0820"],
 | 
					        "detect_code": ["0820"],
 | 
				
			||||||
        "macros_add": ["USBHOST_OTHER", "TWO_RAM_REGIONS"],
 | 
					        "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"],
 | 
					        "release_versions": ["2", "5"],
 | 
				
			||||||
        "device_name": "STM32L476VG",
 | 
					        "device_name": "STM32L476VG",
 | 
				
			||||||
        "bootloader_supported": true
 | 
					        "bootloader_supported": true
 | 
				
			||||||
| 
						 | 
					@ -3978,7 +3978,8 @@
 | 
				
			||||||
            "SPI_ASYNCH",
 | 
					            "SPI_ASYNCH",
 | 
				
			||||||
            "STCLK_OFF_DURING_SLEEP",
 | 
					            "STCLK_OFF_DURING_SLEEP",
 | 
				
			||||||
            "TRNG",
 | 
					            "TRNG",
 | 
				
			||||||
            "USTICKER"
 | 
					            "USTICKER",
 | 
				
			||||||
 | 
					            "QSPI"
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "extra_labels": [
 | 
					        "extra_labels": [
 | 
				
			||||||
            "NORDIC",
 | 
					            "NORDIC",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,10 +26,10 @@ import textwrap
 | 
				
			||||||
from xml.dom.minidom import parse, Node
 | 
					from xml.dom.minidom import parse, Node
 | 
				
			||||||
from argparse import RawTextHelpFormatter
 | 
					from argparse import RawTextHelpFormatter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GENPINMAP_VERSION = "1.2"
 | 
					GENPINMAP_VERSION = "1.3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ADD_DEVICE_IFDEF = 0
 | 
					ADD_DEVICE_IFDEF = 0
 | 
				
			||||||
ADD_QSPI_FEATURE = 0
 | 
					ADD_QSPI_FEATURE = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mcu_file=""
 | 
					mcu_file=""
 | 
				
			||||||
mcu_list = []       #'name'
 | 
					mcu_list = []       #'name'
 | 
				
			||||||
| 
						 | 
					@ -779,7 +779,6 @@ def print_can(l):
 | 
				
			||||||
        out_c_file.write( "#endif\n" )
 | 
					        out_c_file.write( "#endif\n" )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def print_qspi(l):
 | 
					def print_qspi(l):
 | 
				
			||||||
    prev_s = ''
 | 
					 | 
				
			||||||
    for p in l:
 | 
					    for p in l:
 | 
				
			||||||
        result = get_gpio_af_num(p[1], p[2])
 | 
					        result = get_gpio_af_num(p[1], p[2])
 | 
				
			||||||
        if result != 'NOTFOUND':
 | 
					        if result != 'NOTFOUND':
 | 
				
			||||||
| 
						 | 
					@ -789,20 +788,11 @@ def print_qspi(l):
 | 
				
			||||||
                    CommentedLine = "//"
 | 
					                    CommentedLine = "//"
 | 
				
			||||||
                if "RCC_OSC" in PinLabel[p[1]]:
 | 
					                if "RCC_OSC" in PinLabel[p[1]]:
 | 
				
			||||||
                    CommentedLine = "//"
 | 
					                    CommentedLine = "//"
 | 
				
			||||||
            s1 = "%-17s" % (CommentedLine + "    {" + p[0] + ',')
 | 
					            s1 = "%-16s" % (CommentedLine + "  {" + p[0] + ',')
 | 
				
			||||||
            # p[2] : QUADSPI_BK1_IO3 / QUADSPI_CLK / QUADSPI_NCS
 | 
					            # p[2] : QUADSPI_BK1_IO3 / QUADSPI_CLK / QUADSPI_NCS
 | 
				
			||||||
            instance = p[2].split('_')[1].replace("BK", "")
 | 
					            s1 += "%-8s" % ('QSPI_1,')
 | 
				
			||||||
            instance = instance.replace("CLK", "1")
 | 
					            result = result.replace("GPIO_AF10_OTG_FS", "GPIO_AF10_QSPI")
 | 
				
			||||||
            instance = instance.replace("NCS", "1")
 | 
					 | 
				
			||||||
            s1 += "%-7s" % ('QSPI_' + instance + ',')
 | 
					 | 
				
			||||||
            s1 += 'STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, ' + result +')},'
 | 
					            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():
 | 
					            if p[1] in PinLabel.keys():
 | 
				
			||||||
                s1 += ' // Connected to ' + PinLabel[p[1]]
 | 
					                s1 += ' // Connected to ' + PinLabel[p[1]]
 | 
				
			||||||
| 
						 | 
					@ -980,6 +970,7 @@ def parse_BoardFile(fileName):
 | 
				
			||||||
            PinLabel[EachPin] = PinData[EachPin]["GPIO_Label"]
 | 
					            PinLabel[EachPin] = PinData[EachPin]["GPIO_Label"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if "STLK_RX" in PinLabel[EachPin] or "STLK_TX" in PinLabel[EachPin]:
 | 
					            if "STLK_RX" in PinLabel[EachPin] or "STLK_TX" in PinLabel[EachPin]:
 | 
				
			||||||
 | 
					                # Patch waiting for CubeMX correction
 | 
				
			||||||
                if "RX" in PinData[EachPin]["Signal"]:
 | 
					                if "RX" in PinData[EachPin]["Signal"]:
 | 
				
			||||||
                    PinLabel[EachPin] = "STDIO_UART_RX"
 | 
					                    PinLabel[EachPin] = "STDIO_UART_RX"
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
| 
						 | 
					@ -1001,6 +992,7 @@ def parse_BoardFile(fileName):
 | 
				
			||||||
            elif "USART2_TX" in PinLabel[EachPin]:
 | 
					            elif "USART2_TX" in PinLabel[EachPin]:
 | 
				
			||||||
                PinLabel[EachPin] = "STDIO_UART_TX"
 | 
					                PinLabel[EachPin] = "STDIO_UART_TX"
 | 
				
			||||||
            elif "STLINK_RX" in PinLabel[EachPin] or "STLINK_TX" in PinLabel[EachPin]:
 | 
					            elif "STLINK_RX" in PinLabel[EachPin] or "STLINK_TX" in PinLabel[EachPin]:
 | 
				
			||||||
 | 
					                # Patch waiting for CubeMX correction
 | 
				
			||||||
                if "RX" in PinData[EachPin]["Signal"]:
 | 
					                if "RX" in PinData[EachPin]["Signal"]:
 | 
				
			||||||
                    PinLabel[EachPin] = "STDIO_UART_RX"
 | 
					                    PinLabel[EachPin] = "STDIO_UART_RX"
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue