1
0
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:
zedamota 2011-10-12 16:44:11 +01:00
commit 8d5b310f1f
7 changed files with 153 additions and 80 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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() {
}

View File

@ -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 */
/**

View File

@ -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);

View File

@ -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)

View File

@ -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)