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 Mode specifies the SPI mode(Mode=0 uses CPOL=0, CPHA=0, Mode=1 uses CPOL=1, CPHA=1) 00088 * default value = 0 00089 * 00090 */ 00091 QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel = NC, int mode = 0); 00092 00093 /** Configure the data transmission format 00094 * 00095 * @param inst_width Bus width used by instruction phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD) 00096 * @param address_width Bus width used by address phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD) 00097 * @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) 00098 * @param alt_width Bus width used by alt phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD) 00099 * @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) 00100 * @param data_width Bus width used by data phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD) 00101 * @param dummy_cycles Number of dummy clock cycles to be used after alt phase 00102 * 00103 */ 00104 qspi_status_t configure_format(qspi_bus_width_t inst_width, 00105 qspi_bus_width_t address_width, 00106 qspi_address_size_t address_size, 00107 qspi_bus_width_t alt_width, 00108 qspi_alt_size_t alt_size, 00109 qspi_bus_width_t data_width, 00110 int dummy_cycles); 00111 00112 /** Set the qspi bus clock frequency 00113 * 00114 * @param hz SCLK frequency in hz (default = 1MHz) 00115 * @returns 00116 * Returns QSPI_STATUS_SUCCESS on successful, fails if the interface is already init-ed 00117 */ 00118 qspi_status_t set_frequency(int hz = ONE_MHZ); 00119 00120 /** Read from QSPI peripheral with the preset read_instruction and alt_value 00121 * 00122 * @param address Address to be accessed in QSPI peripheral 00123 * @param rx_buffer Buffer for data to be read from the peripheral 00124 * @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 00125 * 00126 * @returns 00127 * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads. 00128 */ 00129 qspi_status_t read(int address, char *rx_buffer, size_t *rx_length); 00130 00131 /** Write to QSPI peripheral using custom write instruction 00132 * 00133 * @param address Address to be accessed in QSPI peripheral 00134 * @param tx_buffer Buffer containing data to be sent to peripheral 00135 * @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 00136 * 00137 * @returns 00138 * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads. 00139 */ 00140 qspi_status_t write(int address, const char *tx_buffer, size_t *tx_length); 00141 00142 /** Read from QSPI peripheral using custom read instruction, alt values 00143 * 00144 * @param instruction Instruction value to be used in instruction phase 00145 * @param alt Alt value to be used in Alternate-byte phase. Use -1 for ignoring Alternate-byte phase 00146 * @param address Address to be accessed in QSPI peripheral 00147 * @param rx_buffer Buffer for data to be read from the peripheral 00148 * @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 00149 * 00150 * @returns 00151 * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads. 00152 */ 00153 qspi_status_t read(int instruction, int alt, int address, char *rx_buffer, size_t *rx_length); 00154 00155 /** Write to QSPI peripheral using custom write instruction, alt values 00156 * 00157 * @param instruction Instruction value to be used in instruction phase 00158 * @param alt Alt value to be used in Alternate-byte phase. Use -1 for ignoring Alternate-byte phase 00159 * @param address Address to be accessed in QSPI peripheral 00160 * @param tx_buffer Buffer containing data to be sent to peripheral 00161 * @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 00162 * 00163 * @returns 00164 * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads. 00165 */ 00166 qspi_status_t write(int instruction, int alt, int address, const char *tx_buffer, size_t *tx_length); 00167 00168 /** Perform a transaction to write to an address(a control register) and get the status results 00169 * 00170 * @param instruction Instruction value to be used in instruction phase 00171 * @param address Some instruction might require address. Use -1 if no address 00172 * @param tx_buffer Buffer containing data to be sent to peripheral 00173 * @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 00174 * @param rx_buffer Buffer for data to be read from the peripheral 00175 * @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 00176 * 00177 * @returns 00178 * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads. 00179 */ 00180 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); 00181 00182 protected: 00183 /** Acquire exclusive access to this SPI bus 00184 */ 00185 virtual void lock(void); 00186 00187 /** Release exclusive access to this SPI bus 00188 */ 00189 virtual void unlock(void); 00190 00191 public: 00192 virtual ~QSPI() 00193 { 00194 } 00195 00196 protected: 00197 qspi_t _qspi; 00198 00199 bool acquire(void); 00200 static QSPI *_owner; 00201 static SingletonPtr<PlatformMutex> _mutex; 00202 qspi_bus_width_t _inst_width; //Bus width for Instruction phase 00203 qspi_bus_width_t _address_width; //Bus width for Address phase 00204 qspi_address_size_t _address_size; 00205 qspi_bus_width_t _alt_width; //Bus width for Alt phase 00206 qspi_alt_size_t _alt_size; 00207 qspi_bus_width_t _data_width; //Bus width for Data phase 00208 qspi_command_t _qspi_command; //QSPI Hal command struct 00209 unsigned int _num_dummy_cycles; //Number of dummy cycles to be used 00210 int _hz; //Bus Frequency 00211 int _mode; //SPI mode 00212 bool _initialized; 00213 PinName _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs; //IO lines, clock and chip select 00214 00215 private: 00216 /* Private acquire function without locking/unlocking 00217 * Implemented in order to avoid duplicate locking and boost performance 00218 */ 00219 bool _acquire(void); 00220 bool _initialize(); 00221 00222 /* 00223 * This function builds the qspi command struct to be send to Hal 00224 */ 00225 inline void _build_qspi_command(int instruction, int address, int alt); 00226 }; 00227 00228 } // namespace mbed 00229 00230 #endif 00231 00232 #endif
Generated on Tue Aug 9 2022 00:37:18 by
