mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +01:00
OP-237 I2C ESC support. This _will_ require you to reconfigure your
ActuatorSettings although for PWM aircrafts it should be done exactly as before Actuator: Store the update times and maximum update time OP-14 I2C: Start tracking short history of events and states in driver for logging OP-237 Flight/Actuator: Support for I2C based ESCs OP-237 MK_ESC: Send all four motors as one atomic transfer OP-237 Flight/Actuator: Allow channels to be mapped to MK I2C interface. Currently mixer channels are either PWM or MK but in the future this will change to support more than 8 channels. OP-16 PiOS/I2C: Further work to try and make I2C more stable, mstly special case handline in IRQ OP-237 I2C ESC: Support for Astect 4 channel ESCs OP-237: When the I2C Actuator write update fails track this OP-237 Actuator Settings: Change the way motor types are selected to keep that information more appropriately within ActuatorSettings instead of MixerSettings Also make motors stay at or above neutral when armed and throttle > 0 git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2366 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
parent
ed11e64bb2
commit
b173d74821
@ -235,6 +235,7 @@ SRC += $(PIOSSTM32F10X)/pios_usb_hid_pwr.c
|
|||||||
SRC += $(PIOSCOMMON)/pios_sdcard.c
|
SRC += $(PIOSCOMMON)/pios_sdcard.c
|
||||||
SRC += $(PIOSCOMMON)/pios_com.c
|
SRC += $(PIOSCOMMON)/pios_com.c
|
||||||
SRC += $(PIOSCOMMON)/pios_bmp085.c
|
SRC += $(PIOSCOMMON)/pios_bmp085.c
|
||||||
|
SRC += $(PIOSCOMMON)/pios_i2c_esc.c
|
||||||
SRC += $(PIOSCOMMON)/pios_iap.c
|
SRC += $(PIOSCOMMON)/pios_iap.c
|
||||||
#SRC += $(PIOSCOMMON)/pios_opahrs.c
|
#SRC += $(PIOSCOMMON)/pios_opahrs.c
|
||||||
#SRC += $(PIOSCOMMON)/pios_opahrs_proto.c
|
#SRC += $(PIOSCOMMON)/pios_opahrs_proto.c
|
||||||
|
@ -67,6 +67,8 @@ static void actuatorTask(void* parameters);
|
|||||||
static int16_t scaleChannel(float value, int16_t max, int16_t min, int16_t neutral);
|
static int16_t scaleChannel(float value, int16_t max, int16_t min, int16_t neutral);
|
||||||
static void setFailsafe();
|
static void setFailsafe();
|
||||||
static float MixerCurve(const float throttle, const float* curve);
|
static float MixerCurve(const float throttle, const float* curve);
|
||||||
|
static bool set_channel(uint8_t mixer_channel, uint16_t value);
|
||||||
|
|
||||||
float ProcessMixer(const int index, const float curve1, const float curve2,
|
float ProcessMixer(const int index, const float curve1, const float curve2,
|
||||||
MixerSettingsData* mixerSettings, ActuatorDesiredData* desired,
|
MixerSettingsData* mixerSettings, ActuatorDesiredData* desired,
|
||||||
const float period);
|
const float period);
|
||||||
@ -99,7 +101,6 @@ int32_t ActuatorInitialize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brieft Main Actuator module task
|
* @brieft Main Actuator module task
|
||||||
*
|
*
|
||||||
@ -201,25 +202,42 @@ static void actuatorTask(void* parameters)
|
|||||||
lastResult[ct] = 0;
|
lastResult[ct] = 0;
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
|
// For motors when armed keep above neutral
|
||||||
|
if((mixer[ct].type == MIXERSETTINGS_MIXER1TYPE_MOTOR) && (status[ct] < 0))
|
||||||
|
status[ct] = 0;
|
||||||
|
|
||||||
command.Channel[ct] = scaleChannel(status[ct],
|
command.Channel[ct] = scaleChannel(status[ct],
|
||||||
settings.ChannelMax[ct],
|
settings.ChannelMax[ct],
|
||||||
settings.ChannelMin[ct],
|
settings.ChannelNeutral[ct],
|
||||||
settings.ChannelNeutral[ct]);
|
settings.ChannelNeutral[ct]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MixerStatusSet(&mixerStatus);
|
MixerStatusSet(&mixerStatus);
|
||||||
|
|
||||||
|
// Store update time
|
||||||
|
command.UpdateTime = 10000*dT;
|
||||||
|
if(command.UpdateTime > command.MaxUpdateTime)
|
||||||
|
command.MaxUpdateTime = command.UpdateTime;
|
||||||
|
|
||||||
// Update output object
|
// Update output object
|
||||||
ActuatorCommandSet(&command);
|
ActuatorCommandSet(&command);
|
||||||
// Update in case read only (eg. during servo configuration)
|
// Update in case read only (eg. during servo configuration)
|
||||||
ActuatorCommandGet(&command);
|
ActuatorCommandGet(&command);
|
||||||
|
|
||||||
// Update servo outputs
|
// Update servo outputs
|
||||||
|
bool success = true;
|
||||||
for (int n = 0; n < ACTUATORCOMMAND_CHANNEL_NUMELEM; ++n)
|
for (int n = 0; n < ACTUATORCOMMAND_CHANNEL_NUMELEM; ++n)
|
||||||
{
|
{
|
||||||
PIOS_Servo_Set( n, command.Channel[n] );
|
success &= set_channel(n, command.Channel[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!success) {
|
||||||
|
command.NumFailedUpdates++;
|
||||||
|
ActuatorCommandSet(&command);
|
||||||
|
AlarmsSet(SYSTEMALARMS_ALARM_ACTUATOR, SYSTEMALARMS_ALARM_CRITICAL);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,13 +403,47 @@ static void setFailsafe()
|
|||||||
// Update servo outputs
|
// Update servo outputs
|
||||||
for (int n = 0; n < ACTUATORCOMMAND_CHANNEL_NUMELEM; ++n)
|
for (int n = 0; n < ACTUATORCOMMAND_CHANNEL_NUMELEM; ++n)
|
||||||
{
|
{
|
||||||
PIOS_Servo_Set( n, command.Channel[n] );
|
set_channel(n, command.Channel[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update output object
|
// Update output object
|
||||||
ActuatorCommandSet(&command);
|
ActuatorCommandSet(&command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool set_channel(uint8_t mixer_channel, uint16_t value) {
|
||||||
|
|
||||||
|
ActuatorSettingsData settings;
|
||||||
|
ActuatorSettingsGet(&settings);
|
||||||
|
|
||||||
|
switch(settings.ChannelType[mixer_channel]) {
|
||||||
|
case ACTUATORSETTINGS_CHANNELTYPE_PWM:
|
||||||
|
PIOS_Servo_Set(settings.ChannelAddr[mixer_channel], value);
|
||||||
|
return true;
|
||||||
|
case ACTUATORSETTINGS_CHANNELTYPE_MK:
|
||||||
|
{
|
||||||
|
ManualControlCommandData manual;
|
||||||
|
ManualControlCommandGet(&manual);
|
||||||
|
/* Unfortunately MK controller take forever to start so keep */
|
||||||
|
/* them spinning when armed */
|
||||||
|
if(manual.Armed)
|
||||||
|
value = (value < 0) ? 1 : value;
|
||||||
|
else
|
||||||
|
value = 0;
|
||||||
|
|
||||||
|
return PIOS_SetMKSpeed(settings.ChannelAddr[mixer_channel],value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ACTUATORSETTINGS_CHANNELTYPE_ASTEC4:
|
||||||
|
return PIOS_SetAstec4Speed(settings.ChannelAddr[mixer_channel],value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
#define PIOS_INCLUDE_GPIO
|
#define PIOS_INCLUDE_GPIO
|
||||||
#define PIOS_INCLUDE_EXTI
|
#define PIOS_INCLUDE_EXTI
|
||||||
#define PIOS_INCLUDE_WDG
|
#define PIOS_INCLUDE_WDG
|
||||||
|
#define PIOS_INCLUDE_I2C_ESC
|
||||||
|
|
||||||
/* Defaults for Logging */
|
/* Defaults for Logging */
|
||||||
#define LOG_FILENAME "PIOS.LOG"
|
#define LOG_FILENAME "PIOS.LOG"
|
||||||
|
@ -120,6 +120,22 @@ static void setDefaults(UAVObjHandle obj, uint16_t instId)
|
|||||||
data.ChannelMin[5] = 1000;
|
data.ChannelMin[5] = 1000;
|
||||||
data.ChannelMin[6] = 1000;
|
data.ChannelMin[6] = 1000;
|
||||||
data.ChannelMin[7] = 1000;
|
data.ChannelMin[7] = 1000;
|
||||||
|
data.ChannelType[0] = 0;
|
||||||
|
data.ChannelType[1] = 0;
|
||||||
|
data.ChannelType[2] = 0;
|
||||||
|
data.ChannelType[3] = 0;
|
||||||
|
data.ChannelType[4] = 0;
|
||||||
|
data.ChannelType[5] = 0;
|
||||||
|
data.ChannelType[6] = 0;
|
||||||
|
data.ChannelType[7] = 0;
|
||||||
|
data.ChannelAddr[0] = 0;
|
||||||
|
data.ChannelAddr[1] = 1;
|
||||||
|
data.ChannelAddr[2] = 2;
|
||||||
|
data.ChannelAddr[3] = 3;
|
||||||
|
data.ChannelAddr[4] = 4;
|
||||||
|
data.ChannelAddr[5] = 5;
|
||||||
|
data.ChannelAddr[6] = 6;
|
||||||
|
data.ChannelAddr[7] = 7;
|
||||||
|
|
||||||
UAVObjSetInstanceData(obj, instId, &data);
|
UAVObjSetInstanceData(obj, instId, &data);
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
#define ACTUATORCOMMAND_H
|
#define ACTUATORCOMMAND_H
|
||||||
|
|
||||||
// Object constants
|
// Object constants
|
||||||
#define ACTUATORCOMMAND_OBJID 3909877022U
|
#define ACTUATORCOMMAND_OBJID 3907024856U
|
||||||
#define ACTUATORCOMMAND_NAME "ActuatorCommand"
|
#define ACTUATORCOMMAND_NAME "ActuatorCommand"
|
||||||
#define ACTUATORCOMMAND_METANAME "ActuatorCommandMeta"
|
#define ACTUATORCOMMAND_METANAME "ActuatorCommandMeta"
|
||||||
#define ACTUATORCOMMAND_ISSINGLEINST 1
|
#define ACTUATORCOMMAND_ISSINGLEINST 1
|
||||||
@ -72,6 +72,9 @@
|
|||||||
// Object data
|
// Object data
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int16_t Channel[8];
|
int16_t Channel[8];
|
||||||
|
uint8_t UpdateTime;
|
||||||
|
uint8_t MaxUpdateTime;
|
||||||
|
uint8_t NumFailedUpdates;
|
||||||
|
|
||||||
} __attribute__((packed)) ActuatorCommandData;
|
} __attribute__((packed)) ActuatorCommandData;
|
||||||
|
|
||||||
@ -79,6 +82,9 @@ typedef struct {
|
|||||||
// Field Channel information
|
// Field Channel information
|
||||||
/* Number of elements for field Channel */
|
/* Number of elements for field Channel */
|
||||||
#define ACTUATORCOMMAND_CHANNEL_NUMELEM 8
|
#define ACTUATORCOMMAND_CHANNEL_NUMELEM 8
|
||||||
|
// Field UpdateTime information
|
||||||
|
// Field MaxUpdateTime information
|
||||||
|
// Field NumFailedUpdates information
|
||||||
|
|
||||||
|
|
||||||
// Generic interface functions
|
// Generic interface functions
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
#define ACTUATORSETTINGS_H
|
#define ACTUATORSETTINGS_H
|
||||||
|
|
||||||
// Object constants
|
// Object constants
|
||||||
#define ACTUATORSETTINGS_OBJID 3054509114U
|
#define ACTUATORSETTINGS_OBJID 844831578U
|
||||||
#define ACTUATORSETTINGS_NAME "ActuatorSettings"
|
#define ACTUATORSETTINGS_NAME "ActuatorSettings"
|
||||||
#define ACTUATORSETTINGS_METANAME "ActuatorSettingsMeta"
|
#define ACTUATORSETTINGS_METANAME "ActuatorSettingsMeta"
|
||||||
#define ACTUATORSETTINGS_ISSINGLEINST 1
|
#define ACTUATORSETTINGS_ISSINGLEINST 1
|
||||||
@ -89,6 +89,8 @@ typedef struct {
|
|||||||
int16_t ChannelMax[8];
|
int16_t ChannelMax[8];
|
||||||
int16_t ChannelNeutral[8];
|
int16_t ChannelNeutral[8];
|
||||||
int16_t ChannelMin[8];
|
int16_t ChannelMin[8];
|
||||||
|
uint8_t ChannelType[8];
|
||||||
|
uint8_t ChannelAddr[8];
|
||||||
|
|
||||||
} __attribute__((packed)) ActuatorSettingsData;
|
} __attribute__((packed)) ActuatorSettingsData;
|
||||||
|
|
||||||
@ -147,6 +149,14 @@ typedef enum { ACTUATORSETTINGS_VTOLMOTORNW_CHANNEL1=0, ACTUATORSETTINGS_VTOLMOT
|
|||||||
// Field ChannelMin information
|
// Field ChannelMin information
|
||||||
/* Number of elements for field ChannelMin */
|
/* Number of elements for field ChannelMin */
|
||||||
#define ACTUATORSETTINGS_CHANNELMIN_NUMELEM 8
|
#define ACTUATORSETTINGS_CHANNELMIN_NUMELEM 8
|
||||||
|
// Field ChannelType information
|
||||||
|
/* Enumeration options for field ChannelType */
|
||||||
|
typedef enum { ACTUATORSETTINGS_CHANNELTYPE_PWM=0, ACTUATORSETTINGS_CHANNELTYPE_MK=1, ACTUATORSETTINGS_CHANNELTYPE_ASTEC4=2 } ActuatorSettingsChannelTypeOptions;
|
||||||
|
/* Number of elements for field ChannelType */
|
||||||
|
#define ACTUATORSETTINGS_CHANNELTYPE_NUMELEM 8
|
||||||
|
// Field ChannelAddr information
|
||||||
|
/* Number of elements for field ChannelAddr */
|
||||||
|
#define ACTUATORSETTINGS_CHANNELADDR_NUMELEM 8
|
||||||
|
|
||||||
|
|
||||||
// Generic interface functions
|
// Generic interface functions
|
||||||
|
172
flight/PiOS/Common/pios_i2c_esc.c
Normal file
172
flight/PiOS/Common/pios_i2c_esc.c
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||||
|
* @{
|
||||||
|
* @addtogroup PIOS_I2C_ESC Code for controlling I2C based ESCs
|
||||||
|
* @brief Deals with the hardware interface to the magnetometers
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file pios_i2c_esc.c
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @brief HMC5843 Magnetic Sensor Functions from AHRS
|
||||||
|
* @see The GNU Public License (GPL) Version 3
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Project Includes */
|
||||||
|
#include "pios.h"
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_I2C_ESC)
|
||||||
|
|
||||||
|
/* HMC5843 Addresses */
|
||||||
|
#define MK_I2C_ADDR 0x29
|
||||||
|
#define ASTEC4_I2C_ADDR 0x02
|
||||||
|
|
||||||
|
bool PIOS_SetMKSpeed(uint8_t motornum, uint8_t speed);
|
||||||
|
|
||||||
|
uint8_t base_address = MK_I2C_ADDR;
|
||||||
|
uint8_t valid_motors = 0;
|
||||||
|
bool PIOS_I2C_ESC_Config()
|
||||||
|
{
|
||||||
|
base_address = MK_I2C_ADDR;
|
||||||
|
valid_motors = 0;
|
||||||
|
for(uint8_t i = 0; i < 4; i ++)
|
||||||
|
if(PIOS_SetMKSpeed(i, 0))
|
||||||
|
valid_motors |= (1 << i);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PIOS_I2C_ESC_SetSpeed(uint8_t speed[4])
|
||||||
|
{
|
||||||
|
/*bool success = true;
|
||||||
|
for(uint8_t i = 0; i < 4; i++) {
|
||||||
|
//if(valid_motors & (1 << i))
|
||||||
|
success &= PIOS_SetMKSpeed(i, speed[i]);
|
||||||
|
}
|
||||||
|
return success; */
|
||||||
|
|
||||||
|
const struct pios_i2c_txn txn_list[] = {
|
||||||
|
{
|
||||||
|
.info = __func__,
|
||||||
|
.addr = MK_I2C_ADDR + 0,
|
||||||
|
.rw = PIOS_I2C_TXN_WRITE,
|
||||||
|
.len = sizeof(speed[0]),
|
||||||
|
.buf = &speed[0],
|
||||||
|
} ,
|
||||||
|
{
|
||||||
|
.info = __func__,
|
||||||
|
.addr = MK_I2C_ADDR + 1,
|
||||||
|
.rw = PIOS_I2C_TXN_WRITE,
|
||||||
|
.len = sizeof(speed[1]),
|
||||||
|
.buf = &speed[1],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.info = __func__,
|
||||||
|
.addr = MK_I2C_ADDR + 2,
|
||||||
|
.rw = PIOS_I2C_TXN_WRITE,
|
||||||
|
.len = sizeof(speed[2]),
|
||||||
|
.buf = &speed[2],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.info = __func__,
|
||||||
|
.addr = MK_I2C_ADDR + 3,
|
||||||
|
.rw = PIOS_I2C_TXN_WRITE,
|
||||||
|
.len = sizeof(speed[3]),
|
||||||
|
.buf = &speed[3],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return PIOS_I2C_Transfer(PIOS_I2C_MAIN_ADAPTER, txn_list, NELEMENTS(txn_list));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PIOS_SetMKSpeed(uint8_t motornum, uint8_t speed) {
|
||||||
|
static uint8_t speeds[4] = {0,0,0,0};
|
||||||
|
|
||||||
|
if(motornum >= 4)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(speeds[motornum] == speed)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const struct pios_i2c_txn txn_list[] = {
|
||||||
|
{
|
||||||
|
.info = __func__,
|
||||||
|
.addr = MK_I2C_ADDR + motornum,
|
||||||
|
.rw = PIOS_I2C_TXN_WRITE,
|
||||||
|
.len = sizeof(speed),
|
||||||
|
.buf = &speed,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return PIOS_I2C_Transfer(PIOS_I2C_MAIN_ADAPTER, txn_list, NELEMENTS(txn_list));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PIOS_SetAstec4Address(uint8_t new_address) {
|
||||||
|
if((new_address < 0) || (new_address > 4))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint8_t data[4] = {250, 0, new_address, 230+new_address};
|
||||||
|
|
||||||
|
const struct pios_i2c_txn txn_list[] = {
|
||||||
|
{
|
||||||
|
.info = __func__,
|
||||||
|
.addr = ASTEC4_I2C_ADDR,
|
||||||
|
.rw = PIOS_I2C_TXN_WRITE,
|
||||||
|
.len = sizeof(data),
|
||||||
|
.buf = &data[0],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return PIOS_I2C_Transfer(PIOS_I2C_MAIN_ADAPTER, txn_list, NELEMENTS(txn_list));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PIOS_SetAstec4Speed(uint8_t motornum, uint8_t speed) {
|
||||||
|
static uint8_t speeds[5] = {0,0,0,0};
|
||||||
|
|
||||||
|
if((motornum < 0) || (motornum >= 4))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
speeds[motornum] = speed;
|
||||||
|
|
||||||
|
if(motornum != 3)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* Write in chunks of four */
|
||||||
|
speeds[4] = 0xAA + speeds[0] + speeds[1] + speeds[2] + speeds[3];
|
||||||
|
|
||||||
|
const struct pios_i2c_txn txn_list[] = {
|
||||||
|
{
|
||||||
|
.info = __func__,
|
||||||
|
.addr = ASTEC4_I2C_ADDR,
|
||||||
|
.rw = PIOS_I2C_TXN_WRITE,
|
||||||
|
.len = sizeof(speeds),
|
||||||
|
.buf = &speeds[0],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return PIOS_I2C_Transfer(PIOS_I2C_MAIN_ADAPTER, txn_list, NELEMENTS(txn_list));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
* @}
|
||||||
|
*/
|
@ -353,7 +353,6 @@ static void go_fsm_fault(struct pios_i2c_adapter *i2c_adapter)
|
|||||||
#endif
|
#endif
|
||||||
/* Note that this transfer has hit a bus error */
|
/* Note that this transfer has hit a bus error */
|
||||||
i2c_adapter->bus_error = true;
|
i2c_adapter->bus_error = true;
|
||||||
// i2c_adapter->curr_state = I2C_STATE_STOPPED;
|
|
||||||
|
|
||||||
i2c_adapter_reset_bus(i2c_adapter);
|
i2c_adapter_reset_bus(i2c_adapter);
|
||||||
|
|
||||||
@ -672,7 +671,7 @@ static void i2c_adapter_reset_bus(struct pios_i2c_adapter *i2c_adapter)
|
|||||||
/* Check SDA line to determine if slave is asserting bus and clock out if so, this may */
|
/* Check SDA line to determine if slave is asserting bus and clock out if so, this may */
|
||||||
/* have to be repeated (due to futher bus errors) but better than clocking 0xFF into an */
|
/* have to be repeated (due to futher bus errors) but better than clocking 0xFF into an */
|
||||||
/* ESC */
|
/* ESC */
|
||||||
bool sda_hung = GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET;
|
//bool sda_hung = GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET;
|
||||||
while(GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET) {
|
while(GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET) {
|
||||||
|
|
||||||
/* Set clock high and wait for any clock stretching to finish. */
|
/* Set clock high and wait for any clock stretching to finish. */
|
||||||
@ -688,17 +687,14 @@ static void i2c_adapter_reset_bus(struct pios_i2c_adapter *i2c_adapter)
|
|||||||
GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
|
GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
|
||||||
PIOS_DELAY_WaituS(2);
|
PIOS_DELAY_WaituS(2);
|
||||||
}
|
}
|
||||||
if(sda_hung) {
|
|
||||||
|
|
||||||
/* Generate a start then stop condition */
|
/* Generate a start then stop condition */
|
||||||
GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
|
GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
|
||||||
PIOS_DELAY_WaituS(2);
|
PIOS_DELAY_WaituS(2);
|
||||||
GPIO_ResetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin);
|
GPIO_ResetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin);
|
||||||
PIOS_DELAY_WaituS(2);
|
PIOS_DELAY_WaituS(2);
|
||||||
GPIO_ResetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin);
|
GPIO_ResetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin);
|
||||||
PIOS_DELAY_WaituS(2);
|
PIOS_DELAY_WaituS(2);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set data and clock high and wait for any clock stretching to finish. */
|
/* Set data and clock high and wait for any clock stretching to finish. */
|
||||||
GPIO_SetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin);
|
GPIO_SetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin);
|
||||||
@ -914,6 +910,8 @@ void PIOS_I2C_EV_IRQ_Handler(uint8_t i2c)
|
|||||||
i2c_adapter = find_i2c_adapter_by_id(i2c);
|
i2c_adapter = find_i2c_adapter_by_id(i2c);
|
||||||
PIOS_DEBUG_Assert(i2c_adapter);
|
PIOS_DEBUG_Assert(i2c_adapter);
|
||||||
|
|
||||||
|
PIOS_DELAY_WaituS(1);
|
||||||
|
|
||||||
uint32_t event = I2C_GetLastEvent(i2c_adapter->cfg->regs);
|
uint32_t event = I2C_GetLastEvent(i2c_adapter->cfg->regs);
|
||||||
|
|
||||||
#if defined(PIOS_I2C_DIAGNOSTICS)
|
#if defined(PIOS_I2C_DIAGNOSTICS)
|
||||||
@ -983,7 +981,7 @@ void PIOS_I2C_EV_IRQ_Handler(uint8_t i2c)
|
|||||||
while (halt) ;
|
while (halt) ;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0: /* Unexplained spurious event. Not sure what to do here. */
|
case 0: /* This triggers an FSM fault sometimes, but not having it stops things working */
|
||||||
case 0x40: /* RxNE only. MSL + BUSY have already been cleared by HW. */
|
case 0x40: /* RxNE only. MSL + BUSY have already been cleared by HW. */
|
||||||
case 0x44: /* RxNE + BTF. MSL + BUSY have already been cleared by HW. */
|
case 0x44: /* RxNE + BTF. MSL + BUSY have already been cleared by HW. */
|
||||||
case I2C_EVENT_MASTER_BYTE_RECEIVED: /* EV7 */
|
case I2C_EVENT_MASTER_BYTE_RECEIVED: /* EV7 */
|
||||||
@ -1011,6 +1009,7 @@ void PIOS_I2C_EV_IRQ_Handler(uint8_t i2c)
|
|||||||
break;
|
break;
|
||||||
case 0x30084: /* Occurs between byte tranmistted and master mode selected */
|
case 0x30084: /* Occurs between byte tranmistted and master mode selected */
|
||||||
case 0x30000: /* Need to throw away this spurious event */
|
case 0x30000: /* Need to throw away this spurious event */
|
||||||
|
//case 0x0: /* Not sure why zeros are occurring */
|
||||||
goto skip_event;
|
goto skip_event;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1026,25 +1025,50 @@ skip_event:
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t i2c_interrupt_history[5];
|
||||||
|
uint8_t i2c_interrupt_history_pointer = 0;
|
||||||
|
|
||||||
void PIOS_I2C_ER_IRQ_Handler(uint8_t i2c)
|
void PIOS_I2C_ER_IRQ_Handler(uint8_t i2c)
|
||||||
{
|
{
|
||||||
struct pios_i2c_adapter *i2c_adapter;
|
struct pios_i2c_adapter *i2c_adapter;
|
||||||
|
|
||||||
i2c_adapter = find_i2c_adapter_by_id(i2c);
|
i2c_adapter = find_i2c_adapter_by_id(i2c);
|
||||||
PIOS_DEBUG_Assert(i2c_adapter);
|
PIOS_DEBUG_Assert(i2c_adapter);
|
||||||
|
|
||||||
|
PIOS_DELAY_WaituS(1);
|
||||||
|
|
||||||
|
|
||||||
#if defined(PIOS_I2C_DIAGNOSTICS)
|
#if defined(PIOS_I2C_DIAGNOSTICS)
|
||||||
uint32_t event = I2C_GetLastEvent(i2c_adapter->cfg->regs);
|
uint32_t event = I2C_GetLastEvent(i2c_adapter->cfg->regs);
|
||||||
|
|
||||||
/* Store event for diagnostics */
|
i2c_interrupt_history[i2c_interrupt_history_pointer] = event;
|
||||||
i2c_event_history[i2c_event_history_pointer] = event;
|
i2c_interrupt_history_pointer = (i2c_interrupt_history_pointer + 1) % 5;
|
||||||
i2c_event_history_pointer = (i2c_event_history_pointer + 1) % I2C_LOG_DEPTH;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_AF)) {
|
#endif
|
||||||
|
|
||||||
|
switch(event) {
|
||||||
|
case 0x70184: /* EV8_2, but system detects own stop byte as erroneous */
|
||||||
|
switch (i2c_adapter->last_byte - i2c_adapter->active_byte + 1) {
|
||||||
|
case 0:
|
||||||
|
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSFER_DONE_LEN_EQ_0);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSFER_DONE_LEN_EQ_1);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSFER_DONE_LEN_EQ_2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSFER_DONE_LEN_GT_2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(event & I2C_FLAG_AF) {
|
||||||
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_NACK);
|
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_NACK);
|
||||||
} else {
|
} else { /* Mostly bus errors here */
|
||||||
i2c_adapter_log_fault(PIOS_I2C_ERROR_INTERRUPT);
|
i2c_adapter_log_fault(PIOS_I2C_ERROR_INTERRUPT);
|
||||||
|
|
||||||
/* Fail hard on any errors for now */
|
/* Fail hard on any errors for now */
|
||||||
|
49
flight/PiOS/inc/pios_i2c_esc.h
Normal file
49
flight/PiOS/inc/pios_i2c_esc.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||||
|
* @{
|
||||||
|
* @addtogroup PIOS_I2C_ESC Code for controlling I2C based ESCs
|
||||||
|
* @brief Deals with the hardware interface to the magnetometers
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file pios_i2c_esc.h
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @brief HMC5843 Magnetic Sensor Functions from AHRS
|
||||||
|
* @see The GNU Public License (GPL) Version 3
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PIOS_I2C_ESC_H
|
||||||
|
#define PIOS_I2C_ESC_H
|
||||||
|
|
||||||
|
/* Public Functions */
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
bool PIOS_I2C_ESC_Config();
|
||||||
|
bool PIOS_I2C_ESC_SetSpeed(uint8_t speed[4]);
|
||||||
|
bool PIOS_SetMKSpeed(uint8_t motornum, uint8_t speed);
|
||||||
|
bool PIOS_SetAstec4Speed(uint8_t motornum, uint8_t speed);
|
||||||
|
|
||||||
|
#endif /* PIOS_I2C_ESC_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
* @}
|
||||||
|
*/
|
@ -92,6 +92,9 @@
|
|||||||
#if defined(PIOS_INCLUDE_HMC5843)
|
#if defined(PIOS_INCLUDE_HMC5843)
|
||||||
#include <pios_hmc5843.h>
|
#include <pios_hmc5843.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(PIOS_INCLUDE_I2C_ESC)
|
||||||
|
#include <pios_i2c_esc.h>
|
||||||
|
#endif
|
||||||
#include <pios_iap.h>
|
#include <pios_iap.h>
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_BL_HELPER)
|
#if defined(PIOS_INCLUDE_BL_HELPER)
|
||||||
|
@ -41,9 +41,6 @@
|
|||||||
6549E0D21279B3C800C5476F /* fifo_buffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fifo_buffer.c; sourceTree = "<group>"; };
|
6549E0D21279B3C800C5476F /* fifo_buffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fifo_buffer.c; sourceTree = "<group>"; };
|
||||||
6549E0D31279B3CF00C5476F /* fifo_buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fifo_buffer.h; sourceTree = "<group>"; };
|
6549E0D31279B3CF00C5476F /* fifo_buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fifo_buffer.h; sourceTree = "<group>"; };
|
||||||
655268BC121FBD2900410C6E /* ahrscalibration.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = ahrscalibration.xml; sourceTree = "<group>"; };
|
655268BC121FBD2900410C6E /* ahrscalibration.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = ahrscalibration.xml; sourceTree = "<group>"; };
|
||||||
655DBA5212DA5B6A00341B9A /* pios_iap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pios_iap.h; sourceTree = "<group>"; };
|
|
||||||
655DBA5312DA5E9900341B9A /* watchdogstatus.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = watchdogstatus.xml; sourceTree = "<group>"; };
|
|
||||||
655DBA8A12DA644300341B9A /* taskmonitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = taskmonitor.c; sourceTree = "<group>"; };
|
|
||||||
65632CBF124E09D900469B77 /* guidance.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = guidance.c; sourceTree = "<group>"; };
|
65632CBF124E09D900469B77 /* guidance.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = guidance.c; sourceTree = "<group>"; };
|
||||||
65632CC1124E09D900469B77 /* guidance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = guidance.h; sourceTree = "<group>"; };
|
65632CC1124E09D900469B77 /* guidance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = guidance.h; sourceTree = "<group>"; };
|
||||||
65632DF51251650300469B77 /* pios_board.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pios_board.h; sourceTree = "<group>"; };
|
65632DF51251650300469B77 /* pios_board.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pios_board.h; sourceTree = "<group>"; };
|
||||||
@ -6786,7 +6783,6 @@
|
|||||||
65B367FD121C2620003EAD18 /* systemstats.xml */,
|
65B367FD121C2620003EAD18 /* systemstats.xml */,
|
||||||
65B367FE121C2620003EAD18 /* telemetrysettings.xml */,
|
65B367FE121C2620003EAD18 /* telemetrysettings.xml */,
|
||||||
65408AA812BB1648004DACC5 /* i2cstats.xml */,
|
65408AA812BB1648004DACC5 /* i2cstats.xml */,
|
||||||
655DBA5312DA5E9900341B9A /* watchdogstatus.xml */,
|
|
||||||
);
|
);
|
||||||
path = uavobjectdefinition;
|
path = uavobjectdefinition;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -7113,7 +7109,6 @@
|
|||||||
65E8EF5B11EEA61E00BBF654 /* System */ = {
|
65E8EF5B11EEA61E00BBF654 /* System */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
655DBA8A12DA644300341B9A /* taskmonitor.c */,
|
|
||||||
65E8EF5C11EEA61E00BBF654 /* alarms.c */,
|
65E8EF5C11EEA61E00BBF654 /* alarms.c */,
|
||||||
65E8EF5D11EEA61E00BBF654 /* inc */,
|
65E8EF5D11EEA61E00BBF654 /* inc */,
|
||||||
65E8EF6511EEA61E00BBF654 /* openpilot.c */,
|
65E8EF6511EEA61E00BBF654 /* openpilot.c */,
|
||||||
@ -7298,7 +7293,6 @@
|
|||||||
65E8F03811EFF25C00BBF654 /* inc */ = {
|
65E8F03811EFF25C00BBF654 /* inc */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
655DBA5212DA5B6A00341B9A /* pios_iap.h */,
|
|
||||||
6526645A122DF972006F9A3C /* pios_i2c_priv.h */,
|
6526645A122DF972006F9A3C /* pios_i2c_priv.h */,
|
||||||
6526645B122DF972006F9A3C /* pios_wdg.h */,
|
6526645B122DF972006F9A3C /* pios_wdg.h */,
|
||||||
651CF9EF120B700D00EEFD70 /* pios_usb_hid_desc.h */,
|
651CF9EF120B700D00EEFD70 /* pios_usb_hid_desc.h */,
|
||||||
|
@ -4,6 +4,9 @@ function [] = OPLogConvert()
|
|||||||
actuatorcommandIdx = 1;
|
actuatorcommandIdx = 1;
|
||||||
ActuatorCommand.timestamp = 0;
|
ActuatorCommand.timestamp = 0;
|
||||||
ActuatorCommand(1).Channel = zeros(1,8);
|
ActuatorCommand(1).Channel = zeros(1,8);
|
||||||
|
ActuatorCommand(1).UpdateTime = 0;
|
||||||
|
ActuatorCommand(1).MaxUpdateTime = 0;
|
||||||
|
ActuatorCommand(1).NumFailedUpdates = 0;
|
||||||
|
|
||||||
actuatordesiredIdx = 1;
|
actuatordesiredIdx = 1;
|
||||||
ActuatorDesired.timestamp = 0;
|
ActuatorDesired.timestamp = 0;
|
||||||
@ -34,6 +37,8 @@ function [] = OPLogConvert()
|
|||||||
ActuatorSettings(1).ChannelMax = zeros(1,8);
|
ActuatorSettings(1).ChannelMax = zeros(1,8);
|
||||||
ActuatorSettings(1).ChannelNeutral = zeros(1,8);
|
ActuatorSettings(1).ChannelNeutral = zeros(1,8);
|
||||||
ActuatorSettings(1).ChannelMin = zeros(1,8);
|
ActuatorSettings(1).ChannelMin = zeros(1,8);
|
||||||
|
ActuatorSettings(1).ChannelType = zeros(1,8);
|
||||||
|
ActuatorSettings(1).ChannelAddr = zeros(1,8);
|
||||||
|
|
||||||
ahrscalibrationIdx = 1;
|
ahrscalibrationIdx = 1;
|
||||||
AHRSCalibration.timestamp = 0;
|
AHRSCalibration.timestamp = 0;
|
||||||
@ -453,13 +458,13 @@ function [] = OPLogConvert()
|
|||||||
|
|
||||||
%% Read object
|
%% Read object
|
||||||
switch objID
|
switch objID
|
||||||
case 3909877022
|
case 3907024856
|
||||||
ActuatorCommand(actuatorcommandIdx) = ReadActuatorCommandObject(fid, timestamp);
|
ActuatorCommand(actuatorcommandIdx) = ReadActuatorCommandObject(fid, timestamp);
|
||||||
actuatorcommandIdx = actuatorcommandIdx + 1;
|
actuatorcommandIdx = actuatorcommandIdx + 1;
|
||||||
case 3562104706
|
case 3562104706
|
||||||
ActuatorDesired(actuatordesiredIdx) = ReadActuatorDesiredObject(fid, timestamp);
|
ActuatorDesired(actuatordesiredIdx) = ReadActuatorDesiredObject(fid, timestamp);
|
||||||
actuatordesiredIdx = actuatordesiredIdx + 1;
|
actuatordesiredIdx = actuatordesiredIdx + 1;
|
||||||
case 3054509114
|
case 844831578
|
||||||
ActuatorSettings(actuatorsettingsIdx) = ReadActuatorSettingsObject(fid, timestamp);
|
ActuatorSettings(actuatorsettingsIdx) = ReadActuatorSettingsObject(fid, timestamp);
|
||||||
actuatorsettingsIdx = actuatorsettingsIdx + 1;
|
actuatorsettingsIdx = actuatorsettingsIdx + 1;
|
||||||
case 806362034
|
case 806362034
|
||||||
@ -611,6 +616,9 @@ function [ActuatorCommand] = ReadActuatorCommandObject(fid, timestamp)
|
|||||||
|
|
||||||
ActuatorCommand.timestamp = timestamp;
|
ActuatorCommand.timestamp = timestamp;
|
||||||
ActuatorCommand.Channel = double(fread(fid, 8, 'int16'));
|
ActuatorCommand.Channel = double(fread(fid, 8, 'int16'));
|
||||||
|
ActuatorCommand.UpdateTime = double(fread(fid, 1, 'uint8'));
|
||||||
|
ActuatorCommand.MaxUpdateTime = double(fread(fid, 1, 'uint8'));
|
||||||
|
ActuatorCommand.NumFailedUpdates = double(fread(fid, 1, 'uint8'));
|
||||||
% read CRC
|
% read CRC
|
||||||
fread(fid, 1, 'uint8');
|
fread(fid, 1, 'uint8');
|
||||||
end
|
end
|
||||||
@ -661,6 +669,8 @@ function [ActuatorSettings] = ReadActuatorSettingsObject(fid, timestamp)
|
|||||||
ActuatorSettings.ChannelMax = double(fread(fid, 8, 'int16'));
|
ActuatorSettings.ChannelMax = double(fread(fid, 8, 'int16'));
|
||||||
ActuatorSettings.ChannelNeutral = double(fread(fid, 8, 'int16'));
|
ActuatorSettings.ChannelNeutral = double(fread(fid, 8, 'int16'));
|
||||||
ActuatorSettings.ChannelMin = double(fread(fid, 8, 'int16'));
|
ActuatorSettings.ChannelMin = double(fread(fid, 8, 'int16'));
|
||||||
|
ActuatorSettings.ChannelType = double(fread(fid, 8, 'uint8'));
|
||||||
|
ActuatorSettings.ChannelAddr = double(fread(fid, 8, 'uint8'));
|
||||||
% read CRC
|
% read CRC
|
||||||
fread(fid, 1, 'uint8');
|
fread(fid, 1, 'uint8');
|
||||||
end
|
end
|
||||||
|
@ -53,6 +53,15 @@ ActuatorCommand::ActuatorCommand(): UAVDataObject(OBJID, ISSINGLEINST, ISSETTING
|
|||||||
ChannelElemNames.append("6");
|
ChannelElemNames.append("6");
|
||||||
ChannelElemNames.append("7");
|
ChannelElemNames.append("7");
|
||||||
fields.append( new UAVObjectField(QString("Channel"), QString("us"), UAVObjectField::INT16, ChannelElemNames, QStringList()) );
|
fields.append( new UAVObjectField(QString("Channel"), QString("us"), UAVObjectField::INT16, ChannelElemNames, QStringList()) );
|
||||||
|
QStringList UpdateTimeElemNames;
|
||||||
|
UpdateTimeElemNames.append("0");
|
||||||
|
fields.append( new UAVObjectField(QString("UpdateTime"), QString("ms x 10"), UAVObjectField::UINT8, UpdateTimeElemNames, QStringList()) );
|
||||||
|
QStringList MaxUpdateTimeElemNames;
|
||||||
|
MaxUpdateTimeElemNames.append("0");
|
||||||
|
fields.append( new UAVObjectField(QString("MaxUpdateTime"), QString("ms x 10"), UAVObjectField::UINT8, MaxUpdateTimeElemNames, QStringList()) );
|
||||||
|
QStringList NumFailedUpdatesElemNames;
|
||||||
|
NumFailedUpdatesElemNames.append("0");
|
||||||
|
fields.append( new UAVObjectField(QString("NumFailedUpdates"), QString(""), UAVObjectField::UINT8, NumFailedUpdatesElemNames, QStringList()) );
|
||||||
|
|
||||||
// Initialize object
|
// Initialize object
|
||||||
initializeFields(fields, (quint8*)&data, NUMBYTES);
|
initializeFields(fields, (quint8*)&data, NUMBYTES);
|
||||||
|
@ -44,6 +44,9 @@ public:
|
|||||||
// Field structure
|
// Field structure
|
||||||
typedef struct {
|
typedef struct {
|
||||||
qint16 Channel[8];
|
qint16 Channel[8];
|
||||||
|
quint8 UpdateTime;
|
||||||
|
quint8 MaxUpdateTime;
|
||||||
|
quint8 NumFailedUpdates;
|
||||||
|
|
||||||
} __attribute__((packed)) DataFields;
|
} __attribute__((packed)) DataFields;
|
||||||
|
|
||||||
@ -51,10 +54,13 @@ public:
|
|||||||
// Field Channel information
|
// Field Channel information
|
||||||
/* Number of elements for field Channel */
|
/* Number of elements for field Channel */
|
||||||
static const quint32 CHANNEL_NUMELEM = 8;
|
static const quint32 CHANNEL_NUMELEM = 8;
|
||||||
|
// Field UpdateTime information
|
||||||
|
// Field MaxUpdateTime information
|
||||||
|
// Field NumFailedUpdates information
|
||||||
|
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
static const quint32 OBJID = 3909877022U;
|
static const quint32 OBJID = 3907024856U;
|
||||||
static const QString NAME;
|
static const QString NAME;
|
||||||
static const QString DESCRIPTION;
|
static const QString DESCRIPTION;
|
||||||
static const bool ISSINGLEINST = 1;
|
static const bool ISSINGLEINST = 1;
|
||||||
|
@ -54,12 +54,42 @@ _fields = [ \
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
uavobject.UAVObjectField(
|
||||||
|
'UpdateTime',
|
||||||
|
'B',
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
'0',
|
||||||
|
],
|
||||||
|
{
|
||||||
|
}
|
||||||
|
),
|
||||||
|
uavobject.UAVObjectField(
|
||||||
|
'MaxUpdateTime',
|
||||||
|
'B',
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
'0',
|
||||||
|
],
|
||||||
|
{
|
||||||
|
}
|
||||||
|
),
|
||||||
|
uavobject.UAVObjectField(
|
||||||
|
'NumFailedUpdates',
|
||||||
|
'B',
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
'0',
|
||||||
|
],
|
||||||
|
{
|
||||||
|
}
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ActuatorCommand(uavobject.UAVObject):
|
class ActuatorCommand(uavobject.UAVObject):
|
||||||
## Object constants
|
## Object constants
|
||||||
OBJID = 3909877022
|
OBJID = 3907024856
|
||||||
NAME = "ActuatorCommand"
|
NAME = "ActuatorCommand"
|
||||||
METANAME = "ActuatorCommandMeta"
|
METANAME = "ActuatorCommandMeta"
|
||||||
ISSINGLEINST = 1
|
ISSINGLEINST = 1
|
||||||
|
@ -259,6 +259,30 @@ ActuatorSettings::ActuatorSettings(): UAVDataObject(OBJID, ISSINGLEINST, ISSETTI
|
|||||||
ChannelMinElemNames.append("6");
|
ChannelMinElemNames.append("6");
|
||||||
ChannelMinElemNames.append("7");
|
ChannelMinElemNames.append("7");
|
||||||
fields.append( new UAVObjectField(QString("ChannelMin"), QString("us"), UAVObjectField::INT16, ChannelMinElemNames, QStringList()) );
|
fields.append( new UAVObjectField(QString("ChannelMin"), QString("us"), UAVObjectField::INT16, ChannelMinElemNames, QStringList()) );
|
||||||
|
QStringList ChannelTypeElemNames;
|
||||||
|
ChannelTypeElemNames.append("0");
|
||||||
|
ChannelTypeElemNames.append("1");
|
||||||
|
ChannelTypeElemNames.append("2");
|
||||||
|
ChannelTypeElemNames.append("3");
|
||||||
|
ChannelTypeElemNames.append("4");
|
||||||
|
ChannelTypeElemNames.append("5");
|
||||||
|
ChannelTypeElemNames.append("6");
|
||||||
|
ChannelTypeElemNames.append("7");
|
||||||
|
QStringList ChannelTypeEnumOptions;
|
||||||
|
ChannelTypeEnumOptions.append("PWM");
|
||||||
|
ChannelTypeEnumOptions.append("MK");
|
||||||
|
ChannelTypeEnumOptions.append("ASTEC4");
|
||||||
|
fields.append( new UAVObjectField(QString("ChannelType"), QString(""), UAVObjectField::ENUM, ChannelTypeElemNames, ChannelTypeEnumOptions) );
|
||||||
|
QStringList ChannelAddrElemNames;
|
||||||
|
ChannelAddrElemNames.append("0");
|
||||||
|
ChannelAddrElemNames.append("1");
|
||||||
|
ChannelAddrElemNames.append("2");
|
||||||
|
ChannelAddrElemNames.append("3");
|
||||||
|
ChannelAddrElemNames.append("4");
|
||||||
|
ChannelAddrElemNames.append("5");
|
||||||
|
ChannelAddrElemNames.append("6");
|
||||||
|
ChannelAddrElemNames.append("7");
|
||||||
|
fields.append( new UAVObjectField(QString("ChannelAddr"), QString(""), UAVObjectField::UINT8, ChannelAddrElemNames, QStringList()) );
|
||||||
|
|
||||||
// Initialize object
|
// Initialize object
|
||||||
initializeFields(fields, (quint8*)&data, NUMBYTES);
|
initializeFields(fields, (quint8*)&data, NUMBYTES);
|
||||||
@ -334,6 +358,22 @@ void ActuatorSettings::setDefaultFieldValues()
|
|||||||
data.ChannelMin[5] = 1000;
|
data.ChannelMin[5] = 1000;
|
||||||
data.ChannelMin[6] = 1000;
|
data.ChannelMin[6] = 1000;
|
||||||
data.ChannelMin[7] = 1000;
|
data.ChannelMin[7] = 1000;
|
||||||
|
data.ChannelType[0] = 0;
|
||||||
|
data.ChannelType[1] = 0;
|
||||||
|
data.ChannelType[2] = 0;
|
||||||
|
data.ChannelType[3] = 0;
|
||||||
|
data.ChannelType[4] = 0;
|
||||||
|
data.ChannelType[5] = 0;
|
||||||
|
data.ChannelType[6] = 0;
|
||||||
|
data.ChannelType[7] = 0;
|
||||||
|
data.ChannelAddr[0] = 0;
|
||||||
|
data.ChannelAddr[1] = 1;
|
||||||
|
data.ChannelAddr[2] = 2;
|
||||||
|
data.ChannelAddr[3] = 3;
|
||||||
|
data.ChannelAddr[4] = 4;
|
||||||
|
data.ChannelAddr[5] = 5;
|
||||||
|
data.ChannelAddr[6] = 6;
|
||||||
|
data.ChannelAddr[7] = 7;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +61,8 @@ public:
|
|||||||
qint16 ChannelMax[8];
|
qint16 ChannelMax[8];
|
||||||
qint16 ChannelNeutral[8];
|
qint16 ChannelNeutral[8];
|
||||||
qint16 ChannelMin[8];
|
qint16 ChannelMin[8];
|
||||||
|
quint8 ChannelType[8];
|
||||||
|
quint8 ChannelAddr[8];
|
||||||
|
|
||||||
} __attribute__((packed)) DataFields;
|
} __attribute__((packed)) DataFields;
|
||||||
|
|
||||||
@ -119,10 +121,18 @@ public:
|
|||||||
// Field ChannelMin information
|
// Field ChannelMin information
|
||||||
/* Number of elements for field ChannelMin */
|
/* Number of elements for field ChannelMin */
|
||||||
static const quint32 CHANNELMIN_NUMELEM = 8;
|
static const quint32 CHANNELMIN_NUMELEM = 8;
|
||||||
|
// Field ChannelType information
|
||||||
|
/* Enumeration options for field ChannelType */
|
||||||
|
typedef enum { CHANNELTYPE_PWM=0, CHANNELTYPE_MK=1, CHANNELTYPE_ASTEC4=2 } ChannelTypeOptions;
|
||||||
|
/* Number of elements for field ChannelType */
|
||||||
|
static const quint32 CHANNELTYPE_NUMELEM = 8;
|
||||||
|
// Field ChannelAddr information
|
||||||
|
/* Number of elements for field ChannelAddr */
|
||||||
|
static const quint32 CHANNELADDR_NUMELEM = 8;
|
||||||
|
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
static const quint32 OBJID = 3054509114U;
|
static const quint32 OBJID = 844831578U;
|
||||||
static const QString NAME;
|
static const QString NAME;
|
||||||
static const QString DESCRIPTION;
|
static const QString DESCRIPTION;
|
||||||
static const bool ISSINGLEINST = 1;
|
static const bool ISSINGLEINST = 1;
|
||||||
|
@ -365,12 +365,49 @@ _fields = [ \
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
uavobject.UAVObjectField(
|
||||||
|
'ChannelType',
|
||||||
|
'b',
|
||||||
|
8,
|
||||||
|
[
|
||||||
|
'0',
|
||||||
|
'1',
|
||||||
|
'2',
|
||||||
|
'3',
|
||||||
|
'4',
|
||||||
|
'5',
|
||||||
|
'6',
|
||||||
|
'7',
|
||||||
|
],
|
||||||
|
{
|
||||||
|
'0' : 'PWM',
|
||||||
|
'1' : 'MK',
|
||||||
|
'2' : 'ASTEC4',
|
||||||
|
}
|
||||||
|
),
|
||||||
|
uavobject.UAVObjectField(
|
||||||
|
'ChannelAddr',
|
||||||
|
'B',
|
||||||
|
8,
|
||||||
|
[
|
||||||
|
'0',
|
||||||
|
'1',
|
||||||
|
'2',
|
||||||
|
'3',
|
||||||
|
'4',
|
||||||
|
'5',
|
||||||
|
'6',
|
||||||
|
'7',
|
||||||
|
],
|
||||||
|
{
|
||||||
|
}
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ActuatorSettings(uavobject.UAVObject):
|
class ActuatorSettings(uavobject.UAVObject):
|
||||||
## Object constants
|
## Object constants
|
||||||
OBJID = 3054509114
|
OBJID = 844831578
|
||||||
NAME = "ActuatorSettings"
|
NAME = "ActuatorSettings"
|
||||||
METANAME = "ActuatorSettingsMeta"
|
METANAME = "ActuatorSettingsMeta"
|
||||||
ISSINGLEINST = 1
|
ISSINGLEINST = 1
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
<object name="ActuatorCommand" singleinstance="true" settings="false">
|
<object name="ActuatorCommand" singleinstance="true" settings="false">
|
||||||
<description>Contains the pulse duration sent to each of the channels. Set by @ref ActuatorModule</description>
|
<description>Contains the pulse duration sent to each of the channels. Set by @ref ActuatorModule</description>
|
||||||
<field name="Channel" units="us" type="int16" elements="8"/>
|
<field name="Channel" units="us" type="int16" elements="8"/>
|
||||||
|
<field name="UpdateTime" units="ms x 10" type="uint8" elements="1"/>
|
||||||
|
<field name="MaxUpdateTime" units="ms x 10" type="uint8" elements="1"/>
|
||||||
|
<field name="NumFailedUpdates" units="" type="uint8" elements="1"/>
|
||||||
<access gcs="readwrite" flight="readwrite"/>
|
<access gcs="readwrite" flight="readwrite"/>
|
||||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
<field name="ChannelMax" units="us" type="int16" elements="8" defaultvalue="1000"/>
|
<field name="ChannelMax" units="us" type="int16" elements="8" defaultvalue="1000"/>
|
||||||
<field name="ChannelNeutral" units="us" type="int16" elements="8" defaultvalue="1000"/>
|
<field name="ChannelNeutral" units="us" type="int16" elements="8" defaultvalue="1000"/>
|
||||||
<field name="ChannelMin" units="us" type="int16" elements="8" defaultvalue="1000"/>
|
<field name="ChannelMin" units="us" type="int16" elements="8" defaultvalue="1000"/>
|
||||||
|
<field name="ChannelType" units="" type="enum" elements="8" options="PWM,MK,ASTEC4" defaultvalue="PWM"/>
|
||||||
|
<field name="ChannelAddr" units="" type="uint8" elements="8" defaultvalue="0,1,2,3,4,5,6,7"/>
|
||||||
<access gcs="readwrite" flight="readwrite"/>
|
<access gcs="readwrite" flight="readwrite"/>
|
||||||
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
|
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
|
||||||
<telemetryflight acked="true" updatemode="onchange" period="0"/>
|
<telemetryflight acked="true" updatemode="onchange" period="0"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user