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 * Indicates that a SPI transaction has completed with the given length. The data written to the slave has been written 58 * to the pointer indicated by the `aInputBuf` argument to the previous call to `otPlatSpiSlavePrepareTransaction()`. 59 * 60 * Once this function is called, `otPlatSpiSlavePrepareTransaction()` is invalid and must be called again for the next 61 * transaction to be valid. 62 * 63 * Note that this function is always called at the end of a transaction, even if `otPlatSpiSlavePrepareTransaction()` 64 * has not yet been called. In such cases, `aOutputBufLen` and `aInputBufLen` will be zero. 65 * 66 * This callback can be called from ISR context. The return value from this function indicates if any further 67 * processing is required. If `TRUE` is returned the platform spi-slave driver implementation must invoke the 68 * transaction process callback (`aProcessCallback` set in `otPlatSpiSlaveEnable()`) which unlike this callback must be 69 * called from the same OS context that any other OpenThread API/callback is called. 70 * 71 * @param[in] aContext Context pointer passed into `otPlatSpiSlaveEnable()`. 72 * @param[in] aOutputBuf Value of `aOutputBuf` from last call to `otPlatSpiSlavePrepareTransaction()`. 73 * @param[in] aOutputBufLen Value of `aOutputBufLen` from last call to `otPlatSpiSlavePrepareTransaction()`. 74 * @param[in] aInputBuf Value of aInputBuf from last call to `otPlatSpiSlavePrepareTransaction()`. 75 * @param[in] aInputBufLen Value of aInputBufLen from last call to `otPlatSpiSlavePrepareTransaction()` 76 * @param[in] aTransactionLength Length of the completed transaction, in bytes. 77 * 78 * @returns TRUE if after this call returns the platform should invoke the process callback `aProcessCallback`, 79 * FALSE if there is nothing to process and no need to invoke the process callback. 80 */ 81 typedef bool (*otPlatSpiSlaveTransactionCompleteCallback)(void *aContext, 82 uint8_t *aOutputBuf, 83 uint16_t aOutputBufLen, 84 uint8_t *aInputBuf, 85 uint16_t aInputBufLen, 86 uint16_t aTransactionLength); 87 88 /** 89 * Invoked after a transaction complete callback is called and returns `TRUE` to do any further processing required. 90 * Unlike `otPlatSpiSlaveTransactionCompleteCallback` which can be called from any OS context (e.g., ISR), this 91 * callback MUST be called from the same OS context as any other OpenThread API/callback. 92 * 93 * @param[in] aContext Context pointer passed into `otPlatSpiSlaveEnable()`. 94 */ 95 typedef void (*otPlatSpiSlaveTransactionProcessCallback)(void *aContext); 96 97 /** 98 * Initialize the SPI slave interface. 99 100 * Note that SPI slave is not fully ready until a transaction is prepared using `otPlatSPISlavePrepareTransaction()`. 101 * 102 * If `otPlatSPISlavePrepareTransaction() is not called before the master begins a transaction, the resulting SPI 103 * transaction will send all `0xFF` bytes and discard all received bytes. 104 * 105 * @param[in] aCompleteCallback Pointer to transaction complete callback. 106 * @param[in] aProcessCallback Pointer to process callback. 107 * @param[in] aContext Context pointer to be passed to callbacks. 108 * 109 * @retval OT_ERROR_NONE Successfully enabled the SPI Slave interface. 110 * @retval OT_ERROR_ALREADY SPI Slave interface is already enabled. 111 * @retval OT_ERROR_FAILED Failed to enable the SPI Slave interface. 112 */ 113 otError otPlatSpiSlaveEnable(otPlatSpiSlaveTransactionCompleteCallback aCompleteCallback, 114 otPlatSpiSlaveTransactionProcessCallback aProcessCallback, 115 void *aContext); 116 117 /** 118 * Shutdown and disable the SPI slave interface. 119 */ 120 void otPlatSpiSlaveDisable(void); 121 122 /** 123 * Prepare data for the next SPI transaction. Data pointers MUST remain valid until the transaction complete callback 124 * is called by the SPI slave driver, or until after the next call to `otPlatSpiSlavePrepareTransaction()`. 125 * 126 * May be called more than once before the SPI master initiates the transaction. Each *successful* call 127 * to this function will cause the previous values from earlier calls to be discarded. 128 * 129 * Not calling this function after a completed transaction is the same as if this function was previously called with 130 * both buffer lengths set to zero and `aRequestTransactionFlag` set to `false`. 131 * 132 * Once `aOutputBufLen` bytes of `aOutputBuf` has been clocked out, the MISO pin shall be set high until the master 133 * finishes the SPI transaction. This is the functional equivalent of padding the end of `aOutputBuf` with `0xFF` bytes 134 * out to the length of the transaction. 135 * 136 * Once `aInputBufLen` bytes of aInputBuf have been clocked in from MOSI, all subsequent values from the MOSI pin are 137 * ignored until the SPI master finishes the transaction. 138 * 139 * Note that even if `aInputBufLen` or `aOutputBufLen` (or both) are exhausted before the SPI master finishes a 140 * transaction, the ongoing size of the transaction must still be kept track of to be passed to the transaction 141 * complete callback. For example, if `aInputBufLen` is equal to 10 and `aOutputBufLen` equal to 20 and the SPI master 142 * clocks out 30 bytes, the value 30 is passed to the transaction complete callback. 143 * 144 * If a `NULL` pointer is passed in as `aOutputBuf` or `aInputBuf` it means that that buffer pointer should not change 145 * from its previous/current value. In this case, the corresponding length argument should be ignored. For example, 146 * `otPlatSpiSlavePrepareTransaction(NULL, 0, aInputBuf, aInputLen, false)` changes the input buffer pointer and its 147 * length but keeps the output buffer pointer same as before. 148 * 149 * Any call to this function while a transaction is in progress will cause all of the arguments to be ignored and the 150 * return value to be `OT_ERROR_BUSY`. 151 * 152 * @param[in] aOutputBuf Data to be written to MISO pin 153 * @param[in] aOutputBufLen Size of the output buffer, in bytes 154 * @param[in] aInputBuf Data to be read from MOSI pin 155 * @param[in] aInputBufLen Size of the input buffer, in bytes 156 * @param[in] aRequestTransactionFlag Set to true if host interrupt should be set 157 * 158 * @retval OT_ERROR_NONE Transaction was successfully prepared. 159 * @retval OT_ERROR_BUSY A transaction is currently in progress. 160 * @retval OT_ERROR_INVALID_STATE otPlatSpiSlaveEnable() hasn't been called. 161 */ 162 otError otPlatSpiSlavePrepareTransaction(uint8_t *aOutputBuf, 163 uint16_t aOutputBufLen, 164 uint8_t *aInputBuf, 165 uint16_t aInputBufLen, 166 bool aRequestTransactionFlag); 167 168 /** 169 * @} 170 */ 171 172 #ifdef __cplusplus 173 } // extern "C" 174 #endif 175 176 #endif // OPENTHREAD_PLATFORM_SPI_SLAVE_H_ 177