mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-18 03:52:11 +01:00
Merge branch 'next' of ssh://git.openpilot.org:22/OpenPilot into next
This commit is contained in:
commit
8d5b310f1f
@ -1,5 +1,12 @@
|
||||
Short summary of changes. For a complete list see the git log.
|
||||
|
||||
2011-10-11
|
||||
Fix for the Mac telemetry rates and specifically how long enumeration took.
|
||||
|
||||
2011-10-08
|
||||
Make the flash chip need to be have bad magic for a full second before erasing
|
||||
settings. Should avoid random lost settings.
|
||||
|
||||
2011-09-12
|
||||
Max rate now ONLY applies to attitude and axis lock mode. Manual rate is the
|
||||
only term that limits the rate mode now (and in axis lock when you push stick
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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() {
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -37,7 +37,6 @@
|
||||
|
||||
#if defined( Q_OS_MAC)
|
||||
|
||||
// todo:
|
||||
|
||||
#elif defined(Q_OS_UNIX)
|
||||
//#elif defined(Q_OS_LINUX)
|
||||
@ -104,10 +103,12 @@ public:
|
||||
void mytest(int num);
|
||||
signals:
|
||||
void deviceUnplugged(int);//just to make pips changes compile
|
||||
private:
|
||||
#if defined( Q_OS_MAC)
|
||||
|
||||
// todo:
|
||||
#endif
|
||||
|
||||
private:
|
||||
#if defined( Q_OS_MAC)
|
||||
|
||||
#elif defined(Q_OS_UNIX)
|
||||
//#elif defined(Q_OS_LINUX)
|
||||
|
@ -44,6 +44,18 @@
|
||||
#include <IOKit/hid/IOHIDLib.h>
|
||||
#include <CoreFoundation/CFString.h>
|
||||
#include <QString>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QCoreApplication>
|
||||
|
||||
class delay : public QThread
|
||||
{
|
||||
public:
|
||||
static void msleep(unsigned long msecs)
|
||||
{
|
||||
QThread::msleep(msecs);
|
||||
}
|
||||
};
|
||||
|
||||
#define BUFFER_SIZE 64
|
||||
|
||||
@ -54,6 +66,8 @@ typedef struct hid_struct hid_t;
|
||||
typedef struct buffer_struct buffer_t;
|
||||
static hid_t *first_hid = NULL;
|
||||
static hid_t *last_hid = NULL;
|
||||
// Make sure we use the correct runloop
|
||||
CFRunLoopRef the_correct_runloop = NULL;
|
||||
struct hid_struct {
|
||||
IOHIDDeviceRef ref;
|
||||
int open;
|
||||
@ -75,9 +89,10 @@ static void free_all_hid(void);
|
||||
static void hid_close(hid_t *);
|
||||
static void attach_callback(void *, IOReturn, void *, IOHIDDeviceRef);
|
||||
static void detach_callback(void *, IOReturn, void *hid_mgr, IOHIDDeviceRef dev);
|
||||
static void timeout_callback(CFRunLoopTimerRef, void *);
|
||||
static void input_callback(void *, IOReturn, void *, IOHIDReportType, uint32_t, uint8_t *, CFIndex);
|
||||
static void output_callback(hid_t *context, IOReturn ret, void *sender, IOHIDReportType type, uint32_t id, uint8_t *data, CFIndex len);
|
||||
static void timeout_callback(CFRunLoopTimerRef, void *);
|
||||
|
||||
|
||||
pjrc_rawhid::pjrc_rawhid()
|
||||
{
|
||||
@ -164,6 +179,8 @@ int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage)
|
||||
CFRelease(hid_manager);
|
||||
return 0;
|
||||
}
|
||||
// Set the run loop reference:
|
||||
the_correct_runloop = CFRunLoopGetCurrent();
|
||||
printf("run loop\n");
|
||||
// let it do the callback for all devices
|
||||
while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource) ;
|
||||
@ -183,47 +200,56 @@ int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage)
|
||||
//
|
||||
int pjrc_rawhid::receive(int num, void *buf, int len, int timeout)
|
||||
{
|
||||
hid_t *hid;
|
||||
buffer_t *b;
|
||||
CFRunLoopTimerRef timer=NULL;
|
||||
CFRunLoopTimerContext context;
|
||||
int ret=0, timeout_occurred=0;
|
||||
hid_t *hid;
|
||||
buffer_t *b;
|
||||
CFRunLoopTimerRef timer=NULL;
|
||||
CFRunLoopTimerContext context;
|
||||
int ret=0, timeout_occurred=0;
|
||||
|
||||
if (len < 1) return 0;
|
||||
hid = get_hid(num);
|
||||
if (!hid || !hid->open) return -1;
|
||||
if ((b = hid->first_buffer) != NULL) {
|
||||
if (len > b->len) len = b->len;
|
||||
memcpy(buf, b->buf, len);
|
||||
hid->first_buffer = b->next;
|
||||
free(b);
|
||||
return len;
|
||||
}
|
||||
memset(&context, 0, sizeof(context));
|
||||
context.info = &timeout_occurred;
|
||||
timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() +
|
||||
(double)timeout / 1000.0, 0, 0, 0, timeout_callback, &context);
|
||||
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
|
||||
while (1) {
|
||||
CFRunLoopRun();
|
||||
if ((b = hid->first_buffer) != NULL) {
|
||||
if (len > b->len) len = b->len;
|
||||
memcpy(buf, b->buf, len);
|
||||
hid->first_buffer = b->next;
|
||||
free(b);
|
||||
ret = len;
|
||||
if (len < 1) return 0;
|
||||
hid = get_hid(num);
|
||||
if (!hid || !hid->open) return -1;
|
||||
if ((b = hid->first_buffer) != NULL) {
|
||||
if (len > b->len) len = b->len;
|
||||
memcpy(buf, b->buf, len);
|
||||
hid->first_buffer = b->next;
|
||||
free(b);
|
||||
return len;
|
||||
}
|
||||
memset(&context, 0, sizeof(context));
|
||||
context.info = &timeout_occurred;
|
||||
timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() +
|
||||
(double)timeout / 1000.0, 0, 0, 0, timeout_callback, &context);
|
||||
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
|
||||
the_correct_runloop = CFRunLoopGetCurrent();
|
||||
//qDebug("--");
|
||||
while (1) {
|
||||
//qDebug(".");
|
||||
CFRunLoopRun(); // Found the problem: somehow the input_callback does not
|
||||
// stop this CFRunLoopRun because it is hooked to a different run loop !!!
|
||||
// Hence the use of the "correct_runloop" variable above.
|
||||
//qDebug(" ..");
|
||||
|
||||
if ((b = hid->first_buffer) != NULL) {
|
||||
if (len > b->len) len = b->len;
|
||||
memcpy(buf, b->buf, len);
|
||||
hid->first_buffer = b->next;
|
||||
free(b);
|
||||
ret = len;
|
||||
//qDebug("*************");
|
||||
break;
|
||||
}
|
||||
if (!hid->open) {
|
||||
printf("pjrc_rawhid_recv, device not open\n");
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (timeout_occurred)
|
||||
break;
|
||||
}
|
||||
if (!hid->open) {
|
||||
printf("pjrc_rawhid_recv, device not open\n");
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (timeout_occurred) break;
|
||||
}
|
||||
CFRunLoopTimerInvalidate(timer);
|
||||
CFRelease(timer);
|
||||
return ret;
|
||||
}
|
||||
CFRunLoopTimerInvalidate(timer);
|
||||
CFRelease(timer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// send - send a packet
|
||||
@ -335,10 +361,11 @@ static void input_callback(void *context, IOReturn ret, void *sender, IOHIDRepor
|
||||
buffer_t *n;
|
||||
hid_t *hid;
|
||||
|
||||
printf("input_callback, report id: %i buf: %x %x, len: %d\n", id, data[0], data[1], len);
|
||||
//qDebug("input_callback, ret: %i - report id: %i buf: %x %x, len: %d\n", ret, id, data[0], data[1], len);
|
||||
if (ret != kIOReturnSuccess || len < 1) return;
|
||||
hid = (hid_t*)context;
|
||||
if (!hid || hid->ref != sender) return;
|
||||
printf("Processing packet");
|
||||
n = (buffer_t *)malloc(sizeof(buffer_t));
|
||||
if (!n) return;
|
||||
if (len > BUFFER_SIZE) len = BUFFER_SIZE;
|
||||
@ -352,14 +379,16 @@ static void input_callback(void *context, IOReturn ret, void *sender, IOHIDRepor
|
||||
hid->last_buffer->next = n;
|
||||
hid->last_buffer = n;
|
||||
}
|
||||
CFRunLoopStop(CFRunLoopGetCurrent());
|
||||
//qDebug() << "Stop CFRunLoop from input_callback" << CFRunLoopGetCurrent();
|
||||
CFRunLoopStop(the_correct_runloop);
|
||||
}
|
||||
|
||||
static void timeout_callback(CFRunLoopTimerRef timer, void *info)
|
||||
{
|
||||
printf("timeout_callback\n");
|
||||
*(int *)info = 1;
|
||||
CFRunLoopStop(CFRunLoopGetCurrent());
|
||||
//qDebug("timeout_callback\n");
|
||||
*(int *)info = 1;
|
||||
//qDebug() << "Stop CFRunLoop from timeout_callback" << CFRunLoopGetCurrent();
|
||||
CFRunLoopStop(CFRunLoopGetCurrent());
|
||||
}
|
||||
|
||||
static void add_hid(hid_t *h)
|
||||
|
Loading…
x
Reference in New Issue
Block a user