Commit 53ba2148 authored by Maxime Robin's avatar Maxime Robin

Sauvegarde de sûreté 16.05 09/03/2017 (compile pas)

parent 5146e006
/*
* See header file for details
*
* This program is free software: you can redistribute it and/or modify\n
* it under the terms of the GNU General Public License as published by\n
* the Free Software Foundation, either version 3 of the License, or\n
* (at your option) any later version.\n
*
* This program is distributed in the hope that it will be useful,\n
* but WITHOUT ANY WARRANTY; without even the implied warranty of\n
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n
* GNU General Public License for more details.\n
*
* You should have received a copy of the GNU General Public License\n
* along with this program. If not, see <http://www.gnu.org/licenses/>.\n
*/
/* Dependencies */
#include <Wire.h>
#include "PCF8574.h"
PCF8574::PCF8574() :
_PORT(0), _PIN(0), _DDR(0), _address(0)
#ifdef PCF8574_INTERRUPT_SUPPORT
, _oldPIN(0), _isrIgnore(0), _pcintPin(0), _intMode(), _intCallback()
#endif
{
}
void PCF8574::begin(uint8_t address) {
/* Store the I2C address and init the Wire library */
_address = address;
Wire.begin();
readGPIO();
}
void PCF8574::pinMode(uint8_t pin, uint8_t mode) {
/* Switch according mode */
switch (mode) {
case INPUT:
_DDR &= ~(1 << pin);
_PORT &= ~(1 << pin);
break;
case INPUT_PULLUP:
_DDR &= ~(1 << pin);
_PORT |= (1 << pin);
break;
case OUTPUT:
_DDR |= (1 << pin);
_PORT &= ~(1 << pin);
break;
default:
break;
}
/* Update GPIO values */
updateGPIO();
}
void PCF8574::digitalWrite(uint8_t pin, uint8_t value) {
/* Set PORT bit value */
if (value)
_PORT |= (1 << pin);
else
_PORT &= ~(1 << pin);
/* Update GPIO values */
updateGPIO();
}
uint8_t PCF8574::digitalRead(uint8_t pin) {
/* Read GPIO */
readGPIO();
#ifdef PCF8574_INTERRUPT_SUPPORT
/* Check for interrupt (manual detection) */
//checkForInterrupt();
#endif
/* Read and return the pin state */
return (_PIN & (1 << pin)) ? HIGH : LOW;
}
void PCF8574::write(uint8_t value) {
/* Store pins values and apply */
_PORT = value;
/* Update GPIO values */
updateGPIO();
}
uint8_t PCF8574::read() {
/* Read GPIO */
readGPIO();
#ifdef PCF8574_INTERRUPT_SUPPORT
/* Check for interrupt (manual detection) */
//checkForInterrupt();
#endif
/* Return current pins values */
return _PIN;
}
void PCF8574::pullUp(uint8_t pin) {
/* Same as pinMode(INPUT_PULLUP) */
pinMode(pin, INPUT_PULLUP); // /!\ pinMode form THE LIBRARY
}
void PCF8574::pullDown(uint8_t pin) {
/* Same as pinMode(INPUT) */
pinMode(pin, INPUT); // /!\ pinMode form THE LIBRARY
}
void PCF8574::clear() {
/* User friendly wrapper for write() */
write(0x00);
}
void PCF8574::set() {
/* User friendly wrapper for write() */
write(0xFF);
}
void PCF8574::toggle(uint8_t pin) {
/* Toggle pin state */
_PORT ^= (1 << pin);
/* Update GPIO values */
updateGPIO();
}
void PCF8574::blink(uint8_t pin, uint16_t count, uint32_t duration) {
/* Compute steps duration */
duration /= count * 2;
/* Loop n times */
while (count--) {
/* Toggle pin 2 times */
toggle(pin);
delay(duration);
toggle(pin);
delay(duration);
}
}
#ifdef PCF8574_INTERRUPT_SUPPORT
void PCF8574::enableInterrupt(uint8_t pin, void (*selfCheckFunction)(void)) {
/* Store interrupt pin number */
_pcintPin = pin;
/* Setup interrupt pin */
#if ARDUINO >= 100
::pinMode(pin, INPUT_PULLUP); // /!\ pinMode form THE ARDUINO CORE
#else
::pinMode(pin, INPUT); // /!\ pinMode form THE ARDUINO CORE
::digitalWrite(pin, HIGH); // /!\ digitalWrite form THE ARDUINO CORE
#endif
/* Attach interrupt handler */
PCattachInterrupt(pin, selfCheckFunction, FALLING);
}
void PCF8574::disableInterrupt() {
/* Detach interrupt handler */
PCdetachInterrupt(_pcintPin);
}
void PCF8574::checkForInterrupt() {
/* Avoid nested interrupt triggered by I2C read/write */
if(_isrIgnore)
return;
else
_isrIgnore = 1;
/* Re-enable interrupts to allow Wire library to work */
sei();
/* Read current pins values */
readGPIO();
/* Check all pins */
for (uint8_t i = 0; i < 8; ++i) {
/* Check for interrupt handler */
if (!_intCallback[i])
continue;
/* Check for interrupt event */
switch (_intMode[i]) {
case CHANGE:
if ((1 << i) & (_PIN ^ _oldPIN))
_intCallback[i]();
break;
case LOW:
if (!(_PIN & (1 << i)))
_intCallback[i]();
break;
case FALLING:
if ((_oldPIN & (1 << i)) && !(_PIN & (1 << i)))
_intCallback[i]();
break;
case RISING:
if (!(_oldPIN & (1 << i)) && (_PIN & (1 << i)))
_intCallback[i]();
break;
}
}
/* Turn off ISR ignore flag */
_isrIgnore = 0;
}
void PCF8574::attachInterrupt(uint8_t pin, void (*userFunc)(void),
uint8_t mode) {
/* Store interrupt mode and callback */
_intMode[pin] = mode;
_intCallback[pin] = userFunc;
}
void PCF8574::detachInterrupt(uint8_t pin) {
/* Void interrupt handler */
_intCallback[pin] = 0;
}
#endif
void PCF8574::readGPIO() {
#ifdef PCF8574_INTERRUPT_SUPPORT
/* Store old _PIN value */
_oldPIN = _PIN;
#endif
/* Start request, wait for data and receive GPIO values as byte */
Wire.requestFrom(_address, (uint8_t) 0x01);
while (Wire.available() < 1)
;
_PIN = I2CREAD();
}
void PCF8574::updateGPIO() {
/* Read current GPIO states */
//readGPIO(); // Experimental
/* Compute new GPIO states */
//uint8_t value = ((_PIN & ~_DDR) & ~(~_DDR & _PORT)) | _PORT; // Experimental
uint8_t value = (_PIN & ~_DDR) | _PORT;
/* Start communication and send GPIO values as byte */
Wire.beginTransmission(_address);
I2CWRITE(value);
Wire.endTransmission();
}
/**
* @brief PCF8574 arduino library
* @author SkyWodd <skywodd@gmail.com>
* @version 2.0
* @link http://skyduino.wordpress.com/
*
* @section intro_sec Introduction
* This class is designed to allow user to use PCF8574 gpio expander like any standard arduino pins.\n
* This class provided standards arduino functions like pinMode, digitalWrite, digitalRead, ...\n
* This new version is fully optimized and documented.\n
* \n
* Please report bug to <skywodd at gmail.com>
*
* @section license_sec License
* This program is free software: you can redistribute it and/or modify\n
* it under the terms of the GNU General Public License as published by\n
* the Free Software Foundation, either version 3 of the License, or\n
* (at your option) any later version.\n
* \n
* This program is distributed in the hope that it will be useful,\n
* but WITHOUT ANY WARRANTY; without even the implied warranty of\n
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n
* GNU General Public License for more details.\n
* \n
* You should have received a copy of the GNU General Public License\n
* along with this program. If not, see <http://www.gnu.org/licenses/>.\n
*
* @section other_sec Others notes and compatibility warning
* Compatible with arduino 1.0.x and >=0023\n
* Retro-compatible with the previous library version
*/
#ifndef PCF8574_H
#define PCF8574_H
/** Comment this define to disable interrupt support */
//#ifndef PCF8574_INTERRUPT_SUPPORT
//#define PCF8574_INTERRUPT_SUPPORT
//#include "PCint.h"
//#include "pins_arduino.h"
//#endif
/* Retro-compatibility with arduino 0023 and previous version */
#if ARDUINO >= 100
#include "Arduino.h"
#define I2CWRITE(x) Wire.write(x)
#define I2CREAD() Wire.read()
#else
#include "WProgram.h"
#define I2CWRITE(x) Wire.send(x)
#define I2CREAD() Wire.receive()
#define INPUT_PULLUP 2
#endif
/**
* @brief PCF8574 Arduino class
*/
class PCF8574 {
public:
/**
* Create a new PCF8574 instance
*/
PCF8574();
/**
* Start the I2C controller and store the PCF8574 chip address
*/
void begin(uint8_t address = 0x21);
/**
* Set the direction of a pin (OUTPUT, INPUT or INPUT_PULLUP)
*
* @param pin The pin to set
* @param mode The new mode of the pin
* @remarks INPUT_PULLUP does physicaly the same thing as INPUT (no software pull-up resistors available) but is REQUIRED if you use external pull-up resistor
*/
void pinMode(uint8_t pin, uint8_t mode);
/**
* Set the state of a pin (HIGH or LOW)
*
* @param pin The pin to set
* @param value The new state of the pin
* @remarks Software pull-up resistors are not available on the PCF8574
*/
void digitalWrite(uint8_t pin, uint8_t value);
/**
* Read the state of a pin
*
* @param pin The pin to read back
* @return
*/
uint8_t digitalRead(uint8_t pin);
/**
* Set the state of all pins in one go
*
* @param value The new value of all pins (1 bit = 1 pin, '1' = HIGH, '0' = LOW)
*/
void write(uint8_t value);
/**
* Read the state of all pins in one go
*
* @return The current value of all pins (1 bit = 1 pin, '1' = HIGH, '0' = LOW)
*/
uint8_t read();
/**
* Exactly like write(0x00), set all pins to LOW
*/
void clear();
/**
* Exactly like write(0xFF), set all pins to HIGH
*/
void set();
/**
* Toggle the state of a pin
*/
void toggle(uint8_t pin);
/**
* Mark a pin as "pulled up"
*
* @warning DO NOTHING - FOR RETRO COMPATIBILITY PURPOSE ONLY
* @deprecated
* @param pin Pin the mark as "pulled up"
*/
void pullUp(uint8_t pin);
/**
* Mark a pin as "pulled down"
*
* @warning DO NOTHING - FOR RETRO COMPATIBILITY PURPOSE ONLY
* @deprecated
* @param pin Pin the mark as "pulled down"
*/
void pullDown(uint8_t pin);
/**
* Make a pin blink N times for T duration
*
* @warning Blocking function, not recommended for new code
* @deprecated
* @param pin The pin to blink
* @param count The number of ON/OFF couples to execute
* @param duration The duration of the whole blink action in milliseconds
*/
void blink(uint8_t pin, uint16_t count, uint32_t duration);
#ifdef PCF8574_INTERRUPT_SUPPORT
/**
* Enable interrupts support and setup interrupts handler
*
* @remarks Any pin can be used as "INT" pin, internally the library use PCINT to work.
* @warning The check wrapping routine must be provided by user and define in the global scope space.
* @param pin The pin OF YOUR ARDUINO (not the PCF8574) to use as "INT" pin for interrupts detection
* @param selfCheckFunction The wrapping routine used to process interrupts events.
* @remarks For best performances you should avoid this "user friendly" fonction and use the standard attachInterrupt() fonction ;)
* @remarks If multiple PCF8574 are wired on the same "INT" pin this function should be called only one time
*/
void enableInterrupt(uint8_t pin, void (*selfCheckFunction)(void));
/**
* Disable interrupts support
*/
void disableInterrupt();
/**
* Check for interrupt and process routine
*
* @remarks Call this routine from your wrapping routine to detect and process interrupts (if any) of this PCF8574 instance.
*/
void checkForInterrupt();
/**
* Attach a function to an interrupt event of a pin of the PCF8574
*
* @param pin The pin to attach the interrupt event on
* @param userFunc The callback function to call when the interrupt event is triggered
* @param mode The interrupt mode to check for, only interrupts events coming from the specified pin and with the specified mode will call the callback function.
* @remarks 1 PCF8574 pin = 1 interrupt, multiple interrupts on the same pin is not supported
*/
void attachInterrupt(uint8_t pin, void (*userFunc)(void), uint8_t mode);
/**
* Detach any interrupt attached to the specified pin
*
* @param pin The pin to detach any interrupt from
*/
void detachInterrupt(uint8_t pin);
#endif
protected:
/** Output pins values */
volatile uint8_t _PORT;
/** Current input pins values */
volatile uint8_t _PIN;
/** Pins modes values (OUTPUT or INPUT) */
volatile uint8_t _DDR;
/** PCF8574 I2C address */
uint8_t _address;
#ifdef PCF8574_INTERRUPT_SUPPORT
/** Old value of _PIN variable */
volatile uint8_t _oldPIN;
/** ISR ignore flag */
volatile uint8_t _isrIgnore;
/** PCINT pin used for "INT" pin handling */
uint8_t _pcintPin;
/** Interrupts modes of pins ( LOW, CHANGE, FALLING, RISING) */
uint8_t _intMode[8];
/** Interrupts callback functions */
void (*_intCallback[8])(void);
#endif
/**
* Read GPIO states and store them in _PIN variable
*
* @remarks Before reading current GPIO states, current _PIN variable value is moved to _oldPIN variable
*/
void readGPIO();
/**
* Write value of _PORT variable to the GPIO
*
* @remarks Only pin marked as OUTPUT are set, for INPUT pins their value are unchanged
* @warning To work properly (and avoid any states conflicts) readGPIO() MUST be called before call this function !
*/
void updateGPIO();
};
#endif
/* Ici sont définis les paramètres et adresses du registre
des paramètres d'acquisition du testeur
On définira une adresse et une place prise en commentaire à coté
*/
#include "Registre.h"
const int selectResolution[4] = {12,14,16,18};
const int selectGain[4] = {1,2,4,8};
const uint8_t mask1 = 0b11000000;
const uint8_t mask2 = 0b00110000;
const uint8_t mask3 = 0b00001100;
const uint8_t mask4 = 0b00000011;
void Registre::getParameterI(int i, int* resolution, int* gain, float* coeff)
{
//i--; //entree 1 = indice 0, entree 2 = indice 1, etc...
uint8_t byteRead;
unsigned short int coeffBrut=0;
int indice;
switch(i) { // Récuperation des gains et résolutions
case 1:
byteRead = i2c_eeprom.read(ADDR_resolutions);
indice = (int)((byteRead & mask1)>>6);
*resolution=selectResolution [indice];
byteRead = i2c_eeprom.read(ADDR_gains);
indice = (int)((byteRead & mask1)>>6);
*gain=selectGain [indice]; break;
case 2:
byteRead = i2c_eeprom.read(ADDR_resolutions);
indice = (int)((byteRead & mask2)>>4);
*resolution=selectResolution [indice];
byteRead = i2c_eeprom.read(ADDR_gains);
indice = (int)((byteRead & mask2)>>4);
*gain=selectGain [indice]; break;
case 3:
byteRead = i2c_eeprom.read(ADDR_resolutions);
indice = (int)((byteRead & mask3)>>2);
*resolution=selectResolution [indice];
byteRead = i2c_eeprom.read(ADDR_gains);
indice = (int)((byteRead & mask3)>>2);
*gain=selectGain [indice]; break;
case 4:
byteRead = i2c_eeprom.read(ADDR_resolutions);
indice = (int)(byteRead & mask4);
*resolution=selectResolution [indice];
byteRead = i2c_eeprom.read(ADDR_gains);
indice = (int)(byteRead & mask4);
*gain=selectGain [indice]; break;
}
//récupération coefficients
//coeffBrut=i2c_eeprom
}
\ No newline at end of file
......@@ -18,7 +18,7 @@ On définira une adresse et une place prise en commentaire à coté
#define ADDR_gains 0x03
//Seleciton des resolutions des entree diff 1 à 4 (poids fort à poids faible)
#define ADDR_resolution 0x04
#define ADDR_resolutions 0x04
// Définition des adresses des coeff des entrées différentielles
// 2 octets par coeff
......@@ -41,3 +41,22 @@ On définira une adresse et une place prise en commentaire à coté
#define ADDR_ETIQ_SHT75 0x31
#include <I2CEEPROM.h>
// 24AA256 - mémoire flash
#ifndef I2C_EEPROM
#define I2C_EEPROM
#define CHIP_ADDRESS 0x50
#define EEPROM_BYTES 32768 // Number of bytes in EEPROM chip
I2CEEPROM i2c_eeprom(CHIP_ADDRESS); // Create I2C EEPROM instance
unsigned int current_address = 0;
#endif
class Registre
{
private:
public:
void getParameterI(int i, int* resolution, int* gain, float* coeff);
};
/*
* i2ckeypad.cpp v0.1 - keypad/I2C expander interface for Arduino
*
* Copyright (c) 2009 Angel Sancho <angelitodeb@gmail.com>
* All rights reserved.
*
* Original source from keypad v0.3 of Mark Stanley <mstanley@technologist.com>
* (http://www.arduino.cc/playground/Main/KeypadTutorial)
*
*
* LICENSE
* -------
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* EXPLANATION
* -----------
* This library is designed for use with PCF8574, but can possibly be
* adapted to other I2C port expanders
*
* Wiring diagrams for PCF8574 and 4x3 keypad can be found under
* examples directory. Library runs correctly without cols pull-up
* resistors but it's better to use it
*
* You can change pin connections between PCF8574 and keypad under
* PIN MAPPING section below
*
* IMPORTANT! You have to call Wire.begin() before init() in your code
*
* ... and sorry for my poor english!
*/
#include "i2ckeypad_perso.h"
#include <Wire.h>
//extern "C" {
// #include "WConstants.h"
//}
/*
* PIN MAPPING
*
* Here you can change your wire mapping between your keypad and PCF8574
* Default mapping is for sparkfun 4x3 keypad
*/
// ne pas tenir compte des commentaires dans le paragraphe de #define suivant
#ifndef PINS_ROWS_COLS
#define PINS_ROWS_COLS
#define COL0 7 // P2 of PCF8574, col0 is usually pin 3 of 4x3 keypads
#define COL1 6 // P0 of PCF8574, col1 is usually pin 1 of 4x3 keypads
#define COL2 5 // P4 of PCF8574, col2 is usually pin 5 of 4x3 keypads
#define COL3 4 // sorry, don't have a 4x4 keypad to try it
#define ROW0 0 // P1 of PCF8574, row0 is usually pin 2 of 4x3 keypads
#define ROW1 1 // P6 of PCF8574, row1 is usually pin 7 of 4x3 keypads
#define ROW2 2 // P5 of PCF8574, row2 is usually pin 6 of 4x3 keypads
#define ROW3 3 // P3 of PCF8574, row3 is usually pin 4 of 4x3 keypads
#endif
/*
* KEYPAD KEY MAPPING
*
* Default key mapping for 4x4 keypads, you can change it here if you have or
* like different keys
*/
const char keymap[4][4] =
{
"789D",
"456G",
"123 ",
"R0E."
};
/*
* VAR AND CONSTANTS DEFINITION. Don't change nothing here
*
*/
// Default row and col pin counts
int num_rows = 4;
int num_cols = 4;
// PCF8574 i2c address
int pcf8574_i2c_addr;
// Current search row
static int row_select;
// Current data set in PCF8574
static int current_data;
// Hex byte statement for each port of PCF8574
const int hex_data[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
// Hex data for each row of keypad in PCF8574
const int pcf8574_row_data[4] =
{
hex_data[ROW1] | hex_data[ROW2] | hex_data[ROW3] |
hex_data[COL0] | hex_data[COL1] | hex_data[COL2] | hex_data[COL3],
hex_data[ROW0] | hex_data[ROW2] | hex_data[ROW3] |
hex_data[COL0] | hex_data[COL1] | hex_data[COL2] | hex_data[COL3],
hex_data[ROW0] | hex_data[ROW1] | hex_data[ROW3] |
hex_data[COL0] | hex_data[COL1] | hex_data[COL2] | hex_data[COL3],
hex_data[ROW0] | hex_data[ROW1] | hex_data[ROW2] |
hex_data[COL0] | hex_data[COL1] | hex_data[COL2] | hex_data[COL3],
};
// Hex data for each col of keypad in PCF8574
int col[4] = {hex_data[COL0], hex_data[COL1], hex_data[COL2], hex_data[COL3]};
/*
* CONSTRUCTORS
*/