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_test_utils.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2018-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 "utest/utest.h" 00018 00019 #include "hal/qspi_api.h" 00020 #include "qspi_test_utils.h" 00021 00022 #include "unity/unity.h" 00023 00024 #include <string.h> // for memset 00025 00026 #include "flash_configs/flash_configs.h" 00027 #include "mbed.h" 00028 00029 static qspi_status_t extended_enable(Qspi &qspi); 00030 static qspi_status_t extended_disable(Qspi &qspi); 00031 static qspi_status_t dual_enable(Qspi &qspi); 00032 static qspi_status_t dual_disable(Qspi &qspi); 00033 static qspi_status_t quad_enable(Qspi &qspi); 00034 static qspi_status_t quad_disable(Qspi &qspi); 00035 00036 void QspiCommand::configure(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, 00037 qspi_bus_width_t data_width, qspi_bus_width_t alt_width, 00038 qspi_address_size_t addr_size, qspi_alt_size_t alt_size, 00039 int dummy_cycles) 00040 { 00041 memset(&_cmd, 0, sizeof(qspi_command_t)); 00042 _cmd.instruction.disabled = _cmd.address.disabled = _cmd.alt.disabled = true; 00043 00044 _cmd.instruction.bus_width = inst_width; 00045 _cmd.address.bus_width = addr_width; 00046 _cmd.address.size = addr_size; 00047 _cmd.alt.bus_width = alt_width; 00048 _cmd.alt.size = alt_size; 00049 _cmd.data.bus_width = data_width; 00050 _cmd.dummy_count = dummy_cycles; 00051 } 00052 00053 void QspiCommand::set_dummy_cycles(int dummy_cycles) 00054 { 00055 _cmd.dummy_count = dummy_cycles; 00056 } 00057 00058 void QspiCommand::build(int instruction, int address, int alt) 00059 { 00060 _cmd.instruction.disabled = (instruction == QSPI_NONE); 00061 if (!_cmd.instruction.disabled) { 00062 _cmd.instruction.value = instruction; 00063 } 00064 00065 _cmd.address.disabled = (address == QSPI_NONE); 00066 if (!_cmd.address.disabled) { 00067 _cmd.address.value = address; 00068 } 00069 00070 _cmd.alt.disabled = (alt == QSPI_NONE); 00071 if (!_cmd.alt.disabled) { 00072 _cmd.alt.value = alt; 00073 } 00074 } 00075 00076 qspi_command_t *QspiCommand::get() 00077 { 00078 return &_cmd; 00079 } 00080 00081 00082 qspi_status_t read_register(uint32_t cmd, uint8_t *buf, uint32_t size, Qspi &q) 00083 { 00084 q.cmd.build(cmd); 00085 return qspi_command_transfer(&q.handle, q.cmd.get(), NULL, 0, buf, size); 00086 } 00087 00088 qspi_status_t write_register(uint32_t cmd, uint8_t *buf, uint32_t size, Qspi &q) 00089 { 00090 q.cmd.build(cmd); 00091 return qspi_command_transfer(&q.handle, q.cmd.get(), buf, size, NULL, 0); 00092 } 00093 00094 00095 QspiStatus flash_wait_for(uint32_t time_us, Qspi &qspi) 00096 { 00097 uint8_t reg[QSPI_STATUS_REG_SIZE]; 00098 qspi_status_t ret; 00099 uint32_t curr_time; 00100 00101 const ticker_data_t *const ticker = get_us_ticker_data(); 00102 const uint32_t start = ticker_read(ticker); 00103 00104 memset(reg, 255, QSPI_STATUS_REG_SIZE); 00105 do { 00106 ret = read_register(STATUS_REG, reg, QSPI_STATUS_REG_SIZE, qspi); 00107 curr_time = ticker_read(ticker); 00108 } while (((reg[0] & STATUS_BIT_WIP) != 0) && ((curr_time - start) < time_us)); 00109 00110 if (((reg[0] & STATUS_BIT_WIP) == 0) && (ret == QSPI_STATUS_OK)) { 00111 return sOK; 00112 } else if (ret != QSPI_STATUS_OK) { 00113 return sError; 00114 } else if ((curr_time - start) >= time_us) { 00115 return sTimeout; 00116 } 00117 return sUnknown; 00118 } 00119 00120 void flash_init(Qspi &qspi) 00121 { 00122 uint8_t status[QSPI_STATUS_REG_SIZE]; 00123 qspi_status_t ret; 00124 00125 qspi.cmd.build(QSPI_CMD_RDSR); 00126 ret = qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, status, QSPI_STATUS_REG_SIZE); 00127 TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret); 00128 00129 qspi.cmd.build(QSPI_CMD_RSTEN); 00130 ret = qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0); 00131 TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret); 00132 00133 WAIT_FOR(WRSR_MAX_TIME, qspi); 00134 00135 qspi.cmd.build(QSPI_CMD_RST); 00136 ret = qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0); 00137 TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret); 00138 00139 WAIT_FOR(WAIT_MAX_TIME, qspi); 00140 } 00141 00142 00143 qspi_status_t write_enable(Qspi &qspi) 00144 { 00145 uint8_t reg[QSPI_STATUS_REG_SIZE]; 00146 qspi.cmd.build(QSPI_CMD_WREN); 00147 00148 if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0) != QSPI_STATUS_OK) { 00149 return QSPI_STATUS_ERROR; 00150 } 00151 WAIT_FOR(WRSR_MAX_TIME, qspi); 00152 00153 memset(reg, 0, QSPI_STATUS_REG_SIZE); 00154 if (read_register(STATUS_REG, reg, QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { 00155 return QSPI_STATUS_ERROR; 00156 } 00157 00158 return ((reg[0] & STATUS_BIT_WEL) != 0 ? QSPI_STATUS_OK : QSPI_STATUS_ERROR); 00159 } 00160 00161 qspi_status_t write_disable(Qspi &qspi) 00162 { 00163 uint8_t reg[QSPI_STATUS_REG_SIZE]; 00164 qspi.cmd.build(QSPI_CMD_WRDI); 00165 00166 if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0) != QSPI_STATUS_OK) { 00167 return QSPI_STATUS_ERROR; 00168 } 00169 WAIT_FOR(WRSR_MAX_TIME, qspi); 00170 00171 memset(reg, 0, QSPI_STATUS_REG_SIZE); 00172 if (read_register(STATUS_REG, reg, QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { 00173 return QSPI_STATUS_ERROR; 00174 } 00175 00176 return ((reg[0] & STATUS_BIT_WEL) == 0 ? QSPI_STATUS_OK : QSPI_STATUS_ERROR); 00177 } 00178 00179 void log_register(uint32_t cmd, uint32_t reg_size, Qspi &qspi, const char *str) 00180 { 00181 qspi_status_t ret; 00182 static uint8_t reg[QSPI_MAX_REG_SIZE]; 00183 00184 ret = read_register(cmd, reg, reg_size, qspi); 00185 TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret); 00186 00187 for (uint32_t j = 0; j < reg_size; j++) { 00188 utest_printf("%s byte %u (MSB first): ", str != NULL ? str : "", j); 00189 for (int i = 0; i < 8; i++) { 00190 utest_printf("%s ", ((reg[j] & (1 << (7 - i))) & 0xFF) == 0 ? "0" : "1"); 00191 } 00192 utest_printf("\r\n"); 00193 } 00194 } 00195 00196 qspi_status_t erase(uint32_t erase_cmd, uint32_t flash_addr, Qspi &qspi) 00197 { 00198 qspi.cmd.build(erase_cmd, flash_addr); 00199 return qspi_command_transfer(&qspi.handle, qspi.cmd.get(), NULL, 0, NULL, 0); 00200 } 00201 00202 qspi_status_t mode_enable(Qspi &qspi, qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width) 00203 { 00204 if(is_extended_mode(inst_width, addr_width, data_width)) { 00205 return extended_enable(qspi); 00206 } else if(is_dual_mode(inst_width, addr_width, data_width)) { 00207 return dual_enable(qspi); 00208 } else if(is_quad_mode(inst_width, addr_width, data_width)) { 00209 return quad_enable(qspi); 00210 } else { 00211 return QSPI_STATUS_OK; 00212 } 00213 } 00214 00215 qspi_status_t mode_disable(Qspi &qspi, qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width) 00216 { 00217 if(is_extended_mode(inst_width, addr_width, data_width)) { 00218 return extended_disable(qspi); 00219 } else if(is_dual_mode(inst_width, addr_width, data_width)) { 00220 return dual_disable(qspi); 00221 } else if(is_quad_mode(inst_width, addr_width, data_width)) { 00222 return quad_disable(qspi); 00223 } else { 00224 return QSPI_STATUS_OK; 00225 } 00226 } 00227 00228 static qspi_status_t extended_enable(Qspi &qspi) 00229 { 00230 #ifdef EXTENDED_SPI_ENABLE 00231 EXTENDED_SPI_ENABLE(); 00232 #else 00233 return QSPI_STATUS_OK; 00234 #endif 00235 } 00236 00237 static qspi_status_t extended_disable(Qspi &qspi) 00238 { 00239 #ifdef EXTENDED_SPI_DISABLE 00240 EXTENDED_SPI_DISABLE(); 00241 #else 00242 return QSPI_STATUS_OK; 00243 #endif 00244 } 00245 00246 static qspi_status_t dual_enable(Qspi &qspi) 00247 { 00248 #ifdef DUAL_ENABLE 00249 DUAL_ENABLE(); 00250 #else 00251 return QSPI_STATUS_OK; 00252 #endif 00253 } 00254 00255 static qspi_status_t dual_disable(Qspi &qspi) 00256 { 00257 #ifdef DUAL_DISABLE 00258 DUAL_DISABLE(); 00259 #else 00260 return QSPI_STATUS_OK; 00261 #endif 00262 00263 } 00264 00265 static qspi_status_t quad_enable(Qspi &qspi) 00266 { 00267 #ifdef QUAD_ENABLE 00268 QUAD_ENABLE(); 00269 #else 00270 return QSPI_STATUS_OK; 00271 #endif 00272 } 00273 00274 static qspi_status_t quad_disable(Qspi &qspi) 00275 { 00276 #ifdef QUAD_DISABLE 00277 QUAD_DISABLE(); 00278 #else 00279 return QSPI_STATUS_OK; 00280 #endif 00281 } 00282 00283 qspi_status_t fast_mode_enable(Qspi &qspi) 00284 { 00285 #ifdef FAST_MODE_ENABLE 00286 FAST_MODE_ENABLE(); 00287 #else 00288 return QSPI_STATUS_OK; 00289 #endif 00290 } 00291 00292 qspi_status_t fast_mode_disable(Qspi &qspi) 00293 { 00294 #ifdef FAST_MODE_DISABLE 00295 FAST_MODE_DISABLE(); 00296 #else 00297 return QSPI_STATUS_OK; 00298 #endif 00299 } 00300 00301 bool is_extended_mode(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width) 00302 { 00303 return (inst_width == QSPI_CFG_BUS_SINGLE) && ((addr_width != QSPI_CFG_BUS_SINGLE) || (data_width != QSPI_CFG_BUS_SINGLE)); 00304 } 00305 00306 bool is_dual_mode(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width) 00307 { 00308 return (inst_width == QSPI_CFG_BUS_DUAL) && (addr_width == QSPI_CFG_BUS_DUAL) && (data_width == QSPI_CFG_BUS_DUAL); 00309 } 00310 00311 bool is_quad_mode(qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width) 00312 { 00313 return (inst_width == QSPI_CFG_BUS_QUAD) && (addr_width == QSPI_CFG_BUS_QUAD) && (data_width == QSPI_CFG_BUS_QUAD); 00314 }
Generated on Tue Aug 9 2022 00:37:18 by
1.7.2