diff --git a/developpment/Makefile b/developpment/Makefile index df753da..ba618ee 100644 --- a/developpment/Makefile +++ b/developpment/Makefile @@ -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) diff --git a/developpment/drivers/pca9685/pca9685.cpp b/developpment/drivers/pca9685/pca9685.cpp new file mode 100644 index 0000000..2952390 --- /dev/null +++ b/developpment/drivers/pca9685/pca9685.cpp @@ -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" < 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 +} diff --git a/developpment/drivers/pca9685/pca9685.h b/developpment/drivers/pca9685/pca9685.h new file mode 100644 index 0000000..3ad7629 --- /dev/null +++ b/developpment/drivers/pca9685/pca9685.h @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#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; +}; diff --git a/developpment/drivers/pca9685/pca9685.o b/developpment/drivers/pca9685/pca9685.o new file mode 100644 index 0000000..1d2a388 Binary files /dev/null and b/developpment/drivers/pca9685/pca9685.o differ diff --git a/developpment/drivers/pf8574/pf8574lcd.c b/developpment/drivers/pf8574/pf8574lcd.c index e8cf802..7dddde3 100755 --- a/developpment/drivers/pf8574/pf8574lcd.c +++ b/developpment/drivers/pf8574/pf8574lcd.c @@ -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,10 +44,10 @@ 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); + S_length = strlen(charvalue); if (S_length > TOTAL_CHAR_CAP) { printf("LCD.C :\t La phrase est trop longue => %d MAX: %d \n", S_length, TOTAL_CHAR_CAP); @@ -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 diff --git a/developpment/drivers/pf8574/pf8574lcd.o b/developpment/drivers/pf8574/pf8574lcd.o index bca9321..ff77426 100644 Binary files a/developpment/drivers/pf8574/pf8574lcd.o and b/developpment/drivers/pf8574/pf8574lcd.o differ diff --git a/developpment/interfacer.cpp b/developpment/interfacer.cpp index c58d028..7b6f324 100644 --- a/developpment/interfacer.cpp +++ b/developpment/interfacer.cpp @@ -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" <