mbed-os5 only for TYBLE16
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
drivers/source/QSPI.cpp@1:9db0e321a9f4, 2019-12-31 (annotated)
- Committer:
- kenjiArai
- Date:
- Tue Dec 31 06:02:27 2019 +0000
- Revision:
- 1:9db0e321a9f4
updated based on mbed-os5.15.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 1:9db0e321a9f4 | 1 | /* mbed Microcontroller Library |
kenjiArai | 1:9db0e321a9f4 | 2 | * Copyright (c) 2006-2018 ARM Limited |
kenjiArai | 1:9db0e321a9f4 | 3 | * SPDX-License-Identifier: Apache-2.0 |
kenjiArai | 1:9db0e321a9f4 | 4 | * |
kenjiArai | 1:9db0e321a9f4 | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
kenjiArai | 1:9db0e321a9f4 | 6 | * you may not use this file except in compliance with the License. |
kenjiArai | 1:9db0e321a9f4 | 7 | * You may obtain a copy of the License at |
kenjiArai | 1:9db0e321a9f4 | 8 | * |
kenjiArai | 1:9db0e321a9f4 | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
kenjiArai | 1:9db0e321a9f4 | 10 | * |
kenjiArai | 1:9db0e321a9f4 | 11 | * Unless required by applicable law or agreed to in writing, software |
kenjiArai | 1:9db0e321a9f4 | 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
kenjiArai | 1:9db0e321a9f4 | 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
kenjiArai | 1:9db0e321a9f4 | 14 | * See the License for the specific language governing permissions and |
kenjiArai | 1:9db0e321a9f4 | 15 | * limitations under the License. |
kenjiArai | 1:9db0e321a9f4 | 16 | */ |
kenjiArai | 1:9db0e321a9f4 | 17 | |
kenjiArai | 1:9db0e321a9f4 | 18 | #include "drivers/QSPI.h" |
kenjiArai | 1:9db0e321a9f4 | 19 | #include "platform/mbed_critical.h" |
kenjiArai | 1:9db0e321a9f4 | 20 | #include <string.h> |
kenjiArai | 1:9db0e321a9f4 | 21 | |
kenjiArai | 1:9db0e321a9f4 | 22 | #if DEVICE_QSPI |
kenjiArai | 1:9db0e321a9f4 | 23 | |
kenjiArai | 1:9db0e321a9f4 | 24 | namespace mbed { |
kenjiArai | 1:9db0e321a9f4 | 25 | |
kenjiArai | 1:9db0e321a9f4 | 26 | QSPI *QSPI::_owner = NULL; |
kenjiArai | 1:9db0e321a9f4 | 27 | SingletonPtr<PlatformMutex> QSPI::_mutex; |
kenjiArai | 1:9db0e321a9f4 | 28 | |
kenjiArai | 1:9db0e321a9f4 | 29 | uint8_t convert_bus_width_to_line_count(qspi_bus_width_t width) |
kenjiArai | 1:9db0e321a9f4 | 30 | { |
kenjiArai | 1:9db0e321a9f4 | 31 | switch (width) { |
kenjiArai | 1:9db0e321a9f4 | 32 | case QSPI_CFG_BUS_SINGLE: |
kenjiArai | 1:9db0e321a9f4 | 33 | return 1; |
kenjiArai | 1:9db0e321a9f4 | 34 | case QSPI_CFG_BUS_DUAL: |
kenjiArai | 1:9db0e321a9f4 | 35 | return 2; |
kenjiArai | 1:9db0e321a9f4 | 36 | case QSPI_CFG_BUS_QUAD: |
kenjiArai | 1:9db0e321a9f4 | 37 | return 4; |
kenjiArai | 1:9db0e321a9f4 | 38 | default: |
kenjiArai | 1:9db0e321a9f4 | 39 | // Unrecognized bus width |
kenjiArai | 1:9db0e321a9f4 | 40 | return 0; |
kenjiArai | 1:9db0e321a9f4 | 41 | } |
kenjiArai | 1:9db0e321a9f4 | 42 | } |
kenjiArai | 1:9db0e321a9f4 | 43 | |
kenjiArai | 1:9db0e321a9f4 | 44 | QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel, int mode) : _qspi() |
kenjiArai | 1:9db0e321a9f4 | 45 | { |
kenjiArai | 1:9db0e321a9f4 | 46 | _qspi_io0 = io0; |
kenjiArai | 1:9db0e321a9f4 | 47 | _qspi_io1 = io1; |
kenjiArai | 1:9db0e321a9f4 | 48 | _qspi_io2 = io2; |
kenjiArai | 1:9db0e321a9f4 | 49 | _qspi_io3 = io3; |
kenjiArai | 1:9db0e321a9f4 | 50 | _qspi_clk = sclk; |
kenjiArai | 1:9db0e321a9f4 | 51 | _qspi_cs = ssel; |
kenjiArai | 1:9db0e321a9f4 | 52 | _static_pinmap = NULL; |
kenjiArai | 1:9db0e321a9f4 | 53 | _inst_width = QSPI_CFG_BUS_SINGLE; |
kenjiArai | 1:9db0e321a9f4 | 54 | _address_width = QSPI_CFG_BUS_SINGLE; |
kenjiArai | 1:9db0e321a9f4 | 55 | _address_size = QSPI_CFG_ADDR_SIZE_24; |
kenjiArai | 1:9db0e321a9f4 | 56 | _alt_width = QSPI_CFG_BUS_SINGLE; |
kenjiArai | 1:9db0e321a9f4 | 57 | _alt_size = 0; |
kenjiArai | 1:9db0e321a9f4 | 58 | _data_width = QSPI_CFG_BUS_SINGLE; |
kenjiArai | 1:9db0e321a9f4 | 59 | _num_dummy_cycles = 0; |
kenjiArai | 1:9db0e321a9f4 | 60 | _mode = mode; |
kenjiArai | 1:9db0e321a9f4 | 61 | _hz = ONE_MHZ; |
kenjiArai | 1:9db0e321a9f4 | 62 | _initialized = false; |
kenjiArai | 1:9db0e321a9f4 | 63 | _init_func = &QSPI::_initialize; |
kenjiArai | 1:9db0e321a9f4 | 64 | |
kenjiArai | 1:9db0e321a9f4 | 65 | //Go ahead init the device here with the default config |
kenjiArai | 1:9db0e321a9f4 | 66 | bool success = (this->*_init_func)(); |
kenjiArai | 1:9db0e321a9f4 | 67 | MBED_ASSERT(success); |
kenjiArai | 1:9db0e321a9f4 | 68 | } |
kenjiArai | 1:9db0e321a9f4 | 69 | |
kenjiArai | 1:9db0e321a9f4 | 70 | QSPI::QSPI(const qspi_pinmap_t &pinmap, int mode) : _qspi() |
kenjiArai | 1:9db0e321a9f4 | 71 | { |
kenjiArai | 1:9db0e321a9f4 | 72 | _qspi_io0 = pinmap.data0_pin; |
kenjiArai | 1:9db0e321a9f4 | 73 | _qspi_io1 = pinmap.data1_pin; |
kenjiArai | 1:9db0e321a9f4 | 74 | _qspi_io2 = pinmap.data2_pin; |
kenjiArai | 1:9db0e321a9f4 | 75 | _qspi_io3 = pinmap.data3_pin; |
kenjiArai | 1:9db0e321a9f4 | 76 | _qspi_clk = pinmap.sclk_pin; |
kenjiArai | 1:9db0e321a9f4 | 77 | _qspi_cs = pinmap.ssel_pin; |
kenjiArai | 1:9db0e321a9f4 | 78 | _static_pinmap = &pinmap; |
kenjiArai | 1:9db0e321a9f4 | 79 | _inst_width = QSPI_CFG_BUS_SINGLE; |
kenjiArai | 1:9db0e321a9f4 | 80 | _address_width = QSPI_CFG_BUS_SINGLE; |
kenjiArai | 1:9db0e321a9f4 | 81 | _address_size = QSPI_CFG_ADDR_SIZE_24; |
kenjiArai | 1:9db0e321a9f4 | 82 | _alt_width = QSPI_CFG_BUS_SINGLE; |
kenjiArai | 1:9db0e321a9f4 | 83 | _alt_size = QSPI_CFG_ALT_SIZE_8; |
kenjiArai | 1:9db0e321a9f4 | 84 | _data_width = QSPI_CFG_BUS_SINGLE; |
kenjiArai | 1:9db0e321a9f4 | 85 | _num_dummy_cycles = 0; |
kenjiArai | 1:9db0e321a9f4 | 86 | _mode = mode; |
kenjiArai | 1:9db0e321a9f4 | 87 | _hz = ONE_MHZ; |
kenjiArai | 1:9db0e321a9f4 | 88 | _initialized = false; |
kenjiArai | 1:9db0e321a9f4 | 89 | _init_func = &QSPI::_initialize_direct; |
kenjiArai | 1:9db0e321a9f4 | 90 | |
kenjiArai | 1:9db0e321a9f4 | 91 | //Go ahead init the device here with the default config |
kenjiArai | 1:9db0e321a9f4 | 92 | bool success = (this->*_init_func)(); |
kenjiArai | 1:9db0e321a9f4 | 93 | MBED_ASSERT(success); |
kenjiArai | 1:9db0e321a9f4 | 94 | } |
kenjiArai | 1:9db0e321a9f4 | 95 | |
kenjiArai | 1:9db0e321a9f4 | 96 | 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) |
kenjiArai | 1:9db0e321a9f4 | 97 | { |
kenjiArai | 1:9db0e321a9f4 | 98 | // Check that alt_size/alt_width are a valid combination |
kenjiArai | 1:9db0e321a9f4 | 99 | uint8_t alt_lines = convert_bus_width_to_line_count(alt_width); |
kenjiArai | 1:9db0e321a9f4 | 100 | if (alt_lines == 0) { |
kenjiArai | 1:9db0e321a9f4 | 101 | return QSPI_STATUS_ERROR; |
kenjiArai | 1:9db0e321a9f4 | 102 | } else if (alt_size % alt_lines != 0) { |
kenjiArai | 1:9db0e321a9f4 | 103 | // Invalid alt size/width combination (alt size is not a multiple of the number of bus lines used to transmit it) |
kenjiArai | 1:9db0e321a9f4 | 104 | return QSPI_STATUS_ERROR; |
kenjiArai | 1:9db0e321a9f4 | 105 | } |
kenjiArai | 1:9db0e321a9f4 | 106 | |
kenjiArai | 1:9db0e321a9f4 | 107 | lock(); |
kenjiArai | 1:9db0e321a9f4 | 108 | _inst_width = inst_width; |
kenjiArai | 1:9db0e321a9f4 | 109 | _address_width = address_width; |
kenjiArai | 1:9db0e321a9f4 | 110 | _address_size = address_size; |
kenjiArai | 1:9db0e321a9f4 | 111 | _alt_width = alt_width; |
kenjiArai | 1:9db0e321a9f4 | 112 | _alt_size = alt_size; |
kenjiArai | 1:9db0e321a9f4 | 113 | _data_width = data_width; |
kenjiArai | 1:9db0e321a9f4 | 114 | _num_dummy_cycles = dummy_cycles; |
kenjiArai | 1:9db0e321a9f4 | 115 | unlock(); |
kenjiArai | 1:9db0e321a9f4 | 116 | |
kenjiArai | 1:9db0e321a9f4 | 117 | return QSPI_STATUS_OK; |
kenjiArai | 1:9db0e321a9f4 | 118 | } |
kenjiArai | 1:9db0e321a9f4 | 119 | |
kenjiArai | 1:9db0e321a9f4 | 120 | qspi_status_t QSPI::set_frequency(int hz) |
kenjiArai | 1:9db0e321a9f4 | 121 | { |
kenjiArai | 1:9db0e321a9f4 | 122 | qspi_status_t ret_status = QSPI_STATUS_OK; |
kenjiArai | 1:9db0e321a9f4 | 123 | |
kenjiArai | 1:9db0e321a9f4 | 124 | if (_initialized) { |
kenjiArai | 1:9db0e321a9f4 | 125 | lock(); |
kenjiArai | 1:9db0e321a9f4 | 126 | _hz = hz; |
kenjiArai | 1:9db0e321a9f4 | 127 | //If the same owner, just change freq. |
kenjiArai | 1:9db0e321a9f4 | 128 | //Otherwise we may have to change mode as well, so call _acquire |
kenjiArai | 1:9db0e321a9f4 | 129 | if (_owner == this) { |
kenjiArai | 1:9db0e321a9f4 | 130 | if (QSPI_STATUS_OK != qspi_frequency(&_qspi, _hz)) { |
kenjiArai | 1:9db0e321a9f4 | 131 | ret_status = QSPI_STATUS_ERROR; |
kenjiArai | 1:9db0e321a9f4 | 132 | } |
kenjiArai | 1:9db0e321a9f4 | 133 | } else { |
kenjiArai | 1:9db0e321a9f4 | 134 | _acquire(); |
kenjiArai | 1:9db0e321a9f4 | 135 | } |
kenjiArai | 1:9db0e321a9f4 | 136 | unlock(); |
kenjiArai | 1:9db0e321a9f4 | 137 | } else { |
kenjiArai | 1:9db0e321a9f4 | 138 | ret_status = QSPI_STATUS_ERROR; |
kenjiArai | 1:9db0e321a9f4 | 139 | } |
kenjiArai | 1:9db0e321a9f4 | 140 | |
kenjiArai | 1:9db0e321a9f4 | 141 | return ret_status; |
kenjiArai | 1:9db0e321a9f4 | 142 | } |
kenjiArai | 1:9db0e321a9f4 | 143 | |
kenjiArai | 1:9db0e321a9f4 | 144 | qspi_status_t QSPI::read(int address, char *rx_buffer, size_t *rx_length) |
kenjiArai | 1:9db0e321a9f4 | 145 | { |
kenjiArai | 1:9db0e321a9f4 | 146 | qspi_status_t ret_status = QSPI_STATUS_ERROR; |
kenjiArai | 1:9db0e321a9f4 | 147 | |
kenjiArai | 1:9db0e321a9f4 | 148 | if (_initialized) { |
kenjiArai | 1:9db0e321a9f4 | 149 | if ((rx_length != NULL) && (rx_buffer != NULL)) { |
kenjiArai | 1:9db0e321a9f4 | 150 | if (*rx_length != 0) { |
kenjiArai | 1:9db0e321a9f4 | 151 | lock(); |
kenjiArai | 1:9db0e321a9f4 | 152 | if (true == _acquire()) { |
kenjiArai | 1:9db0e321a9f4 | 153 | _build_qspi_command(QSPI_NO_INST, address, -1); |
kenjiArai | 1:9db0e321a9f4 | 154 | if (QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) { |
kenjiArai | 1:9db0e321a9f4 | 155 | ret_status = QSPI_STATUS_OK; |
kenjiArai | 1:9db0e321a9f4 | 156 | } |
kenjiArai | 1:9db0e321a9f4 | 157 | } |
kenjiArai | 1:9db0e321a9f4 | 158 | unlock(); |
kenjiArai | 1:9db0e321a9f4 | 159 | } |
kenjiArai | 1:9db0e321a9f4 | 160 | } else { |
kenjiArai | 1:9db0e321a9f4 | 161 | ret_status = QSPI_STATUS_INVALID_PARAMETER; |
kenjiArai | 1:9db0e321a9f4 | 162 | } |
kenjiArai | 1:9db0e321a9f4 | 163 | } |
kenjiArai | 1:9db0e321a9f4 | 164 | |
kenjiArai | 1:9db0e321a9f4 | 165 | return ret_status; |
kenjiArai | 1:9db0e321a9f4 | 166 | } |
kenjiArai | 1:9db0e321a9f4 | 167 | |
kenjiArai | 1:9db0e321a9f4 | 168 | qspi_status_t QSPI::write(int address, const char *tx_buffer, size_t *tx_length) |
kenjiArai | 1:9db0e321a9f4 | 169 | { |
kenjiArai | 1:9db0e321a9f4 | 170 | qspi_status_t ret_status = QSPI_STATUS_ERROR; |
kenjiArai | 1:9db0e321a9f4 | 171 | |
kenjiArai | 1:9db0e321a9f4 | 172 | if (_initialized) { |
kenjiArai | 1:9db0e321a9f4 | 173 | if ((tx_length != NULL) && (tx_buffer != NULL)) { |
kenjiArai | 1:9db0e321a9f4 | 174 | if (*tx_length != 0) { |
kenjiArai | 1:9db0e321a9f4 | 175 | lock(); |
kenjiArai | 1:9db0e321a9f4 | 176 | if (true == _acquire()) { |
kenjiArai | 1:9db0e321a9f4 | 177 | _build_qspi_command(QSPI_NO_INST, address, -1); |
kenjiArai | 1:9db0e321a9f4 | 178 | if (QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) { |
kenjiArai | 1:9db0e321a9f4 | 179 | ret_status = QSPI_STATUS_OK; |
kenjiArai | 1:9db0e321a9f4 | 180 | } |
kenjiArai | 1:9db0e321a9f4 | 181 | } |
kenjiArai | 1:9db0e321a9f4 | 182 | unlock(); |
kenjiArai | 1:9db0e321a9f4 | 183 | } |
kenjiArai | 1:9db0e321a9f4 | 184 | } else { |
kenjiArai | 1:9db0e321a9f4 | 185 | ret_status = QSPI_STATUS_INVALID_PARAMETER; |
kenjiArai | 1:9db0e321a9f4 | 186 | } |
kenjiArai | 1:9db0e321a9f4 | 187 | } |
kenjiArai | 1:9db0e321a9f4 | 188 | |
kenjiArai | 1:9db0e321a9f4 | 189 | return ret_status; |
kenjiArai | 1:9db0e321a9f4 | 190 | } |
kenjiArai | 1:9db0e321a9f4 | 191 | |
kenjiArai | 1:9db0e321a9f4 | 192 | qspi_status_t QSPI::read(qspi_inst_t instruction, int alt, int address, char *rx_buffer, size_t *rx_length) |
kenjiArai | 1:9db0e321a9f4 | 193 | { |
kenjiArai | 1:9db0e321a9f4 | 194 | qspi_status_t ret_status = QSPI_STATUS_ERROR; |
kenjiArai | 1:9db0e321a9f4 | 195 | |
kenjiArai | 1:9db0e321a9f4 | 196 | if (_initialized) { |
kenjiArai | 1:9db0e321a9f4 | 197 | if ((rx_length != NULL) && (rx_buffer != NULL)) { |
kenjiArai | 1:9db0e321a9f4 | 198 | if (*rx_length != 0) { |
kenjiArai | 1:9db0e321a9f4 | 199 | lock(); |
kenjiArai | 1:9db0e321a9f4 | 200 | if (true == _acquire()) { |
kenjiArai | 1:9db0e321a9f4 | 201 | _build_qspi_command(instruction, address, alt); |
kenjiArai | 1:9db0e321a9f4 | 202 | if (QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) { |
kenjiArai | 1:9db0e321a9f4 | 203 | ret_status = QSPI_STATUS_OK; |
kenjiArai | 1:9db0e321a9f4 | 204 | } |
kenjiArai | 1:9db0e321a9f4 | 205 | } |
kenjiArai | 1:9db0e321a9f4 | 206 | unlock(); |
kenjiArai | 1:9db0e321a9f4 | 207 | } |
kenjiArai | 1:9db0e321a9f4 | 208 | } else { |
kenjiArai | 1:9db0e321a9f4 | 209 | ret_status = QSPI_STATUS_INVALID_PARAMETER; |
kenjiArai | 1:9db0e321a9f4 | 210 | } |
kenjiArai | 1:9db0e321a9f4 | 211 | } |
kenjiArai | 1:9db0e321a9f4 | 212 | |
kenjiArai | 1:9db0e321a9f4 | 213 | return ret_status; |
kenjiArai | 1:9db0e321a9f4 | 214 | } |
kenjiArai | 1:9db0e321a9f4 | 215 | |
kenjiArai | 1:9db0e321a9f4 | 216 | qspi_status_t QSPI::write(qspi_inst_t instruction, int alt, int address, const char *tx_buffer, size_t *tx_length) |
kenjiArai | 1:9db0e321a9f4 | 217 | { |
kenjiArai | 1:9db0e321a9f4 | 218 | qspi_status_t ret_status = QSPI_STATUS_ERROR; |
kenjiArai | 1:9db0e321a9f4 | 219 | |
kenjiArai | 1:9db0e321a9f4 | 220 | if (_initialized) { |
kenjiArai | 1:9db0e321a9f4 | 221 | if ((tx_length != NULL) && (tx_buffer != NULL)) { |
kenjiArai | 1:9db0e321a9f4 | 222 | if (*tx_length != 0) { |
kenjiArai | 1:9db0e321a9f4 | 223 | lock(); |
kenjiArai | 1:9db0e321a9f4 | 224 | if (true == _acquire()) { |
kenjiArai | 1:9db0e321a9f4 | 225 | _build_qspi_command(instruction, address, alt); |
kenjiArai | 1:9db0e321a9f4 | 226 | if (QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) { |
kenjiArai | 1:9db0e321a9f4 | 227 | ret_status = QSPI_STATUS_OK; |
kenjiArai | 1:9db0e321a9f4 | 228 | } |
kenjiArai | 1:9db0e321a9f4 | 229 | } |
kenjiArai | 1:9db0e321a9f4 | 230 | unlock(); |
kenjiArai | 1:9db0e321a9f4 | 231 | } |
kenjiArai | 1:9db0e321a9f4 | 232 | } else { |
kenjiArai | 1:9db0e321a9f4 | 233 | ret_status = QSPI_STATUS_INVALID_PARAMETER; |
kenjiArai | 1:9db0e321a9f4 | 234 | } |
kenjiArai | 1:9db0e321a9f4 | 235 | } |
kenjiArai | 1:9db0e321a9f4 | 236 | |
kenjiArai | 1:9db0e321a9f4 | 237 | return ret_status; |
kenjiArai | 1:9db0e321a9f4 | 238 | } |
kenjiArai | 1:9db0e321a9f4 | 239 | |
kenjiArai | 1:9db0e321a9f4 | 240 | qspi_status_t QSPI::command_transfer(qspi_inst_t instruction, int address, const char *tx_buffer, size_t tx_length, const char *rx_buffer, size_t rx_length) |
kenjiArai | 1:9db0e321a9f4 | 241 | { |
kenjiArai | 1:9db0e321a9f4 | 242 | qspi_status_t ret_status = QSPI_STATUS_ERROR; |
kenjiArai | 1:9db0e321a9f4 | 243 | |
kenjiArai | 1:9db0e321a9f4 | 244 | if (_initialized) { |
kenjiArai | 1:9db0e321a9f4 | 245 | lock(); |
kenjiArai | 1:9db0e321a9f4 | 246 | if (true == _acquire()) { |
kenjiArai | 1:9db0e321a9f4 | 247 | _build_qspi_command(instruction, address, -1); //We just need the command |
kenjiArai | 1:9db0e321a9f4 | 248 | if (QSPI_STATUS_OK == qspi_command_transfer(&_qspi, &_qspi_command, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) { |
kenjiArai | 1:9db0e321a9f4 | 249 | ret_status = QSPI_STATUS_OK; |
kenjiArai | 1:9db0e321a9f4 | 250 | } |
kenjiArai | 1:9db0e321a9f4 | 251 | } |
kenjiArai | 1:9db0e321a9f4 | 252 | unlock(); |
kenjiArai | 1:9db0e321a9f4 | 253 | } |
kenjiArai | 1:9db0e321a9f4 | 254 | |
kenjiArai | 1:9db0e321a9f4 | 255 | return ret_status; |
kenjiArai | 1:9db0e321a9f4 | 256 | } |
kenjiArai | 1:9db0e321a9f4 | 257 | |
kenjiArai | 1:9db0e321a9f4 | 258 | void QSPI::lock() |
kenjiArai | 1:9db0e321a9f4 | 259 | { |
kenjiArai | 1:9db0e321a9f4 | 260 | _mutex->lock(); |
kenjiArai | 1:9db0e321a9f4 | 261 | } |
kenjiArai | 1:9db0e321a9f4 | 262 | |
kenjiArai | 1:9db0e321a9f4 | 263 | void QSPI::unlock() |
kenjiArai | 1:9db0e321a9f4 | 264 | { |
kenjiArai | 1:9db0e321a9f4 | 265 | _mutex->unlock(); |
kenjiArai | 1:9db0e321a9f4 | 266 | } |
kenjiArai | 1:9db0e321a9f4 | 267 | |
kenjiArai | 1:9db0e321a9f4 | 268 | // Note: Private helper function to initialize qspi HAL |
kenjiArai | 1:9db0e321a9f4 | 269 | bool QSPI::_initialize() |
kenjiArai | 1:9db0e321a9f4 | 270 | { |
kenjiArai | 1:9db0e321a9f4 | 271 | if (_mode != 0 && _mode != 1) { |
kenjiArai | 1:9db0e321a9f4 | 272 | _initialized = false; |
kenjiArai | 1:9db0e321a9f4 | 273 | return _initialized; |
kenjiArai | 1:9db0e321a9f4 | 274 | } |
kenjiArai | 1:9db0e321a9f4 | 275 | |
kenjiArai | 1:9db0e321a9f4 | 276 | qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode); |
kenjiArai | 1:9db0e321a9f4 | 277 | if (QSPI_STATUS_OK == ret) { |
kenjiArai | 1:9db0e321a9f4 | 278 | _initialized = true; |
kenjiArai | 1:9db0e321a9f4 | 279 | } else { |
kenjiArai | 1:9db0e321a9f4 | 280 | _initialized = false; |
kenjiArai | 1:9db0e321a9f4 | 281 | } |
kenjiArai | 1:9db0e321a9f4 | 282 | |
kenjiArai | 1:9db0e321a9f4 | 283 | return _initialized; |
kenjiArai | 1:9db0e321a9f4 | 284 | } |
kenjiArai | 1:9db0e321a9f4 | 285 | |
kenjiArai | 1:9db0e321a9f4 | 286 | // Note: Private helper function to initialize qspi HAL |
kenjiArai | 1:9db0e321a9f4 | 287 | bool QSPI::_initialize_direct() |
kenjiArai | 1:9db0e321a9f4 | 288 | { |
kenjiArai | 1:9db0e321a9f4 | 289 | if (_mode != 0 && _mode != 1) { |
kenjiArai | 1:9db0e321a9f4 | 290 | _initialized = false; |
kenjiArai | 1:9db0e321a9f4 | 291 | return _initialized; |
kenjiArai | 1:9db0e321a9f4 | 292 | } |
kenjiArai | 1:9db0e321a9f4 | 293 | |
kenjiArai | 1:9db0e321a9f4 | 294 | qspi_status_t ret = qspi_init_direct(&_qspi, _static_pinmap, _hz, _mode); |
kenjiArai | 1:9db0e321a9f4 | 295 | if (QSPI_STATUS_OK == ret) { |
kenjiArai | 1:9db0e321a9f4 | 296 | _initialized = true; |
kenjiArai | 1:9db0e321a9f4 | 297 | } else { |
kenjiArai | 1:9db0e321a9f4 | 298 | _initialized = false; |
kenjiArai | 1:9db0e321a9f4 | 299 | } |
kenjiArai | 1:9db0e321a9f4 | 300 | |
kenjiArai | 1:9db0e321a9f4 | 301 | return _initialized; |
kenjiArai | 1:9db0e321a9f4 | 302 | } |
kenjiArai | 1:9db0e321a9f4 | 303 | |
kenjiArai | 1:9db0e321a9f4 | 304 | // Note: Private function with no locking |
kenjiArai | 1:9db0e321a9f4 | 305 | bool QSPI::_acquire() |
kenjiArai | 1:9db0e321a9f4 | 306 | { |
kenjiArai | 1:9db0e321a9f4 | 307 | if (_owner != this) { |
kenjiArai | 1:9db0e321a9f4 | 308 | //This will set freq as well |
kenjiArai | 1:9db0e321a9f4 | 309 | (this->*_init_func)(); |
kenjiArai | 1:9db0e321a9f4 | 310 | _owner = this; |
kenjiArai | 1:9db0e321a9f4 | 311 | } |
kenjiArai | 1:9db0e321a9f4 | 312 | |
kenjiArai | 1:9db0e321a9f4 | 313 | return _initialized; |
kenjiArai | 1:9db0e321a9f4 | 314 | } |
kenjiArai | 1:9db0e321a9f4 | 315 | |
kenjiArai | 1:9db0e321a9f4 | 316 | void QSPI::_build_qspi_command(qspi_inst_t instruction, int address, int alt) |
kenjiArai | 1:9db0e321a9f4 | 317 | { |
kenjiArai | 1:9db0e321a9f4 | 318 | memset(&_qspi_command, 0, sizeof(qspi_command_t)); |
kenjiArai | 1:9db0e321a9f4 | 319 | //Set up instruction phase parameters |
kenjiArai | 1:9db0e321a9f4 | 320 | _qspi_command.instruction.bus_width = _inst_width; |
kenjiArai | 1:9db0e321a9f4 | 321 | if (instruction != QSPI_NO_INST) { |
kenjiArai | 1:9db0e321a9f4 | 322 | _qspi_command.instruction.value = instruction; |
kenjiArai | 1:9db0e321a9f4 | 323 | _qspi_command.instruction.disabled = false; |
kenjiArai | 1:9db0e321a9f4 | 324 | } else { |
kenjiArai | 1:9db0e321a9f4 | 325 | _qspi_command.instruction.disabled = true; |
kenjiArai | 1:9db0e321a9f4 | 326 | } |
kenjiArai | 1:9db0e321a9f4 | 327 | |
kenjiArai | 1:9db0e321a9f4 | 328 | //Set up address phase parameters |
kenjiArai | 1:9db0e321a9f4 | 329 | _qspi_command.address.bus_width = _address_width; |
kenjiArai | 1:9db0e321a9f4 | 330 | _qspi_command.address.size = _address_size; |
kenjiArai | 1:9db0e321a9f4 | 331 | if (address != -1) { |
kenjiArai | 1:9db0e321a9f4 | 332 | _qspi_command.address.value = address; |
kenjiArai | 1:9db0e321a9f4 | 333 | _qspi_command.address.disabled = false; |
kenjiArai | 1:9db0e321a9f4 | 334 | } else { |
kenjiArai | 1:9db0e321a9f4 | 335 | _qspi_command.address.disabled = true; |
kenjiArai | 1:9db0e321a9f4 | 336 | } |
kenjiArai | 1:9db0e321a9f4 | 337 | |
kenjiArai | 1:9db0e321a9f4 | 338 | //Set up alt phase parameters |
kenjiArai | 1:9db0e321a9f4 | 339 | _qspi_command.alt.bus_width = _alt_width; |
kenjiArai | 1:9db0e321a9f4 | 340 | _qspi_command.alt.size = _alt_size; |
kenjiArai | 1:9db0e321a9f4 | 341 | if (alt != -1) { |
kenjiArai | 1:9db0e321a9f4 | 342 | _qspi_command.alt.value = alt; |
kenjiArai | 1:9db0e321a9f4 | 343 | _qspi_command.alt.disabled = false; |
kenjiArai | 1:9db0e321a9f4 | 344 | } else { |
kenjiArai | 1:9db0e321a9f4 | 345 | _qspi_command.alt.disabled = true; |
kenjiArai | 1:9db0e321a9f4 | 346 | } |
kenjiArai | 1:9db0e321a9f4 | 347 | |
kenjiArai | 1:9db0e321a9f4 | 348 | _qspi_command.dummy_count = _num_dummy_cycles; |
kenjiArai | 1:9db0e321a9f4 | 349 | |
kenjiArai | 1:9db0e321a9f4 | 350 | //Set up bus width for data phase |
kenjiArai | 1:9db0e321a9f4 | 351 | _qspi_command.data.bus_width = _data_width; |
kenjiArai | 1:9db0e321a9f4 | 352 | } |
kenjiArai | 1:9db0e321a9f4 | 353 | |
kenjiArai | 1:9db0e321a9f4 | 354 | } // namespace mbed |
kenjiArai | 1:9db0e321a9f4 | 355 | |
kenjiArai | 1:9db0e321a9f4 | 356 | #endif |