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:
186:707f6e361f3e
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Anna Bridge 186:707f6e361f3e 1 /**
Anna Bridge 186:707f6e361f3e 2 * @file
Anna Bridge 186:707f6e361f3e 3 * @brief SPI Slave API Function Implementations.
Anna Bridge 186:707f6e361f3e 4 */
Anna Bridge 186:707f6e361f3e 5 /* *****************************************************************************
Anna Bridge 186:707f6e361f3e 6 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
Anna Bridge 186:707f6e361f3e 7 *
Anna Bridge 186:707f6e361f3e 8 * Permission is hereby granted, free of charge, to any person obtaining a
Anna Bridge 186:707f6e361f3e 9 * copy of this software and associated documentation files (the "Software"),
Anna Bridge 186:707f6e361f3e 10 * to deal in the Software without restriction, including without limitation
Anna Bridge 186:707f6e361f3e 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
Anna Bridge 186:707f6e361f3e 12 * and/or sell copies of the Software, and to permit persons to whom the
Anna Bridge 186:707f6e361f3e 13 * Software is furnished to do so, subject to the following conditions:
Anna Bridge 186:707f6e361f3e 14 *
Anna Bridge 186:707f6e361f3e 15 * The above copyright notice and this permission notice shall be included
Anna Bridge 186:707f6e361f3e 16 * in all copies or substantial portions of the Software.
Anna Bridge 186:707f6e361f3e 17 *
Anna Bridge 186:707f6e361f3e 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
Anna Bridge 186:707f6e361f3e 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Anna Bridge 186:707f6e361f3e 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Anna Bridge 186:707f6e361f3e 21 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
Anna Bridge 186:707f6e361f3e 22 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
Anna Bridge 186:707f6e361f3e 23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
Anna Bridge 186:707f6e361f3e 24 * OTHER DEALINGS IN THE SOFTWARE.
Anna Bridge 186:707f6e361f3e 25 *
Anna Bridge 186:707f6e361f3e 26 * Except as contained in this notice, the name of Maxim Integrated
Anna Bridge 186:707f6e361f3e 27 * Products, Inc. shall not be used except as stated in the Maxim Integrated
Anna Bridge 186:707f6e361f3e 28 * Products, Inc. Branding Policy.
Anna Bridge 186:707f6e361f3e 29 *
Anna Bridge 186:707f6e361f3e 30 * The mere transfer of this software does not imply any licenses
Anna Bridge 186:707f6e361f3e 31 * of trade secrets, proprietary technology, copyrights, patents,
Anna Bridge 186:707f6e361f3e 32 * trademarks, maskwork rights, or any other form of intellectual
Anna Bridge 186:707f6e361f3e 33 * property whatsoever. Maxim Integrated Products, Inc. retains all
Anna Bridge 186:707f6e361f3e 34 * ownership rights.
Anna Bridge 186:707f6e361f3e 35 *
Anna Bridge 186:707f6e361f3e 36 * $Date: 2016-09-08 17:42:39 -0500 (Thu, 08 Sep 2016) $
Anna Bridge 186:707f6e361f3e 37 * $Revision: 24325 $
Anna Bridge 186:707f6e361f3e 38 **************************************************************************** */
Anna Bridge 186:707f6e361f3e 39
Anna Bridge 186:707f6e361f3e 40 /* **** Includes **** */
Anna Bridge 186:707f6e361f3e 41 #include <stddef.h>
Anna Bridge 186:707f6e361f3e 42 #include <string.h>
Anna Bridge 186:707f6e361f3e 43 #include "mxc_config.h"
Anna Bridge 186:707f6e361f3e 44 #include "mxc_assert.h"
Anna Bridge 186:707f6e361f3e 45 #include "mxc_lock.h"
Anna Bridge 186:707f6e361f3e 46 #include "spis.h"
Anna Bridge 186:707f6e361f3e 47
Anna Bridge 186:707f6e361f3e 48 /**
Anna Bridge 186:707f6e361f3e 49 * @ingroup spis
Anna Bridge 186:707f6e361f3e 50 * @{
Anna Bridge 186:707f6e361f3e 51 */
Anna Bridge 186:707f6e361f3e 52 /* **** Definitions **** */
Anna Bridge 186:707f6e361f3e 53 #define SPIS_FIFO_BUFFER 6
Anna Bridge 186:707f6e361f3e 54
Anna Bridge 186:707f6e361f3e 55 /* **** Globals **** */
Anna Bridge 186:707f6e361f3e 56
Anna Bridge 186:707f6e361f3e 57 static spis_req_t *states[MXC_CFG_SPIS_INSTANCES];
Anna Bridge 186:707f6e361f3e 58
Anna Bridge 186:707f6e361f3e 59 /* **** Functions **** */
Anna Bridge 186:707f6e361f3e 60
Anna Bridge 186:707f6e361f3e 61 static uint32_t SPIS_TransHandler(mxc_spis_regs_t *spis, spis_req_t *req, int spis_num);
Anna Bridge 186:707f6e361f3e 62
Anna Bridge 186:707f6e361f3e 63 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 64 int SPIS_Init(mxc_spis_regs_t *spis, uint8_t mode, const sys_cfg_spis_t *sys_cfg)
Anna Bridge 186:707f6e361f3e 65 {
Anna Bridge 186:707f6e361f3e 66 int err, spis_num;
Anna Bridge 186:707f6e361f3e 67
Anna Bridge 186:707f6e361f3e 68 spis_num = MXC_SPIS_GET_IDX(spis);
Anna Bridge 186:707f6e361f3e 69 MXC_ASSERT(spis_num >= 0);
Anna Bridge 186:707f6e361f3e 70
Anna Bridge 186:707f6e361f3e 71 // Set system level configurations
Anna Bridge 186:707f6e361f3e 72 if ((err = SYS_SPIS_Init(sys_cfg)) != E_NO_ERROR) {
Anna Bridge 186:707f6e361f3e 73 return err;
Anna Bridge 186:707f6e361f3e 74 }
Anna Bridge 186:707f6e361f3e 75
Anna Bridge 186:707f6e361f3e 76 // Initialize state pointers
Anna Bridge 186:707f6e361f3e 77 states[spis_num] = NULL;
Anna Bridge 186:707f6e361f3e 78
Anna Bridge 186:707f6e361f3e 79 // Drain the FIFOs, enable SPIS
Anna Bridge 186:707f6e361f3e 80 spis->gen_ctrl = 0;
Anna Bridge 186:707f6e361f3e 81 spis->gen_ctrl = (MXC_F_SPIS_GEN_CTRL_SPI_SLAVE_EN | MXC_F_SPIS_GEN_CTRL_TX_FIFO_EN |
Anna Bridge 186:707f6e361f3e 82 MXC_F_SPIS_GEN_CTRL_RX_FIFO_EN | ((mode << MXC_F_SPIS_GEN_CTRL_SPI_MODE_POS) & MXC_F_SPIS_GEN_CTRL_SPI_MODE));
Anna Bridge 186:707f6e361f3e 83
Anna Bridge 186:707f6e361f3e 84 // Set the TX FIFO almost empty level
Anna Bridge 186:707f6e361f3e 85 spis->fifo_ctrl = ((spis->fifo_ctrl & ~MXC_F_SPIS_FIFO_CTRL_TX_FIFO_AE_LVL) |
Anna Bridge 186:707f6e361f3e 86 ((MXC_CFG_SPIS_FIFO_DEPTH - SPIS_FIFO_BUFFER) << MXC_F_SPIS_FIFO_CTRL_TX_FIFO_AE_LVL_POS));
Anna Bridge 186:707f6e361f3e 87
Anna Bridge 186:707f6e361f3e 88 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 89 }
Anna Bridge 186:707f6e361f3e 90
Anna Bridge 186:707f6e361f3e 91 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 92 int SPIS_Shutdown(mxc_spis_regs_t *spis)
Anna Bridge 186:707f6e361f3e 93 {
Anna Bridge 186:707f6e361f3e 94 int spis_num, err;
Anna Bridge 186:707f6e361f3e 95 spis_req_t *temp_req;
Anna Bridge 186:707f6e361f3e 96
Anna Bridge 186:707f6e361f3e 97 // Disable and clear interrupts
Anna Bridge 186:707f6e361f3e 98 spis->inten = 0;
Anna Bridge 186:707f6e361f3e 99 spis->intfl = spis->intfl;
Anna Bridge 186:707f6e361f3e 100
Anna Bridge 186:707f6e361f3e 101 // Disable SPIS and FIFOS
Anna Bridge 186:707f6e361f3e 102 spis->gen_ctrl &= ~(MXC_F_SPIS_GEN_CTRL_SPI_SLAVE_EN | MXC_F_SPIS_GEN_CTRL_TX_FIFO_EN |
Anna Bridge 186:707f6e361f3e 103 MXC_F_SPIS_GEN_CTRL_RX_FIFO_EN);
Anna Bridge 186:707f6e361f3e 104
Anna Bridge 186:707f6e361f3e 105 // Call all of the pending callbacks for this SPIS
Anna Bridge 186:707f6e361f3e 106 spis_num = MXC_SPIS_GET_IDX(spis);
Anna Bridge 186:707f6e361f3e 107 if(states[spis_num] != NULL) {
Anna Bridge 186:707f6e361f3e 108
Anna Bridge 186:707f6e361f3e 109 // Save the request
Anna Bridge 186:707f6e361f3e 110 temp_req = states[spis_num];
Anna Bridge 186:707f6e361f3e 111
Anna Bridge 186:707f6e361f3e 112 // Unlock this SPIS
Anna Bridge 186:707f6e361f3e 113 mxc_free_lock((uint32_t*)&states[spis_num]);
Anna Bridge 186:707f6e361f3e 114
Anna Bridge 186:707f6e361f3e 115 // Callback if not NULL
Anna Bridge 186:707f6e361f3e 116 if(temp_req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 117 temp_req->callback(temp_req, E_SHUTDOWN);
Anna Bridge 186:707f6e361f3e 118 }
Anna Bridge 186:707f6e361f3e 119 }
Anna Bridge 186:707f6e361f3e 120
Anna Bridge 186:707f6e361f3e 121 // Clear system level configurations
Anna Bridge 186:707f6e361f3e 122 if ((err = SYS_SPIS_Shutdown()) != E_NO_ERROR) {
Anna Bridge 186:707f6e361f3e 123 return err;
Anna Bridge 186:707f6e361f3e 124 }
Anna Bridge 186:707f6e361f3e 125
Anna Bridge 186:707f6e361f3e 126 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 127 }
Anna Bridge 186:707f6e361f3e 128
Anna Bridge 186:707f6e361f3e 129 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 130 int SPIS_Trans(mxc_spis_regs_t *spis, spis_req_t *req)
Anna Bridge 186:707f6e361f3e 131 {
Anna Bridge 186:707f6e361f3e 132 int spis_num;
Anna Bridge 186:707f6e361f3e 133
Anna Bridge 186:707f6e361f3e 134 // Make sure the SPIS has been initialized
Anna Bridge 186:707f6e361f3e 135 if((spis->gen_ctrl & MXC_F_SPIS_GEN_CTRL_SPI_SLAVE_EN) == 0)
Anna Bridge 186:707f6e361f3e 136 return E_UNINITIALIZED;
Anna Bridge 186:707f6e361f3e 137
Anna Bridge 186:707f6e361f3e 138 // Check the input parameters
Anna Bridge 186:707f6e361f3e 139 if(req == NULL)
Anna Bridge 186:707f6e361f3e 140 return E_NULL_PTR;
Anna Bridge 186:707f6e361f3e 141
Anna Bridge 186:707f6e361f3e 142 if((req->rx_data == NULL) && (req->tx_data == NULL))
Anna Bridge 186:707f6e361f3e 143 return E_NULL_PTR;
Anna Bridge 186:707f6e361f3e 144
Anna Bridge 186:707f6e361f3e 145 if(!(req->len > 0)) {
Anna Bridge 186:707f6e361f3e 146 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 147 }
Anna Bridge 186:707f6e361f3e 148
Anna Bridge 186:707f6e361f3e 149 // Attempt to register this write request
Anna Bridge 186:707f6e361f3e 150 spis_num = MXC_SPIS_GET_IDX(spis);
Anna Bridge 186:707f6e361f3e 151 if(mxc_get_lock((uint32_t*)&states[spis_num], (uint32_t)req) != E_NO_ERROR) {
Anna Bridge 186:707f6e361f3e 152 return E_BUSY;
Anna Bridge 186:707f6e361f3e 153 }
Anna Bridge 186:707f6e361f3e 154
Anna Bridge 186:707f6e361f3e 155 //force deass to a 1 or 0
Anna Bridge 186:707f6e361f3e 156 req->deass = !!req->deass;
Anna Bridge 186:707f6e361f3e 157
Anna Bridge 186:707f6e361f3e 158 // Clear the number of bytes counter
Anna Bridge 186:707f6e361f3e 159 req->read_num = 0;
Anna Bridge 186:707f6e361f3e 160 req->write_num = 0;
Anna Bridge 186:707f6e361f3e 161 req->callback = NULL;
Anna Bridge 186:707f6e361f3e 162
Anna Bridge 186:707f6e361f3e 163 // Start the transaction, keep calling the handler until complete
Anna Bridge 186:707f6e361f3e 164 spis->intfl = (MXC_F_SPIS_INTFL_SS_DEASSERTED | MXC_F_SPIS_INTFL_TX_UNDERFLOW);
Anna Bridge 186:707f6e361f3e 165 while(SPIS_TransHandler(spis, req, spis_num) & (MXC_F_SPIS_INTEN_RX_FIFO_AF |
Anna Bridge 186:707f6e361f3e 166 MXC_F_SPIS_INTEN_TX_FIFO_AE)) {
Anna Bridge 186:707f6e361f3e 167
Anna Bridge 186:707f6e361f3e 168 if((req->tx_data != NULL) && (spis->intfl & MXC_F_SPIS_INTFL_TX_UNDERFLOW)) {
Anna Bridge 186:707f6e361f3e 169 return E_UNDERFLOW;
Anna Bridge 186:707f6e361f3e 170 }
Anna Bridge 186:707f6e361f3e 171
Anna Bridge 186:707f6e361f3e 172 if((req->rx_data != NULL) && (spis->intfl & MXC_F_SPIS_INTFL_RX_LOST_DATA)) {
Anna Bridge 186:707f6e361f3e 173 return E_OVERFLOW;
Anna Bridge 186:707f6e361f3e 174 }
Anna Bridge 186:707f6e361f3e 175
Anna Bridge 186:707f6e361f3e 176 if((req->deass) && (spis->intfl & MXC_F_SPIS_INTFL_SS_DEASSERTED)) {
Anna Bridge 186:707f6e361f3e 177 if(((req->rx_data != NULL) && ((req->read_num + SPIS_NumReadAvail(spis)) < req->len)) ||
Anna Bridge 186:707f6e361f3e 178 ((req->tx_data != NULL) && (req->write_num < req->len))) {
Anna Bridge 186:707f6e361f3e 179
Anna Bridge 186:707f6e361f3e 180 return E_COMM_ERR;
Anna Bridge 186:707f6e361f3e 181 }
Anna Bridge 186:707f6e361f3e 182 }
Anna Bridge 186:707f6e361f3e 183 }
Anna Bridge 186:707f6e361f3e 184
Anna Bridge 186:707f6e361f3e 185 if(req->tx_data == NULL) {
Anna Bridge 186:707f6e361f3e 186 return req->read_num;
Anna Bridge 186:707f6e361f3e 187 }
Anna Bridge 186:707f6e361f3e 188 return req->write_num;
Anna Bridge 186:707f6e361f3e 189 }
Anna Bridge 186:707f6e361f3e 190
Anna Bridge 186:707f6e361f3e 191 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 192 int SPIS_TransAsync(mxc_spis_regs_t *spis, spis_req_t *req)
Anna Bridge 186:707f6e361f3e 193 {
Anna Bridge 186:707f6e361f3e 194 int spis_num;
Anna Bridge 186:707f6e361f3e 195
Anna Bridge 186:707f6e361f3e 196 // Make sure the SPIS has been initialized
Anna Bridge 186:707f6e361f3e 197 if((spis->gen_ctrl & MXC_F_SPIS_GEN_CTRL_SPI_SLAVE_EN) == 0)
Anna Bridge 186:707f6e361f3e 198 return E_UNINITIALIZED;
Anna Bridge 186:707f6e361f3e 199
Anna Bridge 186:707f6e361f3e 200 // Check the input parameters
Anna Bridge 186:707f6e361f3e 201 if(req == NULL)
Anna Bridge 186:707f6e361f3e 202 return E_NULL_PTR;
Anna Bridge 186:707f6e361f3e 203
Anna Bridge 186:707f6e361f3e 204 if((req->rx_data == NULL) && (req->tx_data == NULL))
Anna Bridge 186:707f6e361f3e 205 return E_NULL_PTR;
Anna Bridge 186:707f6e361f3e 206
Anna Bridge 186:707f6e361f3e 207 if(!(req->len > 0)) {
Anna Bridge 186:707f6e361f3e 208 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 209 }
Anna Bridge 186:707f6e361f3e 210
Anna Bridge 186:707f6e361f3e 211 // Attempt to register this write request
Anna Bridge 186:707f6e361f3e 212 spis_num = MXC_SPIS_GET_IDX(spis);
Anna Bridge 186:707f6e361f3e 213 if(mxc_get_lock((uint32_t*)&states[spis_num], (uint32_t)req) != E_NO_ERROR) {
Anna Bridge 186:707f6e361f3e 214 return E_BUSY;
Anna Bridge 186:707f6e361f3e 215 }
Anna Bridge 186:707f6e361f3e 216
Anna Bridge 186:707f6e361f3e 217 //force deass to a 1 or 0
Anna Bridge 186:707f6e361f3e 218 req->deass = !!req->deass;
Anna Bridge 186:707f6e361f3e 219
Anna Bridge 186:707f6e361f3e 220 // Clear the number of bytes counter
Anna Bridge 186:707f6e361f3e 221 req->read_num = 0;
Anna Bridge 186:707f6e361f3e 222 req->write_num = 0;
Anna Bridge 186:707f6e361f3e 223
Anna Bridge 186:707f6e361f3e 224 // Start the transaction, enable the interrupts
Anna Bridge 186:707f6e361f3e 225 spis->intfl = MXC_F_SPIS_INTFL_SS_DEASSERTED;
Anna Bridge 186:707f6e361f3e 226 spis->inten = SPIS_TransHandler(spis, req, spis_num);
Anna Bridge 186:707f6e361f3e 227
Anna Bridge 186:707f6e361f3e 228 if(spis->intfl & MXC_F_SPIS_INTFL_SS_DEASSERTED) {
Anna Bridge 186:707f6e361f3e 229 return E_COMM_ERR;
Anna Bridge 186:707f6e361f3e 230 }
Anna Bridge 186:707f6e361f3e 231
Anna Bridge 186:707f6e361f3e 232 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 233 }
Anna Bridge 186:707f6e361f3e 234
Anna Bridge 186:707f6e361f3e 235 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 236 int SPIS_AbortAsync(spis_req_t *req)
Anna Bridge 186:707f6e361f3e 237 {
Anna Bridge 186:707f6e361f3e 238 int spis_num;
Anna Bridge 186:707f6e361f3e 239
Anna Bridge 186:707f6e361f3e 240 // Check the input parameters
Anna Bridge 186:707f6e361f3e 241 if(req == NULL) {
Anna Bridge 186:707f6e361f3e 242 return E_BAD_PARAM;
Anna Bridge 186:707f6e361f3e 243 }
Anna Bridge 186:707f6e361f3e 244
Anna Bridge 186:707f6e361f3e 245 // Find the request, set to NULL
Anna Bridge 186:707f6e361f3e 246 for(spis_num = 0; spis_num < MXC_CFG_SPIS_INSTANCES; spis_num++) {
Anna Bridge 186:707f6e361f3e 247 if(req == states[spis_num]) {
Anna Bridge 186:707f6e361f3e 248
Anna Bridge 186:707f6e361f3e 249 // Disable interrupts, clear the flags
Anna Bridge 186:707f6e361f3e 250 MXC_SPIS_GET_SPIS(spis_num)->inten = 0;
Anna Bridge 186:707f6e361f3e 251 MXC_SPIS_GET_SPIS(spis_num)->intfl = MXC_SPIS_GET_SPIS(spis_num)->intfl;
Anna Bridge 186:707f6e361f3e 252
Anna Bridge 186:707f6e361f3e 253 // Unlock this SPIS
Anna Bridge 186:707f6e361f3e 254 mxc_free_lock((uint32_t*)&states[spis_num]);
Anna Bridge 186:707f6e361f3e 255
Anna Bridge 186:707f6e361f3e 256 // Callback if not NULL
Anna Bridge 186:707f6e361f3e 257 if(req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 258 req->callback(req, E_ABORT);
Anna Bridge 186:707f6e361f3e 259 }
Anna Bridge 186:707f6e361f3e 260
Anna Bridge 186:707f6e361f3e 261 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 262 }
Anna Bridge 186:707f6e361f3e 263 }
Anna Bridge 186:707f6e361f3e 264
Anna Bridge 186:707f6e361f3e 265 return E_BAD_PARAM;
Anna Bridge 186:707f6e361f3e 266 }
Anna Bridge 186:707f6e361f3e 267
Anna Bridge 186:707f6e361f3e 268 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 269 void SPIS_Handler(mxc_spis_regs_t *spis)
Anna Bridge 186:707f6e361f3e 270 {
Anna Bridge 186:707f6e361f3e 271 int spis_num;
Anna Bridge 186:707f6e361f3e 272 uint32_t flags;
Anna Bridge 186:707f6e361f3e 273 spis_req_t *req;
Anna Bridge 186:707f6e361f3e 274
Anna Bridge 186:707f6e361f3e 275 // Clear the interrupt flags
Anna Bridge 186:707f6e361f3e 276 spis->inten = 0;
Anna Bridge 186:707f6e361f3e 277 flags = spis->intfl;
Anna Bridge 186:707f6e361f3e 278 spis->intfl = flags;
Anna Bridge 186:707f6e361f3e 279
Anna Bridge 186:707f6e361f3e 280 spis_num = MXC_SPIS_GET_IDX(spis);
Anna Bridge 186:707f6e361f3e 281 req = states[spis_num];
Anna Bridge 186:707f6e361f3e 282
Anna Bridge 186:707f6e361f3e 283 // Check for errors
Anna Bridge 186:707f6e361f3e 284 if((flags & MXC_F_SPIS_INTFL_TX_UNDERFLOW) && (req->tx_data != NULL)) {
Anna Bridge 186:707f6e361f3e 285 // Unlock this SPIS
Anna Bridge 186:707f6e361f3e 286 mxc_free_lock((uint32_t*)&states[spis_num]);
Anna Bridge 186:707f6e361f3e 287
Anna Bridge 186:707f6e361f3e 288 // Callback if not NULL
Anna Bridge 186:707f6e361f3e 289 if(req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 290 req->callback(req, E_UNDERFLOW);
Anna Bridge 186:707f6e361f3e 291 }
Anna Bridge 186:707f6e361f3e 292 return;
Anna Bridge 186:707f6e361f3e 293 }
Anna Bridge 186:707f6e361f3e 294 if((flags & MXC_F_SPIS_INTFL_RX_LOST_DATA) && (req->rx_data != NULL)) {
Anna Bridge 186:707f6e361f3e 295 // Unlock this SPIS
Anna Bridge 186:707f6e361f3e 296 mxc_free_lock((uint32_t*)&states[spis_num]);
Anna Bridge 186:707f6e361f3e 297
Anna Bridge 186:707f6e361f3e 298 // Callback if not NULL
Anna Bridge 186:707f6e361f3e 299 if(req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 300 req->callback(req, E_OVERFLOW);
Anna Bridge 186:707f6e361f3e 301 }
Anna Bridge 186:707f6e361f3e 302 return;
Anna Bridge 186:707f6e361f3e 303 }
Anna Bridge 186:707f6e361f3e 304
Anna Bridge 186:707f6e361f3e 305 // Check for deassert
Anna Bridge 186:707f6e361f3e 306 if((flags & MXC_F_SPIS_INTFL_SS_DEASSERTED) && (req != NULL) &&
Anna Bridge 186:707f6e361f3e 307 (req->deass)) {
Anna Bridge 186:707f6e361f3e 308
Anna Bridge 186:707f6e361f3e 309 if(((req->rx_data != NULL) && ((req->read_num + SPIS_NumReadAvail(spis)) < req->len)) ||
Anna Bridge 186:707f6e361f3e 310 ((req->tx_data != NULL) && (req->write_num < req->len))) {
Anna Bridge 186:707f6e361f3e 311
Anna Bridge 186:707f6e361f3e 312 // Unlock this SPIS
Anna Bridge 186:707f6e361f3e 313 mxc_free_lock((uint32_t*)&states[spis_num]);
Anna Bridge 186:707f6e361f3e 314
Anna Bridge 186:707f6e361f3e 315 // Callback if not NULL
Anna Bridge 186:707f6e361f3e 316 if(req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 317 req->callback(states[spis_num], E_COMM_ERR);
Anna Bridge 186:707f6e361f3e 318 }
Anna Bridge 186:707f6e361f3e 319
Anna Bridge 186:707f6e361f3e 320 return;
Anna Bridge 186:707f6e361f3e 321 }
Anna Bridge 186:707f6e361f3e 322 }
Anna Bridge 186:707f6e361f3e 323
Anna Bridge 186:707f6e361f3e 324 // Figure out if this SPIS has an active request
Anna Bridge 186:707f6e361f3e 325 if(flags && (req != NULL)) {
Anna Bridge 186:707f6e361f3e 326
Anna Bridge 186:707f6e361f3e 327 spis->inten = SPIS_TransHandler(spis, req, spis_num);
Anna Bridge 186:707f6e361f3e 328 }
Anna Bridge 186:707f6e361f3e 329 }
Anna Bridge 186:707f6e361f3e 330
Anna Bridge 186:707f6e361f3e 331 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 332 int SPIS_Busy(mxc_spis_regs_t *spis)
Anna Bridge 186:707f6e361f3e 333 {
Anna Bridge 186:707f6e361f3e 334 // Check to see if there are any ongoing transactions
Anna Bridge 186:707f6e361f3e 335 if(states[MXC_SPIS_GET_IDX(spis)] == NULL) {
Anna Bridge 186:707f6e361f3e 336 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 337 }
Anna Bridge 186:707f6e361f3e 338
Anna Bridge 186:707f6e361f3e 339 return E_BUSY;
Anna Bridge 186:707f6e361f3e 340 }
Anna Bridge 186:707f6e361f3e 341
Anna Bridge 186:707f6e361f3e 342 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 343 int SPIS_PrepForSleep(mxc_spis_regs_t *spis)
Anna Bridge 186:707f6e361f3e 344 {
Anna Bridge 186:707f6e361f3e 345 if(SPIS_Busy(spis) != E_NO_ERROR) {
Anna Bridge 186:707f6e361f3e 346 return E_BUSY;
Anna Bridge 186:707f6e361f3e 347 }
Anna Bridge 186:707f6e361f3e 348
Anna Bridge 186:707f6e361f3e 349 // Disable interrupts
Anna Bridge 186:707f6e361f3e 350 spis->inten = 0;
Anna Bridge 186:707f6e361f3e 351 return E_NO_ERROR;
Anna Bridge 186:707f6e361f3e 352 }
Anna Bridge 186:707f6e361f3e 353
Anna Bridge 186:707f6e361f3e 354 /* ************************************************************************* */
Anna Bridge 186:707f6e361f3e 355 static uint32_t SPIS_TransHandler(mxc_spis_regs_t *spis, spis_req_t *req, int spis_num)
Anna Bridge 186:707f6e361f3e 356 {
Anna Bridge 186:707f6e361f3e 357 uint8_t read, write;
Anna Bridge 186:707f6e361f3e 358 uint32_t inten;
Anna Bridge 186:707f6e361f3e 359 unsigned remain, avail, temp_len;
Anna Bridge 186:707f6e361f3e 360 mxc_spis_fifo_regs_t *fifo;
Anna Bridge 186:707f6e361f3e 361
Anna Bridge 186:707f6e361f3e 362 inten = 0;
Anna Bridge 186:707f6e361f3e 363
Anna Bridge 186:707f6e361f3e 364 // Get the FIFOS for this UART
Anna Bridge 186:707f6e361f3e 365 fifo = MXC_SPIS_GET_SPIS_FIFO(spis_num);
Anna Bridge 186:707f6e361f3e 366
Anna Bridge 186:707f6e361f3e 367 // Figure out if we're reading
Anna Bridge 186:707f6e361f3e 368 if(req->rx_data != NULL) {
Anna Bridge 186:707f6e361f3e 369 read = 1;
Anna Bridge 186:707f6e361f3e 370 } else {
Anna Bridge 186:707f6e361f3e 371 read = 0;
Anna Bridge 186:707f6e361f3e 372 }
Anna Bridge 186:707f6e361f3e 373
Anna Bridge 186:707f6e361f3e 374 // Figure out if we're writing
Anna Bridge 186:707f6e361f3e 375 if(req->tx_data != NULL) {
Anna Bridge 186:707f6e361f3e 376 write = 1;
Anna Bridge 186:707f6e361f3e 377 } else {
Anna Bridge 186:707f6e361f3e 378 write = 0;
Anna Bridge 186:707f6e361f3e 379 }
Anna Bridge 186:707f6e361f3e 380
Anna Bridge 186:707f6e361f3e 381 // Put data into the FIFO if we are writing
Anna Bridge 186:707f6e361f3e 382 if(write) {
Anna Bridge 186:707f6e361f3e 383
Anna Bridge 186:707f6e361f3e 384 avail = SPIS_NumWriteAvail(spis);
Anna Bridge 186:707f6e361f3e 385 remain = req->len - req->write_num;
Anna Bridge 186:707f6e361f3e 386
Anna Bridge 186:707f6e361f3e 387 if(remain > avail) {
Anna Bridge 186:707f6e361f3e 388 temp_len = avail;
Anna Bridge 186:707f6e361f3e 389 } else {
Anna Bridge 186:707f6e361f3e 390 temp_len = remain;
Anna Bridge 186:707f6e361f3e 391 }
Anna Bridge 186:707f6e361f3e 392
Anna Bridge 186:707f6e361f3e 393 memcpy((void*)fifo->tx_32, &(req->tx_data[req->write_num]), temp_len);
Anna Bridge 186:707f6e361f3e 394 spis->intfl = MXC_F_SPIS_INTFL_TX_FIFO_AE;
Anna Bridge 186:707f6e361f3e 395 req->write_num += temp_len;
Anna Bridge 186:707f6e361f3e 396 remain = req->len - req->write_num;
Anna Bridge 186:707f6e361f3e 397
Anna Bridge 186:707f6e361f3e 398 // Set the TX interrupts
Anna Bridge 186:707f6e361f3e 399 if(remain) {
Anna Bridge 186:707f6e361f3e 400 inten |= (MXC_F_SPIS_INTEN_TX_FIFO_AE | MXC_F_SPIS_INTFL_TX_UNDERFLOW);
Anna Bridge 186:707f6e361f3e 401 }
Anna Bridge 186:707f6e361f3e 402 }
Anna Bridge 186:707f6e361f3e 403
Anna Bridge 186:707f6e361f3e 404 // Read from the FIFO if we are reading
Anna Bridge 186:707f6e361f3e 405 if(read) {
Anna Bridge 186:707f6e361f3e 406
Anna Bridge 186:707f6e361f3e 407 avail = SPIS_NumReadAvail(MXC_SPIS);
Anna Bridge 186:707f6e361f3e 408 remain = req->len - req->read_num;
Anna Bridge 186:707f6e361f3e 409
Anna Bridge 186:707f6e361f3e 410 if(remain > avail) {
Anna Bridge 186:707f6e361f3e 411 temp_len = avail;
Anna Bridge 186:707f6e361f3e 412 } else {
Anna Bridge 186:707f6e361f3e 413 temp_len = remain;
Anna Bridge 186:707f6e361f3e 414 }
Anna Bridge 186:707f6e361f3e 415
Anna Bridge 186:707f6e361f3e 416 memcpy((void*)&req->rx_data[req->read_num], (void*)&(fifo->rx_8[0]), temp_len);
Anna Bridge 186:707f6e361f3e 417 spis->intfl = MXC_F_SPIS_INTFL_RX_FIFO_AF;
Anna Bridge 186:707f6e361f3e 418 req->read_num += temp_len;
Anna Bridge 186:707f6e361f3e 419 remain = req->len - req->read_num;
Anna Bridge 186:707f6e361f3e 420
Anna Bridge 186:707f6e361f3e 421 // Set the RX interrupts
Anna Bridge 186:707f6e361f3e 422 if(remain) {
Anna Bridge 186:707f6e361f3e 423
Anna Bridge 186:707f6e361f3e 424 // Adjust the almost full threshold
Anna Bridge 186:707f6e361f3e 425 if (remain > (MXC_CFG_SPIS_FIFO_DEPTH - SPIS_FIFO_BUFFER)) {
Anna Bridge 186:707f6e361f3e 426 spis->fifo_ctrl = ((spis->fifo_ctrl & ~MXC_F_SPIS_FIFO_CTRL_RX_FIFO_AF_LVL) |
Anna Bridge 186:707f6e361f3e 427 ((MXC_CFG_SPIS_FIFO_DEPTH - SPIS_FIFO_BUFFER) << MXC_F_SPIS_FIFO_CTRL_RX_FIFO_AF_LVL_POS));
Anna Bridge 186:707f6e361f3e 428
Anna Bridge 186:707f6e361f3e 429 } else {
Anna Bridge 186:707f6e361f3e 430 spis->fifo_ctrl = ((spis->fifo_ctrl & ~MXC_F_SPIS_FIFO_CTRL_RX_FIFO_AF_LVL) |
Anna Bridge 186:707f6e361f3e 431 ((remain-1) << MXC_F_SPIS_FIFO_CTRL_RX_FIFO_AF_LVL_POS));
Anna Bridge 186:707f6e361f3e 432 }
Anna Bridge 186:707f6e361f3e 433
Anna Bridge 186:707f6e361f3e 434 inten |= (MXC_F_SPIS_INTEN_RX_FIFO_AF | MXC_F_SPIS_INTFL_RX_LOST_DATA);
Anna Bridge 186:707f6e361f3e 435 }
Anna Bridge 186:707f6e361f3e 436 }
Anna Bridge 186:707f6e361f3e 437
Anna Bridge 186:707f6e361f3e 438 // Check to see if we've finished reading and writing
Anna Bridge 186:707f6e361f3e 439 if(((read && (req->read_num == req->len)) || !read) &&
Anna Bridge 186:707f6e361f3e 440 ((req->write_num == req->len) || !write)) {
Anna Bridge 186:707f6e361f3e 441
Anna Bridge 186:707f6e361f3e 442 // Unlock this SPIS
Anna Bridge 186:707f6e361f3e 443 mxc_free_lock((uint32_t*)&states[spis_num]);
Anna Bridge 186:707f6e361f3e 444
Anna Bridge 186:707f6e361f3e 445 // Callback if not NULL
Anna Bridge 186:707f6e361f3e 446 if(req->callback != NULL) {
Anna Bridge 186:707f6e361f3e 447 req->callback(req, E_NO_ERROR);
Anna Bridge 186:707f6e361f3e 448 }
Anna Bridge 186:707f6e361f3e 449
Anna Bridge 186:707f6e361f3e 450 return 0;
Anna Bridge 186:707f6e361f3e 451 }
Anna Bridge 186:707f6e361f3e 452
Anna Bridge 186:707f6e361f3e 453 // Enable deassert interrupt
Anna Bridge 186:707f6e361f3e 454 if(req->deass) {
Anna Bridge 186:707f6e361f3e 455 inten |= MXC_F_SPIS_INTEN_SS_DEASSERTED;
Anna Bridge 186:707f6e361f3e 456 }
Anna Bridge 186:707f6e361f3e 457
Anna Bridge 186:707f6e361f3e 458 return inten;
Anna Bridge 186:707f6e361f3e 459 }
Anna Bridge 186:707f6e361f3e 460 /**@} end of ingroup spis*/