1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

PiOS/I2C: Lots of small changes. Added a few weird bus events that are

sometimes thrown, and made errors not lock it up by default.  It works for me,
but since this has historically been associated with lots of lock ups please
check your systems carefully.

PiOS/I2C: Make the bus by default try to recover from errors instead of locking
up

PiOS/I2C: After a bus error and clocking all previous data create a STOP
condition to make sure bus is released (note, this also requires creating a
START condition first)

PiOS/I2C: If the same event hits the I2C bus twice in a row then disregard
second one, there is no situation where we should get the same event multiple
times that matters and this gets us out really quickly to catch the real
events.  I was seeing this with repeated 0x70084 which means byte transmitted.
This is related to STM32 bugs in the IRQ timings I believe.

PiOS/I2C: 1) Mask out some bits we don't care about in the event flags
2) Don't lock up if the give semaphore fails, although why it does is strange
3) Recover from bus failure through the "auto" state path instead of just
coding state

PiOS/I2C: Change the reset bus code to follow
http://www.analog.com/static/imported-files/application_notes/54305147357414AN686_0.pdf
(thanks for the reference Neontangerine).  Although this may actually NOT clear
the bus the first time through, subsequent bus errors should eventually clock
it out.  The up side is it is less likely to clock a bunch of 1s into an ESC
and make it run up.

PiOS/I2C: Some cleaned up code for getting a snippet of the history when
something strange happens

PiOS/I2C: Export logging information from I2C through a UAV object

PiOS/I2C: Improve the diagnostic information

PiOS/I2C: Need to handle the event 0x30084.  This seems to happen between a
byte transmitted and new byte started

PiOS/I2C: Handle the NACK condition by simply going to the stopping state.

PiOS/I2C: Add a new NACK state to handle sending the STOP signal after a NACK
following the STM documentation.  Other error conditions still are not dealt
with.

PiOS/I2C: Should handle the NACK condition from all the write cases.  Need to
think about read cases

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2239 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
peabody124 2010-12-17 07:01:58 +00:00 committed by peabody124
parent c034a35d2c
commit 4b4a66c2d7
16 changed files with 885 additions and 15 deletions

View File

@ -167,6 +167,7 @@ SRC += $(OPUAVOBJ)/manualcontrolsettings.c
SRC += $(OPUAVOBJ)/attitudedesired.c
SRC += $(OPUAVOBJ)/stabilizationsettings.c
SRC += $(OPUAVOBJ)/ahrsstatus.c
SRC += $(OPUAVOBJ)/i2cstats.c
SRC += $(OPUAVOBJ)/baroaltitude.c
SRC += $(OPUAVOBJ)/ahrscalibration.c
SRC += $(OPUAVOBJ)/attitudeactual.c

View File

@ -43,6 +43,7 @@
#include "objectpersistence.h"
#include "manualcontrolcommand.h"
#include "systemstats.h"
#include "i2cstats.h"
// Private constants
@ -69,6 +70,7 @@ static int32_t stackOverflow;
// Private functions
static void objectUpdatedCb(UAVObjEvent * ev);
static void updateStats();
static void updateI2Cstats();
static void updateSystemAlarms();
static void systemTask(void *parameters);
@ -110,7 +112,8 @@ static void systemTask(void *parameters)
// Update the system alarms
updateSystemAlarms();
updateI2Cstats();
// Flash the heartbeat LED
PIOS_LED_Toggle(LED1);
@ -199,6 +202,25 @@ static void objectUpdatedCb(UAVObjEvent * ev)
}
}
/**
* Called periodically to update the I2C statistics
*/
static void updateI2Cstats()
{
I2CStatsData i2cStats;
I2CStatsGet(&i2cStats);
struct pios_i2c_fault_history history;
PIOS_I2C_GetDiagnoistics(&history, &i2cStats.event_errors);
for(uint8_t i = 0; (i < I2C_LOG_DEPTH) && (i < I2CSTATS_EVENT_LOG_NUMELEM); i++) {
i2cStats.event_log[i] = history.event[i];
i2cStats.state_log[i] = history.state[i];
}
i2cStats.last_error_type = history.type;
I2CStatsSet(&i2cStats);
}
/**
* Called periodically to update the system stats
*/

View File

@ -0,0 +1,111 @@
/**
******************************************************************************
* @addtogroup UAVObjects OpenPilot UAVObjects
* @{
* @addtogroup I2CStats I2CStats
* @brief Tracks statistics on the I2C bus.
*
* Autogenerated files and functions for I2CStats Object
* @{
*
* @file i2cstats.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Implementation of the I2CStats object. This file has been
* automatically generated by the UAVObjectGenerator.
*
* @note Object definition file: i2cstats.xml.
* This is an automatically generated file.
* DO NOT modify manually.
*
* @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
*/
#include "openpilot.h"
#include "i2cstats.h"
// Private variables
static UAVObjHandle handle;
// Private functions
static void setDefaults(UAVObjHandle obj, uint16_t instId);
/**
* Initialize object.
* \return 0 Success
* \return -1 Failure
*/
int32_t I2CStatsInitialize()
{
// Register object with the object manager
handle = UAVObjRegister(I2CSTATS_OBJID, I2CSTATS_NAME, I2CSTATS_METANAME, 0,
I2CSTATS_ISSINGLEINST, I2CSTATS_ISSETTINGS, I2CSTATS_NUMBYTES, &setDefaults);
// Done
if (handle != 0)
{
return 0;
}
else
{
return -1;
}
}
/**
* Initialize object fields and metadata with the default values.
* If a default value is not specified the object fields
* will be initialized to zero.
*/
static void setDefaults(UAVObjHandle obj, uint16_t instId)
{
I2CStatsData data;
UAVObjMetadata metadata;
// Initialize object fields to their default values
UAVObjGetInstanceData(obj, instId, &data);
memset(&data, 0, sizeof(I2CStatsData));
UAVObjSetInstanceData(obj, instId, &data);
// Initialize object metadata to their default values
metadata.access = ACCESS_READWRITE;
metadata.gcsAccess = ACCESS_READWRITE;
metadata.telemetryAcked = 0;
metadata.telemetryUpdateMode = UPDATEMODE_PERIODIC;
metadata.telemetryUpdatePeriod = 10000;
metadata.gcsTelemetryAcked = 0;
metadata.gcsTelemetryUpdateMode = UPDATEMODE_MANUAL;
metadata.gcsTelemetryUpdatePeriod = 0;
metadata.loggingUpdateMode = UPDATEMODE_PERIODIC;
metadata.loggingUpdatePeriod = 30000;
UAVObjSetMetadata(obj, &metadata);
}
/**
* Get object handle
*/
UAVObjHandle I2CStatsHandle()
{
return handle;
}
/**
* @}
*/

View File

@ -0,0 +1,107 @@
/**
******************************************************************************
* @addtogroup UAVObjects OpenPilot UAVObjects
* @{
* @addtogroup I2CStats I2CStats
* @brief Tracks statistics on the I2C bus.
*
* Autogenerated files and functions for I2CStats Object
* @{
*
* @file i2cstats.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Implementation of the I2CStats object. This file has been
* automatically generated by the UAVObjectGenerator.
*
* @note Object definition file: i2cstats.xml.
* This is an automatically generated file.
* DO NOT modify manually.
*
* @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 I2CSTATS_H
#define I2CSTATS_H
// Object constants
#define I2CSTATS_OBJID 1063893720U
#define I2CSTATS_NAME "I2CStats"
#define I2CSTATS_METANAME "I2CStatsMeta"
#define I2CSTATS_ISSINGLEINST 1
#define I2CSTATS_ISSETTINGS 0
#define I2CSTATS_NUMBYTES sizeof(I2CStatsData)
// Object access macros
/**
* @function I2CStatsGet(dataOut)
* @brief Populate a I2CStatsData object
* @param[out] dataOut
*/
#define I2CStatsGet(dataOut) UAVObjGetData(I2CStatsHandle(), dataOut)
#define I2CStatsSet(dataIn) UAVObjSetData(I2CStatsHandle(), dataIn)
#define I2CStatsInstGet(instId, dataOut) UAVObjGetInstanceData(I2CStatsHandle(), instId, dataOut)
#define I2CStatsInstSet(instId, dataIn) UAVObjSetInstanceData(I2CStatsHandle(), instId, dataIn)
#define I2CStatsConnectQueue(queue) UAVObjConnectQueue(I2CStatsHandle(), queue, EV_MASK_ALL_UPDATES)
#define I2CStatsConnectCallback(cb) UAVObjConnectCallback(I2CStatsHandle(), cb, EV_MASK_ALL_UPDATES)
#define I2CStatsCreateInstance() UAVObjCreateInstance(I2CStatsHandle())
#define I2CStatsRequestUpdate() UAVObjRequestUpdate(I2CStatsHandle())
#define I2CStatsRequestInstUpdate(instId) UAVObjRequestInstanceUpdate(I2CStatsHandle(), instId)
#define I2CStatsUpdated() UAVObjUpdated(I2CStatsHandle())
#define I2CStatsInstUpdated(instId) UAVObjUpdated(I2CStatsHandle(), instId)
#define I2CStatsGetMetadata(dataOut) UAVObjGetMetadata(I2CStatsHandle(), dataOut)
#define I2CStatsSetMetadata(dataIn) UAVObjSetMetadata(I2CStatsHandle(), dataIn)
#define I2CStatsReadOnly(dataIn) UAVObjReadOnly(I2CStatsHandle())
// Object data
typedef struct {
uint16_t event_errors;
uint16_t fsm_errors;
uint16_t irq_errors;
uint8_t last_error_type;
uint32_t event_log[5];
uint32_t state_log[5];
} __attribute__((packed)) I2CStatsData;
// Field information
// Field event_errors information
// Field fsm_errors information
// Field irq_errors information
// Field last_error_type information
/* Enumeration options for field last_error_type */
typedef enum { I2CSTATS_LAST_ERROR_TYPE_EVENT=0, I2CSTATS_LAST_ERROR_TYPE_FSM=1, I2CSTATS_LAST_ERROR_TYPE_INTERRUPT=2 } I2CStatslast_error_typeOptions;
// Field event_log information
/* Number of elements for field event_log */
#define I2CSTATS_EVENT_LOG_NUMELEM 5
// Field state_log information
/* Number of elements for field state_log */
#define I2CSTATS_STATE_LOG_NUMELEM 5
// Generic interface functions
int32_t I2CStatsInitialize();
UAVObjHandle I2CStatsHandle();
#endif // I2CSTATS_H
/**
* @}
* @}
*/

View File

@ -47,6 +47,7 @@
#include "gpstime.h"
#include "guidancesettings.h"
#include "homelocation.h"
#include "i2cstats.h"
#include "manualcontrolcommand.h"
#include "manualcontrolsettings.h"
#include "mixersettings.h"
@ -91,6 +92,7 @@ void UAVObjectsInitializeAll()
GPSTimeInitialize();
GuidanceSettingsInitialize();
HomeLocationInitialize();
I2CStatsInitialize();
ManualControlCommandInitialize();
ManualControlSettingsInitialize();
MixerSettingsInitialize();

View File

@ -40,6 +40,8 @@
#include <pios_i2c_priv.h>
//#define I2C_HALT_ON_ERRORS
enum i2c_adapter_event {
I2C_EVENT_BUS_ERROR,
I2C_EVENT_START,
@ -55,12 +57,24 @@ enum i2c_adapter_event {
I2C_EVENT_TRANSFER_DONE_LEN_EQ_1,
I2C_EVENT_TRANSFER_DONE_LEN_EQ_2,
I2C_EVENT_TRANSFER_DONE_LEN_GT_2,
I2C_EVENT_NACK,
I2C_EVENT_STOPPED,
I2C_EVENT_AUTO, /* FIXME: remove this */
I2C_EVENT_NUM_EVENTS /* Must be last */
};
#if defined(PIOS_I2C_DIAGNOSTICS)
static struct pios_i2c_fault_history i2c_adapter_fault_history;
static uint32_t i2c_event_history[I2C_LOG_DEPTH];
static uint8_t i2c_event_history_pointer = 0;
static enum i2c_adapter_state i2c_state_history[I2C_LOG_DEPTH];
static uint8_t i2c_state_history_pointer = 0;
static uint16_t i2c_fsm_fault_count = 0;
static uint16_t i2c_bad_event_counter = 0;
static uint16_t i2c_error_interrupt_counter = 0;
#endif
static void go_fsm_fault(struct pios_i2c_adapter *i2c_adapter);
static void go_bus_error(struct pios_i2c_adapter *i2c_adapter);
static void go_stopping(struct pios_i2c_adapter *i2c_adapter);
@ -88,6 +102,8 @@ static void go_w_any_txn_addr(struct pios_i2c_adapter *i2c_adapter);
static void go_w_any_txn_middle(struct pios_i2c_adapter *i2c_adapter);
static void go_w_last_txn_last(struct pios_i2c_adapter *i2c_adapter);
static void go_nack(struct pios_i2c_adapter *i2c_adapter);
struct i2c_adapter_transition {
void (*entry_fn) (struct pios_i2c_adapter * i2c_adapter);
enum i2c_adapter_state next_state[I2C_EVENT_NUM_EVENTS];
@ -99,11 +115,15 @@ static void i2c_adapter_fsm_init(struct pios_i2c_adapter *i2c_adapter);
static bool i2c_adapter_wait_for_stopped(struct pios_i2c_adapter *i2c_adapter);
static void i2c_adapter_reset_bus(struct pios_i2c_adapter *i2c_adapter);
static void i2c_adapter_log_fault(enum pios_i2c_error_type type);
const static struct i2c_adapter_transition i2c_adapter_transitions[I2C_STATE_NUM_STATES] = {
[I2C_STATE_FSM_FAULT] = {
.entry_fn = go_fsm_fault,
},
.next_state = {
[I2C_EVENT_AUTO] = I2C_STATE_STOPPING,
},
},
[I2C_STATE_BUS_ERROR] = {
.entry_fn = go_bus_error,
.next_state = {
@ -134,6 +154,7 @@ const static struct i2c_adapter_transition i2c_adapter_transitions[I2C_STATE_NUM
[I2C_EVENT_STARTED_MORE_TXN_WRITE] = I2C_STATE_W_MORE_TXN_ADDR,
[I2C_EVENT_STARTED_LAST_TXN_READ] = I2C_STATE_R_LAST_TXN_ADDR,
[I2C_EVENT_STARTED_LAST_TXN_WRITE] = I2C_STATE_W_LAST_TXN_ADDR,
[I2C_EVENT_NACK] = I2C_STATE_STOPPING,
[I2C_EVENT_BUS_ERROR] = I2C_STATE_BUS_ERROR,
},
},
@ -258,6 +279,7 @@ const static struct i2c_adapter_transition i2c_adapter_transitions[I2C_STATE_NUM
[I2C_EVENT_ADDR_SENT_LEN_EQ_1] = I2C_STATE_W_MORE_TXN_LAST,
[I2C_EVENT_ADDR_SENT_LEN_EQ_2] = I2C_STATE_W_MORE_TXN_MIDDLE,
[I2C_EVENT_ADDR_SENT_LEN_GT_2] = I2C_STATE_W_MORE_TXN_MIDDLE,
[I2C_EVENT_NACK] = I2C_STATE_NACK,
[I2C_EVENT_BUS_ERROR] = I2C_STATE_BUS_ERROR,
},
},
@ -268,6 +290,7 @@ const static struct i2c_adapter_transition i2c_adapter_transitions[I2C_STATE_NUM
[I2C_EVENT_TRANSFER_DONE_LEN_EQ_1] = I2C_STATE_W_MORE_TXN_LAST,
[I2C_EVENT_TRANSFER_DONE_LEN_EQ_2] = I2C_STATE_W_MORE_TXN_MIDDLE,
[I2C_EVENT_TRANSFER_DONE_LEN_GT_2] = I2C_STATE_W_MORE_TXN_MIDDLE,
[I2C_EVENT_NACK] = I2C_STATE_NACK,
[I2C_EVENT_BUS_ERROR] = I2C_STATE_BUS_ERROR,
},
},
@ -275,7 +298,8 @@ const static struct i2c_adapter_transition i2c_adapter_transitions[I2C_STATE_NUM
[I2C_STATE_W_MORE_TXN_LAST] = {
.entry_fn = go_w_more_txn_last,
.next_state = {
[I2C_EVENT_TRANSFER_DONE_LEN_EQ_0] = I2C_STATE_STARTING,
[I2C_EVENT_TRANSFER_DONE_LEN_EQ_0] = I2C_STATE_STARTING,
[I2C_EVENT_NACK] = I2C_STATE_NACK,
[I2C_EVENT_BUS_ERROR] = I2C_STATE_BUS_ERROR,
},
},
@ -290,6 +314,7 @@ const static struct i2c_adapter_transition i2c_adapter_transitions[I2C_STATE_NUM
[I2C_EVENT_ADDR_SENT_LEN_EQ_1] = I2C_STATE_W_LAST_TXN_LAST,
[I2C_EVENT_ADDR_SENT_LEN_EQ_2] = I2C_STATE_W_LAST_TXN_MIDDLE,
[I2C_EVENT_ADDR_SENT_LEN_GT_2] = I2C_STATE_W_LAST_TXN_MIDDLE,
[I2C_EVENT_NACK] = I2C_STATE_NACK,
[I2C_EVENT_BUS_ERROR] = I2C_STATE_BUS_ERROR,
},
},
@ -300,6 +325,7 @@ const static struct i2c_adapter_transition i2c_adapter_transitions[I2C_STATE_NUM
[I2C_EVENT_TRANSFER_DONE_LEN_EQ_1] = I2C_STATE_W_LAST_TXN_LAST,
[I2C_EVENT_TRANSFER_DONE_LEN_EQ_2] = I2C_STATE_W_LAST_TXN_MIDDLE,
[I2C_EVENT_TRANSFER_DONE_LEN_GT_2] = I2C_STATE_W_LAST_TXN_MIDDLE,
[I2C_EVENT_NACK] = I2C_STATE_NACK,
[I2C_EVENT_BUS_ERROR] = I2C_STATE_BUS_ERROR,
},
},
@ -308,14 +334,29 @@ const static struct i2c_adapter_transition i2c_adapter_transitions[I2C_STATE_NUM
.entry_fn = go_w_last_txn_last,
.next_state = {
[I2C_EVENT_TRANSFER_DONE_LEN_EQ_0] = I2C_STATE_STOPPING,
[I2C_EVENT_NACK] = I2C_STATE_NACK,
[I2C_EVENT_BUS_ERROR] = I2C_STATE_BUS_ERROR,
},
},
[I2C_STATE_NACK] = {
.entry_fn = go_nack,
.next_state = {
[I2C_EVENT_AUTO] = I2C_STATE_STOPPING,
},
},
};
static void go_fsm_fault(struct pios_i2c_adapter *i2c_adapter)
{
#if defined(I2C_HALT_ON_ERRORS)
PIOS_DEBUG_Assert(0);
#endif
/* Note that this transfer has hit a bus error */
i2c_adapter->bus_error = true;
// i2c_adapter->curr_state = I2C_STATE_STOPPED;
i2c_adapter_reset_bus(i2c_adapter);
}
static void go_bus_error(struct pios_i2c_adapter *i2c_adapter)
@ -336,7 +377,9 @@ static void go_stopping(struct pios_i2c_adapter *i2c_adapter)
#ifdef USE_FREERTOS
if (xSemaphoreGiveFromISR(i2c_adapter->sem_ready, &pxHigherPriorityTaskWoken) != pdTRUE) {
#if defined(I2C_HALT_ON_ERRORS)
PIOS_DEBUG_Assert(0);
#endif
}
portEND_SWITCHING_ISR(pxHigherPriorityTaskWoken); /* FIXME: is this the right place for this? */
#endif /* USE_FREERTOS */
@ -521,10 +564,23 @@ static void go_w_last_txn_last(struct pios_i2c_adapter *i2c_adapter)
i2c_adapter->active_byte++;
}
static void go_nack(struct pios_i2c_adapter *i2c_adapter) {
I2C_ITConfig(i2c_adapter->cfg->regs, I2C_IT_BUF, DISABLE);
// SHOULD MOVE THIS INTO A STOPPING STATE AND SET IT ONLY AFTER THE BYTE WAS SENT
I2C_GenerateSTOP(i2c_adapter->cfg->regs, ENABLE);
}
static void i2c_adapter_inject_event(struct pios_i2c_adapter *i2c_adapter, enum i2c_adapter_event event)
{
PIOS_IRQ_Disable();
#if defined(PIOS_I2C_DIAGNOSTICS)
i2c_state_history[i2c_state_history_pointer] = i2c_adapter->curr_state;
i2c_state_history_pointer = (i2c_state_history_pointer + 1) % I2C_LOG_DEPTH;
if(i2c_adapter_transitions[i2c_adapter->curr_state].next_state[event] == I2C_STATE_FSM_FAULT)
i2c_adapter_log_fault(PIOS_I2C_ERROR_FSM);
#endif
/*
* Move to the next state
*
@ -613,15 +669,35 @@ static void i2c_adapter_reset_bus(struct pios_i2c_adapter *i2c_adapter)
GPIO_SetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin);
GPIO_Init(i2c_adapter->cfg->sda.gpio, &sda_gpio_init);
for (uint8_t i = 0; i < 9; i++) {
/* 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 */
/* ESC */
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) {
/* Set clock high and wait for any clock stretching to finish. */
GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
while (GPIO_ReadInputDataBit(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin) == Bit_RESET) ;
PIOS_DELAY_WaituS(2);
/* Set clock low */
GPIO_ResetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
PIOS_DELAY_WaituS(2);
/* Clock high again */
GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
PIOS_DELAY_WaituS(2);
}
if(sda_hung) {
/* Generate a start then stop condition */
GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
PIOS_DELAY_WaituS(2);
GPIO_ResetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin);
PIOS_DELAY_WaituS(2);
GPIO_ResetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin);
PIOS_DELAY_WaituS(2);
}
/* Set data and clock high and wait for any clock stretching to finish. */
@ -631,6 +707,7 @@ static void i2c_adapter_reset_bus(struct pios_i2c_adapter *i2c_adapter)
/* Wait for data to be high */
while (GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) != Bit_SET) ;
/* Bus signals are guaranteed to be high (ie. free) after this point */
/* Initialize the GPIO pins to the peripheral function */
GPIO_Init(i2c_adapter->cfg->scl.gpio, &(i2c_adapter->cfg->scl.init));
@ -675,6 +752,53 @@ static bool i2c_adapter_fsm_terminated(struct pios_i2c_adapter *i2c_adapter)
}
}
/**
* Logs the last N state transitions and N IRQ events due to
* an error condition
* \param[in] i2c the adapter number to log an event for
*/
void i2c_adapter_log_fault(enum pios_i2c_error_type type)
{
#if defined(PIOS_I2C_DIAGNOSTICS)
i2c_adapter_fault_history.type = type;
for(uint8_t i = 0; i < I2C_LOG_DEPTH; i++) {
i2c_adapter_fault_history.event[i] =
i2c_event_history[(I2C_LOG_DEPTH + i2c_event_history_pointer - 1 - i) % I2C_LOG_DEPTH];
i2c_adapter_fault_history.state[i] =
i2c_state_history[(I2C_LOG_DEPTH + i2c_state_history_pointer - 1 - i) % I2C_LOG_DEPTH];
}
switch(type) {
case PIOS_I2C_ERROR_EVENT:
i2c_bad_event_counter++;
break;
case PIOS_I2C_ERROR_FSM:
i2c_fsm_fault_count++;
break;
case PIOS_I2C_ERROR_INTERRUPT:
i2c_error_interrupt_counter++;
break;
}
#endif
}
/**
* Logs the last N state transitions and N IRQ events due to
* an error condition
* \param[out] data address where to copy the pios_i2c_fault_history structure to
* \param[out] counts three uint16 that receive the bad event, fsm, and error irq
* counts
*/
void PIOS_I2C_GetDiagnoistics(struct pios_i2c_fault_history * data, uint16_t * counts)
{
#if defined(PIOS_I2C_DIAGNOSTICS)
memcpy(data, &i2c_adapter_fault_history, sizeof(i2c_adapter_fault_history));
counts[0] = i2c_bad_event_counter;
counts[1] = i2c_fsm_fault_count;
counts[2] = i2c_error_interrupt_counter;
#endif
}
/**
* Initializes IIC driver
* \param[in] mode currently only mode 0 supported
@ -779,13 +903,27 @@ bool PIOS_I2C_Transfer(uint8_t i2c, const struct pios_i2c_txn txn_list[], uint32
void PIOS_I2C_EV_IRQ_Handler(uint8_t i2c)
{
struct pios_i2c_adapter *i2c_adapter;
i2c_adapter = find_i2c_adapter_by_id(i2c);
PIOS_DEBUG_Assert(i2c_adapter);
uint32_t event = I2C_GetLastEvent(i2c_adapter->cfg->regs);
switch (event) {
#if defined(PIOS_I2C_DIAGNOSTICS)
/* Store event for diagnostics */
i2c_event_history[i2c_event_history_pointer] = event;
i2c_event_history_pointer = (i2c_event_history_pointer + 1) % I2C_LOG_DEPTH;
#endif
event &= 0x000700FF;
static uint32_t prev_event = 0;
if((event == prev_event) && (event == 0x70084))
return;
prev_event = event;
switch (event) { /* Mask out all the bits we don't care about */
case (I2C_EVENT_MASTER_MODE_SELECT | 0x40):
/* Unexplained event: EV5 + RxNE : Extraneous Rx. Probably a late NACK from previous read. */
/* Clean up the extra Rx until the root cause is identified and just keep going */
@ -870,8 +1008,16 @@ void PIOS_I2C_EV_IRQ_Handler(uint8_t i2c)
/* Ignore this event and wait for TRANSMITTED in case we can't keep up */
goto skip_event;
break;
case 0x30084: /* Occurs between byte tranmistted and master mode selected */
case 0x30000: /* Need to throw away this spurious event */
goto skip_event;
break;
default:
i2c_adapter_log_fault(PIOS_I2C_ERROR_EVENT);
#if defined(I2C_HALT_ON_ERRORS)
PIOS_DEBUG_Assert(0);
#endif
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_BUS_ERROR);
break;
}
@ -886,8 +1032,23 @@ void PIOS_I2C_ER_IRQ_Handler(uint8_t i2c)
i2c_adapter = find_i2c_adapter_by_id(i2c);
PIOS_DEBUG_Assert(i2c_adapter);
/* Fail hard on any errors for now */
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_BUS_ERROR);
#if defined(PIOS_I2C_DIAGNOSTICS)
uint32_t event = I2C_GetLastEvent(i2c_adapter->cfg->regs);
/* Store event for diagnostics */
i2c_event_history[i2c_event_history_pointer] = event;
i2c_event_history_pointer = (i2c_event_history_pointer + 1) % I2C_LOG_DEPTH;
#endif
if(I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_AF)) {
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_NACK);
} else {
i2c_adapter_log_fault(PIOS_I2C_ERROR_INTERRUPT);
/* Fail hard on any errors for now */
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_BUS_ERROR);
}
}
/**

View File

@ -31,6 +31,8 @@
#ifndef PIOS_I2C_H
#define PIOS_I2C_H
//#define PIOS_I2C_DIAGNOSTICS
#include <stdbool.h>
/* Global Types */
@ -47,11 +49,25 @@ struct pios_i2c_txn {
uint8_t *buf;
};
#define I2C_LOG_DEPTH 5
enum pios_i2c_error_type {
PIOS_I2C_ERROR_EVENT,
PIOS_I2C_ERROR_FSM,
PIOS_I2C_ERROR_INTERRUPT
};
struct pios_i2c_fault_history {
enum pios_i2c_error_type type;
uint32_t event[I2C_LOG_DEPTH];
uint32_t state[I2C_LOG_DEPTH];
};
/* Public Functions */
extern int32_t PIOS_I2C_Init(void);
extern bool PIOS_I2C_Transfer(uint8_t i2c, const struct pios_i2c_txn txn_list[], uint32_t num_txns);
extern void PIOS_I2C_EV_IRQ_Handler(uint8_t i2c);
extern void PIOS_I2C_ER_IRQ_Handler(uint8_t i2c);
extern void PIOS_I2C_GetDiagnoistics(struct pios_i2c_fault_history * data, uint16_t * error_counts);
#endif /* PIOS_I2C_H */

View File

@ -72,7 +72,9 @@ enum i2c_adapter_state {
I2C_STATE_W_LAST_TXN_ADDR,
I2C_STATE_W_LAST_TXN_MIDDLE,
I2C_STATE_W_LAST_TXN_LAST,
I2C_STATE_NACK,
I2C_STATE_NUM_STATES /* Must be last */
};

View File

@ -35,6 +35,7 @@
65322D3B122841F60046CD7C /* gpstime.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = gpstime.xml; sourceTree = "<group>"; };
65322D77122897210046CD7C /* MagOrAccelSensorCal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = MagOrAccelSensorCal.c; path = ../../AHRS/MagOrAccelSensorCal.c; sourceTree = SOURCE_ROOT; };
65345C871288668B00A5E4E8 /* guidancesettings.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = guidancesettings.xml; sourceTree = "<group>"; };
65408AA812BB1648004DACC5 /* i2cstats.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = i2cstats.xml; sourceTree = "<group>"; };
654330231218E9780063F913 /* insgps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = insgps.c; path = ../../AHRS/insgps.c; sourceTree = SOURCE_ROOT; };
6543304F121980300063F913 /* insgps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = insgps.h; sourceTree = "<group>"; };
654612D812B5E9A900B719D0 /* pios_iap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pios_iap.c; sourceTree = "<group>"; };
@ -6799,6 +6800,7 @@
65B367FC121C2620003EAD18 /* systemsettings.xml */,
65B367FD121C2620003EAD18 /* systemstats.xml */,
65B367FE121C2620003EAD18 /* telemetrysettings.xml */,
65408AA812BB1648004DACC5 /* i2cstats.xml */,
);
path = uavobjectdefinition;
sourceTree = "<group>";

View File

@ -200,6 +200,15 @@ function [] = OPLogConvert()
HomeLocation(1).RNE = zeros(1,9);
HomeLocation(1).Be = zeros(1,3);
i2cstatsIdx = 1;
I2CStats.timestamp = 0;
I2CStats(1).event_errors = 0;
I2CStats(1).fsm_errors = 0;
I2CStats(1).irq_errors = 0;
I2CStats(1).last_error_type = 0;
I2CStats(1).event_log = zeros(1,5);
I2CStats(1).state_log = zeros(1,5);
manualcontrolcommandIdx = 1;
ManualControlCommand.timestamp = 0;
ManualControlCommand(1).Connected = 0;
@ -459,6 +468,9 @@ function [] = OPLogConvert()
case 3590360786
HomeLocation(homelocationIdx) = ReadHomeLocationObject(fid, timestamp);
homelocationIdx = homelocationIdx + 1;
case 1063893720
I2CStats(i2cstatsIdx) = ReadI2CStatsObject(fid, timestamp);
i2cstatsIdx = i2cstatsIdx + 1;
case 2841592332
ManualControlCommand(manualcontrolcommandIdx) = ReadManualControlCommandObject(fid, timestamp);
manualcontrolcommandIdx = manualcontrolcommandIdx + 1;
@ -523,7 +535,7 @@ function [] = OPLogConvert()
fclose(fid);
matfile = strrep(logfile,'opl','mat');
save(matfile ,'ActuatorCommand','ActuatorDesired','ActuatorSettings','AHRSCalibration','AHRSSettings','AhrsStatus','AttitudeActual','AttitudeDesired','AttitudeRaw','BaroAltitude','FirmwareIAPObj','FlightBatteryState','FlightTelemetryStats','GCSTelemetryStats','GPSPosition','GPSSatellites','GPSTime','GuidanceSettings','HomeLocation','ManualControlCommand','ManualControlSettings','MixerSettings','MixerStatus','ObjectPersistence','PipXtremeModemSettings','PipXtremeModemStatus','PositionActual','PositionDesired','RateDesired','StabilizationSettings','SystemAlarms','SystemSettings','SystemStats','TelemetrySettings','VelocityActual','VelocityDesired');
save(matfile ,'ActuatorCommand','ActuatorDesired','ActuatorSettings','AHRSCalibration','AHRSSettings','AhrsStatus','AttitudeActual','AttitudeDesired','AttitudeRaw','BaroAltitude','FirmwareIAPObj','FlightBatteryState','FlightTelemetryStats','GCSTelemetryStats','GPSPosition','GPSSatellites','GPSTime','GuidanceSettings','HomeLocation','I2CStats','ManualControlCommand','ManualControlSettings','MixerSettings','MixerStatus','ObjectPersistence','PipXtremeModemSettings','PipXtremeModemStatus','PositionActual','PositionDesired','RateDesired','StabilizationSettings','SystemAlarms','SystemSettings','SystemStats','TelemetrySettings','VelocityActual','VelocityDesired');
end
@ -918,6 +930,25 @@ function [HomeLocation] = ReadHomeLocationObject(fid, timestamp)
fread(fid, 1, 'uint8');
end
function [I2CStats] = ReadI2CStatsObject(fid, timestamp)
if 1
headerSize = 8;
else
I2CStats.instanceID = fread(fid, 1, 'uint16');
headerSize = 10;
end
I2CStats.timestamp = timestamp;
I2CStats.event_errors = double(fread(fid, 1, 'uint16'));
I2CStats.fsm_errors = double(fread(fid, 1, 'uint16'));
I2CStats.irq_errors = double(fread(fid, 1, 'uint16'));
I2CStats.last_error_type = double(fread(fid, 1, 'uint8'));
I2CStats.event_log = double(fread(fid, 5, 'uint32'));
I2CStats.state_log = double(fread(fid, 5, 'uint32'));
% read CRC
fread(fid, 1, 'uint8');
end
function [ManualControlCommand] = ReadManualControlCommandObject(fid, timestamp)
if 1
headerSize = 8;

View File

@ -0,0 +1,155 @@
/**
******************************************************************************
*
* @file i2cstats.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @see The GNU Public License (GPL) Version 3
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVObjectsPlugin UAVObjects Plugin
* @{
*
* @note Object definition file: i2cstats.xml.
* This is an automatically generated file.
* DO NOT modify manually.
*
* @brief The UAVUObjects GCS plugin
*****************************************************************************/
/*
* 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
*/
#include "i2cstats.h"
#include "uavobjectfield.h"
const QString I2CStats::NAME = QString("I2CStats");
/**
* Constructor
*/
I2CStats::I2CStats(): UAVDataObject(OBJID, ISSINGLEINST, ISSETTINGS, NAME)
{
// Create fields
QList<UAVObjectField*> fields;
QStringList event_errorsElemNames;
event_errorsElemNames.append("0");
fields.append( new UAVObjectField(QString("event_errors"), QString(""), UAVObjectField::UINT16, event_errorsElemNames, QStringList()) );
QStringList fsm_errorsElemNames;
fsm_errorsElemNames.append("0");
fields.append( new UAVObjectField(QString("fsm_errors"), QString(""), UAVObjectField::UINT16, fsm_errorsElemNames, QStringList()) );
QStringList irq_errorsElemNames;
irq_errorsElemNames.append("0");
fields.append( new UAVObjectField(QString("irq_errors"), QString(""), UAVObjectField::UINT16, irq_errorsElemNames, QStringList()) );
QStringList last_error_typeElemNames;
last_error_typeElemNames.append("0");
QStringList last_error_typeEnumOptions;
last_error_typeEnumOptions.append("EVENT");
last_error_typeEnumOptions.append("FSM");
last_error_typeEnumOptions.append("INTERRUPT");
fields.append( new UAVObjectField(QString("last_error_type"), QString(""), UAVObjectField::ENUM, last_error_typeElemNames, last_error_typeEnumOptions) );
QStringList event_logElemNames;
event_logElemNames.append("0");
event_logElemNames.append("1");
event_logElemNames.append("2");
event_logElemNames.append("3");
event_logElemNames.append("4");
fields.append( new UAVObjectField(QString("event_log"), QString(""), UAVObjectField::UINT32, event_logElemNames, QStringList()) );
QStringList state_logElemNames;
state_logElemNames.append("0");
state_logElemNames.append("1");
state_logElemNames.append("2");
state_logElemNames.append("3");
state_logElemNames.append("4");
fields.append( new UAVObjectField(QString("state_log"), QString(""), UAVObjectField::UINT32, state_logElemNames, QStringList()) );
// Initialize object
initializeFields(fields, (quint8*)&data, NUMBYTES);
// Set the default field values
setDefaultFieldValues();
}
/**
* Get the default metadata for this object
*/
UAVObject::Metadata I2CStats::getDefaultMetadata()
{
UAVObject::Metadata metadata;
metadata.flightAccess = ACCESS_READWRITE;
metadata.gcsAccess = ACCESS_READWRITE;
metadata.gcsTelemetryAcked = 0;
metadata.gcsTelemetryUpdateMode = UAVObject::UPDATEMODE_MANUAL;
metadata.gcsTelemetryUpdatePeriod = 0;
metadata.flightTelemetryAcked = 0;
metadata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
metadata.flightTelemetryUpdatePeriod = 10000;
metadata.loggingUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
metadata.loggingUpdatePeriod = 30000;
return metadata;
}
/**
* Initialize object fields with the default values.
* If a default value is not specified the object fields
* will be initialized to zero.
*/
void I2CStats::setDefaultFieldValues()
{
}
/**
* Get the object data fields
*/
I2CStats::DataFields I2CStats::getData()
{
QMutexLocker locker(mutex);
return data;
}
/**
* Set the object data fields
*/
void I2CStats::setData(const DataFields& data)
{
QMutexLocker locker(mutex);
// Get metadata
Metadata mdata = getMetadata();
// Update object if the access mode permits
if ( mdata.gcsAccess == ACCESS_READWRITE )
{
this->data = data;
emit objectUpdatedAuto(this); // trigger object updated event
emit objectUpdated(this);
}
}
/**
* Create a clone of this object, a new instance ID must be specified.
* Do not use this function directly to create new instances, the
* UAVObjectManager should be used instead.
*/
UAVDataObject* I2CStats::clone(quint32 instID)
{
I2CStats* obj = new I2CStats();
obj->initialize(instID, this->getMetaObject());
return obj;
}
/**
* Static function to retrieve an instance of the object.
*/
I2CStats* I2CStats::GetInstance(UAVObjectManager* objMngr, quint32 instID)
{
return dynamic_cast<I2CStats*>(objMngr->getObject(I2CStats::OBJID, instID));
}

View File

@ -0,0 +1,94 @@
/**
******************************************************************************
*
* @file i2cstats.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @see The GNU Public License (GPL) Version 3
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVObjectsPlugin UAVObjects Plugin
* @{
*
* @note Object definition file: i2cstats.xml.
* This is an automatically generated file.
* DO NOT modify manually.
*
* @brief The UAVUObjects GCS plugin
*****************************************************************************/
/*
* 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 I2CSTATS_H
#define I2CSTATS_H
#include "uavdataobject.h"
#include "uavobjectmanager.h"
class UAVOBJECTS_EXPORT I2CStats: public UAVDataObject
{
Q_OBJECT
public:
// Field structure
typedef struct {
quint16 event_errors;
quint16 fsm_errors;
quint16 irq_errors;
quint8 last_error_type;
quint32 event_log[5];
quint32 state_log[5];
} __attribute__((packed)) DataFields;
// Field information
// Field event_errors information
// Field fsm_errors information
// Field irq_errors information
// Field last_error_type information
/* Enumeration options for field last_error_type */
typedef enum { LAST_ERROR_TYPE_EVENT=0, LAST_ERROR_TYPE_FSM=1, LAST_ERROR_TYPE_INTERRUPT=2 } last_error_typeOptions;
// Field event_log information
/* Number of elements for field event_log */
static const quint32 EVENT_LOG_NUMELEM = 5;
// Field state_log information
/* Number of elements for field state_log */
static const quint32 STATE_LOG_NUMELEM = 5;
// Constants
static const quint32 OBJID = 1063893720U;
static const QString NAME;
static const bool ISSINGLEINST = 1;
static const bool ISSETTINGS = 0;
static const quint32 NUMBYTES = sizeof(DataFields);
// Functions
I2CStats();
DataFields getData();
void setData(const DataFields& data);
Metadata getDefaultMetadata();
UAVDataObject* clone(quint32 instID);
static I2CStats* GetInstance(UAVObjectManager* objMngr, quint32 instID = 0);
private:
DataFields data;
void setDefaultFieldValues();
};
#endif // I2CSTATS_H

View File

@ -0,0 +1,147 @@
##
##############################################################################
#
# @file i2cstats.py
# @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
# @brief Implementation of the I2CStats object. This file has been
# automatically generated by the UAVObjectGenerator.
#
# @note Object definition file: i2cstats.xml.
# This is an automatically generated file.
# DO NOT modify manually.
#
# @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
#
import uavobject
import struct
from collections import namedtuple
# This is a list of instances of the data fields contained in this object
_fields = [ \
uavobject.UAVObjectField(
'event_errors',
'H',
1,
[
'0',
],
{
}
),
uavobject.UAVObjectField(
'fsm_errors',
'H',
1,
[
'0',
],
{
}
),
uavobject.UAVObjectField(
'irq_errors',
'H',
1,
[
'0',
],
{
}
),
uavobject.UAVObjectField(
'last_error_type',
'b',
1,
[
'0',
],
{
'0' : 'EVENT',
'1' : 'FSM',
'2' : 'INTERRUPT',
}
),
uavobject.UAVObjectField(
'event_log',
'I',
5,
[
'0',
'1',
'2',
'3',
'4',
],
{
}
),
uavobject.UAVObjectField(
'state_log',
'I',
5,
[
'0',
'1',
'2',
'3',
'4',
],
{
}
),
]
class I2CStats(uavobject.UAVObject):
## Object constants
OBJID = 1063893720
NAME = "I2CStats"
METANAME = "I2CStatsMeta"
ISSINGLEINST = 1
ISSETTINGS = 0
def __init__(self):
uavobject.UAVObject.__init__(self,
self.OBJID,
self.NAME,
self.METANAME,
0,
self.ISSINGLEINST)
for f in _fields:
self.add_field(f)
def __str__(self):
s = ("0x%08X (%10u) %-30s %3u bytes format '%s'\n"
% (self.OBJID, self.OBJID, self.NAME, self.get_struct().size, self.get_struct().format))
for f in self.get_tuple()._fields:
s += ("\t%s\n" % f)
return (s)
def main():
# Instantiate the object and dump out some interesting info
x = I2CStats()
print (x)
if __name__ == "__main__":
#import pdb ; pdb.run('main()')
main()

View File

@ -46,7 +46,8 @@ HEADERS += uavobjects_global.h \
ratedesired.h \
firmwareiapobj.h \
pipxtrememodemsettings.h \
pipxtrememodemstatus.h
pipxtrememodemstatus.h \
i2cstats.h
SOURCES += uavobject.cpp \
uavmetaobject.cpp \
@ -90,5 +91,6 @@ SOURCES += uavobject.cpp \
ratedesired.cpp \
firmwareiapobj.cpp \
pipxtrememodemsettings.cpp \
pipxtrememodemstatus.cpp
pipxtrememodemstatus.cpp \
i2cstats.cpp
OTHER_FILES += UAVObjects.pluginspec

View File

@ -49,6 +49,7 @@
#include "gpstime.h"
#include "guidancesettings.h"
#include "homelocation.h"
#include "i2cstats.h"
#include "manualcontrolcommand.h"
#include "manualcontrolsettings.h"
#include "mixersettings.h"
@ -93,6 +94,7 @@ void UAVObjectsInitialize(UAVObjectManager* objMngr)
objMngr->registerObject( new GPSTime() );
objMngr->registerObject( new GuidanceSettings() );
objMngr->registerObject( new HomeLocation() );
objMngr->registerObject( new I2CStats() );
objMngr->registerObject( new ManualControlCommand() );
objMngr->registerObject( new ManualControlSettings() );
objMngr->registerObject( new MixerSettings() );

View File

@ -0,0 +1,15 @@
<xml>
<object name="I2CStats" singleinstance="true" settings="false">
<description>Tracks statistics on the I2C bus.</description>
<field name="event_errors" units="" type="uint16" elements="1"/>
<field name="fsm_errors" units="" type="uint16" elements="1"/>
<field name="irq_errors" units="" type="uint16" elements="1"/>
<field name="last_error_type" units="" type="enum" elements="1" options="EVENT,FSM,INTERRUPT"/>
<field name="event_log" units="" type="uint32" elements="5"/>
<field name="state_log" units="" type="uint32" elements="5"/>
<access gcs="readwrite" flight="readwrite"/>
<telemetrygcs acked="false" updatemode="manual" period="0"/>
<telemetryflight acked="false" updatemode="periodic" period="10000"/>
<logging updatemode="periodic" period="30000"/>
</object>
</xml>