mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-30 20:09:14 +03:00
добавление mysensors в процессе не рабочая версия
This commit is contained in:
@@ -0,0 +1,314 @@
|
||||
/* Arduino DigitalIO Library
|
||||
* Copyright (C) 2013 by William Greiman
|
||||
*
|
||||
* This file is part of the Arduino DigitalIO Library
|
||||
*
|
||||
* This Library 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 Library 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 the Arduino DigitalIO Library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SOFT_I2C_MASTER_H
|
||||
#define SOFT_I2C_MASTER_H
|
||||
/**
|
||||
* @file
|
||||
* @brief AVR Software I2C library
|
||||
*
|
||||
* @defgroup softI2C Software I2C
|
||||
* @details Software Two Wire Interface library.
|
||||
* @{
|
||||
*/
|
||||
#if defined(__AVR__) || defined(DOXYGEN) // AVR only
|
||||
#include <Arduino.h>
|
||||
#include <util/delay_basic.h>
|
||||
#include "DigitalPin.h"
|
||||
#include "I2cConstants.h"
|
||||
//------------------------------------------------------------------------------
|
||||
// State codes.
|
||||
|
||||
/** Stop condition transmitted. */
|
||||
const uint8_t STATE_STOP = 0;
|
||||
|
||||
/** Repeated start condition transmitted. */
|
||||
const uint8_t STATE_REP_START = 1;
|
||||
|
||||
/** Read data transfer active. */
|
||||
const uint8_t STATE_RX_DATA = 2;
|
||||
|
||||
/** Write data transfer active. */
|
||||
const uint8_t STATE_TX_DATA = 3;
|
||||
|
||||
/** Slave address plus read bit transmitted, NACK received. */
|
||||
const uint8_t STATE_RX_ADDR_NACK = 4;
|
||||
|
||||
/** Slave address plus write bit transmitted, NACK received. */
|
||||
const uint8_t STATE_TX_ADDR_NACK = 5;
|
||||
/** Data byte transmitted, NACK received. */
|
||||
const uint8_t STATE_TX_DATA_NACK = 6;
|
||||
//==============================================================================
|
||||
/**
|
||||
* @class I2cMasterBase
|
||||
* @brief Base class for FastI2cMaster, SoftI2cMaster
|
||||
*/
|
||||
class I2cMasterBase
|
||||
{
|
||||
public:
|
||||
I2cMasterBase() : _state(STATE_STOP) {}
|
||||
/** Read a byte
|
||||
*
|
||||
* @note This function should only be used by experts. Data should be
|
||||
* accessed by calling transfer() and transferContinue()
|
||||
*
|
||||
* @param[in] last send a NACK to terminate read if last is true else
|
||||
* send an ACK to continue the read.
|
||||
*
|
||||
* @return byte read from I2C bus
|
||||
*/
|
||||
virtual uint8_t read(uint8_t last) = 0;
|
||||
|
||||
/** Issue a start condition
|
||||
*
|
||||
* @note This function should only be used by experts. Data should be
|
||||
* accessed by calling transfer() and transferContinue()
|
||||
*/
|
||||
virtual void start() = 0;
|
||||
/** Issue a stop condition.
|
||||
*
|
||||
* @note This function should only be used by experts. Data should be
|
||||
* accessed by calling transfer() and transferContinue()
|
||||
*/
|
||||
virtual void stop() = 0;
|
||||
|
||||
bool transfer(uint8_t addressRW, void *buf,
|
||||
size_t nbyte, uint8_t option = I2C_STOP);
|
||||
|
||||
bool transferContinue(void *buf, size_t nbyte, uint8_t option = I2C_STOP);
|
||||
/** Write a byte
|
||||
*
|
||||
* @note This function should only be used by experts. Data should be
|
||||
* accessed by calling transfer() and transferContinue()
|
||||
*
|
||||
* @param[in] data byte to write
|
||||
* @return true for ACK or false for NACK */
|
||||
virtual bool write(uint8_t data) = 0;
|
||||
|
||||
private:
|
||||
uint8_t _state;
|
||||
};
|
||||
//==============================================================================
|
||||
/**
|
||||
* @class SoftI2cMaster
|
||||
* @brief AVR Software I2C master class
|
||||
*/
|
||||
class SoftI2cMaster : public I2cMasterBase
|
||||
{
|
||||
public:
|
||||
SoftI2cMaster() {}
|
||||
SoftI2cMaster(uint8_t sclPin, uint8_t sdaPin);
|
||||
void begin(uint8_t sclPin, uint8_t sdaPin);
|
||||
uint8_t read(uint8_t last);
|
||||
void start();
|
||||
void stop(void);
|
||||
bool write(uint8_t b);
|
||||
|
||||
private:
|
||||
uint8_t _sclBit;
|
||||
uint8_t _sdaBit;
|
||||
volatile uint8_t* _sclDDR;
|
||||
volatile uint8_t* _sdaDDR;
|
||||
volatile uint8_t* _sdaInReg;
|
||||
//----------------------------------------------------------------------------
|
||||
bool readSda()
|
||||
{
|
||||
return *_sdaInReg & _sdaBit;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void sclDelay(uint8_t n)
|
||||
{
|
||||
_delay_loop_1(n);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void writeScl(bool value)
|
||||
{
|
||||
uint8_t s = SREG;
|
||||
noInterrupts();
|
||||
if (value == LOW) {
|
||||
// Pull scl low.
|
||||
*_sclDDR |= _sclBit;
|
||||
} else {
|
||||
// Put scl in high Z input mode.
|
||||
*_sclDDR &= ~_sclBit;
|
||||
}
|
||||
SREG = s;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void writeSda(bool value)
|
||||
{
|
||||
uint8_t s = SREG;
|
||||
noInterrupts();
|
||||
if (value == LOW) {
|
||||
// Pull sda low.
|
||||
*_sdaDDR |= _sdaBit;
|
||||
} else {
|
||||
// Put sda in high Z input mode.
|
||||
*_sdaDDR &= ~_sdaBit;
|
||||
}
|
||||
SREG = s;
|
||||
}
|
||||
};
|
||||
//==============================================================================
|
||||
// Template based fast software I2C
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class FastI2cMaster
|
||||
* @brief AVR Fast software I2C master class.
|
||||
*/
|
||||
template<uint8_t sclPin, uint8_t sdaPin>
|
||||
class FastI2cMaster : public I2cMasterBase
|
||||
{
|
||||
public:
|
||||
//----------------------------------------------------------------------------
|
||||
FastI2cMaster()
|
||||
{
|
||||
begin();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
/** Initialize I2C bus pins. */
|
||||
void begin()
|
||||
{
|
||||
fastDigitalWrite(sclPin, LOW);
|
||||
fastDigitalWrite(sdaPin, LOW);
|
||||
|
||||
sclWrite(HIGH);
|
||||
sdaWrite(HIGH);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
uint8_t read(uint8_t last)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
sdaWrite(HIGH);
|
||||
|
||||
readBit(7, &data);
|
||||
readBit(6, &data);
|
||||
readBit(5, &data);
|
||||
readBit(4, &data);
|
||||
readBit(3, &data);
|
||||
readBit(2, &data);
|
||||
readBit(1, &data);
|
||||
readBit(0, &data);
|
||||
|
||||
// send ACK or NACK
|
||||
sdaWrite(last);
|
||||
sclDelay(4);
|
||||
sclWrite(HIGH);
|
||||
sclDelay(6);
|
||||
sclWrite(LOW);
|
||||
sdaWrite(LOW);
|
||||
return data;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void start()
|
||||
{
|
||||
if (!fastDigitalRead(sdaPin)) {
|
||||
// It's a repeat start.
|
||||
sdaWrite(HIGH);
|
||||
sclDelay(8);
|
||||
sclWrite(HIGH);
|
||||
sclDelay(8);
|
||||
}
|
||||
sdaWrite(LOW);
|
||||
sclDelay(8);
|
||||
sclWrite(LOW);
|
||||
sclDelay(8);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void stop(void)
|
||||
{
|
||||
sdaWrite(LOW);
|
||||
sclDelay(8);
|
||||
sclWrite(HIGH);
|
||||
sclDelay(8);
|
||||
sdaWrite(HIGH);
|
||||
sclDelay(8);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
bool write(uint8_t data)
|
||||
{
|
||||
// write byte
|
||||
writeBit(7, data);
|
||||
writeBit(6, data);
|
||||
writeBit(5, data);
|
||||
writeBit(4, data);
|
||||
writeBit(3, data);
|
||||
writeBit(2, data);
|
||||
writeBit(1, data);
|
||||
writeBit(0, data);
|
||||
|
||||
// get ACK or NACK
|
||||
sdaWrite(HIGH);
|
||||
|
||||
sclWrite(HIGH);
|
||||
sclDelay(5);
|
||||
bool rtn = fastDigitalRead(sdaPin);
|
||||
sclWrite(LOW);
|
||||
sdaWrite(LOW);
|
||||
return rtn == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
//----------------------------------------------------------------------------
|
||||
inline __attribute__((always_inline))
|
||||
void sclWrite(bool value)
|
||||
{
|
||||
fastDdrWrite(sclPin, !value);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline __attribute__((always_inline))
|
||||
void sdaWrite(bool value)
|
||||
{
|
||||
fastDdrWrite(sdaPin, !value);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline __attribute__((always_inline))
|
||||
void readBit(uint8_t bit, uint8_t* data)
|
||||
{
|
||||
sclWrite(HIGH);
|
||||
sclDelay(5);
|
||||
if (fastDigitalRead(sdaPin)) {
|
||||
*data |= 1 << bit;
|
||||
}
|
||||
sclWrite(LOW);
|
||||
if (bit) {
|
||||
sclDelay(6);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void sclDelay(uint8_t n)
|
||||
{
|
||||
_delay_loop_1(n);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline __attribute__((always_inline))
|
||||
void writeBit(uint8_t bit, uint8_t data)
|
||||
{
|
||||
uint8_t mask = 1 << bit;
|
||||
sdaWrite(data & mask);
|
||||
sclWrite(HIGH);
|
||||
sclDelay(5);
|
||||
sclWrite(LOW);
|
||||
sclDelay(5);
|
||||
}
|
||||
};
|
||||
#endif // __AVR__
|
||||
#endif // SOFT_I2C_MASTER_H
|
||||
/** @} */
|
||||
|
||||
Reference in New Issue
Block a user