started on pca9685 driver

master
Kerem Yollu 4 years ago
parent e5179d632d
commit 36c91832ac

@ -1,4 +1,4 @@
cpp_src = $(wildcard *.cpp) $(wildcard ./drivers/bh1750/*.cpp) $(wildcard ./management/*.cpp) $(wildcard ./systems/*.cpp) $(wildcard ./periferals/i2c/*.cpp)
cpp_src = $(wildcard *.cpp) $(wildcard ./drivers/bh1750/*.cpp) $(wildcard ./drivers/pca9685/*.cpp) $(wildcard ./management/*.cpp) $(wildcard ./systems/*.cpp) $(wildcard ./periferals/i2c/*.cpp)
c_src = $(wildcard ./drivers/pf8574/*.c)

@ -0,0 +1,132 @@
#include "pca9685.h"
Pca9685::Pca9685(i2c_ch1_pImpL* i2c, ErrorHandler* err)
{
i2c_pca9685 = i2c;
errorHandling = err;
m_isExternalClock = 0;
m_oscillatorFreq = PCA9685_FREQUENCY_OSCILLATOR;
setPwmFreq(200);
m_currentLED = PCA9685_LED_PWM_REG_START;
errorHandling->addNewError(-1,__FILE__,"Selected duty cycle is too big",KILL);
errorHandling->addNewError(-2,__FILE__,"Selected duty cycle is too small",KILL);
errorHandling->addNewError(-3,__FILE__,"Selected PWM frequency is too fast",SPARE);
errorHandling->addNewError(-4,__FILE__,"Selected PWM frequency is too slow",SPARE);
errorHandling->addNewError(-5,__FILE__,"Oscillator frequency can't be 0 or inferior to 0",KILL);
errorHandling->addNewError(-6,__FILE__,"Oscillator frequency cant't be higher than 50 MHz",KILL);
}
/*Refere to datasheet page 52
*
*
* osc_clock
* prescale vlaue = _______________________ - 1
* 4096 * update_rate
*
*/
void Pca9685::setPwmFreq(uint16_t frequency)
{
if(frequency > 1526)
{
frequency = 1526;
errorHandling->handleError(-3,__FILE__);
}
else if (frequency == 1526) // Rounding correction
{
frequency -= 1;
}
if(frequency < 24)
{
frequency = 24;
errorHandling->handleError(-4,__FILE__);
}
m_currentPrescale = (m_oscillatorFreq / ( 4096 * frequency) ) -1;
sleep();
i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, PCA9685_REG_PRESCALE, m_currentPrescale);
wakeup();
}
void Pca9685::setPwmMicroSeconds(uint16_t microSeconds)
{
}
void Pca9685::setDutyPercent(uint8_t ledNo, uint8_t on, uint8_t off)
{
}
void Pca9685::setDutyRaw(uint8_t ledNo, uint8_t on, uint8_t off)
{
m_currentLED = PCA9685_LED_PWM_REG_START + (ledNo * PCA9685_LED_NEXT_OFFSET);
std::cout << "Led" <<unsigned(ledNo)<<" ON L : " << unsigned(m_currentLED) << std::endl;
std::cout << "Led" <<unsigned(ledNo)<<" ON H : " << unsigned(m_currentLED+PCA9685_PWM_ON_H_OFFSET) << std::endl;
std::cout << "Led" <<unsigned(ledNo)<<" OFF L : " << unsigned(m_currentLED+PCA9685_PWM_OFF_L_OFFSET) << std::endl;
std::cout << "Led" <<unsigned(ledNo)<<" 0FF H : " << unsigned(m_currentLED+PCA9685_PWM_OFF_H_OFFSET) << std::endl;
}
void Pca9685::setDutyMicroSecond(uint8_t ledNo, uint16_t on, uint16_t off)
{
}
void Pca9685::setOnOff(uint8_t ledNo, bool onOff, bool invert)
{
}
void Pca9685::confClk(bool internExtern, uint32_t freq)
{
if(internExtern)
{
m_isExternalClock = 0;
}
else
{
m_isExternalClock = 1;
if(freq > 0)
{
if(freq <= 50000000)
{
m_oscillatorFreq = freq;
}
else
{
errorHandling->handleError(-6,__FILE__);
}
}
else
{
errorHandling->handleError(-5,__FILE__);
}
}
}
void Pca9685::setOutputMode(bool mode)
{
}
void Pca9685::reset()
{
i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, PCA9685_REG_MODE1, PCA9685_MODE1_RESTART);
}
void Pca9685::sleep()
{
m_curMode = i2c_pca9685->readByte(PCA9685_I2C_ADDRESS,PCA9685_REG_MODE1);
m_curMode = m_curMode | PCA9685_MODE1_SLEEP;
i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, PCA9685_REG_MODE1, m_curMode);
}
void Pca9685::wakeup()
{
m_curMode = i2c_pca9685->readByte(PCA9685_I2C_ADDRESS,PCA9685_REG_MODE1);
m_curMode = m_curMode & ~PCA9685_MODE1_SLEEP;
i2c_pca9685->writeWord(PCA9685_I2C_ADDRESS, PCA9685_REG_MODE1, m_curMode);
usleep(PCA9685_OSC_STAB_TIME_US); // refer to datasheet page 14
}

@ -0,0 +1,80 @@
#include <stdint.h>
#include <iostream>
#include <unistd.h>
#include <math.h>
#include "../../periferals/i2c/i2c_ch1_pImpL.hpp"
#include "../../management/errorHandling.h"
// REGISTER ADDRESSES
#define PCA9685_REG_MODE1 0x00 /**< Mode Register 1 */
#define PCA9685_REG_MODE2 0x01 /**< Mode Register 2 */
#define PCA9685_SUBADR1 0x02 /**< I2C-bus subaddress 1 */
#define PCA9685_SUBADR2 0x03 /**< I2C-bus subaddress 2 */
#define PCA9685_SUBADR3 0x04 /**< I2C-bus subaddress 3 */
#define PCA9685_ALLCALLADR 0x05 /**< LED All Call I2C-bus address */
#define PCA9685_LED_PWM_REG_START 0x06 // Start register of the fisrt LED's PWM Register wich also corresponds to LED0_ON_L
#define PCA9685_PWM_ON_H_OFFSET 0x01 // PWM ON HIGH Register for the selected LED
#define PCA9685_PWM_OFF_L_OFFSET 0x02 // PWM OFF LOW Register for the selected LED
#define PCA9685_PWM_OFF_H_OFFSET 0x03 // PWM OFF HIGH Register for the selected LED
#define PCA9685_LED_NEXT_OFFSET 0x04 // Register ON LOW of the next LED
#define PCA9685_LED_FULL_OFF_BIT 0x04 // Bit no to set on the LED OFF HIGH gerister of the selected LED to turn the LED fully OFF
#define PCA9685_LED_FULL_ON_BIT 0x04 // Bit no to set on the LED ON HIGH gerister of the selected LED to turn the LED fully ON
#define PCA9685_ALL_ON_L 0xFA // load all the LEDn_ON registers, low
#define PCA9685_ALL_ON_H 0xFB // load all the LEDn_ON registers, high
#define PCA9685_ALL_OFF_L 0xFC // load all the LEDn_OFF registers, low
#define PCA9685_ALL_OFF_H 0xFD // load all the LEDn_OFF registers,high
#define PCA9685_REG_PRESCALE 0xFE // Prescaler Register for PWM output frequency
#define PCA9685_TESTMODE 0xFF // defines the test mode to be entered
// MODE1 bits
#define PCA9685_MODE1_ALLCAL 0x01 /**< respond to LED All Call I2C-bus address */
#define PCA9685_MODE1_SUB3 0x02 /**< respond to I2C-bus subaddress 3 */
#define PCA9685_MODE1_SUB2 0x04 /**< respond to I2C-bus subaddress 2 */
#define PCA9685_MODE1_SUB1 0x08 /**< respond to I2C-bus subaddress 1 */
#define PCA9685_MODE1_SLEEP 0x10 /**< Low power mode. Oscillator off */
#define PCA9685_MODE1_AI 0x20 /**< Auto-Increment enabled */
#define PCA9685_MODE1_EXTCLK 0x40 /**< Use EXTCLK pin clock */
#define PCA9685_MODE1_RESTART 0x80 /**< Restart enabled */
// MODE2 bits
#define PCA9685_MODE2_OUTNE_0 0x01 /**< Active LOW output enable input */
#define PCA9685_MODE2_OUTNE_1 0x02 /**< Active LOW output enable input - high impedience */
#define PCA9685_MODE2_OUTDRV 0x04 /**< totem pole structure vs open-drain */
#define PCA9685_MODE2_OCH 0x08 /**< Outputs change on ACK vs STOP */
#define PCA9685_MODE2_INVRT 0x10 /**< Output logic state inverted */
#define PCA9685_I2C_ADDRESS 0x40 /**< Default PCA9685 I2C Slave Address */
#define PCA9685_FREQUENCY_OSCILLATOR 25000000 /**< Int. osc. frequency in datasheet */
#define PCA9685_OSC_STAB_TIME_US 500 // Delay to allow time for oscillator to stabilize 500 us
#define PCA9685_PRESCALE_MIN 3 /**< minimum prescale value */
#define PCA9685_PRESCALE_MAX 255 /**< maximum prescale value */
#define PCA9685_PRESCALE_DEF 200 // Default prescaler value | Datasheet Page : 25
class Pca9685
{
public:
Pca9685(i2c_ch1_pImpL* i2c,ErrorHandler* err);
void setPwmFreq(uint16_t frequency);
void setPwmMicroSeconds(uint16_t microSeconds);
void setDutyPercent(uint8_t ledNo, uint8_t on, uint8_t off);
void setDutyRaw(uint8_t ledNo, uint8_t on, uint8_t off);
void setDutyMicroSecond(uint8_t ledNo, uint16_t on, uint16_t off);
void setOnOff(uint8_t ledNo, bool onOff, bool invert);
void confClk(bool internExtern, uint32_t freq);
void setOutputMode(bool mode);
void reset();
void sleep();
void wakeup();
private:
uint8_t m_currentLED;
uint8_t m_curMode;
uint16_t m_currentPwmFreq;
uint8_t m_currentPrescale;
uint8_t m_isExternalClock;
uint32_t m_oscillatorFreq;
ErrorHandler* errorHandling;
i2c_ch1_pImpL* i2c_pca9685;
};

@ -29,7 +29,6 @@ int lcd_init(i2c_ch1_pImpL* i2c)
return 1;
}
// Fonction qui vas afficher une pharse sur la ligne et colone qui lui est indiquée
// Attention la fonction est capable de calculer la liongeure d0ubn phrase mais il ne
// faut pas dépasser la limite d'une ligne totale qui est de 20 charactères max
@ -45,7 +44,7 @@ void lcd_display_string(char line, char pos, char* charvalue)
{
char setPosition = 0;
int i, S_length = 0;
char buf[TOTAL_CHAR_CAP]; // buffer contenant la quantité de char dissponible sur une ligne
//char buf[TOTAL_CHAR_CAP]; // buffer contenant la quantité de char dissponible sur une ligne
S_length = strlen(charvalue);
@ -56,14 +55,6 @@ void lcd_display_string(char line, char pos, char* charvalue)
}
else
{
strcpy(buf, charvalue);
S_length = strlen(buf);
#ifdef LCD_DEBUG
printf("LCD.C :\t Longeure de la prhase => %d \n", S_length);
printf("LCD.C :\t Ligne selectionee => %d \n", line);
#endif
if(line == 1) // Selection de la ligne d'écriture
{
setPosition = pos;
@ -91,12 +82,9 @@ void lcd_display_string(char line, char pos, char* charvalue)
for(i = 0; i < S_length; i++ )
{
lcd_write(buf[i],RS);
lcd_write(charvalue[i],RS);
}
#ifdef LCD_DEBUG
printf("LCD.C :\t Ectiture reussit => %s \n", buf);
#endif
}
else
{
@ -110,11 +98,10 @@ void lcd_display_string(char line, char pos, char* charvalue)
// enregistrer les donées qui lui sont envoyées
void ldc_pulse_En(char data)
{
i2c_pf8574->writeByte(LCD_ADDRS,data | EN | LCD_BACKLIGHT);
usleep(100);
i2c_pf8574->writeByte(LCD_ADDRS,((data & ~EN) | LCD_BACKLIGHT));
usleep(500);
usleep(450);
}
// Cette fonction nous permet d'envoyer un information de 8 bits sous format

@ -14,21 +14,18 @@
#include "./management/commandManager.h"
#include "./drivers/bh1750/bh1750.h"
#include "./drivers/pf8574/pf8574lcd.h"
unsigned int miliSecond = 1000;
#include "./drivers/pca9685/pca9685.h"
ErrorHandler errorHandle;
CommandManager commander;
i2c_ch1_pImpL i2c(1, &errorHandle);
Bh1750 lightSens(&i2c);
Pca9685 pwmGenarator(&i2c, &errorHandle);
int initPlatform()
{
char* Msg = "hello";
char Msg[6] = "hello";
lcd_init(&i2c);
lcd_display_string(1,0,Msg);
// Dev. Module initialisation "Ex i2c_init() ...."
@ -37,11 +34,18 @@ int initPlatform()
void dummy()
{
/*
while(1)
{
std::cout << "value "<< lightSens.continious(BH1750_CONTINUOUS_HIGH_RES_MODE_1,1) << " Lux" <<std::endl;
usleep(150*miliSecond);
// std::cout << "value "<< lightSens.continious(BH1750_CONTINUOUS_HIGH_RES_MODE_1,1) << " Lux" <<std::endl;
std::string Msg = std::to_string(lightSens.continious(BH1750_CONTINUOUS_HIGH_RES_MODE_1,1));
char char_array[TOTAL_CHAR_CAP];
strcpy(char_array, Msg.c_str());
lcd_display_string(2,0, char_array);
usleep(150*1000);
}
*/
}
int main(int argc, char *argv[])
@ -49,13 +53,9 @@ int main(int argc, char *argv[])
// Init
initPlatform();
std::cout << "Main" << std::endl;
// errorHandle.addNewError(-34,__FILE__,"Test eroor 1",SPARE);
// errorHandle.addNewError(-34,__FILE__,"Test eroor 2",KILL);
// errorHandle.handleError(-34,__FILE__);
// errorHandle.handleError(-34,"main");
// commander.addNewCommand("test", "The test command for testing the test", dummy);
// commander(argv[1]);
pwmGenarator.setDutyRaw(1,200,200);
commander.addNewCommand("i2c", "The test command for testing the test", dummy);
commander(argv[1]);

Binary file not shown.

Binary file not shown.
Loading…
Cancel
Save