1. Add comment written in English

2. Rewrite and rebase pca9685 driver
3. Try to fix issue when push the stick of channel 3 to the maxmum position, 0uswill be output to channel 1, should be maxmum pwm signal
4. Fix the code style
This commit is contained in:
crossa
2017-07-13 16:53:28 +02:00
committed by Beat Küng
parent 78b853431d
commit ed319ce5d5
4 changed files with 104 additions and 56 deletions
+46 -21
View File
@@ -1,26 +1,41 @@
/* /****************************************************************************
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * Copyright (c) 2015-2017 PX4 Development Team. All rights reserved.
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Redistribution and use in source and binary forms, with or without
* Lesser General Public License for more details. * modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* *
* Name : PCA9685.cpp
* Original Author : Georgi Todorov * Original Author : Georgi Todorov
* Edited by : Tord Wessman * Edited by : Tord Wessman
* Version : * Created on : Nov 22, 2013
* Created on : Dec 9, 2012 * Rewrite : Fan.zhang 421395590@qq.com
* * Updated on : Mar 2, 2017
* Copyright © 2012 Georgi Todorov <terahz@geodar.com> ****************************************************************************/
*/
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@@ -53,15 +68,25 @@ void PCA9685::init(int bus, int address)
//usleep(10*1000); //usleep(10*1000);
} }
PCA9685::PCA9685() : PCA9685::PCA9685() :
_i2caddr(0x40), _i2caddr(PCA9685_DEFAULT_I2C_ADDR),
_i2cbus(1), _i2cbus(PCA9685_DEFAULT_I2C_BUS),
busfile {},
dataBuffer {} dataBuffer {}
{ {
} }
PCA9685::PCA9685(int bus, int address) :
busfile {},
dataBuffer {}
{
_i2cbus = bus;
_i2caddr = address;
snprintf(busfile, sizeof(busfile), "/dev/i2c-%d", bus);
reset();
}
PCA9685::~PCA9685() PCA9685::~PCA9685()
{ {
reset(); reset();
+37 -21
View File
@@ -1,33 +1,48 @@
/* /****************************************************************************
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * Copyright (c) 2015-2017 PX4 Development Team. All rights reserved.
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Redistribution and use in source and binary forms, with or without
* Lesser General Public License for more details. * modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* *
* Name : PCA9685.h
* Original Author : Georgi Todorov * Original Author : Georgi Todorov
* Edited by : Tord Wessman * Edited by : Tord Wessman
* Version :
* Created on : Nov 22, 2013 * Created on : Nov 22, 2013
* * Rewrite : Fan.zhang 421395590@qq.com
* Copyright © 2012 Georgi Todorov <terahz@geodar.com> * Updated on : Mar 2, 2017
*/ ****************************************************************************/
#ifndef _PCA9685_H #ifndef _PCA9685_H
#define _PCA9685_H #define _PCA9685_H
#include <inttypes.h> #include <inttypes.h>
// Register Definitions // Register Definitions
// 寄存器定义
#define MODE1 0x00 //Mode register 1 #define MODE1 0x00 //Mode register 1
#define MODE2 0x01 //Mode register 2 #define MODE2 0x01 //Mode register 2
#define SUBADR1 0x02 //I2C-bus subaddress 1 #define SUBADR1 0x02 //I2C-bus subaddress 1
@@ -45,15 +60,18 @@
#define ALLLED_OFF_L 0xFC //load all the LEDn_OFF registers, byte 0 (turn 0-7 channels off) #define ALLLED_OFF_L 0xFC //load all the LEDn_OFF registers, byte 0 (turn 0-7 channels off)
#define ALLLED_OFF_H 0xFD //load all the LEDn_OFF registers, byte 1 (turn 8-15 channels off) #define ALLLED_OFF_H 0xFD //load all the LEDn_OFF registers, byte 1 (turn 8-15 channels off)
#define PRE_SCALE 0xFE //prescaler for output frequency #define PRE_SCALE 0xFE //prescaler for output frequency
#define MAX_PWM_RES 4096 //10bit精度 #define MAX_PWM_RES 4096 //Resolution 4096=12bit 分辨率,按2的阶乘计算,12bit为4096
#define CLOCK_FREQ 25000000.0 //25MHz default osc clock #define CLOCK_FREQ 25000000.0 //25MHz default osc clock
#define BUFFER_SIZE 0x08 //1 byte buffer #define BUFFER_SIZE 0x08 //1 byte buffer
#define PCA9685_DEFAULT_I2C_ADDR 0x40 // default i2c address for pca9685 默认i2c地址为0x40
#define PCA9685_DEFAULT_I2C_BUS 1 // default i2c bus for pca9685 默认为1
//! Main class that exports features for PCA9685 chip //! Main class that exports features for PCA9685 chip
class PCA9685 class PCA9685
{ {
public: public:
PCA9685(); PCA9685();
PCA9685(int, int);
void init(int, int); void init(int, int);
virtual ~PCA9685(); virtual ~PCA9685();
void reset(void); void reset(void);
@@ -68,7 +86,5 @@ private:
uint8_t read_byte(int, uint8_t); uint8_t read_byte(int, uint8_t);
void write_byte(int, uint8_t, uint8_t); void write_byte(int, uint8_t, uint8_t);
int openfd(); int openfd();
}; };
#endif #endif
@@ -80,11 +80,15 @@ int rpi_pca9685_pwm_out::initialize_mixer(const char *mixer_filename)
int rpi_pca9685_pwm_out::pwm_initialize() int rpi_pca9685_pwm_out::pwm_initialize()
{ {
/**************初始化PCA9685开始*************/ /**************初始化PCA9685开始*************/
/**************PCA965 initializing********/
pwm.init(1, 0x40); pwm.init(1, 0x40);
usleep(1000 * 100); usleep(1000 * 100);
pwm.setPWMFreq(200); //12BIT 精度输出下,好赢电调可以到200HZ刷新 /****12BIT 精度输出下,好赢电调可以到200HZ刷新***/
/****200HZ for 12bit Resolution, support most of the esc***/
pwm.setPWMFreq(200);
usleep(1000 * 1000); usleep(1000 * 1000);
/**************初始化PCA9685结束************/ /**************初始化PCA9685结束************/
/**************PCA965 initialized********/
return 0; return 0;
} }
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
@@ -95,7 +99,8 @@ void rpi_pca9685_pwm_out::pwm_deinitialize()
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
void rpi_pca9685_pwm_out::send_outputs_pwm(const uint16_t *pwm) void rpi_pca9685_pwm_out::send_outputs_pwm(const uint16_t *pwm)
{ {
//向PCA9685发送数据 /*************向PCA9685发送数据*************/
/*************send pwm signal to pca9685 initializing*************/
int i; int i;
for (i = 0; i < NUM_PWM; ++i) { for (i = 0; i < NUM_PWM; ++i) {
@@ -141,11 +146,12 @@ void rpi_pca9685_pwm_out::task_main(int argc, char *argv[])
_is_running = true; _is_running = true;
/***************初始化PCA9685************/ /***************初始化PCA9685************/
/***************rpc_pca9685_pwm_out*************/
rpi_pca9685_pwm_out::pwm_initialize(); rpi_pca9685_pwm_out::pwm_initialize();
// Set up mixer // Set up mixer
if (initialize_mixer(_mixer_filename) < 0) { if (initialize_mixer(_mixer_filename) < 0) {
PX4_ERR("无法初始化通道混合配置文件"); PX4_ERR("无法初始化通道混合配置文件 Can't loading mixer file");
return; return;
} }
+12 -11
View File
@@ -43,12 +43,12 @@ int RcInput::rpi_rc_init()
//--------------初始化共享内存映射----------------------------// //--------------初始化共享内存映射----------------------------//
if ((this->shmid = shmget(this->key, sizeof(int) * this->_channels, 0666)) if ((this->shmid = shmget(this->key, sizeof(int) * this->_channels, 0666))
< 0) { < 0) {
PX4_WARN("无法访问共享内存"); PX4_WARN("无法访问共享内存。Faild to access shared memory");
return -1; return -1;
} }
if ((this->mem = (int *) shmat(this->shmid, NULL, 0)) == (void *) - 1) { if ((this->mem = (int *) shmat(this->shmid, NULL, 0)) == (void *) - 1) {
PX4_WARN("无法映射共享内存"); PX4_WARN("无法映射共享内存。Faild to mapping shared memory");
return -1; return -1;
} }
@@ -113,11 +113,12 @@ void RcInput::_cycle()
void RcInput::_measure(void) void RcInput::_measure(void)
{ {
uint64_t ts; uint64_t ts;
// PWM 数据发布 // PWM数据发布
// read pwm value from shared memory
int i = 0; int i = 0;
for (i = 0; i < _channels; ++i) { for (i = 0; i < _channels; ++i) {
_data.values[i] = *(this->mem + i); _data.values[i] = (*(this->mem + i) <= 0) ? UINT16_MAX : *(this->mem + i);
} }
ts = hrt_absolute_time(); ts = hrt_absolute_time();
@@ -158,7 +159,7 @@ int rpi_rc_in_main(int argc, char **argv)
if (!strcmp(argv[1], "start")) { if (!strcmp(argv[1], "start")) {
if (rc_input != nullptr && rc_input->isRunning()) { if (rc_input != nullptr && rc_input->isRunning()) {
PX4_WARN("运行中。"); PX4_WARN("运行中。running");
/* this is not an error */ /* this is not an error */
return 0; return 0;
} }
@@ -167,14 +168,14 @@ int rpi_rc_in_main(int argc, char **argv)
// Check if alloc worked. // Check if alloc worked.
if (nullptr == rc_input) { if (nullptr == rc_input) {
PX4_ERR("遥控输入模块初始化错误。"); PX4_ERR("遥控输入模块初始化错误。Rc input moduel initialization faild");
return -1; return -1;
} }
int ret = rc_input->start(); int ret = rc_input->start();
if (ret != 0) { if (ret != 0) {
PX4_ERR("遥控输入模块未能启动"); PX4_ERR("遥控输入模块未能启动。 Rc input module failure");
} }
return 0; return 0;
@@ -183,7 +184,7 @@ int rpi_rc_in_main(int argc, char **argv)
if (!strcmp(argv[1], "stop")) { if (!strcmp(argv[1], "stop")) {
if (rc_input == nullptr || !rc_input->isRunning()) { if (rc_input == nullptr || !rc_input->isRunning()) {
PX4_WARN("模块未运行"); PX4_WARN("模块未运行。 Not runing");
/* this is not an error */ /* this is not an error */
return 0; return 0;
} }
@@ -207,16 +208,16 @@ int rpi_rc_in_main(int argc, char **argv)
if (!strcmp(argv[1], "status")) { if (!strcmp(argv[1], "status")) {
if (rc_input != nullptr && rc_input->isRunning()) { if (rc_input != nullptr && rc_input->isRunning()) {
PX4_INFO("运行中"); PX4_INFO("运行中。 running");
} else { } else {
PX4_INFO("未运行\n"); PX4_INFO("未运行。 Not runing\n");
} }
return 0; return 0;
} }
usage("不知道你要做什么"); usage("不知道你要做什么。 rpi_rc_in start|stop|status");
return 1; return 1;
} }