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.cpp
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 00017 #include "drivers/QSPI.h" 00018 #include "platform/mbed_critical.h" 00019 #include <string.h> 00020 00021 #if DEVICE_QSPI 00022 00023 namespace mbed { 00024 00025 QSPI *QSPI::_owner = NULL; 00026 SingletonPtr<PlatformMutex> QSPI::_mutex; 00027 00028 QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel, int mode) : _qspi() 00029 { 00030 _qspi_io0 = io0; 00031 _qspi_io1 = io1; 00032 _qspi_io2 = io2; 00033 _qspi_io3 = io3; 00034 _qspi_clk = sclk; 00035 _qspi_cs = ssel; 00036 _inst_width = QSPI_CFG_BUS_SINGLE; 00037 _address_width = QSPI_CFG_BUS_SINGLE; 00038 _address_size = QSPI_CFG_ADDR_SIZE_24; 00039 _alt_width = QSPI_CFG_BUS_SINGLE; 00040 _alt_size = QSPI_CFG_ALT_SIZE_8; 00041 _data_width = QSPI_CFG_BUS_SINGLE; 00042 _num_dummy_cycles = 0; 00043 _mode = mode; 00044 _hz = ONE_MHZ; 00045 _initialized = false; 00046 00047 //Go ahead init the device here with the default config 00048 bool success = _initialize(); 00049 MBED_ASSERT(success); 00050 } 00051 00052 qspi_status_t QSPI::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) 00053 { 00054 qspi_status_t ret_status = QSPI_STATUS_OK; 00055 00056 lock(); 00057 _inst_width = inst_width; 00058 _address_width = address_width; 00059 _address_size = address_size; 00060 _alt_width = alt_width; 00061 _alt_size = alt_size; 00062 _data_width = data_width; 00063 _num_dummy_cycles = dummy_cycles; 00064 00065 unlock(); 00066 00067 return ret_status; 00068 } 00069 00070 qspi_status_t QSPI::set_frequency(int hz) 00071 { 00072 qspi_status_t ret_status = QSPI_STATUS_OK; 00073 00074 if (_initialized) { 00075 lock(); 00076 _hz = hz; 00077 //If the same owner, just change freq. 00078 //Otherwise we may have to change mode as well, so call _acquire 00079 if (_owner == this) { 00080 if (QSPI_STATUS_OK != qspi_frequency(&_qspi, _hz)) { 00081 ret_status = QSPI_STATUS_ERROR; 00082 } 00083 } else { 00084 _acquire(); 00085 } 00086 unlock(); 00087 } else { 00088 ret_status = QSPI_STATUS_ERROR; 00089 } 00090 00091 return ret_status; 00092 } 00093 00094 qspi_status_t QSPI::read(int address, char *rx_buffer, size_t *rx_length) 00095 { 00096 qspi_status_t ret_status = QSPI_STATUS_ERROR; 00097 00098 if (_initialized) { 00099 if ((rx_length != NULL) && (rx_buffer != NULL)) { 00100 if (*rx_length != 0) { 00101 lock(); 00102 if (true == _acquire()) { 00103 _build_qspi_command(-1, address, -1); 00104 if (QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) { 00105 ret_status = QSPI_STATUS_OK; 00106 } 00107 } 00108 unlock(); 00109 } 00110 } else { 00111 ret_status = QSPI_STATUS_INVALID_PARAMETER; 00112 } 00113 } 00114 00115 return ret_status; 00116 } 00117 00118 qspi_status_t QSPI::write(int address, const char *tx_buffer, size_t *tx_length) 00119 { 00120 qspi_status_t ret_status = QSPI_STATUS_ERROR; 00121 00122 if (_initialized) { 00123 if ((tx_length != NULL) && (tx_buffer != NULL)) { 00124 if (*tx_length != 0) { 00125 lock(); 00126 if (true == _acquire()) { 00127 _build_qspi_command(-1, address, -1); 00128 if (QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) { 00129 ret_status = QSPI_STATUS_OK; 00130 } 00131 } 00132 unlock(); 00133 } 00134 } else { 00135 ret_status = QSPI_STATUS_INVALID_PARAMETER; 00136 } 00137 } 00138 00139 return ret_status; 00140 } 00141 00142 qspi_status_t QSPI::read(int instruction, int alt, int address, char *rx_buffer, size_t *rx_length) 00143 { 00144 qspi_status_t ret_status = QSPI_STATUS_ERROR; 00145 00146 if (_initialized) { 00147 if ((rx_length != NULL) && (rx_buffer != NULL)) { 00148 if (*rx_length != 0) { 00149 lock(); 00150 if (true == _acquire()) { 00151 _build_qspi_command(instruction, address, alt); 00152 if (QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) { 00153 ret_status = QSPI_STATUS_OK; 00154 } 00155 } 00156 unlock(); 00157 } 00158 } else { 00159 ret_status = QSPI_STATUS_INVALID_PARAMETER; 00160 } 00161 } 00162 00163 return ret_status; 00164 } 00165 00166 qspi_status_t QSPI::write(int instruction, int alt, int address, const char *tx_buffer, size_t *tx_length) 00167 { 00168 qspi_status_t ret_status = QSPI_STATUS_ERROR; 00169 00170 if (_initialized) { 00171 if ((tx_length != NULL) && (tx_buffer != NULL)) { 00172 if (*tx_length != 0) { 00173 lock(); 00174 if (true == _acquire()) { 00175 _build_qspi_command(instruction, address, alt); 00176 if (QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) { 00177 ret_status = QSPI_STATUS_OK; 00178 } 00179 } 00180 unlock(); 00181 } 00182 } else { 00183 ret_status = QSPI_STATUS_INVALID_PARAMETER; 00184 } 00185 } 00186 00187 return ret_status; 00188 } 00189 00190 qspi_status_t QSPI::command_transfer(int instruction, int address, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length) 00191 { 00192 qspi_status_t ret_status = QSPI_STATUS_ERROR; 00193 00194 if (_initialized) { 00195 lock(); 00196 if (true == _acquire()) { 00197 _build_qspi_command(instruction, address, -1); //We just need the command 00198 if (QSPI_STATUS_OK == qspi_command_transfer(&_qspi, &_qspi_command, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) { 00199 ret_status = QSPI_STATUS_OK; 00200 } 00201 } 00202 unlock(); 00203 } 00204 00205 return ret_status; 00206 } 00207 00208 void QSPI::lock() 00209 { 00210 _mutex->lock(); 00211 } 00212 00213 void QSPI::unlock() 00214 { 00215 _mutex->unlock(); 00216 } 00217 00218 // Note: Private helper function to initialize qspi HAL 00219 bool QSPI::_initialize() 00220 { 00221 if (_mode != 0 && _mode != 1) { 00222 _initialized = false; 00223 return _initialized; 00224 } 00225 00226 qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode); 00227 if (QSPI_STATUS_OK == ret) { 00228 _initialized = true; 00229 } else { 00230 _initialized = false; 00231 } 00232 00233 return _initialized; 00234 } 00235 00236 // Note: Private function with no locking 00237 bool QSPI::_acquire() 00238 { 00239 if (_owner != this) { 00240 //This will set freq as well 00241 _initialize(); 00242 _owner = this; 00243 } 00244 00245 return _initialized; 00246 } 00247 00248 void QSPI::_build_qspi_command(int instruction, int address, int alt) 00249 { 00250 memset(&_qspi_command, 0, sizeof(qspi_command_t)); 00251 //Set up instruction phase parameters 00252 _qspi_command.instruction.bus_width = _inst_width; 00253 if (instruction != -1) { 00254 _qspi_command.instruction.value = instruction; 00255 _qspi_command.instruction.disabled = false; 00256 } else { 00257 _qspi_command.instruction.disabled = true; 00258 } 00259 00260 //Set up address phase parameters 00261 _qspi_command.address.bus_width = _address_width; 00262 _qspi_command.address.size = _address_size; 00263 if (address != -1) { 00264 _qspi_command.address.value = address; 00265 _qspi_command.address.disabled = false; 00266 } else { 00267 _qspi_command.address.disabled = true; 00268 } 00269 00270 //Set up alt phase parameters 00271 _qspi_command.alt.bus_width = _alt_width; 00272 _qspi_command.alt.size = _alt_size; 00273 if (alt != -1) { 00274 _qspi_command.alt.value = alt; 00275 _qspi_command.alt.disabled = false; 00276 } else { 00277 _qspi_command.alt.disabled = true; 00278 } 00279 00280 _qspi_command.dummy_count = _num_dummy_cycles; 00281 00282 //Set up bus width for data phase 00283 _qspi_command.data.bus_width = _data_width; 00284 } 00285 00286 } // namespace mbed 00287 00288 #endif
Generated on Tue Aug 9 2022 00:37:18 by
