Files
PX4-Autopilot/src/drivers/linux_pwm_out/PCA9685.h
T

144 lines
5.0 KiB
C++

/****************************************************************************
*
* Copyright (c) 2017 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* 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.
*
*
* Original Author : Georgi Todorov
* Edited by : Tord Wessman
* Created on : Nov 22, 2013
* Rewrite : Fan.zhang 421395590@qq.com
* Updated on : Mar 2, 2017
****************************************************************************/
#pragma once
#include <inttypes.h>
#include "common.h"
namespace linux_pwm_out
{
// Register Definitions
// 寄存器定义
#define MODE1 0x00 //Mode register 1
#define MODE2 0x01 //Mode register 2
#define SUBADR1 0x02 //I2C-bus subaddress 1
#define SUBADR2 0x03 //I2C-bus subaddress 2
#define SUBADR3 0x04 //I2C-bus subaddress 3
#define ALLCALLADR 0x05 //LED All Call I2C-bus address
#define LED0 0x6 //LED0 start register
#define LED0_ON_L 0x6 //LED0 output and brightness control byte 0
#define LED0_ON_H 0x7 //LED0 output and brightness control byte 1
#define LED0_OFF_L 0x8 //LED0 output and brightness control byte 2
#define LED0_OFF_H 0x9 //LED0 output and brightness control byte 3
#define LED_MULTIPLYER 4 // For the other 15 channels
#define ALLLED_ON_L 0xFA //load all the LEDn_ON registers, byte 0 (turn 0-7 channels on)
#define ALLLED_ON_H 0xFB //load all the LEDn_ON registers, byte 1 (turn 8-15 channels on)
#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 PRE_SCALE 0xFE //prescaler for output frequency
#define MAX_PWM_RES 4096 //Resolution 4096=12bit 分辨率,按2的阶乘计算,12bit为4096
#define CLOCK_FREQ 25000000.0 //25MHz default osc clock
#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
class PCA9685 : public PWMOutBase
{
public:
PCA9685();
/**
* Constructor takes bus and address arguments
* @param bus the bus to use in /dev/i2c-%d.
* @param address the device address on bus
*/
PCA9685(int bus, int address);
int init() override { return _fd >= 0 ? 0 : -1; }
int send_output_pwm(const uint16_t *pwm, int num_outputs) override;
int init(int bus, int address);
virtual ~PCA9685();
/** Sets PCA9685 mode to 00 */
void reset();
/**
* Set the frequency of PWM
* @param freq desired frequency. 40Hz to 1000Hz using internal 25MHz oscillator.
*/
void setPWMFreq(int freq);
/**
* PWM a single channel with custom on time.
* send pwm vale to led(channel)
* @param channel
* @param on_value 0-4095 value to turn on the pulse
* @param off_value 0-4095 value to turn off the pulse
*/
void setPWM(uint8_t channel, int on_value, int off_value);
/**
* send pwm value to led(channel),
* value should be range of 0-4095
*/
void setPWM(uint8_t channel, int value);
private:
int _fd = -1; ///< I2C device file descriptor
/**
* Read a single byte from PCA9685
* @param fd file descriptor for I/O
* @param address register address to read from
* @return read byte
*/
uint8_t read_byte(int fd, uint8_t address);
/**
* Write a single byte to PCA9685
* @param fd file descriptor for I/O
* @param address register address to write to
* @param data 8 bit data to write
*/
void write_byte(int fd, uint8_t address, uint8_t data);
/**
* Open device file for PCA9685 I2C bus
* @return fd returns the file descriptor number or -1 on error
*/
int open_fd(int bus, int address);
};
}