2011-06-19 21:02:34 +02:00
|
|
|
#include "pios.h"
|
|
|
|
|
2013-03-15 15:28:53 +01:00
|
|
|
#ifdef PIOS_INCLUDE_RCVR
|
2011-06-19 21:02:34 +02:00
|
|
|
|
|
|
|
#include <pios_rcvr_priv.h>
|
|
|
|
|
2011-07-15 03:52:07 +02:00
|
|
|
enum pios_rcvr_dev_magic {
|
2013-05-19 16:37:30 +02:00
|
|
|
PIOS_RCVR_DEV_MAGIC = 0x99aabbcc,
|
2011-07-15 03:52:07 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct pios_rcvr_dev {
|
2013-05-19 16:37:30 +02:00
|
|
|
enum pios_rcvr_dev_magic magic;
|
|
|
|
uint32_t lower_id;
|
|
|
|
const struct pios_rcvr_driver *driver;
|
2011-07-15 03:52:07 +02:00
|
|
|
};
|
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
static bool PIOS_RCVR_validate(struct pios_rcvr_dev *rcvr_dev)
|
2011-06-19 21:02:34 +02:00
|
|
|
{
|
2013-05-19 16:37:30 +02:00
|
|
|
return rcvr_dev->magic == PIOS_RCVR_DEV_MAGIC;
|
2011-06-19 21:02:34 +02:00
|
|
|
}
|
|
|
|
|
2011-09-01 04:35:03 +02:00
|
|
|
#if defined(PIOS_INCLUDE_FREERTOS)
|
2013-05-19 16:37:30 +02:00
|
|
|
static struct pios_rcvr_dev *PIOS_RCVR_alloc(void)
|
2011-06-19 21:02:34 +02:00
|
|
|
{
|
2013-05-19 16:37:30 +02:00
|
|
|
struct pios_rcvr_dev *rcvr_dev;
|
2011-06-19 21:02:34 +02:00
|
|
|
|
2014-06-11 20:11:48 +02:00
|
|
|
rcvr_dev = (struct pios_rcvr_dev *)pios_malloc(sizeof(*rcvr_dev));
|
2013-05-19 16:37:30 +02:00
|
|
|
if (!rcvr_dev) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2011-06-19 21:02:34 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
rcvr_dev->magic = PIOS_RCVR_DEV_MAGIC;
|
|
|
|
return rcvr_dev;
|
2011-06-19 21:02:34 +02:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
static struct pios_rcvr_dev pios_rcvr_devs[PIOS_RCVR_MAX_DEVS];
|
|
|
|
static uint8_t pios_rcvr_num_devs;
|
2013-05-19 16:37:30 +02:00
|
|
|
static struct pios_rcvr_dev *PIOS_RCVR_alloc(void)
|
2011-06-19 21:02:34 +02:00
|
|
|
{
|
2013-05-19 16:37:30 +02:00
|
|
|
struct pios_rcvr_dev *rcvr_dev;
|
2011-06-19 21:02:34 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
if (pios_rcvr_num_devs >= PIOS_RCVR_MAX_DEVS) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2011-06-19 21:02:34 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
rcvr_dev = &pios_rcvr_devs[pios_rcvr_num_devs++];
|
|
|
|
rcvr_dev->magic = PIOS_RCVR_DEV_MAGIC;
|
2011-06-19 21:02:34 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
return rcvr_dev;
|
2011-06-19 21:02:34 +02:00
|
|
|
}
|
2013-05-19 16:37:30 +02:00
|
|
|
#endif /* if defined(PIOS_INCLUDE_FREERTOS) */
|
2011-06-19 21:02:34 +02:00
|
|
|
|
|
|
|
/**
|
2013-05-19 16:37:30 +02:00
|
|
|
* Initialises RCVR layer
|
|
|
|
* \param[out] handle
|
|
|
|
* \param[in] driver
|
|
|
|
* \param[in] id
|
|
|
|
* \return < 0 if initialisation failed
|
|
|
|
*/
|
|
|
|
int32_t PIOS_RCVR_Init(uint32_t *rcvr_id, const struct pios_rcvr_driver *driver, uint32_t lower_id)
|
2011-06-19 21:02:34 +02:00
|
|
|
{
|
2013-05-19 16:37:30 +02:00
|
|
|
PIOS_DEBUG_Assert(rcvr_id);
|
|
|
|
PIOS_DEBUG_Assert(driver);
|
2011-06-19 21:02:34 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
struct pios_rcvr_dev *rcvr_dev;
|
2011-06-19 21:02:34 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
rcvr_dev = (struct pios_rcvr_dev *)PIOS_RCVR_alloc();
|
|
|
|
if (!rcvr_dev) {
|
|
|
|
goto out_fail;
|
|
|
|
}
|
2011-06-19 21:02:34 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
rcvr_dev->driver = driver;
|
|
|
|
rcvr_dev->lower_id = lower_id;
|
2011-06-19 21:02:34 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
*rcvr_id = (uint32_t)rcvr_dev;
|
|
|
|
return 0;
|
2011-06-19 21:02:34 +02:00
|
|
|
|
|
|
|
out_fail:
|
2013-05-19 16:37:30 +02:00
|
|
|
return -1;
|
2011-06-19 21:02:34 +02:00
|
|
|
}
|
|
|
|
|
2011-09-04 19:37:39 +02:00
|
|
|
/**
|
|
|
|
* @brief Reads an input channel from the appropriate driver
|
|
|
|
* @param[in] rcvr_id driver to read from
|
|
|
|
* @param[in] channel channel to read
|
|
|
|
* @returns Unitless input value
|
|
|
|
* @retval PIOS_RCVR_TIMEOUT indicates a failsafe or timeout from that channel
|
|
|
|
* @retval PIOS_RCVR_INVALID invalid channel for this driver (usually out of range supported)
|
|
|
|
* @retval PIOS_RCVR_NODRIVER driver was not initialized
|
|
|
|
*/
|
2011-07-15 03:52:07 +02:00
|
|
|
int32_t PIOS_RCVR_Read(uint32_t rcvr_id, uint8_t channel)
|
2011-06-19 21:02:34 +02:00
|
|
|
{
|
2013-05-19 16:37:30 +02:00
|
|
|
// Publicly facing API uses channel 1 for first channel
|
|
|
|
if (channel == 0) {
|
|
|
|
return PIOS_RCVR_INVALID;
|
|
|
|
} else {
|
|
|
|
channel--;
|
|
|
|
}
|
2011-09-06 23:35:28 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
if (rcvr_id == 0) {
|
|
|
|
return PIOS_RCVR_NODRIVER;
|
|
|
|
}
|
2011-09-04 06:47:56 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
struct pios_rcvr_dev *rcvr_dev = (struct pios_rcvr_dev *)rcvr_id;
|
2011-06-19 21:02:34 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
if (!PIOS_RCVR_validate(rcvr_dev)) {
|
|
|
|
/* Undefined RCVR port for this board (see pios_board.c) */
|
|
|
|
PIOS_Assert(0);
|
|
|
|
}
|
2011-06-19 21:02:34 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
PIOS_DEBUG_Assert(rcvr_dev->driver->read);
|
2011-06-19 21:02:34 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
return rcvr_dev->driver->read(rcvr_dev->lower_id, channel);
|
2011-06-19 21:02:34 +02:00
|
|
|
}
|
|
|
|
|
2015-04-02 20:09:58 +02:00
|
|
|
/**
|
|
|
|
* @brief Reads input quality from the appropriate driver
|
|
|
|
* @param[in] rcvr_id driver to read from
|
2015-04-03 19:30:36 +02:00
|
|
|
* @returns received signal quality expressed as a %
|
2015-04-02 20:09:58 +02:00
|
|
|
* @retval PIOS_RCVR_NODRIVER driver was not initialized
|
|
|
|
*/
|
|
|
|
uint8_t PIOS_RCVR_GetQuality(uint32_t rcvr_id)
|
|
|
|
{
|
|
|
|
if (rcvr_id == 0) {
|
|
|
|
return PIOS_RCVR_NODRIVER;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct pios_rcvr_dev *rcvr_dev = (struct pios_rcvr_dev *)rcvr_id;
|
|
|
|
|
|
|
|
if (!PIOS_RCVR_validate(rcvr_dev)) {
|
|
|
|
/* Undefined RCVR port for this board (see pios_board.c) */
|
2015-04-20 22:40:42 +02:00
|
|
|
/* As no receiver is available assume min */
|
|
|
|
return 0;
|
2015-04-02 20:09:58 +02:00
|
|
|
}
|
|
|
|
|
2015-04-02 22:41:40 +02:00
|
|
|
if (!rcvr_dev->driver->get_quality) {
|
|
|
|
/* If no quality is available assume max */
|
2015-04-04 15:50:08 +02:00
|
|
|
return 100;
|
2015-04-02 20:09:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return rcvr_dev->driver->get_quality(rcvr_dev->lower_id);
|
|
|
|
}
|
|
|
|
|
2013-06-07 03:08:45 +02:00
|
|
|
/**
|
|
|
|
* @brief Get a semaphore that signals when a new sample is available.
|
|
|
|
* @param[in] rcvr_id driver to read from
|
|
|
|
* @param[in] channel channel to read
|
|
|
|
* @returns The semaphore, or NULL if not supported.
|
|
|
|
*/
|
|
|
|
xSemaphoreHandle PIOS_RCVR_GetSemaphore(uint32_t rcvr_id, uint8_t channel)
|
|
|
|
{
|
|
|
|
// Publicly facing API uses channel 1 for first channel
|
|
|
|
if (channel == 0) {
|
|
|
|
return NULL;
|
|
|
|
} else {
|
|
|
|
channel--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rcvr_id == 0) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct pios_rcvr_dev *rcvr_dev = (struct pios_rcvr_dev *)rcvr_id;
|
|
|
|
|
|
|
|
if (!PIOS_RCVR_validate(rcvr_dev)) {
|
|
|
|
/* Undefined RCVR port for this board (see pios_board.c) */
|
|
|
|
PIOS_Assert(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rcvr_dev->driver->get_semaphore) {
|
|
|
|
return rcvr_dev->driver->get_semaphore(rcvr_dev->lower_id, channel);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-03-15 15:28:53 +01:00
|
|
|
#endif /* PIOS_INCLUDE_RCVR */
|
2011-06-19 21:02:34 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
* @}
|
|
|
|
*/
|