Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
QSPI.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2018 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #ifndef MBED_QSPI_H 00017 #define MBED_QSPI_H 00018 00019 #include "platform/platform.h" 00020 00021 #if defined (DEVICE_QSPI) || defined(DOXYGEN_ONLY) 00022 00023 #include "hal/qspi_api.h" 00024 #include "platform/PlatformMutex.h" 00025 #include "platform/SingletonPtr.h" 00026 #include "platform/NonCopyable.h" 00027 00028 #define ONE_MHZ 1000000 00029 00030 namespace mbed { 00031 00032 /** \addtogroup drivers */ 00033 00034 /** A QSPI Driver, used for communicating with QSPI slave devices 00035 * 00036 * The default format is set to Quad-SPI(1-1-1), and a clock frequency of 1MHz 00037 * Most QSPI devices will also require Chip Select which is indicated by ssel. 00038 * 00039 * @note Synchronization level: Thread safe 00040 * 00041 * Example: 00042 * @code 00043 * // 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 00044 * 00045 * #include "mbed.h" 00046 * 00047 * #define CMD_WRITE 0x02 00048 * #define CMD_READ 0x03 00049 * #define ADDRESS 0x1000 00050 * 00051 * // hardware ssel (where applicable) 00052 * QSPI qspi_device(QSPI_FLASH1_IO0, QSPI_FLASH1_IO1, QSPI_FLASH1_IO2, QSPI_FLASH1_IO3, QSPI_FLASH1_SCK, QSPI_FLASH1_CSN); // io0, io1, io2, io3, sclk, ssel 00053 * 00054 * 00055 * int main() { 00056 * char tx_buf[] = { 0x11, 0x22, 0x33, 0x44 }; 00057 * char rx_buf[4]; 00058 * int buf_len = sizeof(tx_buf); 00059 * 00060 * qspi_status_t result = qspi_device.write(CMD_WRITE, 0, ADDRESS, tx_buf, &buf_len); 00061 * if (result != QSPI_STATUS_OK) { 00062 * printf("Write failed"); 00063 * } 00064 * result = qspi_device.read(CMD_READ, 0, ADDRESS, rx_buf, &buf_len); 00065 * if (result != QSPI_STATUS_OK) { 00066 * printf("Read failed"); 00067 * } 00068 * 00069 * } 00070 * @endcode 00071 * @ingroup drivers 00072 */ 00073 class QSPI : private NonCopyable<QSPI> { 00074 00075 public: 00076 00077 /** Create a QSPI master connected to the specified pins 00078 * 00079 * io0-io3 is used to specify the Pins used for Quad SPI mode 00080 * 00081 * @param io0 1st IO pin used for sending/receiving data during data phase of a transaction 00082 * @param io1 2nd IO pin used for sending/receiving data during data phase of a transaction 00083 * @param io2 3rd IO pin used for sending/receiving data during data phase of a transaction 00084 * @param io3 4th IO pin used for sending/receiving data during data phase of a transaction 00085 * @param sclk QSPI Clock pin 00086 * @param ssel QSPI chip select pin 00087 * @param mode Clock polarity and phase mode (0 - 3) of SPI 00088 * (Default: Mode=0 uses CPOL=0, CPHA=0, Mode=1 uses CPOL=1, CPHA=1) 00089 * 00090 */ 00091 QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel = NC, int mode = 0); 00092 virtual ~QSPI() 00093 { 00094 } 00095 00096 /** Configure the data transmission format 00097 * 00098 * @param inst_width Bus width used by instruction phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD) 00099 * @param address_width Bus width used by address phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD) 00100 * @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) 00101 * @param alt_width Bus width used by alt phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD) 00102 * @param alt_size Size in bits used by alt phase(Valid values are QSPI_CFG_ALT_SIZE_8, QSPI_CFG_ALT_SIZE_16, QSPI_CFG_ALT_SIZE_24, QSPI_CFG_ALT_SIZE_32) 00103 * @param data_width Bus width used by data phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD) 00104 * @param dummy_cycles Number of dummy clock cycles to be used after alt phase 00105 * 00106 */ 00107 qspi_status_t configure_format(qspi_bus_width_t inst_width, 00108 qspi_bus_width_t address_width, 00109 qspi_address_size_t address_size, 00110 qspi_bus_width_t alt_width, 00111 qspi_alt_size_t alt_size, 00112 qspi_bus_width_t data_width, 00113 int dummy_cycles); 00114 00115 /** Set the qspi bus clock frequency 00116 * 00117 * @param hz SCLK frequency in hz (default = 1MHz) 00118 * @returns 00119 * Returns QSPI_STATUS_SUCCESS on successful, fails if the interface is already init-ed 00120 */ 00121 qspi_status_t set_frequency(int hz = ONE_MHZ); 00122 00123 /** Read from QSPI peripheral with the preset read_instruction and alt_value 00124 * 00125 * @param address Address to be accessed in QSPI peripheral 00126 * @param rx_buffer Buffer for data to be read from the peripheral 00127 * @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 00128 * 00129 * @returns 00130 * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads. 00131 */ 00132 qspi_status_t read(int address, char *rx_buffer, size_t *rx_length); 00133 00134 /** Write to QSPI peripheral using custom write instruction 00135 * 00136 * @param address Address to be accessed in QSPI peripheral 00137 * @param tx_buffer Buffer containing data to be sent to peripheral 00138 * @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 00139 * 00140 * @returns 00141 * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads. 00142 */ 00143 qspi_status_t write(int address, const char *tx_buffer, size_t *tx_length); 00144 00145 /** Read from QSPI peripheral using custom read instruction, alt values 00146 * 00147 * @param instruction Instruction value to be used in instruction phase 00148 * @param alt Alt value to be used in Alternate-byte phase. Use -1 for ignoring Alternate-byte phase 00149 * @param address Address to be accessed in QSPI peripheral 00150 * @param rx_buffer Buffer for data to be read from the peripheral 00151 * @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 00152 * 00153 * @returns 00154 * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads. 00155 */ 00156 qspi_status_t read(int instruction, int alt, int address, char *rx_buffer, size_t *rx_length); 00157 00158 /** Write to QSPI peripheral using custom write instruction, alt values 00159 * 00160 * @param instruction Instruction value to be used in instruction phase 00161 * @param alt Alt value to be used in Alternate-byte phase. Use -1 for ignoring Alternate-byte phase 00162 * @param address Address to be accessed in QSPI peripheral 00163 * @param tx_buffer Buffer containing data to be sent to peripheral 00164 * @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 00165 * 00166 * @returns 00167 * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads. 00168 */ 00169 qspi_status_t write(int instruction, int alt, int address, const char *tx_buffer, size_t *tx_length); 00170 00171 /** Perform a transaction to write to an address(a control register) and get the status results 00172 * 00173 * @param instruction Instruction value to be used in instruction phase 00174 * @param address Some instruction might require address. Use -1 if no address 00175 * @param tx_buffer Buffer containing data to be sent to peripheral 00176 * @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 00177 * @param rx_buffer Buffer for data to be read from the peripheral 00178 * @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 00179 * 00180 * @returns 00181 * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads. 00182 */ 00183 qspi_status_t command_transfer(int instruction, int address, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length); 00184 00185 #if !defined(DOXYGEN_ONLY) 00186 protected: 00187 /** Acquire exclusive access to this SPI bus 00188 */ 00189 virtual void lock(void); 00190 00191 /** Release exclusive access to this SPI bus 00192 */ 00193 virtual void unlock(void); 00194 00195 qspi_t _qspi; 00196 00197 bool acquire(void); 00198 static QSPI *_owner; 00199 static SingletonPtr<PlatformMutex> _mutex; 00200 qspi_bus_width_t _inst_width; //Bus width for Instruction phase 00201 qspi_bus_width_t _address_width; //Bus width for Address phase 00202 qspi_address_size_t _address_size; 00203 qspi_bus_width_t _alt_width; //Bus width for Alt phase 00204 qspi_alt_size_t _alt_size; 00205 qspi_bus_width_t _data_width; //Bus width for Data phase 00206 qspi_command_t _qspi_command; //QSPI Hal command struct 00207 unsigned int _num_dummy_cycles; //Number of dummy cycles to be used 00208 int _hz; //Bus Frequency 00209 int _mode; //SPI mode 00210 bool _initialized; 00211 PinName _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs; //IO lines, clock and chip select 00212 00213 private: 00214 /* Private acquire function without locking/unlocking 00215 * Implemented in order to avoid duplicate locking and boost performance 00216 */ 00217 bool _acquire(void); 00218 bool _initialize(); 00219 00220 /* 00221 * This function builds the qspi command struct to be send to Hal 00222 */ 00223 inline void _build_qspi_command(int instruction, int address, int alt); 00224 #endif 00225 }; 00226 00227 } // namespace mbed 00228 00229 #endif 00230 00231 #endif
Generated on Tue Jul 12 2022 20:52:55 by
1.7.2