diff --git a/developpment/Makefile b/developpment/Makefile index 9849f39..df753da 100644 --- a/developpment/Makefile +++ b/developpment/Makefile @@ -1,6 +1,6 @@ cpp_src = $(wildcard *.cpp) $(wildcard ./drivers/bh1750/*.cpp) $(wildcard ./management/*.cpp) $(wildcard ./systems/*.cpp) $(wildcard ./periferals/i2c/*.cpp) -#c_src = $(wildcard ../c/algorithms/*.c) $(wildcard driver/ma120x0/*.c) +c_src = $(wildcard ./drivers/pf8574/*.c) cpp_obj = $(cpp_src:.cpp=.o) c_obj = $(c_src:.c=.o) diff --git a/developpment/drivers/bh1750/bh1750.cpp b/developpment/drivers/bh1750/bh1750.cpp index 536514c..83fb57c 100644 --- a/developpment/drivers/bh1750/bh1750.cpp +++ b/developpment/drivers/bh1750/bh1750.cpp @@ -1,28 +1,28 @@ #include "bh1750.h" -i2c_ch1_pImpL i2c(1); -Bh1750::Bh1750() +Bh1750::Bh1750(i2c_ch1_pImpL *i2c) { + i2c_bh1750 = i2c; currentMode = 0; // no mode selected } uint8_t Bh1750::sleep() { - i2c.writeByte(BH1750_ADDR,BH1750_POWER_DOWN); + i2c_bh1750->writeByte(BH1750_ADDR,BH1750_POWER_DOWN); return 0; } uint8_t Bh1750::wake() { - i2c.writeByte(BH1750_ADDR,BH1750_POWER_ON); + i2c_bh1750->writeByte(BH1750_ADDR,BH1750_POWER_ON); return 0; } uint8_t Bh1750::reset() { - i2c.writeByte(BH1750_ADDR,BH1750_RESET); + i2c_bh1750->writeByte(BH1750_ADDR,BH1750_RESET); return 0; } @@ -35,7 +35,7 @@ float Bh1750::oneShot(uint8_t mode) mode == BH1750_ONE_TIME_HIGH_RES_MODE_2 || mode == BH1750_ONE_TIME_LOW_RES_MODE) { - return i2c.readWord(BH1750_ADDR,mode) / 1.2 ; + return i2c_bh1750->readWord(BH1750_ADDR,mode) / 1.2 ; } } @@ -52,7 +52,7 @@ float Bh1750::continious(uint8_t mode, uint8_t delayMs) mode == BH1750_CONTINUOUS_HIGH_RES_MODE_2 || mode == BH1750_CONTINUOUS_LOW_RES_MODE) { - return i2c.readWord(BH1750_ADDR,mode) / 1.2; + return i2c_bh1750->readWord(BH1750_ADDR,mode) / 1.2; } } std::cout<< "please seelct a continious mode "<< std::endl; diff --git a/developpment/drivers/bh1750/bh1750.h b/developpment/drivers/bh1750/bh1750.h index 043dbac..ffab7c3 100644 --- a/developpment/drivers/bh1750/bh1750.h +++ b/developpment/drivers/bh1750/bh1750.h @@ -33,13 +33,14 @@ class Bh1750 { public: - Bh1750(); + Bh1750(i2c_ch1_pImpL *i2c); uint8_t sleep(); // To be testes uint8_t wake(); // To be tested uint8_t reset(); // To be tested float oneShot(uint8_t mode); // ok float continious(uint8_t mode, uint8_t delayMs); // IMplment delay or make a delay class ??? private: + i2c_ch1_pImpL* i2c_bh1750; uint8_t high; uint8_t low; uint8_t currentMode; diff --git a/developpment/drivers/bh1750/bh1750.o b/developpment/drivers/bh1750/bh1750.o index 44efbf2..93f71e7 100644 Binary files a/developpment/drivers/bh1750/bh1750.o and b/developpment/drivers/bh1750/bh1750.o differ diff --git a/developpment/drivers/pf8574/pf8574lcd.c b/developpment/drivers/pf8574/pf8574lcd.c new file mode 100755 index 0000000..e8cf802 --- /dev/null +++ b/developpment/drivers/pf8574/pf8574lcd.c @@ -0,0 +1,135 @@ +////////////////////////////////////////////////////////// +// Created by : Kerem Yollu +// Project : Multiprise conectée +// Nom : lcd.c +// Header : lcd.h +//_________________________Info_________________________ +// +// Libraire pour le control d'un ecran lcd stadard (HD44780) +// controlée par un expandeur de port PCF8574 en I2C. +// +////////////////////////////////////////////////////////// + +#include "pf8574lcd.h" + +i2c_ch1_pImpL *i2c_pf8574; + +// Fonction pour initialiser l'écran vide en mode 4 bits +int lcd_init(i2c_ch1_pImpL* i2c) +{ + i2c_pf8574 = i2c; + lcd_write(0x03,CMD_MODE); // Mise en mode 4 bit avec 4 essai conssecutif + lcd_write(0x03,CMD_MODE); + lcd_write(0x03,CMD_MODE); + lcd_write(0x02,CMD_MODE); + lcd_write(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE ,CMD_MODE); + lcd_write(LCD_DISPLAYCONTROL| LCD_DISPLAYON ,CMD_MODE); + lcd_write(LCD_CLEARDISPLAY ,CMD_MODE); + lcd_write(LCD_ENTRYMODESET | LCD_ENTRYLEFT ,CMD_MODE); + 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 +// +// LCD 20x4 +// ------------------------------------------- +// ||# # # # # # # # # # # # # # # # # # # #|| +// ||# # # # # # # # # # # # # # # # # # # #|| +// ||# # # # # # # # # # # # # # # # # # # #|| +// ||# # # # # # # # # # # # # # # # # # # #|| +// ------------------------------------------- +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 + + + 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); + exit(1); + } + 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; + } + else if(line ==2) + { + setPosition = 0x40 + pos; + } + else if(line ==3) + { + setPosition = 0x14 + pos; + } + else if(line ==4) + { + setPosition = 0x54 + pos; + } + else + { + setPosition = -1; + } + + if(setPosition >= 0) + { + lcd_write(LCD_SETDDRAMADDR + setPosition, CMD_MODE); + + for(i = 0; i < S_length; i++ ) + { + lcd_write(buf[i],RS); + } + + #ifdef LCD_DEBUG + printf("LCD.C :\t Ectiture reussit => %s \n", buf); + #endif + } + else + { + printf("LCD.C :\t Mauvais numéro de ligne => %d MAX:4 Min:1 \n", line); + exit(1); + } + } +} + +// Cette focntion nous pernet de faire pulser la ppin EN du lcd afin qu'il puisse +// 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); +} + +// Cette fonction nous permet d'envoyer un information de 8 bits sous format +// de 2x4 bites. Celà est necessaire du au fonctionnement de l'expendeur de port PCF8574 +// qui est branché sur l'écran de facon a ce qu'il communiquer en 4 bits. +void lcd_write(char cmd, char mode) +{ + lcd_write_4bits(mode | (cmd & 0xF0)); + lcd_write_4bits(mode | ((cmd << 4) & 0xF0)); +} + +// Fonction nous permettant d'nevoyer 4 bits dinformation sur le PC8574 ainsi que +// le rétroéclairage. +void lcd_write_4bits(char data) +{ + i2c_pf8574->writeByte(LCD_ADDRS,data | LCD_BACKLIGHT); + ldc_pulse_En(data); +} diff --git a/developpment/drivers/pf8574/pf8574lcd.h b/developpment/drivers/pf8574/pf8574lcd.h new file mode 100755 index 0000000..974b7cf --- /dev/null +++ b/developpment/drivers/pf8574/pf8574lcd.h @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../periferals/i2c/i2c_ch1_pImpL.hpp" + +//#include "i2c_ch1_pImpL.cpp" + +// commandes +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags pour mode d'ecriture +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags pour ecran on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags pour display/decalage curseurr +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + +// flags pour function set +#define LCD_8BITMODE 0x10 +#define LCD_4BITMODE 0x00 +#define LCD_2LINE 0x08 +#define LCD_1LINE 0x00 +#define LCD_5x1DOTS 0x04 +#define LCD_5x8DOTS 0x00 + +//flags pour le rétroeclairage +#define LCD_BACKLIGHT 0x08 +#define LCD_NOBACKLIGHT 0x00 + +//Pins de gestion de donées. +#define EN 0x04 // Enable bit +#define RW 0x02 // Read/Write bit +#define RS 0x01 // Register select bit + + +//DIfferents mode enre commande est ecriture +#define CMD_MODE 0x00 +#define CHAR_MODE 0x01 + +//adresse I2C du controlleur pour LCD +#define LCD_ADDRS 0x27 + +//Nombre max de char sur une ligne +#define TOTAL_CHAR_CAP 20 + + +int lcd_init(i2c_ch1_pImpL* i2c); +void lcd_write_char( char charvalue); +void lcd_display_string(char line, char pos, char* charvalue); +void ldc_pulse_En(char data); +void lcd_write(char cmd, char mode); +void lcd_write_4bits(char data); + + diff --git a/developpment/drivers/pf8574/pf8574lcd.o b/developpment/drivers/pf8574/pf8574lcd.o new file mode 100644 index 0000000..bca9321 Binary files /dev/null and b/developpment/drivers/pf8574/pf8574lcd.o differ diff --git a/developpment/interfacer.cpp b/developpment/interfacer.cpp index 4f0eac6..e396442 100644 --- a/developpment/interfacer.cpp +++ b/developpment/interfacer.cpp @@ -9,24 +9,28 @@ #include #include +#include #include "./management/errorHandling.h" #include "./management/commandManager.h" -#include "./systems/systemCall.h" #include "./drivers/bh1750/bh1750.h" -//#include "i2c_ch1_pImpL.cpp" - -#include +#include "./drivers/pf8574/pf8574lcd.h" unsigned int miliSecond = 1000; ErrorHandler errorHandle; CommandManager commander; -//I2C_Driver i2cDriver(1,1); -Bh1750 lightSens; +i2c_ch1_pImpL i2c(1); + +Bh1750 lightSens(&i2c); + + int initPlatform() { + char* Msg = "hello"; + lcd_init(&i2c); + lcd_display_string(1,0,Msg); // Dev. Module initialisation "Ex i2c_init() ...." return 0; } @@ -42,7 +46,6 @@ void dummy() int main(int argc, char *argv[]) { - // Init initPlatform(); std::cout << "Main" << std::endl; diff --git a/developpment/interfacer.o b/developpment/interfacer.o index d8d613f..763439b 100644 Binary files a/developpment/interfacer.o and b/developpment/interfacer.o differ diff --git a/developpment/runtest b/developpment/runtest index e5cd4b4..f4621ab 100755 Binary files a/developpment/runtest and b/developpment/runtest differ diff --git a/training/cpp/Makefile b/training/cpp/Makefile new file mode 100644 index 0000000..df753da --- /dev/null +++ b/training/cpp/Makefile @@ -0,0 +1,22 @@ +cpp_src = $(wildcard *.cpp) $(wildcard ./drivers/bh1750/*.cpp) $(wildcard ./management/*.cpp) $(wildcard ./systems/*.cpp) $(wildcard ./periferals/i2c/*.cpp) + +c_src = $(wildcard ./drivers/pf8574/*.c) + +cpp_obj = $(cpp_src:.cpp=.o) +c_obj = $(c_src:.c=.o) +CC = g++ +CFLAGS = -Wall -pedantic -li2c +LDFLAGS = +EXEC = runtest + + +all : $(EXEC) + +$(EXEC): $(cpp_obj) $(c_obj) + $(CC) -o $@ $^ $(LDFLAGS) + +clean: + rm -rf $(c_obj) $(cpp_obj) $(EXEC) + +cleanall: + rm -rf $(c_obj) $(cpp_obj) $(EXEC) diff --git a/training/cpp/drivers/bh1750/bh1750.cpp b/training/cpp/drivers/bh1750/bh1750.cpp new file mode 100644 index 0000000..83fb57c --- /dev/null +++ b/training/cpp/drivers/bh1750/bh1750.cpp @@ -0,0 +1,61 @@ +#include "bh1750.h" + + + +Bh1750::Bh1750(i2c_ch1_pImpL *i2c) +{ + i2c_bh1750 = i2c; + currentMode = 0; // no mode selected +} + +uint8_t Bh1750::sleep() +{ + i2c_bh1750->writeByte(BH1750_ADDR,BH1750_POWER_DOWN); + return 0; +} + +uint8_t Bh1750::wake() +{ + i2c_bh1750->writeByte(BH1750_ADDR,BH1750_POWER_ON); + return 0; +} + +uint8_t Bh1750::reset() +{ + i2c_bh1750->writeByte(BH1750_ADDR,BH1750_RESET); + return 0; +} + + +float Bh1750::oneShot(uint8_t mode) +{ + if(mode > 0) + { + if( mode == BH1750_ONE_TIME_HIGH_RES_MODE_1 || + mode == BH1750_ONE_TIME_HIGH_RES_MODE_2 || + mode == BH1750_ONE_TIME_LOW_RES_MODE) + { + return i2c_bh1750->readWord(BH1750_ADDR,mode) / 1.2 ; + + } + } + std::cout<< "please seelct a one shot mode "<< std::endl; + exit(1); + return 0; +} + +float Bh1750::continious(uint8_t mode, uint8_t delayMs) +{ + if(mode > 0) + { + if( mode == BH1750_CONTINUOUS_HIGH_RES_MODE_1 || + mode == BH1750_CONTINUOUS_HIGH_RES_MODE_2 || + mode == BH1750_CONTINUOUS_LOW_RES_MODE) + { + return i2c_bh1750->readWord(BH1750_ADDR,mode) / 1.2; + } + } + std::cout<< "please seelct a continious mode "<< std::endl; + exit(1); + return 0; +} diff --git a/training/cpp/drivers/bh1750/bh1750.h b/training/cpp/drivers/bh1750/bh1750.h new file mode 100644 index 0000000..ffab7c3 --- /dev/null +++ b/training/cpp/drivers/bh1750/bh1750.h @@ -0,0 +1,50 @@ + +#ifndef _BH1750_H_ +#define _BH1750_H_ + +#include +#include +#include +#include "../../periferals/i2c/i2c_ch1_pImpL.hpp" + + +//Start measurement at 4lx resolution. Time typically 16ms. +#define BH1750_CONTINUOUS_LOW_RES_MODE 0x13 +//Start measurement at 1lx resolution. Time typically 120ms +#define BH1750_CONTINUOUS_HIGH_RES_MODE_1 0x10 +//Start measurement at 0.5lx resolution. Time typically 120ms +#define BH1750_CONTINUOUS_HIGH_RES_MODE_2 0x11 +//Start measurement at 1lx resolution. Time typically 120ms +//Device is automatically set to Power Down after measurement. +#define BH1750_ONE_TIME_HIGH_RES_MODE_1 0x20 +//Start measurement at 0.5lx resolution. Time typically 120ms +//Device is automatically set to Power Down after measurement. +#define BH1750_ONE_TIME_HIGH_RES_MODE_2 0x21 +//Start measurement at 1lx resolution. Time typically 120ms +//Device is automatically set to Power Down after measurement. +#define BH1750_ONE_TIME_LOW_RES_MODE 0x23 + +#define BH1750_POWER_DOWN 0x00 // No active state +#define BH1750_POWER_ON 0x01 // Power on +#define BH1750_RESET 0x07 // Reset data register value + +#define BH1750_ADDR 0x23 // Device Adress + +class Bh1750 +{ + public: + Bh1750(i2c_ch1_pImpL *i2c); + uint8_t sleep(); // To be testes + uint8_t wake(); // To be tested + uint8_t reset(); // To be tested + float oneShot(uint8_t mode); // ok + float continious(uint8_t mode, uint8_t delayMs); // IMplment delay or make a delay class ??? + private: + i2c_ch1_pImpL* i2c_bh1750; + uint8_t high; + uint8_t low; + uint8_t currentMode; + uint8_t currentState; +}; + +#endif // _BH1750_H_ diff --git a/training/cpp/drivers/bh1750/bh1750.o b/training/cpp/drivers/bh1750/bh1750.o new file mode 100644 index 0000000..93f71e7 Binary files /dev/null and b/training/cpp/drivers/bh1750/bh1750.o differ diff --git a/training/cpp/drivers/bh1750/bh1750.py b/training/cpp/drivers/bh1750/bh1750.py new file mode 100644 index 0000000..9b85f24 --- /dev/null +++ b/training/cpp/drivers/bh1750/bh1750.py @@ -0,0 +1,69 @@ +#!/usr/bin/python +#--------------------------------------------------------------------- +# ___ ___ _ ____ +# / _ \/ _ \(_) __/__ __ __ +# / , _/ ___/ /\ \/ _ \/ // / +# /_/|_/_/ /_/___/ .__/\_, / +# /_/ /___/ +# +# bh1750.py +# Read data from a BH1750 digital light sensor. +# +# Author : Matt Hawkins +# Date : 26/06/2018 +# +# For more information please visit : +# https://www.raspberrypi-spy.co.uk/?s=bh1750 +# +#--------------------------------------------------------------------- +import smbus +import time + +# Define some constants from the datasheet + +DEVICE = 0x23 # Default device I2C address + +POWER_DOWN = 0x00 # No active state +POWER_ON = 0x01 # Power on +RESET = 0x07 # Reset data register value + +# Start measurement at 4lx resolution. Time typically 16ms. +CONTINUOUS_LOW_RES_MODE = 0x13 +# Start measurement at 1lx resolution. Time typically 120ms +CONTINUOUS_HIGH_RES_MODE_1 = 0x10 +# Start measurement at 0.5lx resolution. Time typically 120ms +CONTINUOUS_HIGH_RES_MODE_2 = 0x11 +# Start measurement at 1lx resolution. Time typically 120ms +# Device is automatically set to Power Down after measurement. +ONE_TIME_HIGH_RES_MODE_1 = 0x20 +# Start measurement at 0.5lx resolution. Time typically 120ms +# Device is automatically set to Power Down after measurement. +ONE_TIME_HIGH_RES_MODE_2 = 0x21 +# Start measurement at 1lx resolution. Time typically 120ms +# Device is automatically set to Power Down after measurement. +ONE_TIME_LOW_RES_MODE = 0x23 + +#bus = smbus.SMBus(0) # Rev 1 Pi uses 0 +bus = smbus.SMBus(1) # Rev 2 Pi uses 1 + +def convertToNumber(data): + # Simple function to convert 2 bytes of data + # into a decimal number. Optional parameter 'decimals' + # will round to specified number of decimal places. + result=(data[1] + (256 * data[0])) / 1.2 + return (result) + +def readLight(addr=DEVICE): + # Read data from I2C interface + data = bus.read_i2c_block_data(addr,ONE_TIME_HIGH_RES_MODE_1) + return convertToNumber(data) + +def main(): + + while True: + lightLevel=readLight() + print("Light Level : " + format(lightLevel,'.2f') + " lx") + time.sleep(0.5) + +if __name__=="__main__": + main() diff --git a/training/cpp/drivers/pf8574/pf8574lcd.c b/training/cpp/drivers/pf8574/pf8574lcd.c new file mode 100755 index 0000000..e8cf802 --- /dev/null +++ b/training/cpp/drivers/pf8574/pf8574lcd.c @@ -0,0 +1,135 @@ +////////////////////////////////////////////////////////// +// Created by : Kerem Yollu +// Project : Multiprise conectée +// Nom : lcd.c +// Header : lcd.h +//_________________________Info_________________________ +// +// Libraire pour le control d'un ecran lcd stadard (HD44780) +// controlée par un expandeur de port PCF8574 en I2C. +// +////////////////////////////////////////////////////////// + +#include "pf8574lcd.h" + +i2c_ch1_pImpL *i2c_pf8574; + +// Fonction pour initialiser l'écran vide en mode 4 bits +int lcd_init(i2c_ch1_pImpL* i2c) +{ + i2c_pf8574 = i2c; + lcd_write(0x03,CMD_MODE); // Mise en mode 4 bit avec 4 essai conssecutif + lcd_write(0x03,CMD_MODE); + lcd_write(0x03,CMD_MODE); + lcd_write(0x02,CMD_MODE); + lcd_write(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE ,CMD_MODE); + lcd_write(LCD_DISPLAYCONTROL| LCD_DISPLAYON ,CMD_MODE); + lcd_write(LCD_CLEARDISPLAY ,CMD_MODE); + lcd_write(LCD_ENTRYMODESET | LCD_ENTRYLEFT ,CMD_MODE); + 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 +// +// LCD 20x4 +// ------------------------------------------- +// ||# # # # # # # # # # # # # # # # # # # #|| +// ||# # # # # # # # # # # # # # # # # # # #|| +// ||# # # # # # # # # # # # # # # # # # # #|| +// ||# # # # # # # # # # # # # # # # # # # #|| +// ------------------------------------------- +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 + + + 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); + exit(1); + } + 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; + } + else if(line ==2) + { + setPosition = 0x40 + pos; + } + else if(line ==3) + { + setPosition = 0x14 + pos; + } + else if(line ==4) + { + setPosition = 0x54 + pos; + } + else + { + setPosition = -1; + } + + if(setPosition >= 0) + { + lcd_write(LCD_SETDDRAMADDR + setPosition, CMD_MODE); + + for(i = 0; i < S_length; i++ ) + { + lcd_write(buf[i],RS); + } + + #ifdef LCD_DEBUG + printf("LCD.C :\t Ectiture reussit => %s \n", buf); + #endif + } + else + { + printf("LCD.C :\t Mauvais numéro de ligne => %d MAX:4 Min:1 \n", line); + exit(1); + } + } +} + +// Cette focntion nous pernet de faire pulser la ppin EN du lcd afin qu'il puisse +// 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); +} + +// Cette fonction nous permet d'envoyer un information de 8 bits sous format +// de 2x4 bites. Celà est necessaire du au fonctionnement de l'expendeur de port PCF8574 +// qui est branché sur l'écran de facon a ce qu'il communiquer en 4 bits. +void lcd_write(char cmd, char mode) +{ + lcd_write_4bits(mode | (cmd & 0xF0)); + lcd_write_4bits(mode | ((cmd << 4) & 0xF0)); +} + +// Fonction nous permettant d'nevoyer 4 bits dinformation sur le PC8574 ainsi que +// le rétroéclairage. +void lcd_write_4bits(char data) +{ + i2c_pf8574->writeByte(LCD_ADDRS,data | LCD_BACKLIGHT); + ldc_pulse_En(data); +} diff --git a/training/cpp/drivers/pf8574/pf8574lcd.h b/training/cpp/drivers/pf8574/pf8574lcd.h new file mode 100755 index 0000000..974b7cf --- /dev/null +++ b/training/cpp/drivers/pf8574/pf8574lcd.h @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../periferals/i2c/i2c_ch1_pImpL.hpp" + +//#include "i2c_ch1_pImpL.cpp" + +// commandes +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags pour mode d'ecriture +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags pour ecran on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags pour display/decalage curseurr +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + +// flags pour function set +#define LCD_8BITMODE 0x10 +#define LCD_4BITMODE 0x00 +#define LCD_2LINE 0x08 +#define LCD_1LINE 0x00 +#define LCD_5x1DOTS 0x04 +#define LCD_5x8DOTS 0x00 + +//flags pour le rétroeclairage +#define LCD_BACKLIGHT 0x08 +#define LCD_NOBACKLIGHT 0x00 + +//Pins de gestion de donées. +#define EN 0x04 // Enable bit +#define RW 0x02 // Read/Write bit +#define RS 0x01 // Register select bit + + +//DIfferents mode enre commande est ecriture +#define CMD_MODE 0x00 +#define CHAR_MODE 0x01 + +//adresse I2C du controlleur pour LCD +#define LCD_ADDRS 0x27 + +//Nombre max de char sur une ligne +#define TOTAL_CHAR_CAP 20 + + +int lcd_init(i2c_ch1_pImpL* i2c); +void lcd_write_char( char charvalue); +void lcd_display_string(char line, char pos, char* charvalue); +void ldc_pulse_En(char data); +void lcd_write(char cmd, char mode); +void lcd_write_4bits(char data); + + diff --git a/training/cpp/drivers/pf8574/pf8574lcd.o b/training/cpp/drivers/pf8574/pf8574lcd.o new file mode 100644 index 0000000..bca9321 Binary files /dev/null and b/training/cpp/drivers/pf8574/pf8574lcd.o differ diff --git a/training/cpp/interfacer.cpp b/training/cpp/interfacer.cpp new file mode 100644 index 0000000..b3ca31c --- /dev/null +++ b/training/cpp/interfacer.cpp @@ -0,0 +1,62 @@ +/* + * Authors : Kerem Yollu & Edwin Koch + * Date : 07.03.2021 + * + * Description : + * TODO : Write description or doxygene + * + */ + +#include +#include +#include +#include "./management/errorHandling.h" +#include "./management/commandManager.h" +#include "./drivers/bh1750/bh1750.h" +#include "./drivers/pf8574/pf8574lcd.h" + +unsigned int miliSecond = 1000; + + +ErrorHandler errorHandle; +CommandManager commander; +i2c_ch1_pImpL i2c(1); + +Bh1750 lightSens(&i2c); + + + +int initPlatform() +{ + char* Msg = "hello"; + lcd_init(&i2c); + lcd_display_string(1,1,Msg); + // Dev. Module initialisation "Ex i2c_init() ...." + return 0; +} + +void dummy() +{ + while(1) + { + std::cout << "value "<< lightSens.continious(BH1750_CONTINUOUS_HIGH_RES_MODE_1,1) << " Lux" <= MAX_MUNBER_OF_COMMANDS) // Check if the command list is full + { + std::cout << "Error | Intern | Command list is full!" << std::endl; + exit(1); + } + if(getLookUpIndex(commmand) >= 0) // Chek for command duplicats + { + std::cout << "Error | Intern | Command already exitst!" << std::endl; + exit(1); + } + + + commandLookup[emptyIndex].commmand = commmand; + commandLookup[emptyIndex].description = description; + commandLookup[emptyIndex].callBack = callBack; + emptyIndex++; +} + +void CommandManager::operator()(const std::string cmdName) +{ + int index = 0; + + if(cmdName == "help" || cmdName == "Help") + { + printHelp(); + exit(1); + } + + if(cmdName == "-h" || cmdName == "-H") + { + printCommads(); + exit(1); + } + + index = getLookUpIndex(cmdName); + + if(index < 0) + { + std::cout << "Error | Intern | Invalid Command!" << std::endl; + exit(1); + } + + commandLookup[index].callBack(); + exit(1); +} + + +// +// Privat memeber functions +// + + +int CommandManager::getLookUpIndex(const std::string& cmd) +{ + int index = 0; + for (index = 0; index < emptyIndex; index++) + { + if(commandLookup[index].commmand == cmd) + { + return index; + } + } + return -1; +} + +void CommandManager::printHelp() +{ + std::cout << "Function : printHelp is under construction" << std::endl; +} + +void CommandManager::printCommads() +{ + std::cout << "Function : printCommads is under construction" << std::endl; +} + diff --git a/training/cpp/management/commandManager.h b/training/cpp/management/commandManager.h new file mode 100644 index 0000000..5d7eff2 --- /dev/null +++ b/training/cpp/management/commandManager.h @@ -0,0 +1,53 @@ +/* + * Authors : Kerem Yollu & Edwin Koch + * Date : 07.03.2021 + * + * Description : + * TODO : Inplement singleton pattern + * TODO : Write description + * TODO : Comment the code wiht odxygen + * + */ + + +#ifndef _COMMMANDMANAGER_H_ +#define _COMMMANDMANAGER_H_ + +#include +#include +#include +#include + +#define MAX_MUNBER_OF_COMMANDS 4 + +class CommandManager +{ + public: + typedef std::function commanCallback_t; + CommandManager(); + void addNewCommand( const std::string& commmand, + const std::string& description, + commanCallback_t callBack); + + void operator()(const std::string cmdName); + + + private: + unsigned int emptyIndex; + + struct commant_t{ + std::string commmand; + std::string description; + commanCallback_t callBack; // The Callback function could only be a void returning a void. + }; + + std::array commandLookup; + int getLookUpIndex(const std::string& cmd); // If command exists retunrs the index otherwise -1 + void printHelp(); // Prints all awailbale commands and their description. + void printCommads(); // Prints all awailable commnads without description. +}; + + + + +#endif // _COMMMANDMANAGER_H_ diff --git a/training/cpp/management/commandManager.o b/training/cpp/management/commandManager.o new file mode 100644 index 0000000..c9eefcf Binary files /dev/null and b/training/cpp/management/commandManager.o differ diff --git a/training/cpp/management/errorHandling.cpp b/training/cpp/management/errorHandling.cpp new file mode 100644 index 0000000..9e30a38 --- /dev/null +++ b/training/cpp/management/errorHandling.cpp @@ -0,0 +1,58 @@ +#include "errorHandling.h" + +ErrorHandler::ErrorHandler(): emptyIndex(0) +{ +} + + +void ErrorHandler::handleError(int errNo) +{ + int index = 0; + + index = getLookUpIndex(errNo); + + if(index < 0) + { + std::cout << "The given error number does not exist\n" << "Tipp: use \"addNewError(Integer, String)\""<< std::endl; + exit(1); + } + + std::cout << "Error | " << errNo << " | \"" << errorLookup[index].errMessage << "\""<= MAX_NUMBER_OF_ERRORS) // Check if list is full + { + std::cout << "Error | Ultimate | List is full" << std::endl; + exit(1); + } + + if(getLookUpIndex(no) >= 0) // Check if Error No already exists + { + std::cout << "Error | Intern | Error No: "<< no << " Exists ! PLease choose a different number !" << std::endl; + exit(1); + } + + errorLookup[emptyIndex].errNo = no; + errorLookup[emptyIndex].errMessage = message; + emptyIndex++; +} + +// +// Privat memeber functions +// + +int ErrorHandler::getLookUpIndex(int errNo) +{ + int i = 0; + for(i = 0; i < emptyIndex; i++) + { + if(errNo == errorLookup[i].errNo) + { + return i; + } + } + return -1; +} diff --git a/training/cpp/management/errorHandling.h b/training/cpp/management/errorHandling.h new file mode 100644 index 0000000..b9dbe92 --- /dev/null +++ b/training/cpp/management/errorHandling.h @@ -0,0 +1,41 @@ +/* + * Authors : Kerem Yollu & Edwin Koch + * Date : 07.03.2021 + * + * Description : + * TODO : Inplement singleton pattern + * TODO : Write description + * TODO : Comment the code wiht odxygen + * + */ + + +#ifndef _ERRORHANDLIG_H_ +#define _ERRORHANDLIG_H_ + +#include +#include +#include + +#define MAX_NUMBER_OF_ERRORS 255 + + +class ErrorHandler +{ + public: + ErrorHandler(); + void addNewError(const int& no, const std::string& message); + void handleError(int no); + private: + + struct error_t { //Struture of error entry for the errorLookup table + int errNo; + std::string errMessage; + }; + + unsigned int emptyIndex; // Indicates the next empty slot in the errorLookup table. + std::array errorLookup; // Where the errors go. + int getLookUpIndex(int errNo); // If error number exists returns the index otherwise -1 +}; + +#endif // _ERRORHANDLIG_H_ diff --git a/training/cpp/management/errorHandling.o b/training/cpp/management/errorHandling.o new file mode 100644 index 0000000..5826368 Binary files /dev/null and b/training/cpp/management/errorHandling.o differ diff --git a/training/cpp/periferals/i2c/i2c.hpp b/training/cpp/periferals/i2c/i2c.hpp new file mode 100644 index 0000000..be49920 --- /dev/null +++ b/training/cpp/periferals/i2c/i2c.hpp @@ -0,0 +1,96 @@ +#ifndef _I2C_H_ +#define _I2C_H_ + +namespace serial +{ + enum i2c_id + { + i2c_ch0, + i2c_ch1 + }; + + // + // Base template class + // + + template + class I2C + { + public: + I2C(const uint8_t& mode); // Mode : Master or Slave + uint8_t readByte(const uint8_t& address, const uint8_t& reg); + uint16_t readWord(const uint8_t& address, const uint8_t& reg); + uint8_t writeByte(const uint8_t& address, const uint8_t& data); + uint8_t writeWord(const uint8_t& address, const uint8_t& reg, const uint16_t& data); + + private: + }; + + // + // Template for channel 0 + // + template<> + class I2C + { + public: + I2C(const uint8_t& mode):pImpL(mode) + { + } + uint8_t readByte(const uint8_t& address, const uint8_t& reg) + { + return pImpL -> readByte(address, reg); + } + uint16_t readWord(const uint8_t& address, const uint8_t& reg) + { + return pImpL -> readWord(address,reg); + } + uint8_t writeByte(const uint8_t& address, const uint8_t& data) + { + return pImpL -> writeByte(address, data); + } + uint8_t writeWord(const uint8_t& address, const uint8_t& reg, const uint16_t& data) + { + return pImpL -> writeWord(address, reg, data); + } + + private: + class i2c_ch0_pImpL; + std::unique_ptr pImpL; + }; + + // + // Template for channel 1 + // + template<> + class I2C + { + public: + I2C(const uint8_t& mode):pImpL(mode) + { + } + uint8_t readByte(const uint8_t& address, const uint8_t& reg) + { + return pImpL -> readByte(address, reg); + } + uint16_t readWord(const uint8_t& address, const uint8_t& reg) + { + return pImpL -> readWord(address,reg); + } + uint8_t writeByte(const uint8_t& address, const uint8_t& data) + { + return pImpL -> writeByte(address, data); + } + uint8_t writeWord(const uint8_t& address, const uint8_t& reg, const uint16_t& data) + { + return pImpL -> writeWord(address, reg, data); + } + + private: + class i2c_ch1_pImpL; + std::unique_ptr pImpL; + }; + +}// Namespace serial + + +#endif // _I2C_H_ diff --git a/training/cpp/periferals/i2c/i2c_ch0_pImpL.cpp b/training/cpp/periferals/i2c/i2c_ch0_pImpL.cpp new file mode 100644 index 0000000..6201bc8 --- /dev/null +++ b/training/cpp/periferals/i2c/i2c_ch0_pImpL.cpp @@ -0,0 +1,106 @@ +#include "i2c_ch0_pImpL.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PORT_I2C "/dev/i2c-1" + +// some curious things https://www.john.geek.nz/2012/12/update-reading-data-from-a-bosch-bmp085-with-a-raspberry-pi/ + + +i2c_ch0_pImpL::i2c_ch0_pImpL(const uint8_t& mode) +{ + char filename[20]; + snprintf(filename, 19, "/dev/i2c-%d", 0); + + deviceDescriptor = open(filename, O_RDWR); + if (deviceDescriptor < 0) { + std::cout << "unable to open : "<< deviceDescriptor << " ! quiting" << std::endl; + exit(1); + } +} + +uint8_t i2c_ch0_pImpL::writeByte(const uint8_t& address, const uint8_t& data) // retuns 0 when a sucsessful transation ocures +{ + if (ioctl(deviceDescriptor, I2C_SLAVE, address) < 0) + { + std::cout << "Unable to reach device : "<< address << " ! quiting" << std::endl; + exit(1); + } + + send_buffer[0] = data; + + if ((write(deviceDescriptor, send_buffer, 1)) != 1) + { + std::cout << "Unable to write quiting" << std::endl; + exit(0); + } + return 0; +} + +uint8_t i2c_ch0_pImpL::readByte(const uint8_t& address, const uint8_t& reg) +{ + if (ioctl(deviceDescriptor, I2C_SLAVE, address) < 0) + { + std::cout << "Unable to reach device : "<< address << " ! quiting" << std::endl; + exit(1); + } + + writeByte(address,reg); //Initiate a write to indicate the desired register to read + + if (read(deviceDescriptor, recieve_buffer, 1) != 1) // An then initare a read request of 1 byte + { + std::cout << "Unable to read quiting" << std::endl; + exit(1); + } + return recieve_buffer[0] ; +} + + +uint8_t i2c_ch0_pImpL::writeWord(const uint8_t& address, const uint8_t& reg, const uint16_t& data) // retuns 0 when a sucsessful transation ocures +{ + + if (ioctl(deviceDescriptor, I2C_SLAVE, address) < 0) + { + std::cout << "Unable to reach device : "<< address << " ! quiting" << std::endl; + exit(1); + } + + send_buffer[0] = reg; + send_buffer[1] = data; + + if ((write(deviceDescriptor, send_buffer, 2)) != 2) + { + std::cout << "Unable to write quiting" << std::endl; + exit(0); + } + return 0; +} + +uint16_t i2c_ch0_pImpL::readWord(const uint8_t& address, const uint8_t& reg) +{ + uint16_t result = 0 ; + if (ioctl(deviceDescriptor, I2C_SLAVE, address) < 0) + { + std::cout << "Unable to reach device : "<< address << " ! quiting" << std::endl; + exit(1); + } + + writeByte(address,reg); //Initiate a write to indicate the desired register to read + + if (read(deviceDescriptor, recieve_buffer, 2) != 2) // An then initare a read request of 2 bytes + { + std::cout << "Unable to read quiting" << std::endl; + exit(1); + } + result = (recieve_buffer[0] << 8) + recieve_buffer[1] ; + return result ; +} diff --git a/training/cpp/periferals/i2c/i2c_ch0_pImpL.h b/training/cpp/periferals/i2c/i2c_ch0_pImpL.h new file mode 100644 index 0000000..51fa22a --- /dev/null +++ b/training/cpp/periferals/i2c/i2c_ch0_pImpL.h @@ -0,0 +1,32 @@ +#ifndef _I2C_CH0_PIMPL_H_ +#define _I2C_CH0_PIMPL_H_ + +#include +#include +#include +#include "../../management/errorHandling.h" +#include "../../systems/systemCall.h" + +class i2c_ch0_pImpL +{ + public: + i2c_ch0_pImpL(const uint8_t& mode); // Mode : Master or Slave + uint8_t readByte(const uint8_t& address, const uint8_t& reg); + uint16_t readWord(const uint8_t& address, const uint8_t& reg); + uint8_t writeByte(const uint8_t& address, const uint8_t& data); + uint8_t writeWord(const uint8_t& address, const uint8_t& reg, const uint16_t& data); + + + private: + int16_t deviceDescriptor; + uint8_t device_address; + uint8_t device_reg; + uint8_t send_buffer[32]; + uint8_t recieve_buffer[32]; + uint8_t blocks; + uint8_t channel; + uint8_t mode; +}; + + +#endif // _I2C_CH0_PIMPL_H_ diff --git a/training/cpp/periferals/i2c/i2c_ch0_pImpL.o b/training/cpp/periferals/i2c/i2c_ch0_pImpL.o new file mode 100644 index 0000000..b47e8ec Binary files /dev/null and b/training/cpp/periferals/i2c/i2c_ch0_pImpL.o differ diff --git a/training/cpp/periferals/i2c/i2c_ch1_pImpL.cpp b/training/cpp/periferals/i2c/i2c_ch1_pImpL.cpp new file mode 100644 index 0000000..7818b65 --- /dev/null +++ b/training/cpp/periferals/i2c/i2c_ch1_pImpL.cpp @@ -0,0 +1,106 @@ +#include "i2c_ch1_pImpL.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PORT_I2C "/dev/i2c-1" + +// some curious things https://www.john.geek.nz/2012/12/update-reading-data-from-a-bosch-bmp085-with-a-raspberry-pi/ + + +i2c_ch1_pImpL::i2c_ch1_pImpL(const uint8_t& mode) +{ + char filename[20]; + snprintf(filename, 19, "/dev/i2c-%d", 1); + + deviceDescriptor = open(filename, O_RDWR); + if (deviceDescriptor < 0) { + std::cout << "unable to open : "<< deviceDescriptor << " ! quiting" << std::endl; + exit(1); + } +} + +uint8_t i2c_ch1_pImpL::writeByte(const uint8_t& address, const uint8_t& data) // retuns 0 when a sucsessful transation ocures +{ + if (ioctl(deviceDescriptor, I2C_SLAVE, address) < 0) + { + std::cout << "Unable to reach device : "<< address << " ! quiting" << std::endl; + exit(1); + } + + send_buffer[0] = data; + + if ((write(deviceDescriptor, send_buffer, 1)) != 1) + { + std::cout << "Unable to write quiting" << std::endl; + exit(0); + } + return 0; +} + +uint8_t i2c_ch1_pImpL::readByte(const uint8_t& address, const uint8_t& reg) +{ + if (ioctl(deviceDescriptor, I2C_SLAVE, address) < 0) + { + std::cout << "Unable to reach device : "<< address << " ! quiting" << std::endl; + exit(1); + } + + writeByte(address,reg); //Initiate a write to indicate the desired register to read + + if (read(deviceDescriptor, recieve_buffer, 1) != 1) // An then initare a read request of 1 byte + { + std::cout << "Unable to read quiting" << std::endl; + exit(1); + } + return recieve_buffer[0] ; +} + + +uint8_t i2c_ch1_pImpL::writeWord(const uint8_t& address, const uint8_t& reg, const uint16_t& data) // retuns 0 when a sucsessful transation ocures +{ + + if (ioctl(deviceDescriptor, I2C_SLAVE, address) < 0) + { + std::cout << "Unable to reach device : "<< address << " ! quiting" << std::endl; + exit(1); + } + + send_buffer[0] = reg; + send_buffer[1] = data; + + if ((write(deviceDescriptor, send_buffer, 2)) != 2) + { + std::cout << "Unable to write quiting" << std::endl; + exit(0); + } + return 0; +} + +uint16_t i2c_ch1_pImpL::readWord(const uint8_t& address, const uint8_t& reg) +{ + uint16_t result = 0 ; + if (ioctl(deviceDescriptor, I2C_SLAVE, address) < 0) + { + std::cout << "Unable to reach device : "<< address << " ! quiting" << std::endl; + exit(1); + } + + writeByte(address,reg); //Initiate a write to indicate the desired register to read + + if (read(deviceDescriptor, recieve_buffer, 2) != 2) // An then initare a read request of 2 bytes + { + std::cout << "Unable to read quiting" << std::endl; + exit(1); + } + result = (recieve_buffer[0] << 8) + recieve_buffer[1] ; + return result ; +} diff --git a/training/cpp/periferals/i2c/i2c_ch1_pImpL.hpp b/training/cpp/periferals/i2c/i2c_ch1_pImpL.hpp new file mode 100644 index 0000000..d53d85f --- /dev/null +++ b/training/cpp/periferals/i2c/i2c_ch1_pImpL.hpp @@ -0,0 +1,32 @@ +#ifndef _I2C_CH1_PIMPL_H_ +#define _I2C_CH1_PIMPL_H_ + +#include +#include +#include +#include "../../systems/systemCall.h" +#include "../../management/errorHandling.h" + +class i2c_ch1_pImpL +{ + public: + i2c_ch1_pImpL(const uint8_t& mode); // Mode : Master or Slave + uint8_t readByte(const uint8_t& address, const uint8_t& reg); + uint16_t readWord(const uint8_t& address, const uint8_t& reg); + uint8_t writeByte(const uint8_t& address, const uint8_t& data); + uint8_t writeWord(const uint8_t& address, const uint8_t& reg, const uint16_t& data); + + + private: + int16_t deviceDescriptor; + uint8_t device_address; + uint8_t device_reg; + uint8_t send_buffer[32]; + uint8_t recieve_buffer[32]; + uint8_t blocks; + uint8_t channel; + uint8_t mode; +}; + + +#endif // _I2C_CH1_PIMPL_H_ diff --git a/training/cpp/periferals/i2c/i2c_ch1_pImpL.o b/training/cpp/periferals/i2c/i2c_ch1_pImpL.o new file mode 100644 index 0000000..8402b60 Binary files /dev/null and b/training/cpp/periferals/i2c/i2c_ch1_pImpL.o differ diff --git a/training/cpp/periferals/i2c/i2c_driver.cpp b/training/cpp/periferals/i2c/i2c_driver.cpp new file mode 100644 index 0000000..d0a2ea3 --- /dev/null +++ b/training/cpp/periferals/i2c/i2c_driver.cpp @@ -0,0 +1,106 @@ +#include "i2c_driver.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PORT_I2C "/dev/i2c-1" + +// some curious things https://www.john.geek.nz/2012/12/update-reading-data-from-a-bosch-bmp085-with-a-raspberry-pi/ + + +I2C_Driver::I2C_Driver(const uint8_t& channel, const uint8_t& mode) +{ + char filename[20]; + snprintf(filename, 19, "/dev/i2c-%d", channel); + + deviceDescriptor = open(filename, O_RDWR); + if (deviceDescriptor < 0) { + std::cout << "unable to open : "<< deviceDescriptor << " ! quiting" << std::endl; + exit(1); + } +} + +uint8_t I2C_Driver::writeByte(const uint8_t& address, const uint8_t& data) // retuns 0 when a sucsessful transation ocures +{ + if (ioctl(deviceDescriptor, I2C_SLAVE, address) < 0) + { + std::cout << "Unable to reach device : "<< address << " ! quiting" << std::endl; + exit(1); + } + + send_buffer[0] = data; + + if ((write(deviceDescriptor, send_buffer, 1)) != 1) + { + std::cout << "Unable to write quiting" << std::endl; + exit(0); + } + return 0; +} + +uint8_t I2C_Driver::readByte(const uint8_t& address, const uint8_t& reg) +{ + if (ioctl(deviceDescriptor, I2C_SLAVE, address) < 0) + { + std::cout << "Unable to reach device : "<< address << " ! quiting" << std::endl; + exit(1); + } + + writeByte(address,reg); //Initiate a write to indicate the desired register to read + + if (read(deviceDescriptor, recieve_buffer, 1) != 1) // An then initare a read request of 1 byte + { + std::cout << "Unable to read quiting" << std::endl; + exit(1); + } + return recieve_buffer[0] ; +} + + +uint8_t I2C_Driver::writeWord(const uint8_t& address, const uint8_t& reg, const uint16_t& data) // retuns 0 when a sucsessful transation ocures +{ + + if (ioctl(deviceDescriptor, I2C_SLAVE, address) < 0) + { + std::cout << "Unable to reach device : "<< address << " ! quiting" << std::endl; + exit(1); + } + + send_buffer[0] = reg; + send_buffer[1] = data; + + if ((write(deviceDescriptor, send_buffer, 2)) != 2) + { + std::cout << "Unable to write quiting" << std::endl; + exit(0); + } + return 0; +} + +uint16_t I2C_Driver::readWord(const uint8_t& address, const uint8_t& reg) +{ + uint16_t result = 0 ; + if (ioctl(deviceDescriptor, I2C_SLAVE, address) < 0) + { + std::cout << "Unable to reach device : "<< address << " ! quiting" << std::endl; + exit(1); + } + + writeByte(address,reg); //Initiate a write to indicate the desired register to read + + if (read(deviceDescriptor, recieve_buffer, 2) != 2) // An then initare a read request of 2 bytes + { + std::cout << "Unable to read quiting" << std::endl; + exit(1); + } + result = (recieve_buffer[0] << 8) + recieve_buffer[1] ; + return result ; +} diff --git a/training/cpp/periferals/i2c/i2c_driver.h b/training/cpp/periferals/i2c/i2c_driver.h new file mode 100644 index 0000000..dd69c05 --- /dev/null +++ b/training/cpp/periferals/i2c/i2c_driver.h @@ -0,0 +1,28 @@ +#include +#include +#include +#include "../../management/errorHandling.h" +#include "../../systems/systemCall.h" + +class I2C_Driver +{ + public: + I2C_Driver(const uint8_t& channel, const uint8_t& mode); + uint8_t readByte(const uint8_t& address, const uint8_t& reg); + uint16_t readWord(const uint8_t& address, const uint8_t& reg); + uint8_t writeByte(const uint8_t& address, const uint8_t& data); + uint8_t writeWord(const uint8_t& address, const uint8_t& reg, const uint16_t& data); + + + private: + int16_t deviceDescriptor; + uint8_t device_address; + uint8_t device_reg; + uint8_t send_buffer[32]; + uint8_t recieve_buffer[32]; + uint8_t blocks; + uint8_t channel; + uint8_t mode; +}; + + diff --git a/training/cpp/periferals/i2c/i2c_driver.o b/training/cpp/periferals/i2c/i2c_driver.o new file mode 100644 index 0000000..57c9c26 Binary files /dev/null and b/training/cpp/periferals/i2c/i2c_driver.o differ diff --git a/training/cpp/runtest b/training/cpp/runtest new file mode 100755 index 0000000..3eb7820 Binary files /dev/null and b/training/cpp/runtest differ diff --git a/training/cpp/systems/systemCall.cpp b/training/cpp/systems/systemCall.cpp new file mode 100644 index 0000000..d703676 --- /dev/null +++ b/training/cpp/systems/systemCall.cpp @@ -0,0 +1,15 @@ +#include "systemCall.h" + + +std::string execBash(const char* cmd) { + std::array buffer; + std::string result; + std::unique_ptr pipe(popen(cmd, "r"), pclose); + if (!pipe) { + throw std::runtime_error("popen() failed!"); + } + while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { + result += buffer.data(); + } + return result; +} diff --git a/training/cpp/systems/systemCall.h b/training/cpp/systems/systemCall.h new file mode 100644 index 0000000..ffe2e16 --- /dev/null +++ b/training/cpp/systems/systemCall.h @@ -0,0 +1,14 @@ +#ifndef _SYSTEMCALL_H_ +#define _SYSTEMCALL_H_ + +#include +#include +#include +#include +#include +#include + +// Ide from : https://stackoverflow.com/questions/478898/how-do-i-execute-a-command-and-get-the-output-of-the-command-within-c-using-po +std::string execBash(const char* cmd); + +#endif // _SYSTEMCALL_H_ diff --git a/training/cpp/systems/systemCall.o b/training/cpp/systems/systemCall.o new file mode 100644 index 0000000..f7b9606 Binary files /dev/null and b/training/cpp/systems/systemCall.o differ