[actuators] separate files for asctec_v2

This commit is contained in:
Felix Ruess
2013-03-04 14:07:56 +01:00
parent fcb6a18e00
commit e33d6ef9dc
7 changed files with 257 additions and 109 deletions
+1 -1
View File
@@ -56,7 +56,7 @@
<servo name="LEFT" no="3" min="0" neutral="20" max="255"/> <servo name="LEFT" no="3" min="0" neutral="20" max="255"/>
</servos--> </servos-->
<servos driver="Asctec"> <servos driver="Asctec_v2">
<servo name="FRONT" no="0" min="0" neutral="1" max="200"/> <servo name="FRONT" no="0" min="0" neutral="1" max="200"/>
<servo name="BACK" no="1" min="0" neutral="1" max="200"/> <servo name="BACK" no="1" min="0" neutral="1" max="200"/>
<servo name="LEFT" no="2" min="0" neutral="1" max="200"/> <servo name="LEFT" no="2" min="0" neutral="1" max="200"/>
+2 -2
View File
@@ -4,7 +4,7 @@
<airframe name="lisa_asctec"> <airframe name="lisa_asctec">
<servos driver="Asctec"> <servos driver="Asctec_v2">
<servo name="FRONT" no="0" min="0" neutral="3" max="200"/> <servo name="FRONT" no="0" min="0" neutral="3" max="200"/>
<servo name="BACK" no="1" min="0" neutral="3" max="200"/> <servo name="BACK" no="1" min="0" neutral="3" max="200"/>
<servo name="LEFT" no="2" min="0" neutral="3" max="200"/> <servo name="LEFT" no="2" min="0" neutral="3" max="200"/>
@@ -198,7 +198,7 @@
<define name="RADIO_CONTROL_SPEKTRUM_SIGNS" value="\{1,1,-1,1,-1,-1,-1,1,1,1,1,1\}"/> <define name="RADIO_CONTROL_SPEKTRUM_SIGNS" value="\{1,1,-1,1,-1,-1,-1,1,1,1,1,1\}"/>
<define name="USE_I2C_ACTUATORS_REBOOT_HACK"/> <define name="USE_I2C_ACTUATORS_REBOOT_HACK"/>
</target> </target>
<target name="sim" board="pc"> <target name="nps" board="pc">
<subsystem name="fdm" type="jsbsim"/> <subsystem name="fdm" type="jsbsim"/>
<subsystem name="radio_control" type="ppm"/> <subsystem name="radio_control" type="ppm"/>
<subsystem name="motor_mixing"/> <subsystem name="motor_mixing"/>
@@ -2,10 +2,24 @@
# #
# required xml configuration: # required xml configuration:
# #
# servo section with driver="Asctec" # servo section with driver="Asctec_v2"
# command_laws section to map motor_mixing commands to servos # command_laws section to map motor_mixing commands to servos
# #
include $(CFG_SHARED)/actuators_asctec.makefile $(TARGET).CFLAGS += -DACTUATORS
ap.srcs += subsystems/actuators/actuators_asctec_v2.c
ap.CFLAGS += -DACTUATORS_ASCTEC_V2_PROTOCOL ifeq ($(ARCH), lpc21)
ap.CFLAGS += -DACTUATORS_ASCTEC_V2_DEVICE=i2c0
ap.CFLAGS += -DUSE_I2C0 -DI2C0_SCLL=150 -DI2C0_SCLH=150
endif
ifeq ($(ARCH), stm32)
ap.CFLAGS += -DACTUATORS_ASCTEC_V2_DEVICE=i2c1
ap.CFLAGS += -DUSE_I2C1
endif
# Simulator
nps.srcs += subsystems/actuators/actuators_asctec_v2.c
nps.CFLAGS += -DUSE_I2C0 -DACTUATORS_ASCTEC_DEVICE=i2c0
@@ -35,6 +35,8 @@
#define ASCTEC_MIN_THROTTLE 0 #define ASCTEC_MIN_THROTTLE 0
#define ASCTEC_MAX_THROTTLE 200 #define ASCTEC_MAX_THROTTLE 200
#define ACTUATORS_ASCTEC_SLAVE_ADDR 0x02
struct ActuatorsAsctec actuators_asctec; struct ActuatorsAsctec actuators_asctec;
uint32_t actuators_delay_time; uint32_t actuators_delay_time;
@@ -46,12 +48,8 @@ void actuators_asctec_init(void) {
actuators_asctec.new_addr = FRONT; actuators_asctec.new_addr = FRONT;
actuators_asctec.i2c_trans.status = I2CTransSuccess; actuators_asctec.i2c_trans.status = I2CTransSuccess;
actuators_asctec.i2c_trans.type = I2CTransTx; actuators_asctec.i2c_trans.type = I2CTransTx;
actuators_asctec.i2c_trans.slave_addr = 0x02; actuators_asctec.i2c_trans.slave_addr = ACTUATORS_ASCTEC_SLAVE_ADDR;
#ifdef ACTUATORS_ASCTEC_V2_PROTOCOL
actuators_asctec.i2c_trans.len_w = 5;
#else
actuators_asctec.i2c_trans.len_w = 4; actuators_asctec.i2c_trans.len_w = 4;
#endif
actuators_asctec.nb_err = 0; actuators_asctec.nb_err = 0;
#if defined ACTUATORS_START_DELAY && ! defined SITL #if defined ACTUATORS_START_DELAY && ! defined SITL
@@ -64,7 +62,6 @@ void actuators_asctec_init(void) {
} }
#ifndef ACTUATORS_ASCTEC_V2_PROTOCOL
void actuators_asctec_set(bool_t motors_on) { void actuators_asctec_set(bool_t motors_on) {
#if defined ACTUATORS_START_DELAY && ! defined SITL #if defined ACTUATORS_START_DELAY && ! defined SITL
if (!actuators_delay_done) { if (!actuators_delay_done) {
@@ -120,7 +117,8 @@ void actuators_asctec_set(bool_t motors_on) {
actuators_asctec.i2c_trans.buf[0] = 250; actuators_asctec.i2c_trans.buf[0] = 250;
actuators_asctec.i2c_trans.buf[1] = actuators_asctec.cur_addr; actuators_asctec.i2c_trans.buf[1] = actuators_asctec.cur_addr;
actuators_asctec.i2c_trans.buf[2] = actuators_asctec.new_addr; actuators_asctec.i2c_trans.buf[2] = actuators_asctec.new_addr;
actuators_asctec.i2c_trans.buf[3] = 230 + actuators_asctec.cur_addr + actuators_asctec.new_addr; actuators_asctec.i2c_trans.buf[3] = 230 + actuators_asctec.cur_addr +
actuators_asctec.new_addr;
actuators_asctec.cur_addr = actuators_asctec.new_addr; actuators_asctec.cur_addr = actuators_asctec.new_addr;
break; break;
case NONE: case NONE:
@@ -134,87 +132,7 @@ void actuators_asctec_set(bool_t motors_on) {
} }
actuators_asctec.cmd = NONE; actuators_asctec.cmd = NONE;
actuators_asctec.i2c_trans.type = I2CTransTx; // Can be reset I2C driver I2CTransmit(ACTUATORS_ASCTEC_DEVICE, actuators_asctec.i2c_trans,
i2c_submit(&ACTUATORS_ASCTEC_DEVICE, &actuators_asctec.i2c_trans); ACTUATORS_ASCTEC_SLAVE_ADDR, 4);
} }
#else /* ! ACTUATORS_ASCTEC_V2_PROTOCOL */
void actuators_asctec_set(bool_t motors_on) {
#if defined ACTUATORS_START_DELAY && ! defined SITL
if (!actuators_delay_done) {
if (SysTimeTimer(actuators_delay_time) < USEC_OF_SEC(ACTUATORS_START_DELAY)) {
#ifdef USE_I2C_ACTUATORS_REBOOT_HACK
//Lisa-L with Asctech v2 motors only start after reflashing when a bus error was sensed on stm32-i2c.
//multiple re-init solves the problem.
i2c1_init();
#endif
return;
}
else actuators_delay_done = TRUE;
}
#endif
switch (actuators_asctec.i2c_trans.status) {
case I2CTransFailed:
actuators_asctec.nb_err++;
actuators_asctec.i2c_trans.status = I2CTransDone;
break;
case I2CTransSuccess:
case I2CTransDone:
actuators_asctec.i2c_trans.status = I2CTransDone;
break;
default:
actuators_asctec.nb_err++;
return;
}
#ifdef KILL_MOTORS
actuators_asctec.i2c_trans.buf[0] = 0;
actuators_asctec.i2c_trans.buf[1] = 0;
actuators_asctec.i2c_trans.buf[2] = 0;
actuators_asctec.i2c_trans.buf[3] = 0;
actuators_asctec.i2c_trans.buf[4] = 0xAA;
#else
switch (actuators_asctec.cmd) {
case TEST:
actuators_asctec.i2c_trans.buf[0] = 251;
actuators_asctec.i2c_trans.buf[1] = actuators_asctec.cur_addr;
actuators_asctec.i2c_trans.buf[2] = 0;
actuators_asctec.i2c_trans.buf[3] = 231 + actuators_asctec.cur_addr;
actuators_asctec.i2c_trans.len_w = 4;
break;
case REVERSE:
actuators_asctec.i2c_trans.buf[0] = 254;
actuators_asctec.i2c_trans.buf[1] = actuators_asctec.cur_addr;
actuators_asctec.i2c_trans.buf[2] = 0;
actuators_asctec.i2c_trans.buf[3] = 234 + actuators_asctec.cur_addr;
actuators_asctec.i2c_trans.len_w = 4;
break;
case SET_ADDR:
actuators_asctec.i2c_trans.buf[0] = 250;
actuators_asctec.i2c_trans.buf[1] = actuators_asctec.cur_addr;
actuators_asctec.i2c_trans.buf[2] = actuators_asctec.new_addr;
actuators_asctec.i2c_trans.buf[3] = 230 + actuators_asctec.cur_addr + actuators_asctec.new_addr;
actuators_asctec.cur_addr = actuators_asctec.new_addr;
actuators_asctec.i2c_trans.len_w = 4;
break;
case NONE:
actuators_asctec.i2c_trans.buf[0] = actuators_asctec.cmds[SERVO_FRONT];
actuators_asctec.i2c_trans.buf[1] = actuators_asctec.cmds[SERVO_BACK];
actuators_asctec.i2c_trans.buf[2] = actuators_asctec.cmds[SERVO_LEFT];
actuators_asctec.i2c_trans.buf[3] = actuators_asctec.cmds[SERVO_RIGHT];
actuators_asctec.i2c_trans.buf[4] = 0xAA + actuators_asctec.i2c_trans.buf[0] + actuators_asctec.i2c_trans.buf[1] +
actuators_asctec.i2c_trans.buf[2] + actuators_asctec.i2c_trans.buf[3];
actuators_asctec.i2c_trans.len_w = 5;
break;
default:
break;
}
actuators_asctec.cmd = NONE;
#endif
actuators_asctec.i2c_trans.type = I2CTransTx; // Can be reset I2C driver
i2c_submit(&ACTUATORS_ASCTEC_DEVICE, &actuators_asctec.i2c_trans);
}
#endif /* ACTUATORS_ASCTEC_V2_PROTOCOL */
@@ -0,0 +1,141 @@
/*
* Copyright (C) 2013 The Paparazzi Team
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/** @file actuators_asctec_v2.c
* Actuators driver for Asctec v2 motor controllers.
*/
#include "subsystems/actuators.h"
#include "subsystems/actuators/actuators_asctec_v2.h"
#include "mcu_periph/i2c.h"
#include "mcu_periph/sys_time.h"
#define ACTUATORS_ASCTEC_V2_SLAVE_ADDR 0x02
struct ActuatorsAsctecV2 actuators_asctec_v2;
uint32_t actuators_delay_time;
bool_t actuators_delay_done;
void actuators_asctec_v2_init(void) {
actuators_asctec_v2.cmd = NONE;
actuators_asctec_v2.cur_addr = FRONT;
actuators_asctec_v2.new_addr = FRONT;
actuators_asctec_v2.i2c_trans.status = I2CTransSuccess;
actuators_asctec_v2.i2c_trans.type = I2CTransTx;
actuators_asctec_v2.i2c_trans.slave_addr = ACTUATORS_ASCTEC_V2_SLAVE_ADDR;
actuators_asctec_v2.i2c_trans.len_w = 5;
actuators_asctec_v2.nb_err = 0;
#if defined ACTUATORS_START_DELAY && ! defined SITL
actuators_delay_done = FALSE;
SysTimeTimerStart(actuators_delay_time);
#else
actuators_delay_done = TRUE;
actuators_delay_time = 0;
#endif
}
void actuators_asctec_v2_set(bool_t motors_on) {
#if defined ACTUATORS_START_DELAY && ! defined SITL
if (!actuators_delay_done) {
if (SysTimeTimer(actuators_delay_time) < USEC_OF_SEC(ACTUATORS_START_DELAY)) {
#ifdef USE_I2C_ACTUATORS_REBOOT_HACK
//Lisa-L with Asctech v2 motors only start after reflashing when a bus error was sensed on stm32-i2c.
//multiple re-init solves the problem.
i2c1_init();
#endif
return;
}
else actuators_delay_done = TRUE;
}
#endif
switch (actuators_asctec_v2.i2c_trans.status) {
case I2CTransFailed:
actuators_asctec_v2.nb_err++;
actuators_asctec_v2.i2c_trans.status = I2CTransDone;
break;
case I2CTransSuccess:
case I2CTransDone:
actuators_asctec_v2.i2c_trans.status = I2CTransDone;
break;
default:
actuators_asctec_v2.nb_err++;
return;
}
#ifdef KILL_MOTORS
actuators_asctec_v2.i2c_trans.buf[0] = 0;
actuators_asctec_v2.i2c_trans.buf[1] = 0;
actuators_asctec_v2.i2c_trans.buf[2] = 0;
actuators_asctec_v2.i2c_trans.buf[3] = 0;
actuators_asctec_v2.i2c_trans.buf[4] = 0xAA;
#else
switch (actuators_asctec_v2.cmd) {
case TEST:
actuators_asctec_v2.i2c_trans.buf[0] = 251;
actuators_asctec_v2.i2c_trans.buf[1] = actuators_asctec_v2.cur_addr;
actuators_asctec_v2.i2c_trans.buf[2] = 0;
actuators_asctec_v2.i2c_trans.buf[3] = 231 + actuators_asctec_v2.cur_addr;
actuators_asctec_v2.i2c_trans.len_w = 4;
break;
case REVERSE:
actuators_asctec_v2.i2c_trans.buf[0] = 254;
actuators_asctec_v2.i2c_trans.buf[1] = actuators_asctec_v2.cur_addr;
actuators_asctec_v2.i2c_trans.buf[2] = 0;
actuators_asctec_v2.i2c_trans.buf[3] = 234 + actuators_asctec_v2.cur_addr;
actuators_asctec_v2.i2c_trans.len_w = 4;
break;
case SET_ADDR:
actuators_asctec_v2.i2c_trans.buf[0] = 250;
actuators_asctec_v2.i2c_trans.buf[1] = actuators_asctec_v2.cur_addr;
actuators_asctec_v2.i2c_trans.buf[2] = actuators_asctec_v2.new_addr;
actuators_asctec_v2.i2c_trans.buf[3] = 230 + actuators_asctec_v2.cur_addr +
actuators_asctec_v2.new_addr;
actuators_asctec_v2.cur_addr = actuators_asctec_v2.new_addr;
actuators_asctec_v2.i2c_trans.len_w = 4;
break;
case NONE:
actuators_asctec_v2.i2c_trans.buf[0] = actuators_asctec_v2.cmds[SERVO_FRONT];
actuators_asctec_v2.i2c_trans.buf[1] = actuators_asctec_v2.cmds[SERVO_BACK];
actuators_asctec_v2.i2c_trans.buf[2] = actuators_asctec_v2.cmds[SERVO_LEFT];
actuators_asctec_v2.i2c_trans.buf[3] = actuators_asctec_v2.cmds[SERVO_RIGHT];
actuators_asctec_v2.i2c_trans.buf[4] = 0xAA + actuators_asctec_v2.i2c_trans.buf[0] +
actuators_asctec_v2.i2c_trans.buf[1] +
actuators_asctec_v2.i2c_trans.buf[2] +
actuators_asctec_v2.i2c_trans.buf[3];
actuators_asctec_v2.i2c_trans.len_w = 5;
break;
default:
break;
}
actuators_asctec_v2.cmd = NONE;
#endif
actuators_asctec_v2.i2c_trans.type = I2CTransTx; // Can be reset I2C driver
i2c_submit(&ACTUATORS_ASCTEC_V2_DEVICE, &actuators_asctec_v2.i2c_trans);
}
@@ -0,0 +1,75 @@
/*
* Copyright (C) 2009-2013 The Paparazzi Team
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/** @file actuators_asctec_v2.h
* Actuators driver for Asctec v2 motor controllers.
*/
#ifndef ACTUATORS_ASCTEC_V2_H
#define ACTUATORS_ASCTEC_V2_H
#include "mcu_periph/i2c.h"
#include "generated/airframe.h"
enum actuators_asctec_v2_cmd { NONE,
TEST,
REVERSE,
SET_ADDR };
enum actuators_asctec_v2_addr { FRONT,
BACK,
LEFT,
RIGHT };
struct ActuatorsAsctecV2 {
enum actuators_asctec_v2_cmd cmd;
enum actuators_asctec_v2_addr cur_addr;
enum actuators_asctec_v2_addr new_addr;
int32_t cmds[4];
struct i2c_transaction i2c_trans;
volatile uint32_t nb_err;
};
extern struct ActuatorsAsctecV2 actuators_asctec_v2;
#define actuators_asctec_v2_SetCommand(_v) { \
actuators_asctec_v2.cmd = _v; \
}
#define actuators_asctec_v2_SetNewAddr(_v) { \
actuators_asctec_v2.new_addr = _v; \
}
#define actuators_asctec_v2_SetCurAddr(_v) { \
actuators_asctec_v2.cur_addr = _v; \
}
extern void actuators_asctec_v2_init(void);
extern void actuators_asctec_v2_set(bool_t motors_on);
#define ActuatorAsctec_v2Set(_i, _v) { actuators_asctec_v2.cmds[_i] = _v; }
#define ActuatorsAsctec_v2Init() actuators_asctec_v2_init()
#define ActuatorsAsctec_v2Commit() actuators_asctec_v2_set(autopilot_motors_on)
#endif /* ACTUATORS_ASCTEC_H */