EVE 1.0
iqrf.h
Go to the documentation of this file.
1 #ifndef IQRF_H_INCLUDED
2 #define IQRF_H_INCLUDED
3 /**********************************************************************/
4 /*
5  * Copyright (c) 2016, Jetro AS
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without modification,
9  * are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  * derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONRIBUTORS ``AS IS'' AND ANY EXPRESS
20  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
22  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
28  * OF SUCH DAMAGE.
29  *
30  * This file is part of the EVE platform.
31  */
32 
33 /**
34  * \file
35  * @brief Driver for IQRF radio modules
36  *
37  * @author DT, Jetro AS
38  */ /******************************************************************/
39 
40 #include <core/mwork.h>
41 #include <core/uwork.h>
42 #include <dev/spi.h>
43 
44 /**
45  * \defgroup iqrf IQRF module driver
46  * \ingroup extdrv
47  * \{
48  *
49  */
50 
51 /**
52  * @brief Custom periferal number for Bridge
53  */
54 #define IQRF_PNUM_BRIDGE (0x30)
55 
56 /**
57  * @brief SPI buffer length (max IQRF packet size + 4)
58  */
59 #define IQRF_SPI_BUFFER_LENGTH (68)
60 
61 /**
62  * @brief Worst estimate for response timeslot length in 10 ms. intervals.
63  */
64 #define IQRF_RESPONSE_TIMESLOT_LENGTH_WORST_ESTIMATE (5)
65 
66 /**
67  * @brief Value used as an invalid timestamp value
68  */
69 #define IQRF_INVALID_TIMESTAMP (0xFFFFFFFF)
70 
71 /* forward */ struct iqrf_t;
72 
73 /**
74  * Possible response types
75  */
77 {
78  IQRF_TYPE_CONFIRMATION, //!< DPA Confirmation
79  IQRF_TYPE_RESPONSE, //!< DPA Response
80  IQRF_TYPE_ERROR, //!< DPA error
81  IQRF_TYPE_TIMEOUT, //!< Timeout
82 };
83 
84 /**
85  * DPA protocol header
86  */
88 {
89  uint16_t NADR; //!< Node address
90  uint8_t PNUM; //!< Periphery number (address)
91  uint8_t PCMD; //!< Periphery command
92  uint16_t HWPID; //!< Hardware profile ID
93 };
94 
95 /**
96  * DPA request
97  */
99 {
100  struct iqrf_dpa_header_t Hdr; //!< DPA header
101  uint8_t Data[0]; //!< Data, associated with the request
102 };
103 
104 /**
105  * DPA confirmation message
106  */
108 {
109  struct iqrf_dpa_header_t Hdr; //!< DPA header
110  uint8_t ErrN; //!< Error number (= 0xFF for confirmation messages)
111  uint8_t DpaValue; //!< DPA value
112  uint8_t HopsRequest; //!< Number of hops in the forward (request) distribution path
113  uint8_t TimeslotRequest; //!< Timeslot length for the request in 10 ms intervals
114  uint8_t HopsResponse; //!< Number of hops in the backward (response) distribution path
115 };
116 
117 /**
118  * DPA response message
119  */
121 {
122  struct iqrf_dpa_header_t Hdr; //!< DPA header
123  uint8_t ErrN; //! Error number (= 0x00 for response messages)
124  uint8_t DpaValue; //!< DPA value
125  uint8_t Data[0]; //!< Data, associated with the response
126 };
127 
128 /**
129  * DPA broadcast message
130  */
132 {
133  struct iqrf_dpa_header_t Hdr; //!< DPA header
134  uint8_t Data[0]; //!< Data, associated with the response
135 };
136 
137 /**
138  * Per-instance IQRF global handlers (callbacks) table
139  */
141 {
142  /** Called when an IQRF device goes offline */
143  void (*OnOffline)(const struct iqrf_t *Iqrf);
144 
145  /** Called when an IQRF device goes online */
146  void (*OnOnline)(const struct iqrf_t *Iqrf);
147 
148  /** Called when an IQRF device receives a DPA request */
149  void (*OnDpaRequest)(const struct iqrf_t *Iqrf, uint8_t Cmd, const uint8_t *Data, uint8_t Length);
150 
151  /** Called when an IQRF device receives a broadcast DPA request */
152  void (*OnBroadcastRequest)(const struct iqrf_t *Iqrf, const struct iqrf_dpa_broadcast_t *Dpa, uint8_t Length);
153 
154  /** Called when an IQRF device receives an FRC request */
155  void (*OnFrcRequest)(const struct iqrf_t *Iqrf, uint8_t Cmd, const uint8_t *Data, uint8_t Length);
156 };
157 
158 /**
159  * Per-request handler (callback), which receives notification about the request lifecycle
160  *
161  * @param Iqrf IQRF instance
162  * @param Type Type of notification
163  * @param Dpa Pointer to the DPA response structure. It can contain iqrf_dpa_confirmation_t as well.
164  * @param Length Length of the data in the DPA response.
165  */
166 typedef void (*iqrf_response_handler_t)(const struct iqrf_t *Iqrf,
167  enum iqrf_response_type_t Type,
168  const struct iqrf_dpa_response_t *Dpa,
169  uint8_t Length);
170 
171 /**
172  * IQRF module state structure
173  */
175 {
176  const struct iqrf_t *Iqrf; //!< Module instance
177  uint8_t Nadr; //!< Node's NADR
178  uint8_t RxLen; //!< Length of data in Rx buffer
179  uint8_t TxLen[2]; //!< Length of data in Tx buffers
180  uint8_t TxIdx; //!< Index of currently used TX buffer
181  uint8_t Pos; //!< Position of the currently transferred byte in a buffer
182  uint8_t /*enum iqrf_xfer_phase_t*/ Phase; //!< Thansfer phase
183  bool XferStatus; //!< True if last transfer has finished successfully.
184  uint8_t Channel; //!< Radio channel
185  uint8_t /*enum iqrfapp_state_t*/ State; //!< State
186  uint16_t Hwpid; //!< HWPID
187  struct work_t Work; //!< IQRF work
188  struct uwork_t UWork; //!< IQRF microsecond scheduler
189  struct mwork_t RoutingTimer; //!< IQRF millisecond scheduler
190 
191  uint8_t HopsRequest; //!< Copy of HopsRequest from the last confirmation message
192  uint8_t TimeslotRequest; //!< Copy of TimeslotRequest from the last confirmation message
193  uint8_t HopsResponse; //!< Copy of HopsResponse from the last confirmation message
194  uint8_t TimeslotResponse; /*!< Calculated or predicted timeslot length for
195  the backward (response) distribution path */
196  uint32_t ConfirmationTimestamp; //!< Timestamp for the last confirmation message
197  iqrf_response_handler_t ResponseHandler; //!< Per-request response handler (callback)
198 
199  uint8_t Rx[IQRF_SPI_BUFFER_LENGTH]; //!< SPI receive buffer (max IQRF packet size + 4)
200  uint8_t Tx[2][IQRF_SPI_BUFFER_LENGTH]; //!< SPI transmit buffers (max IQRF packet size + 4)
201 };
202 
203 /**
204  * @brief IQRF instance structure
205  */
206 struct iqrf_t
207 {
208  struct iqrf_state_t *State; //!< IRRF state
209  const struct spi_t* Spi; //!< Spi instance
210  struct spi_cs_t SpiCs; //!< Spi CS flags
211  uint32_t SpiBaudrate; //!< Spi speed (should be 250000 for IQRF)
212  const struct iqrf_global_handlers_t *Handlers; //!< pointer to the IQRF global handlers table
213  uint8_t IrqPin; //!< IRQ pin
214  bool IsCoordinator; //!< True if the interface represents an IQRF coordinator
215 };
216 
217 /**
218  * IQRF interrupt handler
219  *
220  * @param Iqrf IQRF instance
221  */
222 void IqrfInterruptCb(const struct iqrf_t *Iqrf);
223 
224 /**
225  * Init an IQRF driver instance
226  *
227  * @param Iqrf IQRF instance
228  */
229 void IqrfInit(const struct iqrf_t *Iqrf);
230 
231 /**
232  * Checks if an IQRF driver is busy
233  *
234  * @param Iqrf IQRF instance
235  * @return true if the instance is busy, false if IqrfSendDpaRequest can be called.
236  */
237 bool IqrfIsBusy(const struct iqrf_t* Iqrf);
238 
239 /**
240  * Send a DPA request to the IQRF module
241  *
242  * @param Iqrf IQRF instance
243  * @param ResponseHandler A handler (callback), which receives notification about the request lifecycle
244  * @param Request DPA request
245  * @param DataLen Length of data field in the DPA request
246  * @return true if the request was sent to the IQRF, false in case of any error
247  */
248 bool IqrfSendDpaRequest(const struct iqrf_t *Iqrf,
249  iqrf_response_handler_t ResponseHandler,
250  const struct iqrf_dpa_request_t *Request,
251  uint8_t DataLen);
252 
253 /**
254  * Send a response to a DPA request
255  *
256  * @param Iqrf IQRF instance
257  * @param Data DPA response data
258  * @param DataLen Length of the DPA response data
259  * @return true if the response was sent to the IQRF, false in case of any error
260  */
261 bool IqrfSendDpaResponse(const struct iqrf_t *Iqrf, const uint8_t *Data, uint8_t DataLen);
262 
263 /**
264  * Send a response with error code
265  *
266  * @param Iqrf IQRF instance
267  * @param ErrorCode Error code
268  * @return true if the response was sent to the IQRF, false in case of any error
269  */
270 bool IqrfSendDpaError(const struct iqrf_t* Iqrf, uint8_t ErrorCode);
271 
272 /**
273  * Send a response to a FRC request
274  *
275  * @param Iqrf IQRF instance
276  * @param Status FRC status
277  * @return true if the response was sent to the IQRF, false in case of any error
278  */
279 bool IqrfSendFrcResponse(const struct iqrf_t* Iqrf, uint16_t Status);
280 
281 /**
282  * Get time in system ticks required to complete
283  * a routing with the given parameters
284  *
285  * @param HopsRequest HopsRequest field of the confirmation message
286  * @param TimeslotRequest TimeslotRequest field of the confirmation message
287  * @param HopsResponse HopsResponse field of the confirmation message
288  * @param TimeslotResponse Expected duration of the response message, number of timeslots
289  *
290  * @return Expected routing time in system tick intervals
291  */
293  uint8_t HopsRequest,
294  uint8_t TimeslotRequest,
295  uint8_t HopsResponse,
296  uint8_t TimeslotResponse);
297 
298 /**
299  * Get point in time when routing is going to be completed.
300  *
301  * @param Iqrf IQRF instance
302  *
303  * @return System time when routing is expected to be completed.
304  * IQRF_INVALID_TIMESTAMP if no routing is in progress.
305  */
306 uint32_t IqrfGetExpectedRoutingCompleteTimestamp(const struct iqrf_t* Iqrf);
307 
308 /** @} */
309 
310 #endif /* IQRF_H_INCLUDED */
uint16_t NADR
Node address.
Definition: iqrf.h:89
Header file for the EVE millisecond-scale work scheduling.
uint8_t DpaValue
Error number (= 0x00 for response messages)
Definition: iqrf.h:124
#define IQRF_SPI_BUFFER_LENGTH
SPI buffer length (max IQRF packet size + 4)
Definition: iqrf.h:59
uint16_t HWPID
Hardware profile ID.
Definition: iqrf.h:92
bool IqrfSendDpaRequest(const struct iqrf_t *Iqrf, iqrf_response_handler_t ResponseHandler, const struct iqrf_dpa_request_t *Request, uint8_t DataLen)
void(* iqrf_response_handler_t)(const struct iqrf_t *Iqrf, enum iqrf_response_type_t Type, const struct iqrf_dpa_response_t *Dpa, uint8_t Length)
Definition: iqrf.h:166
uint8_t RxLen
Length of data in Rx buffer.
Definition: iqrf.h:178
Definition: mwork.h:182
uint8_t Pos
Position of the currently transferred byte in a buffer.
Definition: iqrf.h:181
bool XferStatus
True if last transfer has finished successfully.
Definition: iqrf.h:183
DPA error.
Definition: iqrf.h:80
bool IqrfSendDpaResponse(const struct iqrf_t *Iqrf, const uint8_t *Data, uint8_t DataLen)
uint8_t HopsResponse
Number of hops in the backward (response) distribution path.
Definition: iqrf.h:114
Timeout.
Definition: iqrf.h:81
const struct spi_t * Spi
Spi instance.
Definition: iqrf.h:209
bool IqrfSendFrcResponse(const struct iqrf_t *Iqrf, uint16_t Status)
Definition: spi.h:113
uint8_t TimeslotRequest
Copy of TimeslotRequest from the last confirmation message.
Definition: iqrf.h:192
Driver for the MCU&#39;s SPI blocks.
uint8_t HopsRequest
Copy of HopsRequest from the last confirmation message.
Definition: iqrf.h:191
uint8_t Phase
Thansfer phase.
Definition: iqrf.h:182
uint8_t TimeslotRequest
Timeslot length for the request in 10 ms intervals.
Definition: iqrf.h:113
uint16_t Hwpid
HWPID.
Definition: iqrf.h:186
DPA Confirmation.
Definition: iqrf.h:78
uint32_t ConfirmationTimestamp
Timestamp for the last confirmation message.
Definition: iqrf.h:196
bool IqrfIsBusy(const struct iqrf_t *Iqrf)
struct iqrf_state_t * State
IRRF state.
Definition: iqrf.h:208
uint8_t TxIdx
Index of currently used TX buffer.
Definition: iqrf.h:180
bool IqrfSendDpaError(const struct iqrf_t *Iqrf, uint8_t ErrorCode)
Header file for the EVE microsecond-scale work scheduling.
const struct iqrf_global_handlers_t * Handlers
pointer to the IQRF global handlers table
Definition: iqrf.h:212
uint8_t HopsResponse
Copy of HopsResponse from the last confirmation message.
Definition: iqrf.h:193
uint32_t IqrfGetExpectedRoutingTime(uint8_t HopsRequest, uint8_t TimeslotRequest, uint8_t HopsResponse, uint8_t TimeslotResponse)
uint8_t Nadr
Node&#39;s NADR.
Definition: iqrf.h:177
uint8_t HopsRequest
Number of hops in the forward (request) distribution path.
Definition: iqrf.h:112
void IqrfInterruptCb(const struct iqrf_t *Iqrf)
bool IsCoordinator
True if the interface represents an IQRF coordinator.
Definition: iqrf.h:214
const struct iqrf_t * Iqrf
Module instance.
Definition: iqrf.h:176
iqrf_response_handler_t ResponseHandler
Per-request response handler (callback)
Definition: iqrf.h:197
uint32_t IqrfGetExpectedRoutingCompleteTimestamp(const struct iqrf_t *Iqrf)
uint8_t Channel
Radio channel.
Definition: iqrf.h:184
Definition: uwork.h:142
uint8_t IrqPin
IRQ pin.
Definition: iqrf.h:213
uint8_t PNUM
Periphery number (address)
Definition: iqrf.h:90
void IqrfInit(const struct iqrf_t *Iqrf)
uint8_t PCMD
Periphery command.
Definition: iqrf.h:91
IQRF instance structure.
Definition: iqrf.h:206
iqrf_response_type_t
Definition: iqrf.h:76
uint8_t State
State.
Definition: iqrf.h:185
uint8_t TimeslotResponse
Definition: iqrf.h:194
uint8_t ErrN
Error number (= 0xFF for confirmation messages)
Definition: iqrf.h:110
Definition: spi.h:166
Definition: work.h:140
uint32_t SpiBaudrate
Spi speed (should be 250000 for IQRF)
Definition: iqrf.h:211
DPA Response.
Definition: iqrf.h:79
uint8_t DpaValue
DPA value.
Definition: iqrf.h:111