Mistake on this page?
Report an issue in GitHub or email us
QSPI.h
1 /* mbed Microcontroller Library
2  * Copyright (c) 2006-2018 ARM Limited
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #ifndef MBED_QSPI_H
18 #define MBED_QSPI_H
19 
20 #include "platform/platform.h"
21 
22 #if DEVICE_QSPI || defined(DOXYGEN_ONLY)
23 
24 #include "hal/qspi_api.h"
25 #include "platform/PlatformMutex.h"
26 #include "platform/SingletonPtr.h"
27 #include "platform/NonCopyable.h"
28 
29 #define ONE_MHZ 1000000
30 
31 #define QSPI_NO_INST (-1)
32 
33 namespace mbed {
34 /** \defgroup drivers-public-api-spi SPI
35  * \ingroup drivers-public-api
36  */
37 
38 /**
39  * \defgroup drivers_QSPI QSPI class
40  * \ingroup drivers-public-api-spi
41  * @{
42  */
43 
44 /** Type representing a QSPI instruction
45  */
46 typedef int qspi_inst_t;
47 
48 /** A QSPI Driver, used for communicating with QSPI slave devices
49  *
50  * The default format is set to Quad-SPI(1-1-1), and a clock frequency of 1MHz
51  * Most QSPI devices will also require Chip Select which is indicated by ssel.
52  *
53  * @note Synchronization level: Thread safe
54  *
55  * Example:
56  * @code
57  * // 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
58  *
59  * #include "mbed.h"
60  *
61  * #define CMD_WRITE 0x02
62  * #define CMD_READ 0x03
63  * #define ADDRESS 0x1000
64  *
65  * // hardware ssel (where applicable)
66  * 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
67  *
68  *
69  * int main() {
70  * char tx_buf[] = { 0x11, 0x22, 0x33, 0x44 };
71  * char rx_buf[4];
72  * int buf_len = sizeof(tx_buf);
73  *
74  * qspi_status_t result = qspi_device.write(CMD_WRITE, 0, ADDRESS, tx_buf, &buf_len);
75  * if (result != QSPI_STATUS_OK) {
76  * printf("Write failed");
77  * }
78  * result = qspi_device.read(CMD_READ, 0, ADDRESS, rx_buf, &buf_len);
79  * if (result != QSPI_STATUS_OK) {
80  * printf("Read failed");
81  * }
82  *
83  * }
84  * @endcode
85  */
86 class QSPI : private NonCopyable<QSPI> {
87 
88 public:
89 
90  /** Create a QSPI master connected to the specified pins
91  *
92  * io0-io3 is used to specify the Pins used for Quad SPI mode
93  *
94  * @param io0 1st IO pin used for sending/receiving data during data phase of a transaction
95  * @param io1 2nd IO pin used for sending/receiving data during data phase of a transaction
96  * @param io2 3rd IO pin used for sending/receiving data during data phase of a transaction
97  * @param io3 4th IO pin used for sending/receiving data during data phase of a transaction
98  * @param sclk QSPI Clock pin
99  * @param ssel QSPI chip select pin
100  * @param mode Clock polarity and phase mode (0 - 3) of SPI
101  * (Default: Mode=0 uses CPOL=0, CPHA=0, Mode=1 uses CPOL=1, CPHA=1)
102  *
103  */
104  QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel = NC, int mode = 0);
105 
106  /** Create a QSPI master connected to the specified pins
107  *
108  * io0-io3 is used to specify the Pins used for Quad SPI mode
109  *
110  * @param pinmap reference to structure which holds static pinmap
111  * @param mode Clock polarity and phase mode (0 - 3) of SPI
112  * (Default: Mode=0 uses CPOL=0, CPHA=0, Mode=1 uses CPOL=1, CPHA=1)
113  *
114  */
115  QSPI(const qspi_pinmap_t &pinmap, int mode = 0);
116  QSPI(const qspi_pinmap_t &&, int = 0) = delete; // prevent passing of temporary objects
117 
118  virtual ~QSPI();
119 
120  /** Configure the data transmission format
121  *
122  * @param inst_width Bus width used by instruction phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD)
123  * @param address_width Bus width used by address phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD)
124  * @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)
125  * @param alt_width Bus width used by alt phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD)
126  * @param alt_size Size in bits used by alt phase (must be a multiple of the number of bus lines indicated in alt_width)
127  * @param data_width Bus width used by data phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD)
128  * @param dummy_cycles Number of dummy clock cycles to be used after alt phase
129  *
130  */
132  qspi_bus_width_t address_width,
133  qspi_address_size_t address_size,
134  qspi_bus_width_t alt_width,
135  qspi_alt_size_t alt_size,
136  qspi_bus_width_t data_width,
137  int dummy_cycles);
138 
139  /** Set the qspi bus clock frequency
140  *
141  * @param hz SCLK frequency in hz (default = 1MHz)
142  * @returns
143  * Returns QSPI_STATUS_SUCCESS on successful, fails if the interface is already init-ed
144  */
145  qspi_status_t set_frequency(int hz = ONE_MHZ);
146 
147  /** Read from QSPI peripheral with the preset read_instruction and alt_value
148  *
149  * @param address Address to be accessed in QSPI peripheral
150  * @param rx_buffer Buffer for data to be read from the peripheral
151  * @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
152  *
153  * @returns
154  * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
155  */
156  qspi_status_t read(int address, char *rx_buffer, size_t *rx_length);
157 
158  /** Write to QSPI peripheral using custom write instruction
159  *
160  * @param address Address to be accessed in QSPI peripheral
161  * @param tx_buffer Buffer containing data to be sent to peripheral
162  * @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
163  *
164  * @returns
165  * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
166  */
167  qspi_status_t write(int address, const char *tx_buffer, size_t *tx_length);
168 
169  /** Read from QSPI peripheral using custom read instruction, alt values
170  *
171  * @param instruction Instruction value to be used in instruction phase. Use QSPI_NO_INST to skip the instruction phase
172  * @param alt Alt value to be used in Alternate-byte phase. Use -1 for ignoring Alternate-byte phase
173  * @param address Address to be accessed in QSPI peripheral
174  * @param rx_buffer Buffer for data to be read from the peripheral
175  * @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
176  *
177  * @returns
178  * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
179  */
180  qspi_status_t read(qspi_inst_t instruction, int alt, int address, char *rx_buffer, size_t *rx_length);
181 
182  /** Write to QSPI peripheral using custom write instruction, alt values
183  *
184  * @param instruction Instruction value to be used in instruction phase. Use QSPI_NO_INST to skip the instruction phase
185  * @param alt Alt value to be used in Alternate-byte phase. Use -1 for ignoring Alternate-byte phase
186  * @param address Address to be accessed in QSPI peripheral
187  * @param tx_buffer Buffer containing data to be sent to peripheral
188  * @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
189  *
190  * @returns
191  * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
192  */
193  qspi_status_t write(qspi_inst_t instruction, int alt, int address, const char *tx_buffer, size_t *tx_length);
194 
195  /** Perform a transaction to write to an address(a control register) and get the status results
196  *
197  * @param instruction Instruction value to be used in instruction phase. Use QSPI_NO_INST to skip the instruction phase
198  * @param address Some instruction might require address. Use -1 if no address
199  * @param tx_buffer Buffer containing data to be sent to peripheral
200  * @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
201  * @param rx_buffer Buffer for data to be read from the peripheral
202  * @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
203  *
204  * @returns
205  * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
206  */
207  qspi_status_t command_transfer(qspi_inst_t instruction, int address, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length);
208 
209 #if !defined(DOXYGEN_ONLY)
210 protected:
211  /** Acquire exclusive access to this SPI bus
212  */
213  virtual void lock(void);
214 
215  /** Release exclusive access to this SPI bus
216  */
217  virtual void unlock(void);
218 
219  qspi_t _qspi;
220 
221  static SingletonPtr<PlatformMutex> _mutex;
222  qspi_bus_width_t _inst_width; //Bus width for Instruction phase
223  qspi_bus_width_t _address_width; //Bus width for Address phase
224  qspi_address_size_t _address_size;
225  qspi_bus_width_t _alt_width; //Bus width for Alt phase
226  qspi_alt_size_t _alt_size;
227  qspi_bus_width_t _data_width; //Bus width for Data phase
228  qspi_command_t _qspi_command; //QSPI Hal command struct
229  unsigned int _num_dummy_cycles; //Number of dummy cycles to be used
230  int _hz; //Bus Frequency
231  int _mode; //SPI mode
232  bool _initialized;
233  PinName _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs; //IO lines, clock and chip select
234  const qspi_pinmap_t *_static_pinmap;
235  bool (QSPI::* _init_func)(void);
236 
237 private:
238  bool _initialize();
239  bool _initialize_direct();
240 
241  /*
242  * This function builds the qspi command struct to be send to Hal
243  */
244  inline void _build_qspi_command(qspi_inst_t instruction, int address, int alt);
245 #endif
246 };
247 
248 /** @}*/
249 
250 } // namespace mbed
251 
252 #endif
253 
254 #endif
QSPI command.
Definition: qspi_api.h:92
QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel=NC, int mode=0)
Create a QSPI master connected to the specified pins.
qspi_status_t set_frequency(int hz=1000000)
Set the qspi bus clock frequency.
struct qspi_s qspi_t
QSPI HAL object.
Definition: qspi_api.h:40
qspi_status_t write(int address, const char *tx_buffer, size_t *tx_length)
Write to QSPI peripheral using custom write instruction.
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:162
qspi_status_t command_transfer(qspi_inst_t instruction, int address, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length)
Perform a transaction to write to an address(a control register) and get the status results...
enum qspi_address_size qspi_address_size_t
Address size in bits.
int qspi_inst_t
Type representing a QSPI instruction.
Definition: QSPI.h:46
uint8_t qspi_alt_size_t
Alternative size in bits.
Definition: qspi_api.h:79
enum qspi_bus_width qspi_bus_width_t
QSPI Bus width.
qspi_status_t read(int address, char *rx_buffer, size_t *rx_length)
Read from QSPI peripheral with the preset read_instruction and alt_value.
Definition: ATHandler.h:46
A QSPI Driver, used for communicating with QSPI slave devices.
Definition: QSPI.h:86
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)
Configure the data transmission format.
enum qspi_status qspi_status_t
QSPI return status.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.