diff --git a/flight/Modules/ManualControl/manualcontrol.c b/flight/Modules/ManualControl/manualcontrol.c index e8b18fefb..6186a6af9 100644 --- a/flight/Modules/ManualControl/manualcontrol.c +++ b/flight/Modules/ManualControl/manualcontrol.c @@ -456,7 +456,7 @@ static bool updateRcvrActivityCompare(uint32_t rcvr_id, struct rcvr_activity_fsm break; } - ReceiverActivityActiveGroupSet(&group); + ReceiverActivityActiveGroupSet((uint8_t*)&group); ReceiverActivityActiveChannelSet(&channel); activity_updated = true; } diff --git a/flight/OpenPilot/System/pios_board_posix.c b/flight/OpenPilot/System/pios_board_posix.c index 37fadd760..48d6839bc 100644 --- a/flight/OpenPilot/System/pios_board_posix.c +++ b/flight/OpenPilot/System/pios_board_posix.c @@ -33,11 +33,19 @@ #include "attitudeactual.h" #include "positionactual.h" #include "velocityactual.h" +#include "manualcontrolsettings.h" +#if defined(PIOS_INCLUDE_RCVR) #include "pios_rcvr_priv.h" -struct pios_rcvr_channel_map pios_rcvr_channel_to_id_map[PIOS_RCVR_MAX_CHANNELS]; -uint32_t pios_rcvr_max_channel; +/* One slot per selectable receiver group. + * eg. PWM, PPM, GCS, SPEKTRUM1, SPEKTRUM2, SBUS + * NOTE: No slot in this map for NONE. + */ +uint32_t pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE]; + +#endif /* PIOS_INCLUDE_RCVR */ + void Stack_Change() { } diff --git a/flight/PiOS.posix/inc/pios_rcvr.h b/flight/PiOS.posix/inc/pios_rcvr.h index a32160894..ab493cd35 100644 --- a/flight/PiOS.posix/inc/pios_rcvr.h +++ b/flight/PiOS.posix/inc/pios_rcvr.h @@ -31,21 +31,24 @@ #ifndef PIOS_RCVR_H #define PIOS_RCVR_H -struct pios_rcvr_channel_map { - uint32_t id; - uint8_t channel; -}; - -extern struct pios_rcvr_channel_map pios_rcvr_channel_to_id_map[]; - struct pios_rcvr_driver { - void (*init)(uint32_t id); - int32_t (*read)(uint32_t id, uint8_t channel); + void (*init)(uint32_t id); + int32_t (*read)(uint32_t id, uint8_t channel); }; /* Public Functions */ extern int32_t PIOS_RCVR_Read(uint32_t rcvr_id, uint8_t channel); +/*! Define error codes for PIOS_RCVR_Get */ +enum PIOS_RCVR_errors { + /*! Indicates that a failsafe condition or missing receiver detected for that channel */ + PIOS_RCVR_TIMEOUT = 0, + /*! Channel is invalid for this driver (usually out of range supported) */ + PIOS_RCVR_INVALID = -1, + /*! Indicates that the driver for this channel has not been initialized */ + PIOS_RCVR_NODRIVER = -2 +}; + #endif /* PIOS_RCVR_H */ /** diff --git a/flight/PiOS.posix/posix/pios_rcvr.c b/flight/PiOS.posix/posix/pios_rcvr.c index 652730547..719cb9769 100644 --- a/flight/PiOS.posix/posix/pios_rcvr.c +++ b/flight/PiOS.posix/posix/pios_rcvr.c @@ -21,32 +21,39 @@ static bool PIOS_RCVR_validate(struct pios_rcvr_dev * rcvr_dev) } #if defined(PIOS_INCLUDE_FREERTOS) && 0 -static struct pios_rcvr_dev * PIOS_RCVR_alloc(void) -{ - struct pios_rcvr_dev * rcvr_dev; - - rcvr_dev = (struct pios_rcvr_dev *)malloc(sizeof(*rcvr_dev)); - if (!rcvr_dev) return (NULL); - - rcvr_dev->magic = PIOS_RCVR_DEV_MAGIC; - return(rcvr_dev); -} +//static struct pios_rcvr_dev * PIOS_RCVR_alloc(void) +//{ +// struct pios_rcvr_dev * rcvr_dev; +// +// rcvr_dev = (struct pios_rcvr_dev *)pvPortMalloc(sizeof(*rcvr_dev)); +// if (!rcvr_dev) return (NULL); +// +// rcvr_dev->magic = PIOS_RCVR_DEV_MAGIC; +// return(rcvr_dev); +//} #else static struct pios_rcvr_dev pios_rcvr_devs[PIOS_RCVR_MAX_DEVS]; static uint8_t pios_rcvr_num_devs; -static struct pios_rcvr_dev * PIOS_RCVR_alloc(void) +static uint32_t PIOS_RCVR_alloc(void) { struct pios_rcvr_dev * rcvr_dev; if (pios_rcvr_num_devs >= PIOS_RCVR_MAX_DEVS) { - return (NULL); + return (PIOS_RCVR_MAX_DEVS+1); } rcvr_dev = &pios_rcvr_devs[pios_rcvr_num_devs++]; rcvr_dev->magic = PIOS_RCVR_DEV_MAGIC; - return (rcvr_dev); + return (pios_rcvr_num_devs); } +static struct pios_rcvr_dev * PIOS_RCVR_find_dev(uint32_t rcvr_dev_id) +{ + if (!rcvr_dev_id) return NULL; + if (rcvr_dev_id>pios_rcvr_num_devs+1) return NULL; + return &pios_rcvr_devs[rcvr_dev_id-1]; +} + #endif /** @@ -56,35 +63,53 @@ static struct pios_rcvr_dev * PIOS_RCVR_alloc(void) * \param[in] id * \return < 0 if initialisation failed */ -int32_t PIOS_RCVR_Init(uint32_t * rcvr_id, const struct pios_rcvr_driver * driver, const uint32_t lower_id) +int32_t PIOS_RCVR_Init(uint32_t * rcvr_id, const struct pios_rcvr_driver * driver, uint32_t lower_id) { PIOS_DEBUG_Assert(rcvr_id); PIOS_DEBUG_Assert(driver); + uint32_t rcvr_dev_id; struct pios_rcvr_dev * rcvr_dev; - rcvr_dev = (struct pios_rcvr_dev *) PIOS_RCVR_alloc(); + rcvr_dev_id = PIOS_RCVR_alloc(); + rcvr_dev = PIOS_RCVR_find_dev(rcvr_dev_id); if (!rcvr_dev) goto out_fail; rcvr_dev->driver = driver; rcvr_dev->lower_id = lower_id; - - *rcvr_id = pios_rcvr_num_devs - 1; - + *rcvr_id = rcvr_dev_id; return(0); out_fail: return(-1); } +/** + * @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 + */ int32_t PIOS_RCVR_Read(uint32_t rcvr_id, uint8_t channel) { - struct pios_rcvr_dev * rcvr_dev = &pios_rcvr_devs[rcvr_id]; + // Publicly facing API uses channel 1 for first channel + if(channel == 0) + return PIOS_RCVR_INVALID; + else + channel--; + + if (rcvr_id == 0) + return PIOS_RCVR_NODRIVER; + + struct pios_rcvr_dev * rcvr_dev = PIOS_RCVR_find_dev(rcvr_id); if (!PIOS_RCVR_validate(rcvr_dev)) { /* Undefined RCVR port for this board (see pios_board.c) */ - PIOS_DEBUG_Assert(0); + PIOS_Assert(0); } PIOS_DEBUG_Assert(rcvr_dev->driver->read);