2 ******************************************************************************
3 * @addtogroup PIOS PIOS Core hardware abstraction layer
5 * @addtogroup PIOS_GCSRCVR GCS Receiver Input Functions
6 * @brief Code to read the channels within the GCS Receiver UAVObject
10 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
11 * @brief GCS Input functions (STM32 dependent)
12 * @see The GNU Public License (GPL) Version 3
14 *****************************************************************************/
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #ifdef PIOS_INCLUDE_GCSRCVR
35 #include "uavobjectmanager.h"
37 #include "pios_gcsrcvr_priv.h"
39 static GCSReceiverData gcsreceiverdata
;
41 /* Provide a RCVR driver */
42 static int32_t PIOS_GCSRCVR_Get(uint32_t rcvr_id
, uint8_t channel
);
43 static void PIOS_gcsrcvr_Supervisor(uint32_t ppm_id
);
45 const struct pios_rcvr_driver pios_gcsrcvr_rcvr_driver
= {
46 .read
= PIOS_GCSRCVR_Get
,
50 enum pios_gcsrcvr_dev_magic
{
51 PIOS_GCSRCVR_DEV_MAGIC
= 0xe9da5c56,
54 struct pios_gcsrcvr_dev
{
55 enum pios_gcsrcvr_dev_magic magic
;
61 static struct pios_gcsrcvr_dev
*global_gcsrcvr_dev
;
63 static bool PIOS_gcsrcvr_validate(struct pios_gcsrcvr_dev
*gcsrcvr_dev
)
65 return gcsrcvr_dev
->magic
== PIOS_GCSRCVR_DEV_MAGIC
;
68 #if defined(PIOS_INCLUDE_FREERTOS)
69 static struct pios_gcsrcvr_dev
*PIOS_gcsrcvr_alloc(void)
71 struct pios_gcsrcvr_dev
*gcsrcvr_dev
;
73 gcsrcvr_dev
= (struct pios_gcsrcvr_dev
*)pios_malloc(sizeof(*gcsrcvr_dev
));
78 gcsrcvr_dev
->magic
= PIOS_GCSRCVR_DEV_MAGIC
;
79 gcsrcvr_dev
->Fresh
= false;
80 gcsrcvr_dev
->supv_timer
= 0;
82 /* The update callback cannot receive the device pointer, so set it in a global */
83 global_gcsrcvr_dev
= gcsrcvr_dev
;
88 static struct pios_gcsrcvr_dev pios_gcsrcvr_devs
[PIOS_GCSRCVR_MAX_DEVS
];
89 static uint8_t pios_gcsrcvr_num_devs
;
90 static struct pios_gcsrcvr_dev
*PIOS_gcsrcvr_alloc(void)
92 struct pios_gcsrcvr_dev
*gcsrcvr_dev
;
94 if (pios_gcsrcvr_num_devs
>= PIOS_GCSRCVR_MAX_DEVS
) {
98 gcsrcvr_dev
= &pios_gcsrcvr_devs
[pios_gcsrcvr_num_devs
++];
99 gcsrcvr_dev
->magic
= PIOS_GCSRCVR_DEV_MAGIC
;
100 gcsrcvr_dev
->Fresh
= false;
101 gcsrcvr_dev
->supv_timer
= 0;
103 global_gcsrcvr_dev
= gcsrcvr_dev
;
107 #endif /* if defined(PIOS_INCLUDE_FREERTOS) */
109 static void gcsreceiver_updated(UAVObjEvent
*ev
)
111 struct pios_gcsrcvr_dev
*gcsrcvr_dev
= global_gcsrcvr_dev
;
113 if (ev
->obj
== GCSReceiverHandle()) {
114 GCSReceiverGet(&gcsreceiverdata
);
115 gcsrcvr_dev
->Fresh
= true;
119 extern int32_t PIOS_GCSRCVR_Init(__attribute__((unused
)) uint32_t *gcsrcvr_id
)
121 struct pios_gcsrcvr_dev
*gcsrcvr_dev
;
123 /* Allocate the device structure */
124 gcsrcvr_dev
= (struct pios_gcsrcvr_dev
*)PIOS_gcsrcvr_alloc();
129 for (uint8_t i
= 0; i
< GCSRECEIVER_CHANNEL_NUMELEM
; i
++) {
131 gcsreceiverdata
.Channel
[i
] = PIOS_RCVR_TIMEOUT
;
134 /* Register uavobj callback */
135 GCSReceiverConnectCallback(gcsreceiver_updated
);
137 /* Register the failsafe timer callback. */
138 if (!PIOS_RTC_RegisterTickCallback(PIOS_gcsrcvr_Supervisor
, (uint32_t)gcsrcvr_dev
)) {
139 PIOS_DEBUG_Assert(0);
146 * Get the value of an input channel
147 * \param[in] channel Number of the channel desired (zero based)
148 * \output PIOS_RCVR_INVALID channel not available
149 * \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver
150 * \output >=0 channel value
152 static int32_t PIOS_GCSRCVR_Get(__attribute__((unused
)) uint32_t rcvr_id
, uint8_t channel
)
154 if (channel
>= GCSRECEIVER_CHANNEL_NUMELEM
) {
155 /* channel is out of range */
156 return PIOS_RCVR_INVALID
;
159 return gcsreceiverdata
.Channel
[channel
];
162 static void PIOS_gcsrcvr_Supervisor(uint32_t gcsrcvr_id
)
164 /* Recover our device context */
165 struct pios_gcsrcvr_dev
*gcsrcvr_dev
= (struct pios_gcsrcvr_dev
*)gcsrcvr_id
;
167 if (!PIOS_gcsrcvr_validate(gcsrcvr_dev
)) {
168 /* Invalid device specified */
175 if (++(gcsrcvr_dev
->supv_timer
) < (PIOS_GCSRCVR_TIMEOUT_MS
* 1000 / 625)) {
178 gcsrcvr_dev
->supv_timer
= 0;
180 if (!gcsrcvr_dev
->Fresh
) {
181 for (int32_t i
= 0; i
< GCSRECEIVER_CHANNEL_NUMELEM
; i
++) {
182 gcsreceiverdata
.Channel
[i
] = PIOS_RCVR_TIMEOUT
;
186 gcsrcvr_dev
->Fresh
= false;
189 #endif /* PIOS_INCLUDE_GCSRCVR */