RTC auf true

Committer:
kevman
Date:
Wed Mar 13 11:03:24 2019 +0000
Revision:
2:7aab896b1a3b
Parent:
0:38ceb79fef03
2019-03-13

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevman 0:38ceb79fef03 1 /* mbed Microcontroller Library
kevman 0:38ceb79fef03 2 * Copyright (c) 2006-2018 ARM Limited
kevman 0:38ceb79fef03 3 *
kevman 0:38ceb79fef03 4 * Licensed under the Apache License, Version 2.0 (the "License");
kevman 0:38ceb79fef03 5 * you may not use this file except in compliance with the License.
kevman 0:38ceb79fef03 6 * You may obtain a copy of the License at
kevman 0:38ceb79fef03 7 *
kevman 0:38ceb79fef03 8 * http://www.apache.org/licenses/LICENSE-2.0
kevman 0:38ceb79fef03 9 *
kevman 0:38ceb79fef03 10 * Unless required by applicable law or agreed to in writing, software
kevman 0:38ceb79fef03 11 * distributed under the License is distributed on an "AS IS" BASIS,
kevman 0:38ceb79fef03 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kevman 0:38ceb79fef03 13 * See the License for the specific language governing permissions and
kevman 0:38ceb79fef03 14 * limitations under the License.
kevman 0:38ceb79fef03 15 */
kevman 0:38ceb79fef03 16
kevman 0:38ceb79fef03 17 #include "drivers/QSPI.h"
kevman 0:38ceb79fef03 18 #include "platform/mbed_critical.h"
kevman 0:38ceb79fef03 19 #include <string.h>
kevman 0:38ceb79fef03 20
kevman 0:38ceb79fef03 21 #if DEVICE_QSPI
kevman 0:38ceb79fef03 22
kevman 0:38ceb79fef03 23 namespace mbed {
kevman 0:38ceb79fef03 24
kevman 0:38ceb79fef03 25 QSPI *QSPI::_owner = NULL;
kevman 0:38ceb79fef03 26 SingletonPtr<PlatformMutex> QSPI::_mutex;
kevman 0:38ceb79fef03 27
kevman 0:38ceb79fef03 28 QSPI::QSPI(PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel, int mode) : _qspi()
kevman 0:38ceb79fef03 29 {
kevman 0:38ceb79fef03 30 _qspi_io0 = io0;
kevman 0:38ceb79fef03 31 _qspi_io1 = io1;
kevman 0:38ceb79fef03 32 _qspi_io2 = io2;
kevman 0:38ceb79fef03 33 _qspi_io3 = io3;
kevman 0:38ceb79fef03 34 _qspi_clk = sclk;
kevman 0:38ceb79fef03 35 _qspi_cs = ssel;
kevman 0:38ceb79fef03 36 _inst_width = QSPI_CFG_BUS_SINGLE;
kevman 0:38ceb79fef03 37 _address_width = QSPI_CFG_BUS_SINGLE;
kevman 0:38ceb79fef03 38 _address_size = QSPI_CFG_ADDR_SIZE_24;
kevman 0:38ceb79fef03 39 _alt_width = QSPI_CFG_BUS_SINGLE;
kevman 0:38ceb79fef03 40 _alt_size = QSPI_CFG_ALT_SIZE_8;
kevman 0:38ceb79fef03 41 _data_width = QSPI_CFG_BUS_SINGLE;
kevman 0:38ceb79fef03 42 _num_dummy_cycles = 0;
kevman 0:38ceb79fef03 43 _mode = mode;
kevman 0:38ceb79fef03 44 _hz = ONE_MHZ;
kevman 0:38ceb79fef03 45 _initialized = false;
kevman 0:38ceb79fef03 46
kevman 0:38ceb79fef03 47 //Go ahead init the device here with the default config
kevman 0:38ceb79fef03 48 bool success = _initialize();
kevman 0:38ceb79fef03 49 MBED_ASSERT(success);
kevman 0:38ceb79fef03 50 }
kevman 0:38ceb79fef03 51
kevman 0:38ceb79fef03 52 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)
kevman 0:38ceb79fef03 53 {
kevman 0:38ceb79fef03 54 qspi_status_t ret_status = QSPI_STATUS_OK;
kevman 0:38ceb79fef03 55
kevman 0:38ceb79fef03 56 lock();
kevman 0:38ceb79fef03 57 _inst_width = inst_width;
kevman 0:38ceb79fef03 58 _address_width = address_width;
kevman 0:38ceb79fef03 59 _address_size = address_size;
kevman 0:38ceb79fef03 60 _alt_width = alt_width;
kevman 0:38ceb79fef03 61 _alt_size = alt_size;
kevman 0:38ceb79fef03 62 _data_width = data_width;
kevman 0:38ceb79fef03 63 _num_dummy_cycles = dummy_cycles;
kevman 0:38ceb79fef03 64
kevman 0:38ceb79fef03 65 unlock();
kevman 0:38ceb79fef03 66
kevman 0:38ceb79fef03 67 return ret_status;
kevman 0:38ceb79fef03 68 }
kevman 0:38ceb79fef03 69
kevman 0:38ceb79fef03 70 qspi_status_t QSPI::set_frequency(int hz)
kevman 0:38ceb79fef03 71 {
kevman 0:38ceb79fef03 72 qspi_status_t ret_status = QSPI_STATUS_OK;
kevman 0:38ceb79fef03 73
kevman 0:38ceb79fef03 74 if (_initialized) {
kevman 0:38ceb79fef03 75 lock();
kevman 0:38ceb79fef03 76 _hz = hz;
kevman 0:38ceb79fef03 77 //If the same owner, just change freq.
kevman 0:38ceb79fef03 78 //Otherwise we may have to change mode as well, so call _acquire
kevman 0:38ceb79fef03 79 if (_owner == this) {
kevman 0:38ceb79fef03 80 if (QSPI_STATUS_OK != qspi_frequency(&_qspi, _hz)) {
kevman 0:38ceb79fef03 81 ret_status = QSPI_STATUS_ERROR;
kevman 0:38ceb79fef03 82 }
kevman 0:38ceb79fef03 83 } else {
kevman 0:38ceb79fef03 84 _acquire();
kevman 0:38ceb79fef03 85 }
kevman 0:38ceb79fef03 86 unlock();
kevman 0:38ceb79fef03 87 } else {
kevman 0:38ceb79fef03 88 ret_status = QSPI_STATUS_ERROR;
kevman 0:38ceb79fef03 89 }
kevman 0:38ceb79fef03 90
kevman 0:38ceb79fef03 91 return ret_status;
kevman 0:38ceb79fef03 92 }
kevman 0:38ceb79fef03 93
kevman 0:38ceb79fef03 94 qspi_status_t QSPI::read(int address, char *rx_buffer, size_t *rx_length)
kevman 0:38ceb79fef03 95 {
kevman 0:38ceb79fef03 96 qspi_status_t ret_status = QSPI_STATUS_ERROR;
kevman 0:38ceb79fef03 97
kevman 0:38ceb79fef03 98 if (_initialized) {
kevman 0:38ceb79fef03 99 if ((rx_length != NULL) && (rx_buffer != NULL)) {
kevman 0:38ceb79fef03 100 if (*rx_length != 0) {
kevman 0:38ceb79fef03 101 lock();
kevman 0:38ceb79fef03 102 if (true == _acquire()) {
kevman 0:38ceb79fef03 103 _build_qspi_command(-1, address, -1);
kevman 0:38ceb79fef03 104 if (QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
kevman 0:38ceb79fef03 105 ret_status = QSPI_STATUS_OK;
kevman 0:38ceb79fef03 106 }
kevman 0:38ceb79fef03 107 }
kevman 0:38ceb79fef03 108 unlock();
kevman 0:38ceb79fef03 109 }
kevman 0:38ceb79fef03 110 } else {
kevman 0:38ceb79fef03 111 ret_status = QSPI_STATUS_INVALID_PARAMETER;
kevman 0:38ceb79fef03 112 }
kevman 0:38ceb79fef03 113 }
kevman 0:38ceb79fef03 114
kevman 0:38ceb79fef03 115 return ret_status;
kevman 0:38ceb79fef03 116 }
kevman 0:38ceb79fef03 117
kevman 0:38ceb79fef03 118 qspi_status_t QSPI::write(int address, const char *tx_buffer, size_t *tx_length)
kevman 0:38ceb79fef03 119 {
kevman 0:38ceb79fef03 120 qspi_status_t ret_status = QSPI_STATUS_ERROR;
kevman 0:38ceb79fef03 121
kevman 0:38ceb79fef03 122 if (_initialized) {
kevman 0:38ceb79fef03 123 if ((tx_length != NULL) && (tx_buffer != NULL)) {
kevman 0:38ceb79fef03 124 if (*tx_length != 0) {
kevman 0:38ceb79fef03 125 lock();
kevman 0:38ceb79fef03 126 if (true == _acquire()) {
kevman 0:38ceb79fef03 127 _build_qspi_command(-1, address, -1);
kevman 0:38ceb79fef03 128 if (QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
kevman 0:38ceb79fef03 129 ret_status = QSPI_STATUS_OK;
kevman 0:38ceb79fef03 130 }
kevman 0:38ceb79fef03 131 }
kevman 0:38ceb79fef03 132 unlock();
kevman 0:38ceb79fef03 133 }
kevman 0:38ceb79fef03 134 } else {
kevman 0:38ceb79fef03 135 ret_status = QSPI_STATUS_INVALID_PARAMETER;
kevman 0:38ceb79fef03 136 }
kevman 0:38ceb79fef03 137 }
kevman 0:38ceb79fef03 138
kevman 0:38ceb79fef03 139 return ret_status;
kevman 0:38ceb79fef03 140 }
kevman 0:38ceb79fef03 141
kevman 0:38ceb79fef03 142 qspi_status_t QSPI::read(int instruction, int alt, int address, char *rx_buffer, size_t *rx_length)
kevman 0:38ceb79fef03 143 {
kevman 0:38ceb79fef03 144 qspi_status_t ret_status = QSPI_STATUS_ERROR;
kevman 0:38ceb79fef03 145
kevman 0:38ceb79fef03 146 if (_initialized) {
kevman 0:38ceb79fef03 147 if ((rx_length != NULL) && (rx_buffer != NULL)) {
kevman 0:38ceb79fef03 148 if (*rx_length != 0) {
kevman 0:38ceb79fef03 149 lock();
kevman 0:38ceb79fef03 150 if (true == _acquire()) {
kevman 0:38ceb79fef03 151 _build_qspi_command(instruction, address, alt);
kevman 0:38ceb79fef03 152 if (QSPI_STATUS_OK == qspi_read(&_qspi, &_qspi_command, rx_buffer, rx_length)) {
kevman 0:38ceb79fef03 153 ret_status = QSPI_STATUS_OK;
kevman 0:38ceb79fef03 154 }
kevman 0:38ceb79fef03 155 }
kevman 0:38ceb79fef03 156 unlock();
kevman 0:38ceb79fef03 157 }
kevman 0:38ceb79fef03 158 } else {
kevman 0:38ceb79fef03 159 ret_status = QSPI_STATUS_INVALID_PARAMETER;
kevman 0:38ceb79fef03 160 }
kevman 0:38ceb79fef03 161 }
kevman 0:38ceb79fef03 162
kevman 0:38ceb79fef03 163 return ret_status;
kevman 0:38ceb79fef03 164 }
kevman 0:38ceb79fef03 165
kevman 0:38ceb79fef03 166 qspi_status_t QSPI::write(int instruction, int alt, int address, const char *tx_buffer, size_t *tx_length)
kevman 0:38ceb79fef03 167 {
kevman 0:38ceb79fef03 168 qspi_status_t ret_status = QSPI_STATUS_ERROR;
kevman 0:38ceb79fef03 169
kevman 0:38ceb79fef03 170 if (_initialized) {
kevman 0:38ceb79fef03 171 if ((tx_length != NULL) && (tx_buffer != NULL)) {
kevman 0:38ceb79fef03 172 if (*tx_length != 0) {
kevman 0:38ceb79fef03 173 lock();
kevman 0:38ceb79fef03 174 if (true == _acquire()) {
kevman 0:38ceb79fef03 175 _build_qspi_command(instruction, address, alt);
kevman 0:38ceb79fef03 176 if (QSPI_STATUS_OK == qspi_write(&_qspi, &_qspi_command, tx_buffer, tx_length)) {
kevman 0:38ceb79fef03 177 ret_status = QSPI_STATUS_OK;
kevman 0:38ceb79fef03 178 }
kevman 0:38ceb79fef03 179 }
kevman 0:38ceb79fef03 180 unlock();
kevman 0:38ceb79fef03 181 }
kevman 0:38ceb79fef03 182 } else {
kevman 0:38ceb79fef03 183 ret_status = QSPI_STATUS_INVALID_PARAMETER;
kevman 0:38ceb79fef03 184 }
kevman 0:38ceb79fef03 185 }
kevman 0:38ceb79fef03 186
kevman 0:38ceb79fef03 187 return ret_status;
kevman 0:38ceb79fef03 188 }
kevman 0:38ceb79fef03 189
kevman 0:38ceb79fef03 190 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)
kevman 0:38ceb79fef03 191 {
kevman 0:38ceb79fef03 192 qspi_status_t ret_status = QSPI_STATUS_ERROR;
kevman 0:38ceb79fef03 193
kevman 0:38ceb79fef03 194 if (_initialized) {
kevman 0:38ceb79fef03 195 lock();
kevman 0:38ceb79fef03 196 if (true == _acquire()) {
kevman 0:38ceb79fef03 197 _build_qspi_command(instruction, address, -1); //We just need the command
kevman 0:38ceb79fef03 198 if (QSPI_STATUS_OK == qspi_command_transfer(&_qspi, &_qspi_command, (const void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length)) {
kevman 0:38ceb79fef03 199 ret_status = QSPI_STATUS_OK;
kevman 0:38ceb79fef03 200 }
kevman 0:38ceb79fef03 201 }
kevman 0:38ceb79fef03 202 unlock();
kevman 0:38ceb79fef03 203 }
kevman 0:38ceb79fef03 204
kevman 0:38ceb79fef03 205 return ret_status;
kevman 0:38ceb79fef03 206 }
kevman 0:38ceb79fef03 207
kevman 0:38ceb79fef03 208 void QSPI::lock()
kevman 0:38ceb79fef03 209 {
kevman 0:38ceb79fef03 210 _mutex->lock();
kevman 0:38ceb79fef03 211 }
kevman 0:38ceb79fef03 212
kevman 0:38ceb79fef03 213 void QSPI::unlock()
kevman 0:38ceb79fef03 214 {
kevman 0:38ceb79fef03 215 _mutex->unlock();
kevman 0:38ceb79fef03 216 }
kevman 0:38ceb79fef03 217
kevman 0:38ceb79fef03 218 // Note: Private helper function to initialize qspi HAL
kevman 0:38ceb79fef03 219 bool QSPI::_initialize()
kevman 0:38ceb79fef03 220 {
kevman 0:38ceb79fef03 221 if (_mode != 0 && _mode != 1) {
kevman 0:38ceb79fef03 222 _initialized = false;
kevman 0:38ceb79fef03 223 return _initialized;
kevman 0:38ceb79fef03 224 }
kevman 0:38ceb79fef03 225
kevman 0:38ceb79fef03 226 qspi_status_t ret = qspi_init(&_qspi, _qspi_io0, _qspi_io1, _qspi_io2, _qspi_io3, _qspi_clk, _qspi_cs, _hz, _mode);
kevman 0:38ceb79fef03 227 if (QSPI_STATUS_OK == ret) {
kevman 0:38ceb79fef03 228 _initialized = true;
kevman 0:38ceb79fef03 229 } else {
kevman 0:38ceb79fef03 230 _initialized = false;
kevman 0:38ceb79fef03 231 }
kevman 0:38ceb79fef03 232
kevman 0:38ceb79fef03 233 return _initialized;
kevman 0:38ceb79fef03 234 }
kevman 0:38ceb79fef03 235
kevman 0:38ceb79fef03 236 // Note: Private function with no locking
kevman 0:38ceb79fef03 237 bool QSPI::_acquire()
kevman 0:38ceb79fef03 238 {
kevman 0:38ceb79fef03 239 if (_owner != this) {
kevman 0:38ceb79fef03 240 //This will set freq as well
kevman 0:38ceb79fef03 241 _initialize();
kevman 0:38ceb79fef03 242 _owner = this;
kevman 0:38ceb79fef03 243 }
kevman 0:38ceb79fef03 244
kevman 0:38ceb79fef03 245 return _initialized;
kevman 0:38ceb79fef03 246 }
kevman 0:38ceb79fef03 247
kevman 0:38ceb79fef03 248 void QSPI::_build_qspi_command(int instruction, int address, int alt)
kevman 0:38ceb79fef03 249 {
kevman 0:38ceb79fef03 250 memset(&_qspi_command, 0, sizeof(qspi_command_t));
kevman 0:38ceb79fef03 251 //Set up instruction phase parameters
kevman 0:38ceb79fef03 252 _qspi_command.instruction.bus_width = _inst_width;
kevman 0:38ceb79fef03 253 if (instruction != -1) {
kevman 0:38ceb79fef03 254 _qspi_command.instruction.value = instruction;
kevman 0:38ceb79fef03 255 _qspi_command.instruction.disabled = false;
kevman 0:38ceb79fef03 256 } else {
kevman 0:38ceb79fef03 257 _qspi_command.instruction.disabled = true;
kevman 0:38ceb79fef03 258 }
kevman 0:38ceb79fef03 259
kevman 0:38ceb79fef03 260 //Set up address phase parameters
kevman 0:38ceb79fef03 261 _qspi_command.address.bus_width = _address_width;
kevman 0:38ceb79fef03 262 _qspi_command.address.size = _address_size;
kevman 0:38ceb79fef03 263 if (address != -1) {
kevman 0:38ceb79fef03 264 _qspi_command.address.value = address;
kevman 0:38ceb79fef03 265 _qspi_command.address.disabled = false;
kevman 0:38ceb79fef03 266 } else {
kevman 0:38ceb79fef03 267 _qspi_command.address.disabled = true;
kevman 0:38ceb79fef03 268 }
kevman 0:38ceb79fef03 269
kevman 0:38ceb79fef03 270 //Set up alt phase parameters
kevman 0:38ceb79fef03 271 _qspi_command.alt.bus_width = _alt_width;
kevman 0:38ceb79fef03 272 _qspi_command.alt.size = _alt_size;
kevman 0:38ceb79fef03 273 if (alt != -1) {
kevman 0:38ceb79fef03 274 _qspi_command.alt.value = alt;
kevman 0:38ceb79fef03 275 _qspi_command.alt.disabled = false;
kevman 0:38ceb79fef03 276 } else {
kevman 0:38ceb79fef03 277 _qspi_command.alt.disabled = true;
kevman 0:38ceb79fef03 278 }
kevman 0:38ceb79fef03 279
kevman 0:38ceb79fef03 280 _qspi_command.dummy_count = _num_dummy_cycles;
kevman 0:38ceb79fef03 281
kevman 0:38ceb79fef03 282 //Set up bus width for data phase
kevman 0:38ceb79fef03 283 _qspi_command.data.bus_width = _data_width;
kevman 0:38ceb79fef03 284 }
kevman 0:38ceb79fef03 285
kevman 0:38ceb79fef03 286 } // namespace mbed
kevman 0:38ceb79fef03 287
kevman 0:38ceb79fef03 288 #endif