Mbed OS Reference
Loading...
Searching...
No Matches
OSPI.h
1/* mbed Microcontroller Library
2 * Copyright (c) 2006-2020 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_OSPI_H
18#define MBED_OSPI_H
19
20#include "platform/platform.h"
21
22#if DEVICE_OSPI || defined(DOXYGEN_ONLY)
23
24#include "hal/ospi_api.h"
25#include "rtos/Mutex.h"
26#include "platform/SingletonPtr.h"
27#include "platform/NonCopyable.h"
28
29#define ONE_MHZ 1000000
30
31#define OSPI_NO_INST (-1)
32
33namespace mbed {
34/** \defgroup drivers-public-api-spi SPI
35 * \ingroup drivers-public-api
36 */
37
38/**
39 * \defgroup drivers_OSPI OSPI class
40 * \ingroup drivers-public-api-spi
41 * @{
42 */
43
44/** Type representing a OSPI instruction
45 */
46typedef int ospi_inst_t;
47
48/** A OSPI Driver, used for communicating with OSPI slave devices
49 *
50 * The default format is set to OCTO-SPI(1-1-1), and a clock frequency of 1MHz
51 * Most OSPI 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 OSPI 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 * OSPI ospi_device(OSPI_FLASH1_IO0, OSPI_FLASH1_IO1, OSPI_FLASH1_IO2, OSPI_FLASH1_IO3, OSPI_FLASH1_IO4, OSPI_FLASH1_IO5, OSPI_FLASH1_IO6,
67 * OSPI_FLASH1_SCK, OSPI_FLASH1_CSN, OSPI_FLASH1_DQS); // io0, io1, io2, io3, io4, io5, io6, io7, sclk, ssel, dqs
68 *
69 *
70 * int main() {
71 * char tx_buf[] = { 0x11, 0x22, 0x33, 0x44 };
72 * char rx_buf[4];
73 * int buf_len = sizeof(tx_buf);
74 *
75 * ospi_status_t result = ospi_device.write(CMD_WRITE, 0, ADDRESS, tx_buf, &buf_len);
76 * if (result != OSPI_STATUS_OK) {
77 * printf("Write failed");
78 * }
79 * result = ospi_device.read(CMD_READ, 0, ADDRESS, rx_buf, &buf_len);
80 * if (result != OSPI_STATUS_OK) {
81 * printf("Read failed");
82 * }
83 *
84 * }
85 * @endcode
86 */
87class OSPI : private NonCopyable<OSPI> {
88
89public:
90
91 /** Create a OSPI master connected to the specified pins
92 *
93 * io0-io3 is used to specify the Pins used for Quad SPI mode
94 *
95 * @param io0 1st IO pin used for sending/receiving data during data phase of a transaction
96 * @param io1 2nd IO pin used for sending/receiving data during data phase of a transaction
97 * @param io2 3rd IO pin used for sending/receiving data during data phase of a transaction
98 * @param io3 4th IO pin used for sending/receiving data during data phase of a transaction
99 * @param io4 5th IO pin used for sending/receiving data during data phase of a transaction
100 * @param io5 6th IO pin used for sending/receiving data during data phase of a transaction
101 * @param io6 7th IO pin used for sending/receiving data during data phase of a transaction
102 * @param io7 8th IO pin used for sending/receiving data during data phase of a transaction
103 * @param sclk OSPI Clock pin
104 * @param ssel OSPI chip select pin
105 * @param dqs OSPI dqs pin
106 * @param mode Clock polarity and phase mode (0 - 3) of SPI
107 * (Default: Mode=0 uses CPOL=0, CPHA=0, Mode=1 uses CPOL=1, CPHA=1)
108 *
109 */
110 OSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName io4, PinName io5, PinName io6, PinName io7,
111 PinName sclk, PinName ssel = NC, PinName dqs = NC, int mode = 0);
112
113 /** Create a OSPI master connected to the specified pins
114 *
115 * io0-io3 is used to specify the Pins used for Quad SPI mode
116 *
117 * @param pinmap reference to structure which holds static pinmap
118 * @param mode Clock polarity and phase mode (0 - 3) of SPI
119 * (Default: Mode=0 uses CPOL=0, CPHA=0, Mode=1 uses CPOL=1, CPHA=1)
120 *
121 */
122 OSPI(const ospi_pinmap_t &pinmap, int mode = 0);
123 OSPI(const ospi_pinmap_t &&, int = 0) = delete; // prevent passing of temporary objects
124
125 virtual ~OSPI()
126 {
127 }
128
129 /** Configure the data transmission format
130 *
131 * @param inst_width Bus width used by instruction phase(Valid values are OSPI_CFG_BUS_SINGLE, OSPI_CFG_BUS_DUAL, OSPI_CFG_BUS_QUAD)
132 * @param inst_size Size in bits used by instruction phase
133 * @param address_width Bus width used by address phase(Valid values are OSPI_CFG_BUS_SINGLE, OSPI_CFG_BUS_DUAL, OSPI_CFG_BUS_QUAD)
134 * @param address_size Size in bits used by address phase(Valid values are OSPI_CFG_ADDR_SIZE_8, OSPI_CFG_ADDR_SIZE_16, OSPI_CFG_ADDR_SIZE_24, OSPI_CFG_ADDR_SIZE_32)
135 * @param alt_width Bus width used by alt phase(Valid values are OSPI_CFG_BUS_SINGLE, OSPI_CFG_BUS_DUAL, OSPI_CFG_BUS_QUAD)
136 * @param alt_size Size in bits used by alt phase (must be a multiple of the number of bus lines indicated in alt_width)
137 * @param data_width Bus width used by data phase(Valid values are OSPI_CFG_BUS_SINGLE, OSPI_CFG_BUS_DUAL, OSPI_CFG_BUS_QUAD)
138 * @param dummy_cycles Number of dummy clock cycles to be used after alt phase
139 *
140 */
141 ospi_status_t configure_format(ospi_bus_width_t inst_width,
142 ospi_inst_size_t inst_size,
143 ospi_bus_width_t address_width,
144 ospi_address_size_t address_size,
145 ospi_bus_width_t alt_width,
146 ospi_alt_size_t alt_size,
147 ospi_bus_width_t data_width,
148 int dummy_cycles);
149
150 /** Set the ospi bus clock frequency
151 *
152 * @param hz SCLK frequency in hz (default = 1MHz)
153 * @returns
154 * Returns OSPI_STATUS_SUCCESS on successful, fails if the interface is already init-ed
155 */
156 ospi_status_t set_frequency(int hz = ONE_MHZ);
157
158 /** Read from OSPI peripheral with the preset read_instruction and alt_value
159 *
160 * @param address Address to be accessed in OSPI peripheral
161 * @param rx_buffer Buffer for data to be read from the peripheral
162 * @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
163 *
164 * @returns
165 * Returns OSPI_STATUS_SUCCESS on successful reads and OSPI_STATUS_ERROR on failed reads.
166 */
167 ospi_status_t read(int address, char *rx_buffer, size_t *rx_length);
168
169 /** Write to OSPI peripheral using custom write instruction
170 *
171 * @param address Address to be accessed in OSPI peripheral
172 * @param tx_buffer Buffer containing data to be sent to peripheral
173 * @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
174 *
175 * @returns
176 * Returns OSPI_STATUS_SUCCESS on successful reads and OSPI_STATUS_ERROR on failed reads.
177 */
178 ospi_status_t write(int address, const char *tx_buffer, size_t *tx_length);
179
180 /** Read from OSPI peripheral using custom read instruction, alt values
181 *
182 * @param instruction Instruction value to be used in instruction phase. Use OSPI_NO_INST to skip the instruction phase
183 * @param alt Alt value to be used in Alternate-byte phase. Use -1 for ignoring Alternate-byte phase
184 * @param address Address to be accessed in OSPI peripheral
185 * @param rx_buffer Buffer for data to be read from the peripheral
186 * @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
187 *
188 * @returns
189 * Returns OSPI_STATUS_SUCCESS on successful reads and OSPI_STATUS_ERROR on failed reads.
190 */
191 ospi_status_t read(ospi_inst_t instruction, int alt, int address, char *rx_buffer, size_t *rx_length);
192
193 /** Write to OSPI peripheral using custom write instruction, alt values
194 *
195 * @param instruction Instruction value to be used in instruction phase. Use OSPI_NO_INST to skip the instruction phase
196 * @param alt Alt value to be used in Alternate-byte phase. Use -1 for ignoring Alternate-byte phase
197 * @param address Address to be accessed in OSPI peripheral
198 * @param tx_buffer Buffer containing data to be sent to peripheral
199 * @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
200 *
201 * @returns
202 * Returns OSPI_STATUS_SUCCESS on successful reads and OSPI_STATUS_ERROR on failed reads.
203 */
204 ospi_status_t write(ospi_inst_t instruction, int alt, int address, const char *tx_buffer, size_t *tx_length);
205
206 /** Perform a transaction to write to an address(a control register) and get the status results
207 *
208 * @param instruction Instruction value to be used in instruction phase. Use OSPI_NO_INST to skip the instruction phase
209 * @param address Some instruction might require address. Use -1 if no address
210 * @param tx_buffer Buffer containing data to be sent to peripheral
211 * @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
212 * @param rx_buffer Buffer for data to be read from the peripheral
213 * @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
214 *
215 * @returns
216 * Returns OSPI_STATUS_SUCCESS on successful reads and OSPI_STATUS_ERROR on failed reads.
217 */
218 ospi_status_t command_transfer(ospi_inst_t instruction, int address, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length);
219
220#if !defined(DOXYGEN_ONLY)
221protected:
222 /** Acquire exclusive access to this SPI bus
223 */
224 virtual void lock(void);
225
226 /** Release exclusive access to this SPI bus
227 */
228 virtual void unlock(void);
229
230 ospi_t _ospi;
231
232 static SingletonPtr<rtos::Mutex> _mutex;
233 ospi_bus_width_t _inst_width; //Bus width for Instruction phase
234 ospi_inst_size_t _inst_size; //Instruction Size
235 ospi_bus_width_t _address_width; //Bus width for Address phase
236 ospi_address_size_t _address_size;
237 ospi_bus_width_t _alt_width; //Bus width for Alt phase
238 ospi_alt_size_t _alt_size;
239 ospi_bus_width_t _data_width; //Bus width for Data phase
240 ospi_command_t _ospi_command; //OSPI Hal command struct
241 unsigned int _num_dummy_cycles; //Number of dummy cycles to be used
242 int _hz; //Bus Frequency
243 int _mode; //SPI mode
244 bool _initialized;
245 PinName _ospi_io0, _ospi_io1, _ospi_io2, _ospi_io3, _ospi_io4, _ospi_io5, _ospi_io6, _ospi_io7, _ospi_clk, _ospi_cs, _ospi_dqs; //IO lines, clock, chip select and dqs
246 const ospi_pinmap_t *_static_pinmap;
247 bool (OSPI::* _init_func)(void);
248
249private:
250 bool _initialize();
251 bool _initialize_direct();
252
253 /*
254 * This function builds the ospi command struct to be send to Hal
255 */
256 inline void _build_ospi_command(ospi_inst_t instruction, int address, int alt);
257#endif
258};
259
260/** @}*/
261
262} // namespace mbed
263
264#endif
265
266#endif
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:162
A OSPI Driver, used for communicating with OSPI slave devices.
Definition: OSPI.h:87
ospi_status_t read(int address, char *rx_buffer, size_t *rx_length)
Read from OSPI peripheral with the preset read_instruction and alt_value.
ospi_status_t read(ospi_inst_t instruction, int alt, int address, char *rx_buffer, size_t *rx_length)
Read from OSPI peripheral using custom read instruction, alt values.
ospi_status_t configure_format(ospi_bus_width_t inst_width, ospi_inst_size_t inst_size, ospi_bus_width_t address_width, ospi_address_size_t address_size, ospi_bus_width_t alt_width, ospi_alt_size_t alt_size, ospi_bus_width_t data_width, int dummy_cycles)
Configure the data transmission format.
ospi_status_t write(int address, const char *tx_buffer, size_t *tx_length)
Write to OSPI peripheral using custom write instruction.
OSPI(const ospi_pinmap_t &pinmap, int mode=0)
Create a OSPI master connected to the specified pins.
ospi_status_t command_transfer(ospi_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.
ospi_status_t set_frequency(int hz=1000000)
Set the ospi bus clock frequency.
ospi_status_t write(ospi_inst_t instruction, int alt, int address, const char *tx_buffer, size_t *tx_length)
Write to OSPI peripheral using custom write instruction, alt values.
OSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName io4, PinName io5, PinName io6, PinName io7, PinName sclk, PinName ssel=NC, PinName dqs=NC, int mode=0)
Create a OSPI master connected to the specified pins.
int ospi_inst_t
Type representing a OSPI instruction.
Definition: OSPI.h:46
Utility class for creating and using a singleton.
Definition: SingletonPtr.h:88