mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
188:bcfe06ba3d64
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 188:bcfe06ba3d64 1 /***************************************************************************//**
AnnaBridge 188:bcfe06ba3d64 2 * @file rtc_rtcc.c
AnnaBridge 188:bcfe06ba3d64 3 *******************************************************************************
AnnaBridge 188:bcfe06ba3d64 4 * @section License
AnnaBridge 188:bcfe06ba3d64 5 * <b>(C) Copyright 2018 Silicon Labs, http://www.silabs.com</b>
AnnaBridge 188:bcfe06ba3d64 6 *******************************************************************************
AnnaBridge 188:bcfe06ba3d64 7 *
AnnaBridge 188:bcfe06ba3d64 8 * SPDX-License-Identifier: Apache-2.0
AnnaBridge 188:bcfe06ba3d64 9 *
AnnaBridge 188:bcfe06ba3d64 10 * Licensed under the Apache License, Version 2.0 (the "License"); you may
AnnaBridge 188:bcfe06ba3d64 11 * not use this file except in compliance with the License.
AnnaBridge 188:bcfe06ba3d64 12 * You may obtain a copy of the License at
AnnaBridge 188:bcfe06ba3d64 13 *
AnnaBridge 188:bcfe06ba3d64 14 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 188:bcfe06ba3d64 15 *
AnnaBridge 188:bcfe06ba3d64 16 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 188:bcfe06ba3d64 17 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
AnnaBridge 188:bcfe06ba3d64 18 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 188:bcfe06ba3d64 19 * See the License for the specific language governing permissions and
AnnaBridge 188:bcfe06ba3d64 20 * limitations under the License.
AnnaBridge 188:bcfe06ba3d64 21 *
AnnaBridge 188:bcfe06ba3d64 22 ******************************************************************************/
AnnaBridge 188:bcfe06ba3d64 23
AnnaBridge 188:bcfe06ba3d64 24 #include "device.h"
AnnaBridge 188:bcfe06ba3d64 25 #if DEVICE_QSPI && defined(QSPI_PRESENT)
AnnaBridge 188:bcfe06ba3d64 26
AnnaBridge 188:bcfe06ba3d64 27 #include "stddef.h"
AnnaBridge 188:bcfe06ba3d64 28 #include "qspi_api.h"
AnnaBridge 188:bcfe06ba3d64 29 #include "mbed_error.h"
AnnaBridge 188:bcfe06ba3d64 30 #include "em_cmu.h"
AnnaBridge 188:bcfe06ba3d64 31 #include "em_qspi.h"
AnnaBridge 188:bcfe06ba3d64 32 #include "pinmap.h"
AnnaBridge 188:bcfe06ba3d64 33 #include "PeripheralPins.h"
AnnaBridge 188:bcfe06ba3d64 34 #include "pinmap_function.h"
AnnaBridge 188:bcfe06ba3d64 35
AnnaBridge 188:bcfe06ba3d64 36 qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel, uint32_t hz, uint8_t mode)
AnnaBridge 188:bcfe06ba3d64 37 {
AnnaBridge 188:bcfe06ba3d64 38
AnnaBridge 188:bcfe06ba3d64 39 #if defined(QSPI_FLASH_EN)
AnnaBridge 188:bcfe06ba3d64 40 pin_mode(QSPI_FLASH_EN, PushPull);
AnnaBridge 188:bcfe06ba3d64 41 GPIO_PinOutSet((GPIO_Port_TypeDef)(QSPI_FLASH_EN >> 4 & 0xF), QSPI_FLASH_EN & 0xF);
AnnaBridge 188:bcfe06ba3d64 42 #endif
AnnaBridge 188:bcfe06ba3d64 43
AnnaBridge 188:bcfe06ba3d64 44 // There's only one QSPI per chip for now
AnnaBridge 188:bcfe06ba3d64 45 obj->instance = QSPI0;
AnnaBridge 188:bcfe06ba3d64 46 obj->io0 = io0;
AnnaBridge 188:bcfe06ba3d64 47 obj->io1 = io1;
AnnaBridge 188:bcfe06ba3d64 48 obj->io2 = io2;
AnnaBridge 188:bcfe06ba3d64 49 obj->io3 = io3;
AnnaBridge 188:bcfe06ba3d64 50 obj->ssel = ssel;
AnnaBridge 188:bcfe06ba3d64 51 obj->sclk = sclk;
AnnaBridge 188:bcfe06ba3d64 52
AnnaBridge 188:bcfe06ba3d64 53 CMU_ClockEnable(cmuClock_GPIO, true);
AnnaBridge 188:bcfe06ba3d64 54
AnnaBridge 188:bcfe06ba3d64 55 #if (CORE_CLOCK_SOURCE == HFXO)
AnnaBridge 188:bcfe06ba3d64 56 CMU_ClockSelectSet(cmuClock_QSPI0REF, cmuSelect_HFXO);
AnnaBridge 188:bcfe06ba3d64 57 #endif
AnnaBridge 188:bcfe06ba3d64 58
AnnaBridge 188:bcfe06ba3d64 59 CMU_ClockEnable(cmuClock_QSPI0, true);
AnnaBridge 188:bcfe06ba3d64 60 CMU_ClockEnable(cmuClock_QSPI0REF, true);
AnnaBridge 188:bcfe06ba3d64 61
AnnaBridge 188:bcfe06ba3d64 62 qspi_frequency(obj, hz);
AnnaBridge 188:bcfe06ba3d64 63
AnnaBridge 188:bcfe06ba3d64 64 if (mode) {
AnnaBridge 188:bcfe06ba3d64 65 obj->instance->CONFIG |= QSPI_CONFIG_SELCLKPOL | QSPI_CONFIG_SELCLKPHASE;
AnnaBridge 188:bcfe06ba3d64 66 } else {
AnnaBridge 188:bcfe06ba3d64 67 obj->instance->CONFIG &= ~(QSPI_CONFIG_SELCLKPOL | QSPI_CONFIG_SELCLKPHASE);
AnnaBridge 188:bcfe06ba3d64 68 }
AnnaBridge 188:bcfe06ba3d64 69
AnnaBridge 188:bcfe06ba3d64 70 uint32_t loc = pin_location(io0, PinMap_QSPI_DQ0);
AnnaBridge 188:bcfe06ba3d64 71 if (loc != pin_location(io1, PinMap_QSPI_DQ1) ||
AnnaBridge 188:bcfe06ba3d64 72 loc != pin_location(io2, PinMap_QSPI_DQ2) ||
AnnaBridge 188:bcfe06ba3d64 73 loc != pin_location(io3, PinMap_QSPI_DQ3) ||
AnnaBridge 188:bcfe06ba3d64 74 loc != pin_location(sclk, PinMap_QSPI_SCLK) ||
AnnaBridge 188:bcfe06ba3d64 75 loc != pin_location(ssel, PinMap_QSPI_CS0)) {
AnnaBridge 188:bcfe06ba3d64 76 // All pins need to be on the same location number
AnnaBridge 188:bcfe06ba3d64 77 qspi_free(obj);
AnnaBridge 188:bcfe06ba3d64 78 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 79 }
AnnaBridge 188:bcfe06ba3d64 80
AnnaBridge 188:bcfe06ba3d64 81 // Configure QSPI pins
AnnaBridge 188:bcfe06ba3d64 82 GPIO_PinOutClear((GPIO_Port_TypeDef)(io0 >> 4 & 0xF), io0 & 0xF);
AnnaBridge 188:bcfe06ba3d64 83 pin_mode(io0, PushPull);
AnnaBridge 188:bcfe06ba3d64 84
AnnaBridge 188:bcfe06ba3d64 85 GPIO_PinOutClear((GPIO_Port_TypeDef)(io1 >> 4 & 0xF), io1 & 0xF);
AnnaBridge 188:bcfe06ba3d64 86 pin_mode(io1, PushPull);
AnnaBridge 188:bcfe06ba3d64 87
AnnaBridge 188:bcfe06ba3d64 88 GPIO_PinOutClear((GPIO_Port_TypeDef)(io2 >> 4 & 0xF), io2 & 0xF);
AnnaBridge 188:bcfe06ba3d64 89 pin_mode(io2, PushPull);
AnnaBridge 188:bcfe06ba3d64 90
AnnaBridge 188:bcfe06ba3d64 91 GPIO_PinOutClear((GPIO_Port_TypeDef)(io3 >> 4 & 0xF), io3 & 0xF);
AnnaBridge 188:bcfe06ba3d64 92 pin_mode(io3, PushPull);
AnnaBridge 188:bcfe06ba3d64 93
AnnaBridge 188:bcfe06ba3d64 94 GPIO_PinOutClear((GPIO_Port_TypeDef)(sclk >> 4 & 0xF), sclk & 0xF);
AnnaBridge 188:bcfe06ba3d64 95 pin_mode(sclk, PushPull);
AnnaBridge 188:bcfe06ba3d64 96
AnnaBridge 188:bcfe06ba3d64 97 GPIO_PinOutSet((GPIO_Port_TypeDef)(ssel >> 4 & 0xF), ssel & 0xF);
AnnaBridge 188:bcfe06ba3d64 98 pin_mode(ssel, PushPull);
AnnaBridge 188:bcfe06ba3d64 99
AnnaBridge 188:bcfe06ba3d64 100
AnnaBridge 188:bcfe06ba3d64 101 // Configure QSPI routing to GPIO
AnnaBridge 188:bcfe06ba3d64 102 obj->instance->ROUTELOC0 = loc;
AnnaBridge 188:bcfe06ba3d64 103 obj->instance->ROUTEPEN = QSPI_ROUTEPEN_SCLKPEN
AnnaBridge 188:bcfe06ba3d64 104 | QSPI_ROUTEPEN_CS0PEN
AnnaBridge 188:bcfe06ba3d64 105 | QSPI_ROUTEPEN_DQ0PEN
AnnaBridge 188:bcfe06ba3d64 106 | QSPI_ROUTEPEN_DQ1PEN
AnnaBridge 188:bcfe06ba3d64 107 | QSPI_ROUTEPEN_DQ2PEN
AnnaBridge 188:bcfe06ba3d64 108 | QSPI_ROUTEPEN_DQ3PEN;
AnnaBridge 188:bcfe06ba3d64 109
AnnaBridge 188:bcfe06ba3d64 110 // Configure direct read
AnnaBridge 188:bcfe06ba3d64 111 QSPI_ReadConfig_TypeDef readConfig = QSPI_READCONFIG_DEFAULT;
AnnaBridge 188:bcfe06ba3d64 112 QSPI_ReadConfig(obj->instance, &readConfig);
AnnaBridge 188:bcfe06ba3d64 113
AnnaBridge 188:bcfe06ba3d64 114 // Configure direct write
AnnaBridge 188:bcfe06ba3d64 115 QSPI_WriteConfig_TypeDef writeConfig = QSPI_WRITECONFIG_DEFAULT;
AnnaBridge 188:bcfe06ba3d64 116 QSPI_WriteConfig(obj->instance, &writeConfig);
AnnaBridge 188:bcfe06ba3d64 117
AnnaBridge 188:bcfe06ba3d64 118 return QSPI_STATUS_OK;
AnnaBridge 188:bcfe06ba3d64 119 }
AnnaBridge 188:bcfe06ba3d64 120
AnnaBridge 188:bcfe06ba3d64 121 qspi_status_t qspi_free(qspi_t *obj)
AnnaBridge 188:bcfe06ba3d64 122 {
AnnaBridge 188:bcfe06ba3d64 123 pin_mode(obj->io0, Disabled);
AnnaBridge 188:bcfe06ba3d64 124 pin_mode(obj->io1, Disabled);
AnnaBridge 188:bcfe06ba3d64 125 pin_mode(obj->io2, Disabled);
AnnaBridge 188:bcfe06ba3d64 126 pin_mode(obj->io3, Disabled);
AnnaBridge 188:bcfe06ba3d64 127 pin_mode(obj->ssel, Disabled);
AnnaBridge 188:bcfe06ba3d64 128 pin_mode(obj->sclk, Disabled);
AnnaBridge 188:bcfe06ba3d64 129
AnnaBridge 188:bcfe06ba3d64 130 obj->instance->ROUTEPEN = 0;
AnnaBridge 188:bcfe06ba3d64 131
AnnaBridge 188:bcfe06ba3d64 132 QSPI_Enable(obj->instance, false);
AnnaBridge 188:bcfe06ba3d64 133 CMU_ClockEnable(cmuClock_QSPI0REF, false);
AnnaBridge 188:bcfe06ba3d64 134 CMU_ClockEnable(cmuClock_QSPI0, false);
AnnaBridge 188:bcfe06ba3d64 135
AnnaBridge 188:bcfe06ba3d64 136 return QSPI_STATUS_OK;
AnnaBridge 188:bcfe06ba3d64 137 }
AnnaBridge 188:bcfe06ba3d64 138
AnnaBridge 188:bcfe06ba3d64 139 qspi_status_t qspi_frequency(qspi_t *obj, int hz)
AnnaBridge 188:bcfe06ba3d64 140 {
AnnaBridge 188:bcfe06ba3d64 141 if (hz <= 0) {
AnnaBridge 188:bcfe06ba3d64 142 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 143 }
AnnaBridge 188:bcfe06ba3d64 144
AnnaBridge 188:bcfe06ba3d64 145 QSPI_Enable(obj->instance, false);
AnnaBridge 188:bcfe06ba3d64 146
AnnaBridge 188:bcfe06ba3d64 147 // Need at least a DIV4 for non-PHY mode and SDR transfers
AnnaBridge 188:bcfe06ba3d64 148 uint32_t basefreq = CMU_ClockFreqGet(cmuClock_QSPI0REF);
AnnaBridge 188:bcfe06ba3d64 149 uint32_t basediv = 4;
AnnaBridge 188:bcfe06ba3d64 150 if ((uint32_t)hz < (basefreq / basediv)) {
AnnaBridge 188:bcfe06ba3d64 151 basediv = (basefreq / hz) + 1;
AnnaBridge 188:bcfe06ba3d64 152 }
AnnaBridge 188:bcfe06ba3d64 153
AnnaBridge 188:bcfe06ba3d64 154 QSPI_Init_TypeDef initQspi = QSPI_INIT_DEFAULT;
AnnaBridge 188:bcfe06ba3d64 155 initQspi.divisor = basediv;
AnnaBridge 188:bcfe06ba3d64 156 QSPI_Init(obj->instance, &initQspi);
AnnaBridge 188:bcfe06ba3d64 157
AnnaBridge 188:bcfe06ba3d64 158 return QSPI_STATUS_OK;
AnnaBridge 188:bcfe06ba3d64 159 }
AnnaBridge 188:bcfe06ba3d64 160
AnnaBridge 188:bcfe06ba3d64 161 qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void *data, size_t *length)
AnnaBridge 188:bcfe06ba3d64 162 {
AnnaBridge 188:bcfe06ba3d64 163 QSPI_WriteConfig_TypeDef cfg = QSPI_WRITECONFIG_DEFAULT;
AnnaBridge 188:bcfe06ba3d64 164 uint32_t to_write = *length;
AnnaBridge 188:bcfe06ba3d64 165
AnnaBridge 188:bcfe06ba3d64 166 // Enforce word-sized access
AnnaBridge 188:bcfe06ba3d64 167 if ((to_write & 0x3) != 0) {
AnnaBridge 188:bcfe06ba3d64 168 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 169 }
AnnaBridge 188:bcfe06ba3d64 170
AnnaBridge 188:bcfe06ba3d64 171 cfg.dummyCycles = command->dummy_count;
AnnaBridge 188:bcfe06ba3d64 172
AnnaBridge 188:bcfe06ba3d64 173 if (command->instruction.disabled) {
AnnaBridge 188:bcfe06ba3d64 174 cfg.opCode = 0x02;
AnnaBridge 188:bcfe06ba3d64 175 } else {
AnnaBridge 188:bcfe06ba3d64 176 cfg.opCode = command->instruction.value;
AnnaBridge 188:bcfe06ba3d64 177 }
AnnaBridge 188:bcfe06ba3d64 178
AnnaBridge 188:bcfe06ba3d64 179 if (command->address.disabled) {
AnnaBridge 188:bcfe06ba3d64 180 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 181 } else {
AnnaBridge 188:bcfe06ba3d64 182 if (command->address.bus_width == QSPI_CFG_BUS_SINGLE) {
AnnaBridge 188:bcfe06ba3d64 183 cfg.addrTransfer = qspiTransferSingle;
AnnaBridge 188:bcfe06ba3d64 184 } else if (command->address.bus_width == QSPI_CFG_BUS_DUAL) {
AnnaBridge 188:bcfe06ba3d64 185 cfg.addrTransfer = qspiTransferDual;
AnnaBridge 188:bcfe06ba3d64 186 } else if (command->address.bus_width == QSPI_CFG_BUS_QUAD) {
AnnaBridge 188:bcfe06ba3d64 187 cfg.addrTransfer = qspiTransferQuad;
AnnaBridge 188:bcfe06ba3d64 188 } else {
AnnaBridge 188:bcfe06ba3d64 189 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 190 }
AnnaBridge 188:bcfe06ba3d64 191 }
AnnaBridge 188:bcfe06ba3d64 192
AnnaBridge 188:bcfe06ba3d64 193 if (command->data.bus_width == QSPI_CFG_BUS_SINGLE) {
AnnaBridge 188:bcfe06ba3d64 194 cfg.dataTransfer = qspiTransferSingle;
AnnaBridge 188:bcfe06ba3d64 195 } else if (command->data.bus_width == QSPI_CFG_BUS_DUAL) {
AnnaBridge 188:bcfe06ba3d64 196 cfg.dataTransfer = qspiTransferDual;
AnnaBridge 188:bcfe06ba3d64 197 } else if (command->data.bus_width == QSPI_CFG_BUS_QUAD) {
AnnaBridge 188:bcfe06ba3d64 198 cfg.dataTransfer = qspiTransferQuad;
AnnaBridge 188:bcfe06ba3d64 199 }
AnnaBridge 188:bcfe06ba3d64 200
AnnaBridge 188:bcfe06ba3d64 201 QSPI_WriteConfig(obj->instance, &cfg);
AnnaBridge 188:bcfe06ba3d64 202
AnnaBridge 188:bcfe06ba3d64 203 if (!command->alt.disabled) {
AnnaBridge 188:bcfe06ba3d64 204 // Do not support alt mode in write mode
AnnaBridge 188:bcfe06ba3d64 205 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 206 }
AnnaBridge 188:bcfe06ba3d64 207
AnnaBridge 188:bcfe06ba3d64 208 // Do an indirect write
AnnaBridge 188:bcfe06ba3d64 209 obj->instance->INDAHBADDRTRIGGER = QSPI0_MEM_BASE;
AnnaBridge 188:bcfe06ba3d64 210 obj->instance->INDIRECTWRITEXFERSTART = command->address.value;
AnnaBridge 188:bcfe06ba3d64 211 obj->instance->INDIRECTWRITEXFERNUMBYTES = to_write;
AnnaBridge 188:bcfe06ba3d64 212 obj->instance->INDIRECTWRITEXFERCTRL = QSPI_INDIRECTWRITEXFERCTRL_START;
AnnaBridge 188:bcfe06ba3d64 213
AnnaBridge 188:bcfe06ba3d64 214 // For the size of the transfer, poll the SRAM and fetch words from the SRAM
AnnaBridge 188:bcfe06ba3d64 215 for (uint32_t i = 0; i < to_write; i+=4) {
AnnaBridge 188:bcfe06ba3d64 216 // Wait for the QSPI in case we're writing too fast
AnnaBridge 188:bcfe06ba3d64 217 while (((obj->instance->SRAMFILL & _QSPI_SRAMFILL_SRAMFILLINDACWRITE_MASK) >> _QSPI_SRAMFILL_SRAMFILLINDACWRITE_SHIFT) >= 126);
AnnaBridge 188:bcfe06ba3d64 218
AnnaBridge 188:bcfe06ba3d64 219 // Unaligned access is fine on CM3/CM4 provided we stick to LDR/STR
AnnaBridge 188:bcfe06ba3d64 220 // With the line below, the compiler can't really do anything else anyways
AnnaBridge 188:bcfe06ba3d64 221 *((uint32_t*)QSPI0_MEM_BASE) = ((uint32_t*)data)[i/4];
AnnaBridge 188:bcfe06ba3d64 222 }
AnnaBridge 188:bcfe06ba3d64 223
AnnaBridge 188:bcfe06ba3d64 224 return QSPI_STATUS_OK;
AnnaBridge 188:bcfe06ba3d64 225 }
AnnaBridge 188:bcfe06ba3d64 226
AnnaBridge 188:bcfe06ba3d64 227 qspi_status_t qspi_command_transfer(qspi_t *obj, const qspi_command_t *command, const void *tx_data, size_t tx_size, void *rx_data, size_t rx_size)
AnnaBridge 188:bcfe06ba3d64 228 {
AnnaBridge 188:bcfe06ba3d64 229 QSPI_StigCmd_TypeDef cfg;
AnnaBridge 188:bcfe06ba3d64 230
AnnaBridge 188:bcfe06ba3d64 231 if (tx_size > 8 || rx_size > 8) {
AnnaBridge 188:bcfe06ba3d64 232 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 233 }
AnnaBridge 188:bcfe06ba3d64 234
AnnaBridge 188:bcfe06ba3d64 235 cfg.writeDataSize = tx_size;
AnnaBridge 188:bcfe06ba3d64 236 cfg.writeBuffer = (void*)tx_data;
AnnaBridge 188:bcfe06ba3d64 237
AnnaBridge 188:bcfe06ba3d64 238 cfg.readDataSize = rx_size;
AnnaBridge 188:bcfe06ba3d64 239 cfg.readBuffer = rx_data;
AnnaBridge 188:bcfe06ba3d64 240
AnnaBridge 188:bcfe06ba3d64 241 if (command->address.disabled) {
AnnaBridge 188:bcfe06ba3d64 242 cfg.addrSize = 0;
AnnaBridge 188:bcfe06ba3d64 243 cfg.address = 0;
AnnaBridge 188:bcfe06ba3d64 244 } else {
AnnaBridge 188:bcfe06ba3d64 245 if (command->address.size == QSPI_CFG_ADDR_SIZE_8) {
AnnaBridge 188:bcfe06ba3d64 246 cfg.addrSize = 1;
AnnaBridge 188:bcfe06ba3d64 247 } else if (command->address.size == QSPI_CFG_ADDR_SIZE_16) {
AnnaBridge 188:bcfe06ba3d64 248 cfg.addrSize = 2;
AnnaBridge 188:bcfe06ba3d64 249 } else if (command->address.size == QSPI_CFG_ADDR_SIZE_24) {
AnnaBridge 188:bcfe06ba3d64 250 cfg.addrSize = 3;
AnnaBridge 188:bcfe06ba3d64 251 } else if (command->address.size == QSPI_CFG_ADDR_SIZE_32) {
AnnaBridge 188:bcfe06ba3d64 252 cfg.addrSize = 4;
AnnaBridge 188:bcfe06ba3d64 253 } else {
AnnaBridge 188:bcfe06ba3d64 254 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 255 }
AnnaBridge 188:bcfe06ba3d64 256 cfg.address = command->address.value;
AnnaBridge 188:bcfe06ba3d64 257 }
AnnaBridge 188:bcfe06ba3d64 258
AnnaBridge 188:bcfe06ba3d64 259 if (command->instruction.disabled) {
AnnaBridge 188:bcfe06ba3d64 260 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 261 } else {
AnnaBridge 188:bcfe06ba3d64 262 cfg.cmdOpcode = command->instruction.value;
AnnaBridge 188:bcfe06ba3d64 263 }
AnnaBridge 188:bcfe06ba3d64 264
AnnaBridge 188:bcfe06ba3d64 265 cfg.dummyCycles = command->dummy_count;
AnnaBridge 188:bcfe06ba3d64 266
AnnaBridge 188:bcfe06ba3d64 267 if (!command->alt.disabled) {
AnnaBridge 188:bcfe06ba3d64 268 cfg.modeBitEnable = true;
AnnaBridge 188:bcfe06ba3d64 269 obj->instance->MODEBITCONFIG = command->alt.value & _QSPI_MODEBITCONFIG_MODE_MASK;
AnnaBridge 188:bcfe06ba3d64 270
AnnaBridge 188:bcfe06ba3d64 271 if(command->alt.size != QSPI_CFG_ALT_SIZE_8) {
AnnaBridge 188:bcfe06ba3d64 272 //do not support 'alt' bigger than 8 bit
AnnaBridge 188:bcfe06ba3d64 273 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 274 }
AnnaBridge 188:bcfe06ba3d64 275 } else {
AnnaBridge 188:bcfe06ba3d64 276 cfg.modeBitEnable = false;
AnnaBridge 188:bcfe06ba3d64 277 }
AnnaBridge 188:bcfe06ba3d64 278
AnnaBridge 188:bcfe06ba3d64 279 QSPI_ExecStigCmd(obj->instance, &cfg);
AnnaBridge 188:bcfe06ba3d64 280
AnnaBridge 188:bcfe06ba3d64 281 return QSPI_STATUS_OK;
AnnaBridge 188:bcfe06ba3d64 282 }
AnnaBridge 188:bcfe06ba3d64 283
AnnaBridge 188:bcfe06ba3d64 284 qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t *length)
AnnaBridge 188:bcfe06ba3d64 285 {
AnnaBridge 188:bcfe06ba3d64 286 QSPI_ReadConfig_TypeDef cfg = QSPI_READCONFIG_DEFAULT;
AnnaBridge 188:bcfe06ba3d64 287 uint32_t to_read = *length;
AnnaBridge 188:bcfe06ba3d64 288
AnnaBridge 188:bcfe06ba3d64 289 // Enforce word-sized access
AnnaBridge 188:bcfe06ba3d64 290 if ((to_read & 0x3) != 0) {
AnnaBridge 188:bcfe06ba3d64 291 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 292 }
AnnaBridge 188:bcfe06ba3d64 293
AnnaBridge 188:bcfe06ba3d64 294 cfg.dummyCycles = command->dummy_count;
AnnaBridge 188:bcfe06ba3d64 295
AnnaBridge 188:bcfe06ba3d64 296 if (command->instruction.disabled) {
AnnaBridge 188:bcfe06ba3d64 297 cfg.opCode = 0x03;
AnnaBridge 188:bcfe06ba3d64 298 cfg.instTransfer = qspiTransferSingle;
AnnaBridge 188:bcfe06ba3d64 299 } else {
AnnaBridge 188:bcfe06ba3d64 300 cfg.opCode = command->instruction.value;
AnnaBridge 188:bcfe06ba3d64 301 if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE) {
AnnaBridge 188:bcfe06ba3d64 302 cfg.instTransfer = qspiTransferSingle;
AnnaBridge 188:bcfe06ba3d64 303 } else if (command->instruction.bus_width == QSPI_CFG_BUS_DUAL) {
AnnaBridge 188:bcfe06ba3d64 304 cfg.instTransfer = qspiTransferDual;
AnnaBridge 188:bcfe06ba3d64 305 } else if (command->instruction.bus_width == QSPI_CFG_BUS_QUAD) {
AnnaBridge 188:bcfe06ba3d64 306 cfg.instTransfer = qspiTransferQuad;
AnnaBridge 188:bcfe06ba3d64 307 } else {
AnnaBridge 188:bcfe06ba3d64 308 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 309 }
AnnaBridge 188:bcfe06ba3d64 310 }
AnnaBridge 188:bcfe06ba3d64 311
AnnaBridge 188:bcfe06ba3d64 312 if (command->address.disabled) {
AnnaBridge 188:bcfe06ba3d64 313 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 314 } else {
AnnaBridge 188:bcfe06ba3d64 315 if (command->address.bus_width == QSPI_CFG_BUS_SINGLE) {
AnnaBridge 188:bcfe06ba3d64 316 cfg.addrTransfer = qspiTransferSingle;
AnnaBridge 188:bcfe06ba3d64 317 } else if (command->address.bus_width == QSPI_CFG_BUS_DUAL) {
AnnaBridge 188:bcfe06ba3d64 318 cfg.addrTransfer = qspiTransferDual;
AnnaBridge 188:bcfe06ba3d64 319 } else if (command->address.bus_width == QSPI_CFG_BUS_QUAD) {
AnnaBridge 188:bcfe06ba3d64 320 cfg.addrTransfer = qspiTransferQuad;
AnnaBridge 188:bcfe06ba3d64 321 } else {
AnnaBridge 188:bcfe06ba3d64 322 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 323 }
AnnaBridge 188:bcfe06ba3d64 324 }
AnnaBridge 188:bcfe06ba3d64 325
AnnaBridge 188:bcfe06ba3d64 326 if (command->data.bus_width == QSPI_CFG_BUS_SINGLE) {
AnnaBridge 188:bcfe06ba3d64 327 cfg.dataTransfer = qspiTransferSingle;
AnnaBridge 188:bcfe06ba3d64 328 } else if (command->data.bus_width == QSPI_CFG_BUS_DUAL) {
AnnaBridge 188:bcfe06ba3d64 329 cfg.dataTransfer = qspiTransferDual;
AnnaBridge 188:bcfe06ba3d64 330 } else if (command->data.bus_width == QSPI_CFG_BUS_QUAD) {
AnnaBridge 188:bcfe06ba3d64 331 cfg.dataTransfer = qspiTransferQuad;
AnnaBridge 188:bcfe06ba3d64 332 }
AnnaBridge 188:bcfe06ba3d64 333
AnnaBridge 188:bcfe06ba3d64 334 QSPI_ReadConfig(obj->instance, &cfg);
AnnaBridge 188:bcfe06ba3d64 335
AnnaBridge 188:bcfe06ba3d64 336 if (!command->alt.disabled) {
AnnaBridge 188:bcfe06ba3d64 337 // Need to set up alt mode manually, called 'mode bits' in EFM32GG11 refman
AnnaBridge 188:bcfe06ba3d64 338 obj->instance->DEVINSTRRDCONFIG |= QSPI_DEVINSTRRDCONFIG_MODEBITENABLE;
AnnaBridge 188:bcfe06ba3d64 339 obj->instance->MODEBITCONFIG = command->alt.value & _QSPI_MODEBITCONFIG_MODE_MASK;
AnnaBridge 188:bcfe06ba3d64 340
AnnaBridge 188:bcfe06ba3d64 341 if(command->alt.size != QSPI_CFG_ALT_SIZE_8) {
AnnaBridge 188:bcfe06ba3d64 342 // Do not support 'alt' bigger than 8 bit
AnnaBridge 188:bcfe06ba3d64 343 return QSPI_STATUS_INVALID_PARAMETER;
AnnaBridge 188:bcfe06ba3d64 344 }
AnnaBridge 188:bcfe06ba3d64 345 }
AnnaBridge 188:bcfe06ba3d64 346
AnnaBridge 188:bcfe06ba3d64 347 // Do an indirect read
AnnaBridge 188:bcfe06ba3d64 348 obj->instance->INDAHBADDRTRIGGER = QSPI0_MEM_BASE;
AnnaBridge 188:bcfe06ba3d64 349 obj->instance->INDIRECTREADXFERSTART = command->address.value;
AnnaBridge 188:bcfe06ba3d64 350 obj->instance->INDIRECTREADXFERNUMBYTES = to_read;
AnnaBridge 188:bcfe06ba3d64 351 obj->instance->INDIRECTREADXFERCTRL = QSPI_INDIRECTREADXFERCTRL_START;
AnnaBridge 188:bcfe06ba3d64 352
AnnaBridge 188:bcfe06ba3d64 353 // For the size of the transfer, poll the SRAM and fetch words from the SRAM
AnnaBridge 188:bcfe06ba3d64 354 for (uint32_t i = 0; i < to_read; i+=4) {
AnnaBridge 188:bcfe06ba3d64 355 // Wait for the FIFO in case we're reading too fast
AnnaBridge 188:bcfe06ba3d64 356 while ((obj->instance->SRAMFILL & _QSPI_SRAMFILL_SRAMFILLINDACREAD_MASK) >> _QSPI_SRAMFILL_SRAMFILLINDACREAD_SHIFT == 0);
AnnaBridge 188:bcfe06ba3d64 357
AnnaBridge 188:bcfe06ba3d64 358 // Unaligned access is fine on CM3/CM4 provided we stick to LDR/STR
AnnaBridge 188:bcfe06ba3d64 359 // With the line below, the compiler can't really do anything else anyways
AnnaBridge 188:bcfe06ba3d64 360 ((uint32_t*)data)[i/4] = *((uint32_t*)QSPI0_MEM_BASE);
AnnaBridge 188:bcfe06ba3d64 361 }
AnnaBridge 188:bcfe06ba3d64 362
AnnaBridge 188:bcfe06ba3d64 363 return QSPI_STATUS_OK;
AnnaBridge 188:bcfe06ba3d64 364 }
AnnaBridge 188:bcfe06ba3d64 365
AnnaBridge 188:bcfe06ba3d64 366 #endif /* DEVICE_QSPI && QSPI_PRESENT */