dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pios_uavtalkrcvr.c
Go to the documentation of this file.
1 
17 /*
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 3 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful, but
24  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26  * for more details.
27  *
28  * You should have received a copy of the GNU General Public License along
29  * with this program; if not, see <http://www.gnu.org/licenses/>
30  */
31 
32 /* Project Includes */
33 #include "pios.h"
34 
35 #if defined(PIOS_INCLUDE_UAVTALKRCVR)
36 
37 #include "pios_uavtalkrcvr_priv.h"
38 
39 #ifndef PIOS_UAVTALKRCVR_TIMEOUT_MS
40 #define PIOS_UAVTALKRCVR_TIMEOUT_MS 350
41 #endif
42 
43 static UAVTalkReceiverData uavreceiverdata;
44 
45 /* Provide a RCVR driver */
46 static int32_t PIOS_UAVTALKRCVR_Get(uintptr_t rcvr_id, uint8_t channel);
47 static void PIOS_uavtalkrcvr_Supervisor(uintptr_t rcvr_id);
48 
50  .read = PIOS_UAVTALKRCVR_Get,
51 };
52 
53 /* Local Variables */
54 enum pios_uavtalkrcvr_dev_magic {
55  PIOS_UAVTALKRCVR_DEV_MAGIC = 0xe9da5c56,
56 };
57 
58 struct pios_uavtalkrcvr_dev {
59  enum pios_uavtalkrcvr_dev_magic magic;
60 
61  uint16_t supv_timer;
62  volatile bool Fresh;
63 };
64 
65 static struct pios_uavtalkrcvr_dev *global_uavtalkrcvr_dev;
66 
67 static bool PIOS_uavtalkrcvr_validate(struct pios_uavtalkrcvr_dev *uavtalkrcvr_dev)
68 {
69  return (uavtalkrcvr_dev->magic == PIOS_UAVTALKRCVR_DEV_MAGIC);
70 }
71 
72 static struct pios_uavtalkrcvr_dev *PIOS_uavtalkrcvr_alloc(void)
73 {
74  struct pios_uavtalkrcvr_dev * uavtalkrcvr_dev;
75 
76  uavtalkrcvr_dev = (struct pios_uavtalkrcvr_dev *)PIOS_malloc(sizeof(*uavtalkrcvr_dev));
77  if (!uavtalkrcvr_dev) return(NULL);
78 
79  uavtalkrcvr_dev->magic = PIOS_UAVTALKRCVR_DEV_MAGIC;
80  uavtalkrcvr_dev->Fresh = false;
81  uavtalkrcvr_dev->supv_timer = 0;
82 
83  /* The update callback cannot receive the device pointer, so set it in a global */
84  global_uavtalkrcvr_dev = uavtalkrcvr_dev;
85 
86  return(uavtalkrcvr_dev);
87 }
88 
89 static void uavreceiver_updated(const UAVObjEvent *ev,
90  void *ctx, void *obj, int len)
91 {
92  struct pios_uavtalkrcvr_dev *uavtalkrcvr_dev = global_uavtalkrcvr_dev;
93  if (ev->obj == UAVTalkReceiverHandle()) {
95  UAVTalkReceiverGet(&uavreceiverdata);
96 
97  uavtalkrcvr_dev->Fresh = true;
98  }
99 }
100 
101 extern int32_t PIOS_UAVTALKRCVR_Init(uintptr_t *uavtalkrcvr_id)
102 {
103  struct pios_uavtalkrcvr_dev *uavtalkrcvr_dev;
104 
105  /* Allocate the device structure */
106  uavtalkrcvr_dev = (struct pios_uavtalkrcvr_dev *)PIOS_uavtalkrcvr_alloc();
107  if (!uavtalkrcvr_dev)
108  return -1;
109 
110  for (uint8_t i = 0; i < UAVTALKRECEIVER_CHANNEL_NUMELEM; i++) {
111  /* Flush channels */
112  uavreceiverdata.Channel[i] = PIOS_RCVR_TIMEOUT;
113  }
114 
115  /* Register uavobj callback */
116  UAVTalkReceiverConnectCallback(uavreceiver_updated);
117 
118  /* Register the failsafe timer callback. */
119  if (!PIOS_RTC_RegisterTickCallback(PIOS_uavtalkrcvr_Supervisor, (uintptr_t)uavtalkrcvr_dev)) {
121  }
122 
123  return 0;
124 }
125 
133 static int32_t PIOS_UAVTALKRCVR_Get(uintptr_t rcvr_id, uint8_t channel)
134 {
135  if (channel >= UAVTALKRECEIVER_CHANNEL_NUMELEM) {
136  /* channel is out of range */
137  return PIOS_RCVR_INVALID;
138  }
139 
140  return (uavreceiverdata.Channel[channel]);
141 }
142 
143 static void PIOS_uavtalkrcvr_Supervisor(uintptr_t uavtalkrcvr_id) {
144  /* Recover our device context */
145  struct pios_uavtalkrcvr_dev * uavtalkrcvr_dev = (struct pios_uavtalkrcvr_dev *)uavtalkrcvr_id;
146 
147  if (!PIOS_uavtalkrcvr_validate(uavtalkrcvr_dev)) {
148  /* Invalid device specified */
149  return;
150  }
151 
152  /* Compare RTC ticks to timeout in ms */
153  if ((++uavtalkrcvr_dev->supv_timer) <
154  (PIOS_UAVTALKRCVR_TIMEOUT_MS * 1000 / PIOS_RTC_Rate())) {
155  return;
156  }
157  uavtalkrcvr_dev->supv_timer = 0;
158 
159  if (!uavtalkrcvr_dev->Fresh) {
160  for (int32_t i = 0; i < UAVTALKRECEIVER_CHANNEL_NUMELEM; i++)
161  uavreceiverdata.Channel[i] = PIOS_RCVR_TIMEOUT;
162  }
163 
164  uavtalkrcvr_dev->Fresh = false;
165 }
166 
167 #endif /* PIOS_INCLUDE_UAVTALKRCVR */
168 
int32_t(* read)(uintptr_t id, uint8_t channel)
Definition: pios_rcvr.h:35
Main PiOS header to include all the compiled in PiOS options.
#define PIOS_DEBUG_Assert(test)
Definition: pios_debug.h:51
void * PIOS_malloc(size_t size)
Definition: pios_heap.c:125
bool PIOS_RTC_RegisterTickCallback(void(*fn)(uintptr_t id), uintptr_t data)
Definition: pios_delay.c:185
UAVObjHandle obj
float PIOS_RTC_Rate()
Definition: pios_delay.c:175
uint8_t i
Definition: msp_messages.h:97
uint32_t magic
int32_t PIOS_UAVTALKRCVR_Init(uintptr_t *gcsrcvr_id)
GCS receiver private functions.
void PIOS_RCVR_Active()
const struct pios_rcvr_driver pios_uavtalk_rcvr_driver