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 namespace mbed {
32 
33 /** \addtogroup drivers */
34 
35 /** A QSPI Driver, used for communicating with QSPI slave devices
36  *
37  * The default format is set to Quad-SPI(1-1-1), and a clock frequency of 1MHz
38  * Most QSPI devices will also require Chip Select which is indicated by ssel.
39  *
40  * @note Synchronization level: Thread safe
41  *
42  * Example:
43  * @code
44  * // 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
45  *
46  * #include "mbed.h"
47  *
48  * #define CMD_WRITE 0x02
49  * #define CMD_READ 0x03
50  * #define ADDRESS 0x1000
51  *
52  * // hardware ssel (where applicable)
53  * 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
54  *
55  *
56  * int main() {
57  * char tx_buf[] = { 0x11, 0x22, 0x33, 0x44 };
58  * char rx_buf[4];
59  * int buf_len = sizeof(tx_buf);
60  *
61  * qspi_status_t result = qspi_device.write(CMD_WRITE, 0, ADDRESS, tx_buf, &buf_len);
62  * if (result != QSPI_STATUS_OK) {
63  * printf("Write failed");
64  * }
65  * result = qspi_device.read(CMD_READ, 0, ADDRESS, rx_buf, &buf_len);
66  * if (result != QSPI_STATUS_OK) {
67  * printf("Read failed");
68  * }
69  *
70  * }
71  * @endcode
72  * @ingroup drivers
73  */
74 class QSPI : private NonCopyable<QSPI> {
75 
76 public:
77 
78  /** Create a QSPI master connected to the specified pins
79  *
80  * io0-io3 is used to specify the Pins used for Quad SPI mode
81  *
82  * @param io0 1st IO pin used for sending/receiving data during data phase of a transaction
83  * @param io1 2nd IO pin used for sending/receiving data during data phase of a transaction
84  * @param io2 3rd IO pin used for sending/receiving data during data phase of a transaction
85  * @param io3 4th IO pin used for sending/receiving data during data phase of a transaction
86  * @param sclk QSPI Clock pin
87  * @param ssel QSPI chip select pin
88  * @param mode Clock polarity and phase mode (0 - 3) of SPI
89  * (Default: Mode=0 uses CPOL=0, CPHA=0, Mode=1 uses CPOL=1, CPHA=1)
90  *
91  */
92  QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel = NC, int mode = 0);
93  virtual ~QSPI()
94  {
95  }
96 
97  /** Configure the data transmission format
98  *
99  * @param inst_width Bus width used by instruction phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD)
100  * @param address_width Bus width used by address phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD)
101  * @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)
102  * @param alt_width Bus width used by alt phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD)
103  * @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)
104  * @param data_width Bus width used by data phase(Valid values are QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_DUAL, QSPI_CFG_BUS_QUAD)
105  * @param dummy_cycles Number of dummy clock cycles to be used after alt phase
106  *
107  */
109  qspi_bus_width_t address_width,
110  qspi_address_size_t address_size,
111  qspi_bus_width_t alt_width,
112  qspi_alt_size_t alt_size,
113  qspi_bus_width_t data_width,
114  int dummy_cycles);
115 
116  /** Set the qspi bus clock frequency
117  *
118  * @param hz SCLK frequency in hz (default = 1MHz)
119  * @returns
120  * Returns QSPI_STATUS_SUCCESS on successful, fails if the interface is already init-ed
121  */
122  qspi_status_t set_frequency(int hz = ONE_MHZ);
123 
124  /** Read from QSPI peripheral with the preset read_instruction and alt_value
125  *
126  * @param address Address to be accessed in QSPI peripheral
127  * @param rx_buffer Buffer for data to be read from the peripheral
128  * @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
129  *
130  * @returns
131  * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
132  */
133  qspi_status_t read(int address, char *rx_buffer, size_t *rx_length);
134 
135  /** Write to QSPI peripheral using custom write instruction
136  *
137  * @param address Address to be accessed in QSPI peripheral
138  * @param tx_buffer Buffer containing data to be sent to peripheral
139  * @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
140  *
141  * @returns
142  * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
143  */
144  qspi_status_t write(int address, const char *tx_buffer, size_t *tx_length);
145 
146  /** Read from QSPI peripheral using custom read instruction, alt values
147  *
148  * @param instruction Instruction value to be used in instruction phase
149  * @param alt Alt value to be used in Alternate-byte phase. Use -1 for ignoring Alternate-byte phase
150  * @param address Address to be accessed in QSPI peripheral
151  * @param rx_buffer Buffer for data to be read from the peripheral
152  * @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
153  *
154  * @returns
155  * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
156  */
157  qspi_status_t read(int instruction, int alt, int address, char *rx_buffer, size_t *rx_length);
158 
159  /** Write to QSPI peripheral using custom write instruction, alt values
160  *
161  * @param instruction Instruction value to be used in instruction phase
162  * @param alt Alt value to be used in Alternate-byte phase. Use -1 for ignoring Alternate-byte phase
163  * @param address Address to be accessed in QSPI peripheral
164  * @param tx_buffer Buffer containing data to be sent to peripheral
165  * @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
166  *
167  * @returns
168  * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
169  */
170  qspi_status_t write(int instruction, int alt, int address, const char *tx_buffer, size_t *tx_length);
171 
172  /** Perform a transaction to write to an address(a control register) and get the status results
173  *
174  * @param instruction Instruction value to be used in instruction phase
175  * @param address Some instruction might require address. Use -1 if no address
176  * @param tx_buffer Buffer containing data to be sent to peripheral
177  * @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
178  * @param rx_buffer Buffer for data to be read from the peripheral
179  * @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
180  *
181  * @returns
182  * Returns QSPI_STATUS_SUCCESS on successful reads and QSPI_STATUS_ERROR on failed reads.
183  */
184  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);
185 
186 #if !defined(DOXYGEN_ONLY)
187 protected:
188  /** Acquire exclusive access to this SPI bus
189  */
190  virtual void lock(void);
191 
192  /** Release exclusive access to this SPI bus
193  */
194  virtual void unlock(void);
195 
196  qspi_t _qspi;
197 
198  bool acquire(void);
199  static QSPI *_owner;
200  static SingletonPtr<PlatformMutex> _mutex;
201  qspi_bus_width_t _inst_width; //Bus width for Instruction phase
202  qspi_bus_width_t _address_width; //Bus width for Address phase
203  qspi_address_size_t _address_size;
204  qspi_bus_width_t _alt_width; //Bus width for Alt phase
205  qspi_alt_size_t _alt_size;
206  qspi_bus_width_t _data_width; //Bus width for Data phase
207  qspi_command_t _qspi_command; //QSPI Hal command struct
208  unsigned int _num_dummy_cycles; //Number of dummy cycles to be used
209  int _hz; //Bus Frequency
210  int _mode; //SPI mode
211  bool _initialized;
212  PinName _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs; //IO lines, clock and chip select
213 
214 private:
215  /* Private acquire function without locking/unlocking
216  * Implemented in order to avoid duplicate locking and boost performance
217  */
218  bool _acquire(void);
219  bool _initialize();
220 
221  /*
222  * This function builds the qspi command struct to be send to Hal
223  */
224  inline void _build_qspi_command(int instruction, int address, int alt);
225 #endif
226 };
227 
228 } // namespace mbed
229 
230 #endif
231 
232 #endif
QSPI command.
Definition: qspi_api.h:74
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:168
enum qspi_alt_size qspi_alt_size_t
Alternative size in bits.
enum qspi_address_size qspi_address_size_t
Address size in bits.
enum qspi_bus_width qspi_bus_width_t
QSPI Bus width.
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)
Perform a transaction to write to an address(a control register) and get the status results...
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.
A QSPI Driver, used for communicating with QSPI slave devices.
Definition: QSPI.h:74
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.