1 /* 2 * Copyright (c) 2016, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file spi-slave.h 31 * @brief 32 * This file includes the platform abstraction for SPI slave communication. 33 */ 34 35 #ifndef OPENTHREAD_PLATFORM_SPI_SLAVE_H_ 36 #define OPENTHREAD_PLATFORM_SPI_SLAVE_H_ 37 38 #include <stdbool.h> 39 #include <stdint.h> 40 41 #include <openthread/error.h> 42 43 #ifdef __cplusplus 44 extern "C" { 45 #endif 46 47 /** 48 * @addtogroup plat-spi-slave 49 * 50 * @brief 51 * This module includes the platform abstraction for SPI slave communication. 52 * 53 * @{ 54 * 55 */ 56 57 /** 58 * Indicates that a SPI transaction has completed with the given length. The data written to the slave has been written 59 * to the pointer indicated by the `aInputBuf` argument to the previous call to `otPlatSpiSlavePrepareTransaction()`. 60 * 61 * Once this function is called, `otPlatSpiSlavePrepareTransaction()` is invalid and must be called again for the next 62 * transaction to be valid. 63 * 64 * Note that this function is always called at the end of a transaction, even if `otPlatSpiSlavePrepareTransaction()` 65 * has not yet been called. In such cases, `aOutputBufLen` and `aInputBufLen` will be zero. 66 * 67 * This callback can be called from ISR context. The return value from this function indicates if any further 68 * processing is required. If `TRUE` is returned the platform spi-slave driver implementation must invoke the 69 * transaction process callback (`aProcessCallback` set in `otPlatSpiSlaveEnable()`) which unlike this callback must be 70 * called from the same OS context that any other OpenThread API/callback is called. 71 * 72 * @param[in] aContext Context pointer passed into `otPlatSpiSlaveEnable()`. 73 * @param[in] aOutputBuf Value of `aOutputBuf` from last call to `otPlatSpiSlavePrepareTransaction()`. 74 * @param[in] aOutputBufLen Value of `aOutputBufLen` from last call to `otPlatSpiSlavePrepareTransaction()`. 75 * @param[in] aInputBuf Value of aInputBuf from last call to `otPlatSpiSlavePrepareTransaction()`. 76 * @param[in] aInputBufLen Value of aInputBufLen from last call to `otPlatSpiSlavePrepareTransaction()` 77 * @param[in] aTransactionLength Length of the completed transaction, in bytes. 78 * 79 * @returns TRUE if after this call returns the platform should invoke the process callback `aProcessCallback`, 80 * FALSE if there is nothing to process and no need to invoke the process callback. 81 */ 82 typedef bool (*otPlatSpiSlaveTransactionCompleteCallback)(void *aContext, 83 uint8_t *aOutputBuf, 84 uint16_t aOutputBufLen, 85 uint8_t *aInputBuf, 86 uint16_t aInputBufLen, 87 uint16_t aTransactionLength); 88 89 /** 90 * Invoked after a transaction complete callback is called and returns `TRUE` to do any further processing required. 91 * Unlike `otPlatSpiSlaveTransactionCompleteCallback` which can be called from any OS context (e.g., ISR), this 92 * callback MUST be called from the same OS context as any other OpenThread API/callback. 93 * 94 * @param[in] aContext Context pointer passed into `otPlatSpiSlaveEnable()`. 95 * 96 */ 97 typedef void (*otPlatSpiSlaveTransactionProcessCallback)(void *aContext); 98 99 /** 100 * Initialize the SPI slave interface. 101 102 * Note that SPI slave is not fully ready until a transaction is prepared using `otPlatSPISlavePrepareTransaction()`. 103 * 104 * If `otPlatSPISlavePrepareTransaction() is not called before the master begins a transaction, the resulting SPI 105 * transaction will send all `0xFF` bytes and discard all received bytes. 106 * 107 * @param[in] aCompleteCallback Pointer to transaction complete callback. 108 * @param[in] aProcessCallback Pointer to process callback. 109 * @param[in] aContext Context pointer to be passed to callbacks. 110 * 111 * @retval OT_ERROR_NONE Successfully enabled the SPI Slave interface. 112 * @retval OT_ERROR_ALREADY SPI Slave interface is already enabled. 113 * @retval OT_ERROR_FAILED Failed to enable the SPI Slave interface. 114 * 115 */ 116 otError otPlatSpiSlaveEnable(otPlatSpiSlaveTransactionCompleteCallback aCompleteCallback, 117 otPlatSpiSlaveTransactionProcessCallback aProcessCallback, 118 void *aContext); 119 120 /** 121 * Shutdown and disable the SPI slave interface. 122 */ 123 void otPlatSpiSlaveDisable(void); 124 125 /** 126 * Prepare data for the next SPI transaction. Data pointers MUST remain valid until the transaction complete callback 127 * is called by the SPI slave driver, or until after the next call to `otPlatSpiSlavePrepareTransaction()`. 128 * 129 * May be called more than once before the SPI master initiates the transaction. Each *successful* call 130 * to this function will cause the previous values from earlier calls to be discarded. 131 * 132 * Not calling this function after a completed transaction is the same as if this function was previously called with 133 * both buffer lengths set to zero and `aRequestTransactionFlag` set to `false`. 134 * 135 * Once `aOutputBufLen` bytes of `aOutputBuf` has been clocked out, the MISO pin shall be set high until the master 136 * finishes the SPI transaction. This is the functional equivalent of padding the end of `aOutputBuf` with `0xFF` bytes 137 * out to the length of the transaction. 138 * 139 * Once `aInputBufLen` bytes of aInputBuf have been clocked in from MOSI, all subsequent values from the MOSI pin are 140 * ignored until the SPI master finishes the transaction. 141 * 142 * Note that even if `aInputBufLen` or `aOutputBufLen` (or both) are exhausted before the SPI master finishes a 143 * transaction, the ongoing size of the transaction must still be kept track of to be passed to the transaction 144 * complete callback. For example, if `aInputBufLen` is equal to 10 and `aOutputBufLen` equal to 20 and the SPI master 145 * clocks out 30 bytes, the value 30 is passed to the transaction complete callback. 146 * 147 * If a `NULL` pointer is passed in as `aOutputBuf` or `aInputBuf` it means that that buffer pointer should not change 148 * from its previous/current value. In this case, the corresponding length argument should be ignored. For example, 149 * `otPlatSpiSlavePrepareTransaction(NULL, 0, aInputBuf, aInputLen, false)` changes the input buffer pointer and its 150 * length but keeps the output buffer pointer same as before. 151 * 152 * Any call to this function while a transaction is in progress will cause all of the arguments to be ignored and the 153 * return value to be `OT_ERROR_BUSY`. 154 * 155 * @param[in] aOutputBuf Data to be written to MISO pin 156 * @param[in] aOutputBufLen Size of the output buffer, in bytes 157 * @param[in] aInputBuf Data to be read from MOSI pin 158 * @param[in] aInputBufLen Size of the input buffer, in bytes 159 * @param[in] aRequestTransactionFlag Set to true if host interrupt should be set 160 * 161 * @retval OT_ERROR_NONE Transaction was successfully prepared. 162 * @retval OT_ERROR_BUSY A transaction is currently in progress. 163 * @retval OT_ERROR_INVALID_STATE otPlatSpiSlaveEnable() hasn't been called. 164 * 165 */ 166 otError otPlatSpiSlavePrepareTransaction(uint8_t *aOutputBuf, 167 uint16_t aOutputBufLen, 168 uint8_t *aInputBuf, 169 uint16_t aInputBufLen, 170 bool aRequestTransactionFlag); 171 172 /** 173 * @} 174 * 175 */ 176 177 #ifdef __cplusplus 178 } // extern "C" 179 #endif 180 181 #endif // OPENTHREAD_PLATFORM_SPI_SLAVE_H_ 182