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" AND
17  *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20  *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /**
29  * @file
30  *   This file contains definitions for a SPI interface to the OpenThread stack.
31  */
32 
33 #ifndef NCP_SPI_HPP_
34 #define NCP_SPI_HPP_
35 
36 #include "openthread-core-config.h"
37 
38 #include "lib/spinel/spi_frame.hpp"
39 #include "ncp/ncp_base.hpp"
40 
41 namespace ot {
42 namespace Ncp {
43 
44 class NcpSpi : public NcpBase
45 {
46 public:
47     /**
48      * Initializes the object.
49      *
50      * @param[in]  aInstance  A pointer to the OpenThread instance structure.
51      *
52      */
53     explicit NcpSpi(Instance *aInstance);
54 
55 private:
56     enum
57     {
58         /**
59          * SPI tx and rx buffer size (should fit a max length frame + SPI header).
60          *
61          */
62         kSpiBufferSize = OPENTHREAD_CONFIG_NCP_SPI_BUFFER_SIZE,
63 
64         /**
65          * Size of the SPI header (in bytes).
66          *
67          */
68         kSpiHeaderSize = Spinel::SpiFrame::kHeaderSize,
69     };
70 
71     enum TxState
72     {
73         kTxStateIdle,            // No frame to send.
74         kTxStateSending,         // A frame is ready to be sent.
75         kTxStateHandlingSendDone // The frame was sent successfully, waiting to prepare the next one (if any).
76     };
77 
78     typedef uint8_t LargeFrameBuffer[kSpiBufferSize];
79     typedef uint8_t EmptyFrameBuffer[kSpiHeaderSize];
80 
81     static bool SpiTransactionComplete(void    *aContext,
82                                        uint8_t *aOutputBuf,
83                                        uint16_t aOutputLen,
84                                        uint8_t *aInputBuf,
85                                        uint16_t aInputLen,
86                                        uint16_t aTransLen);
87     bool        SpiTransactionComplete(uint8_t *aOutputBuf,
88                                        uint16_t aOutputLen,
89                                        uint8_t *aInputBuf,
90                                        uint16_t aInputLen,
91                                        uint16_t aTransLen);
92 
93     static void SpiTransactionProcess(void *aContext);
94     void        SpiTransactionProcess(void);
95 
96     static void HandleFrameAddedToTxBuffer(void                    *aContext,
97                                            Spinel::Buffer::FrameTag aFrameTag,
98                                            Spinel::Buffer::Priority aPriority,
99                                            Spinel::Buffer          *aBuffer);
100 
101     static void PrepareTxFrame(Tasklet &aTasklet);
102     void        PrepareTxFrame(void);
103     void        HandleRxFrame(void);
104     void        PrepareNextSpiSendFrame(void);
105 
106     volatile TxState mTxState;
107     volatile bool    mHandlingRxFrame;
108     volatile bool    mResetFlag;
109 
110     Tasklet mPrepareTxFrameTask;
111 
112     uint16_t         mSendFrameLength;
113     LargeFrameBuffer mSendFrame;
114     EmptyFrameBuffer mEmptySendFrameFullAccept;
115     EmptyFrameBuffer mEmptySendFrameZeroAccept;
116 
117     LargeFrameBuffer mReceiveFrame;
118     EmptyFrameBuffer mEmptyReceiveFrame;
119 };
120 
121 } // namespace Ncp
122 } // namespace ot
123 
124 #endif // NCP_SPI_HPP_
125