Merge pull request #609 from marceloaqno/dev-rpi-i2c
RPi: Add support for I2C
This commit is contained in:
+3
-15
@@ -71,22 +71,10 @@
|
||||
#elif defined(ARDUINO_ARCH_SAMD)
|
||||
#include "core/MyHwSAMD.cpp"
|
||||
#elif defined(__linux__)
|
||||
// Remove PSTR macros from debug prints
|
||||
#undef PSTR
|
||||
#define PSTR(x) (x)
|
||||
//#undef F
|
||||
//#define F(x) (x)
|
||||
#define PROGMEM
|
||||
#define vsnprintf_P(...) vsnprintf( __VA_ARGS__ )
|
||||
#define snprintf_P(...) snprintf( __VA_ARGS__ )
|
||||
#define memcpy_P memcpy
|
||||
#define pgm_read_dword(x) (*x)
|
||||
#define pgm_read_byte_near(x) (*x)
|
||||
#include "core/MyHwLinuxGeneric.cpp"
|
||||
// Ugly hack
|
||||
#ifdef LINUX_ARCH_RASPBERRYPI
|
||||
#undef hwDigitalWrite
|
||||
#define hwDigitalWrite(__pin, __value) (digitalWrite(__pin, __value))
|
||||
#include "core/MyHwRPi.cpp"
|
||||
#else
|
||||
#include "core/MyHwLinuxGeneric.cpp"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
+25
-2
@@ -36,12 +36,15 @@
|
||||
|
||||
// Implement these as functions or macros
|
||||
/*
|
||||
#define hwDigitalWrite(__pin, __value)
|
||||
#define hwInit() MY_SERIALDEVICE.begin(BAUD_RATE)
|
||||
#define hwWatchdogReset() wdt_reset()
|
||||
#define hwReboot() wdt_enable(WDTO_15MS); while (1)
|
||||
#define hwMillis() millis()
|
||||
|
||||
#define hwDigitalWrite(__pin, __value)
|
||||
#define hwDigitalRead(__pin)
|
||||
#define hwPinMode(__pin, __value)
|
||||
|
||||
void hwReadConfigBlock(void* buf, void* adr, size_t length);
|
||||
void hwWriteConfigBlock(void* buf, void* adr, size_t length);
|
||||
void hwWriteConfig(int adr, uint8_t value);
|
||||
@@ -75,8 +78,28 @@ int8_t hwSleep(uint8_t interrupt, uint8_t mode, unsigned long ms);
|
||||
*/
|
||||
int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms);
|
||||
|
||||
#if defined(MY_DEBUG) || defined(MY_SPECIAL_DEBUG)
|
||||
/**
|
||||
* CPU voltage
|
||||
* @return CPU voltage in mV
|
||||
*/
|
||||
uint16_t hwCPUVoltage();
|
||||
|
||||
/**
|
||||
* CPU frequency
|
||||
* @return CPU frequency in 1/10Mhz
|
||||
*/
|
||||
uint16_t hwCPUFrequency();
|
||||
|
||||
/**
|
||||
* Free memory
|
||||
* @return free memory in bytes
|
||||
*/
|
||||
uint16_t hwFreeMem();
|
||||
#endif
|
||||
|
||||
#ifdef MY_DEBUG
|
||||
void hwDebugPrint(const char *fmt, ... );
|
||||
void hwDebugPrint(const char *fmt, ... );
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -161,6 +161,7 @@ int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mo
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MY_DEBUG) || defined(MY_SPECIAL_DEBUG)
|
||||
uint16_t hwCPUVoltage() {
|
||||
// Measure Vcc against 1.1V Vref
|
||||
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
@@ -214,8 +215,7 @@ uint16_t hwFreeMem() {
|
||||
int v;
|
||||
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef MY_DEBUG
|
||||
void hwDebugPrint(const char *fmt, ... ) {
|
||||
|
||||
@@ -114,6 +114,7 @@ int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mo
|
||||
return MY_SLEEP_NOT_POSSIBLE;
|
||||
}
|
||||
|
||||
#if defined(MY_DEBUG) || defined(MY_SPECIAL_DEBUG)
|
||||
ADC_MODE(ADC_VCC);
|
||||
|
||||
uint16_t hwCPUVoltage() {
|
||||
@@ -129,6 +130,7 @@ uint16_t hwCPUFrequency() {
|
||||
uint16_t hwFreeMem() {
|
||||
return ESP.getFreeHeap();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MY_DEBUG
|
||||
void hwDebugPrint(const char *fmt, ... ) {
|
||||
|
||||
+23
-82
@@ -20,109 +20,43 @@
|
||||
#include "MyHwLinuxGeneric.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include "SoftEeprom.h"
|
||||
#include "log.h"
|
||||
|
||||
static const char* CONFIG_FILE = MY_LINUX_CONFIG_FILE;
|
||||
static const size_t _length = 1024; // ATMega328 has 1024 bytes
|
||||
static uint8_t _config[_length];
|
||||
|
||||
bool CheckConfigFile()
|
||||
{
|
||||
struct stat fileInfo;
|
||||
|
||||
if (stat(CONFIG_FILE, &fileInfo) != 0) {
|
||||
//File does not exist. Create it.
|
||||
debug("Config file %s does not exist, creating new config file.\n", CONFIG_FILE);
|
||||
std::ofstream myFile(CONFIG_FILE, std::ios::out | std::ios::binary);
|
||||
if (!myFile) {
|
||||
debug("Unable to create config file %s.\n", CONFIG_FILE);
|
||||
return false;
|
||||
}
|
||||
myFile.write((const char*)_config, _length);
|
||||
myFile.close();
|
||||
} else if (fileInfo.st_size < 0 || (size_t)fileInfo.st_size != _length) {
|
||||
debug("Config file %s is not the correct size of %i. Please remove the file and a new one will be created.\n", CONFIG_FILE, _length);
|
||||
return false;
|
||||
} else {
|
||||
//Read config into local memory.
|
||||
std::ifstream myFile(CONFIG_FILE, std::ios::in | std::ios::binary);
|
||||
if (!myFile) {
|
||||
debug("Unable to open config to file %s for reading.\n", CONFIG_FILE);
|
||||
return false;
|
||||
}
|
||||
myFile.read((char*)_config, _length);
|
||||
myFile.close();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
static SoftEeprom eeprom = SoftEeprom(MY_LINUX_CONFIG_FILE, 1024); // ATMega328 has 1024 bytes
|
||||
|
||||
void hwInit()
|
||||
{
|
||||
for (size_t i = 0; i < _length; i++) {
|
||||
_config[i] = 0xFF;
|
||||
}
|
||||
|
||||
if (!CheckConfigFile()) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef MY_GATEWAY_SERIAL
|
||||
MY_SERIALDEVICE.begin(MY_BAUD_RATE);
|
||||
#ifdef MY_LINUX_SERIAL_GROUPNAME
|
||||
if (!MY_SERIALDEVICE.setGroupPerm(MY_LINUX_SERIAL_GROUPNAME)) {
|
||||
debug("Unable to change permission for serial port device.\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
#ifdef MY_GATEWAY_SERIAL
|
||||
MY_SERIALDEVICE.begin(MY_BAUD_RATE);
|
||||
#ifdef MY_LINUX_SERIAL_GROUPNAME
|
||||
if (!MY_SERIALDEVICE.setGroupPerm(MY_LINUX_SERIAL_GROUPNAME)) {
|
||||
mys_log(LOG_ERR, "Unable to change permission for serial port device.\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void hwReadConfigBlock(void* buf, void* addr, size_t length)
|
||||
{
|
||||
unsigned long int offs = reinterpret_cast<unsigned long int>(addr);
|
||||
|
||||
if (length && offs + length <= _length) {
|
||||
memcpy(buf, _config+offs, length);
|
||||
}
|
||||
eeprom.readBlock(buf, addr, length);
|
||||
}
|
||||
|
||||
void hwWriteConfigBlock(void* buf, void* addr, size_t length)
|
||||
{
|
||||
unsigned long int offs = reinterpret_cast<unsigned long int>(addr);
|
||||
|
||||
if (length && offs + length <= _length) {
|
||||
memcpy(_config+offs, buf, length);
|
||||
|
||||
std::ofstream myFile(CONFIG_FILE, std::ios::out | std::ios::in | std::ios::binary);
|
||||
if (!myFile) {
|
||||
debug("Unable to write config to file %s.\n", CONFIG_FILE);
|
||||
return;
|
||||
}
|
||||
myFile.seekp(offs);
|
||||
myFile.write((const char*)buf, length);
|
||||
myFile.close();
|
||||
}
|
||||
eeprom.writeBlock(buf, addr, length);
|
||||
}
|
||||
|
||||
uint8_t hwReadConfig(int adr)
|
||||
uint8_t hwReadConfig(int addr)
|
||||
{
|
||||
uint8_t value = 0xFF;
|
||||
hwReadConfigBlock(&value, reinterpret_cast<void*>(adr), 1);
|
||||
return value;
|
||||
return eeprom.readByte(addr);
|
||||
}
|
||||
|
||||
void hwWriteConfig(int adr, uint8_t value)
|
||||
void hwWriteConfig(int addr, uint8_t value)
|
||||
{
|
||||
uint8_t curr = hwReadConfig(adr);
|
||||
if (curr != value) {
|
||||
hwWriteConfigBlock(&value, reinterpret_cast<void*>(adr), 1);
|
||||
}
|
||||
eeprom.writeByte(addr, value);
|
||||
}
|
||||
|
||||
void hwRandomNumberInit()
|
||||
@@ -130,6 +64,11 @@ void hwRandomNumberInit()
|
||||
randomSeed(time(NULL));
|
||||
}
|
||||
|
||||
unsigned long hwMillis()
|
||||
{
|
||||
return millis();
|
||||
}
|
||||
|
||||
// Not supported!
|
||||
int8_t hwSleep(unsigned long ms)
|
||||
{
|
||||
@@ -160,6 +99,7 @@ int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mo
|
||||
return MY_SLEEP_NOT_POSSIBLE;
|
||||
}
|
||||
|
||||
#if defined(MY_DEBUG) || defined(MY_SPECIAL_DEBUG)
|
||||
uint16_t hwCPUVoltage()
|
||||
{
|
||||
// TODO: Not supported!
|
||||
@@ -177,6 +117,7 @@ uint16_t hwFreeMem()
|
||||
// TODO: Not supported!
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MY_DEBUG
|
||||
void hwDebugPrint(const char *fmt, ...)
|
||||
|
||||
+11
-11
@@ -33,21 +33,21 @@
|
||||
|
||||
#define MY_SERIALDEVICE Serial
|
||||
|
||||
// Define these as macros
|
||||
#define hwDigitalWrite(__pin, __value) digitalWrite(__pin, __value)
|
||||
#define hwDigitalRead(__pin) digitalRead(__pin)
|
||||
#define hwPinMode(__pin, __value) pinMode(__pin, __value)
|
||||
|
||||
// Define these as macros (do nothing)
|
||||
#define hwWatchdogReset()
|
||||
#define hwReboot()
|
||||
#define hwMillis() millis()
|
||||
|
||||
#define hwDigitalWrite(__pin, __value) _Pragma("GCC error \"Not supported on linux-generic\"")
|
||||
#define hwDigitalRead(__pin) _Pragma("GCC error \"Not supported on linux-generic\"")
|
||||
#define hwPinMode(__pin, __value) _Pragma("GCC error \"Not supported on linux-generic\"")
|
||||
|
||||
void hwInit();
|
||||
void hwReadConfigBlock(void* buf, void* adr, size_t length);
|
||||
void hwWriteConfigBlock(void* buf, void* adr, size_t length);
|
||||
uint8_t hwReadConfig(int adr);
|
||||
void hwWriteConfig(int adr, uint8_t value);
|
||||
void hwRandomNumberInit();
|
||||
inline void hwReadConfigBlock(void* buf, void* addr, size_t length);
|
||||
inline void hwWriteConfigBlock(void* buf, void* addr, size_t length);
|
||||
inline uint8_t hwReadConfig(int addr);
|
||||
inline void hwWriteConfig(int addr, uint8_t value);
|
||||
inline void hwRandomNumberInit();
|
||||
inline unsigned long hwMillis();
|
||||
|
||||
#ifdef MY_RF24_IRQ_PIN
|
||||
static pthread_mutex_t hw_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "MyHwRPi.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include "SoftEeprom.h"
|
||||
#include "log.h"
|
||||
|
||||
static SoftEeprom eeprom = SoftEeprom(MY_LINUX_CONFIG_FILE, 1024); // ATMega328 has 1024 bytes
|
||||
|
||||
void hwInit()
|
||||
{
|
||||
if (!bcm2835_init()) {
|
||||
mys_log(LOG_ERR, "Failed to initialized bcm2835.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef MY_GATEWAY_SERIAL
|
||||
MY_SERIALDEVICE.begin(MY_BAUD_RATE);
|
||||
#ifdef MY_LINUX_SERIAL_GROUPNAME
|
||||
if (!MY_SERIALDEVICE.setGroupPerm(MY_LINUX_SERIAL_GROUPNAME)) {
|
||||
mys_log(LOG_ERR, "Unable to change permission for serial port device.\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void hwReadConfigBlock(void* buf, void* adr, size_t length)
|
||||
{
|
||||
eeprom.readBlock(buf, adr, length);
|
||||
}
|
||||
|
||||
void hwWriteConfigBlock(void* buf, void* adr, size_t length)
|
||||
{
|
||||
eeprom.writeBlock(buf, adr, length);
|
||||
}
|
||||
|
||||
uint8_t hwReadConfig(int adr)
|
||||
{
|
||||
return eeprom.readByte(adr);
|
||||
}
|
||||
|
||||
void hwWriteConfig(int adr, uint8_t value)
|
||||
{
|
||||
eeprom.writeByte(adr, value);
|
||||
}
|
||||
|
||||
void hwRandomNumberInit()
|
||||
{
|
||||
randomSeed(time(NULL));
|
||||
}
|
||||
|
||||
unsigned long hwMillis()
|
||||
{
|
||||
return millis();
|
||||
}
|
||||
|
||||
// Not supported!
|
||||
int8_t hwSleep(unsigned long ms)
|
||||
{
|
||||
(void)ms;
|
||||
|
||||
return MY_SLEEP_NOT_POSSIBLE;
|
||||
}
|
||||
|
||||
// Not supported!
|
||||
int8_t hwSleep(uint8_t interrupt, uint8_t mode, unsigned long ms)
|
||||
{
|
||||
(void)interrupt;
|
||||
(void)mode;
|
||||
(void)ms;
|
||||
|
||||
return MY_SLEEP_NOT_POSSIBLE;
|
||||
}
|
||||
|
||||
// Not supported!
|
||||
int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms)
|
||||
{
|
||||
(void)interrupt1;
|
||||
(void)mode1;
|
||||
(void)interrupt2;
|
||||
(void)mode2;
|
||||
(void)ms;
|
||||
|
||||
return MY_SLEEP_NOT_POSSIBLE;
|
||||
}
|
||||
|
||||
#if defined(MY_DEBUG) || defined(MY_SPECIAL_DEBUG)
|
||||
uint16_t hwCPUVoltage()
|
||||
{
|
||||
// TODO: Not supported!
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t hwCPUFrequency()
|
||||
{
|
||||
// TODO: Not supported!
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t hwFreeMem()
|
||||
{
|
||||
// TODO: Not supported!
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MY_DEBUG
|
||||
void hwDebugPrint(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
mys_log_v(LOG_DEBUG, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
void hwDigitalWrite(uint8_t pin, uint8_t value)
|
||||
{
|
||||
digitalWrite(pin, value);
|
||||
}
|
||||
|
||||
int hwDigitalRead(uint8_t pin)
|
||||
{
|
||||
return digitalRead(pin);
|
||||
}
|
||||
|
||||
void hwPinMode(uint8_t pin, uint8_t mode)
|
||||
{
|
||||
pinMode(pin, mode);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef MyHwRPi_h
|
||||
#define MyHwRPi_h
|
||||
|
||||
#include "MyHwLinuxGeneric.h"
|
||||
|
||||
#undef hwDigitalWrite
|
||||
inline void hwDigitalWrite(uint8_t, uint8_t);
|
||||
|
||||
#undef hwDigitalRead
|
||||
inline int hwDigitalRead(uint8_t);
|
||||
|
||||
#undef hwPinMode
|
||||
inline void hwPinMode(uint8_t, uint8_t);
|
||||
|
||||
#endif
|
||||
@@ -140,6 +140,7 @@ int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mo
|
||||
return MY_SLEEP_NOT_POSSIBLE;
|
||||
}
|
||||
|
||||
#if defined(MY_DEBUG) || defined(MY_SPECIAL_DEBUG)
|
||||
uint16_t hwCPUVoltage() {
|
||||
// TODO: Not supported!
|
||||
return 0;
|
||||
@@ -154,6 +155,7 @@ uint16_t hwFreeMem() {
|
||||
// TODO: Not supported!
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MY_DEBUG
|
||||
void hwDebugPrint(const char *fmt, ... ) {
|
||||
|
||||
+13
-6
@@ -22,6 +22,7 @@
|
||||
#include <csignal>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <syslog.h>
|
||||
#include <errno.h>
|
||||
@@ -56,7 +57,7 @@ static int daemonize(void)
|
||||
/* Fork off the parent process */
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
mys_log(LOG_ERR, "fork: %s", strerror(errno));
|
||||
mys_log(LOG_ERR, "fork: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/* If we got a good PID, then we can exit the parent process. */
|
||||
@@ -72,20 +73,26 @@ static int daemonize(void)
|
||||
/* Create a new SID for the child process */
|
||||
sid = setsid();
|
||||
if (sid < 0) {
|
||||
mys_log(LOG_ERR, "setsid: %s", strerror(errno));
|
||||
mys_log(LOG_ERR, "setsid: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Change the current working directory. This prevents the current
|
||||
directory from being locked; hence not being able to remove it. */
|
||||
if ((chdir("/")) < 0) {
|
||||
mys_log(LOG_ERR, "chdir(\"/\"): %s", strerror(errno));
|
||||
mys_log(LOG_ERR, "chdir(\"/\"): %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
freopen( "/dev/null", "r", stdin);
|
||||
freopen( "/dev/null", "r", stdout);
|
||||
freopen( "/dev/null", "r", stderr);
|
||||
if (freopen( "/dev/null", "r", stdin) == NULL) {
|
||||
mys_log(LOG_ERR, "freopen: %s\n", strerror(errno));
|
||||
}
|
||||
if (freopen( "/dev/null", "r", stdout) == NULL) {
|
||||
mys_log(LOG_ERR, "freopen: %s\n", strerror(errno));
|
||||
}
|
||||
if (freopen( "/dev/null", "r", stderr) == NULL) {
|
||||
mys_log(LOG_ERR, "freopen: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,18 @@
|
||||
using namespace rpi_util;
|
||||
#endif
|
||||
|
||||
#undef PSTR
|
||||
#define PSTR(x) (x)
|
||||
#undef F
|
||||
#define F(x) (x)
|
||||
#define PROGMEM __attribute__(( section(".progmem.data") ))
|
||||
#define vsnprintf_P(...) vsnprintf( __VA_ARGS__ )
|
||||
#define snprintf_P(...) snprintf( __VA_ARGS__ )
|
||||
#define memcpy_P memcpy
|
||||
#define pgm_read_byte(p) (*(p))
|
||||
#define pgm_read_dword(p) (*(p))
|
||||
#define pgm_read_byte_near(p) (*(p))
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#define HALF_PI 1.5707963267948966192313216916398
|
||||
#define TWO_PI 6.283185307179586476925286766559
|
||||
|
||||
@@ -84,7 +84,7 @@ void EthernetServer::begin(IPAddress address)
|
||||
}
|
||||
|
||||
if (p == NULL) {
|
||||
mys_log(LOG_ERR, "failed to bind\n");
|
||||
mys_log(LOG_ERR, "Failed to bind!\n");
|
||||
freeaddrinfo(servinfo);
|
||||
return;
|
||||
}
|
||||
@@ -142,7 +142,7 @@ size_t EthernetServer::write(const uint8_t *buffer, size_t size)
|
||||
client.stop();
|
||||
clients[i] = clients.back();
|
||||
clients.pop_back();
|
||||
mys_log(LOG_DEBUG, "Client disconnected.");
|
||||
mys_log(LOG_DEBUG, "Client disconnected.\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ void EthernetServer::_accept()
|
||||
}
|
||||
}
|
||||
if (no_free_slots) {
|
||||
mys_log(LOG_DEBUG, "Max number of ethernet clients reached.");
|
||||
mys_log(LOG_DEBUG, "Max number of ethernet clients reached.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,10 +34,19 @@
|
||||
|
||||
class Print {
|
||||
private:
|
||||
int write_error;
|
||||
size_t printNumber(unsigned long n, uint8_t base);
|
||||
size_t printFloat(double number, uint8_t digits);
|
||||
|
||||
protected:
|
||||
void setWriteError(int err = 1) { write_error = err; }
|
||||
|
||||
public:
|
||||
Print() : write_error(0) {}
|
||||
|
||||
int getWriteError() { return write_error; }
|
||||
void clearWriteError() { setWriteError(0); }
|
||||
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
size_t write(const char *str) {
|
||||
if (str == NULL)
|
||||
|
||||
@@ -194,18 +194,32 @@ int SerialPort::read()
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
::read(sd, &c, 1);
|
||||
return c;
|
||||
int ret = ::read(sd, &c, 1);
|
||||
if (ret < 0) {
|
||||
mys_log(LOG_ERR, "Serial - read failed: %s\n", strerror(errno));
|
||||
} else if (ret == 1) {
|
||||
return c;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t SerialPort::write(uint8_t b)
|
||||
{
|
||||
return ::write(sd, &b, 1);
|
||||
int ret = ::write(sd, &b, 1);
|
||||
if (ret < 0) {
|
||||
mys_log(LOG_ERR, "Serial - write failed: %s\n", strerror(errno));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t SerialPort::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
return ::write(sd, buffer, size);
|
||||
int ret = ::write(sd, buffer, size);
|
||||
if (ret < 0) {
|
||||
mys_log(LOG_ERR, "Serial - write failed: %s\n", strerror(errno));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SerialPort::peek()
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include "log.h"
|
||||
#include "SoftEeprom.h"
|
||||
|
||||
SoftEeprom::SoftEeprom(const char *fileName, size_t length)
|
||||
{
|
||||
struct stat fileInfo;
|
||||
|
||||
_fileName = strdup(fileName);
|
||||
if (_fileName == NULL) {
|
||||
perror("Error: ");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_length = length;
|
||||
_values = new uint8_t[_length];
|
||||
for (size_t i = 0; i < _length; ++i) {
|
||||
_values[i] = 0xFF;
|
||||
}
|
||||
|
||||
if (stat(_fileName, &fileInfo) != 0) {
|
||||
//File does not exist. Create it.
|
||||
mys_log(LOG_INFO, "Config file %s does not exist, creating new config file.\n", _fileName);
|
||||
std::ofstream myFile(_fileName, std::ios::out | std::ios::binary);
|
||||
if (!myFile) {
|
||||
mys_log(LOG_ERR, "Unable to create config file %s.\n", _fileName);
|
||||
exit(1);
|
||||
}
|
||||
myFile.write((const char*)_values, _length);
|
||||
myFile.close();
|
||||
} else if (fileInfo.st_size < 0 || (size_t)fileInfo.st_size != _length) {
|
||||
mys_log(LOG_ERR, "Config file %s is not the correct size of %zu. Please remove the file and a new one will be created.\n", _fileName, _length);
|
||||
exit(1);
|
||||
} else {
|
||||
//Read config into local memory.
|
||||
std::ifstream myFile(_fileName, std::ios::in | std::ios::binary);
|
||||
if (!myFile) {
|
||||
mys_log(LOG_ERR, "Unable to open config to file %s for reading.\n", _fileName);
|
||||
exit(1);
|
||||
}
|
||||
myFile.read((char*)_values, _length);
|
||||
myFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
SoftEeprom::~SoftEeprom()
|
||||
{
|
||||
delete[] _values;
|
||||
free(_fileName);
|
||||
}
|
||||
|
||||
void SoftEeprom::readBlock(void* buf, void* addr, size_t length)
|
||||
{
|
||||
static bool config_to_mem = false;
|
||||
unsigned long int offs = reinterpret_cast<unsigned long int>(addr);
|
||||
|
||||
if (!config_to_mem) {
|
||||
//Read config into local memory.
|
||||
std::ifstream myFile(_fileName, std::ios::in | std::ios::binary);
|
||||
if (!myFile) {
|
||||
mys_log(LOG_ERR, "Unable to open config to file %s for reading.\n", _fileName);
|
||||
exit(1);
|
||||
}
|
||||
myFile.read((char*)_values, _length);
|
||||
myFile.close();
|
||||
|
||||
config_to_mem = true;
|
||||
}
|
||||
|
||||
if (length && offs + length <= _length) {
|
||||
memcpy(buf, _values+offs, length);
|
||||
}
|
||||
}
|
||||
|
||||
void SoftEeprom::writeBlock(void* buf, void* addr, size_t length)
|
||||
{
|
||||
unsigned long int offs = reinterpret_cast<unsigned long int>(addr);
|
||||
|
||||
if (length && offs + length <= _length) {
|
||||
memcpy(_values+offs, buf, length);
|
||||
|
||||
std::ofstream myFile(_fileName, std::ios::out | std::ios::in | std::ios::binary);
|
||||
if (!myFile) {
|
||||
mys_log(LOG_ERR, "Unable to write config to file %s.\n", _fileName);
|
||||
return;
|
||||
}
|
||||
myFile.seekp(offs);
|
||||
myFile.write((const char*)buf, length);
|
||||
myFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t SoftEeprom::readByte(int addr)
|
||||
{
|
||||
uint8_t value = 0xFF;
|
||||
readBlock(&value, reinterpret_cast<void*>(addr), 1);
|
||||
return value;
|
||||
}
|
||||
|
||||
void SoftEeprom::writeByte(int addr, uint8_t value)
|
||||
{
|
||||
uint8_t curr = readByte(addr);
|
||||
if (curr != value) {
|
||||
writeBlock(&value, reinterpret_cast<void*>(addr), 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This a software emulation of EEPROM that uses a file for data storage.
|
||||
* A copy of the eeprom values are also held in memory for faster reading.
|
||||
*/
|
||||
|
||||
#ifndef SoftEeprom_h
|
||||
#define SoftEeprom_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* SoftEeprom class
|
||||
*/
|
||||
class SoftEeprom {
|
||||
|
||||
private:
|
||||
size_t _length; //!< @brief Eeprom max size.
|
||||
char *_fileName; //!< @brief file where the eeprom values are stored.
|
||||
uint8_t *_values; //!< @brief copy of the eeprom values held in memory for a faster reading.
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief SoftEeprom constructor.
|
||||
*/
|
||||
SoftEeprom(const char *fileName, size_t length);
|
||||
/**
|
||||
* @brief SoftEeprom destructor.
|
||||
*/
|
||||
~SoftEeprom();
|
||||
/**
|
||||
* @brief Read a block of bytes from eeprom.
|
||||
*
|
||||
* @param buf buffer to copy to.
|
||||
* @param addr eeprom address to read from.
|
||||
* @param length number of bytes to read.
|
||||
*/
|
||||
void readBlock(void* buf, void* addr, size_t length);
|
||||
/**
|
||||
* @brief Write a block of bytes to eeprom.
|
||||
*
|
||||
* @param buf buffer to read from.
|
||||
* @param addr eeprom address to write to.
|
||||
* @param length number of bytes to write.
|
||||
*/
|
||||
void writeBlock(void* buf, void* addr, size_t length);
|
||||
/**
|
||||
* @brief Read a byte from eeprom.
|
||||
*
|
||||
* @param addr eeprom address to read from.
|
||||
* @return the read byte.
|
||||
*/
|
||||
uint8_t readByte(int addr);
|
||||
/**
|
||||
* @brief Write a byte to eeprom.
|
||||
*
|
||||
* @param addr eeprom address to write to.
|
||||
* @param value to write.
|
||||
*/
|
||||
void writeByte(int addr, uint8_t value);
|
||||
};
|
||||
|
||||
#endif
|
||||
+1
-10
@@ -31,16 +31,7 @@ SPIClass SPI = SPIClass();
|
||||
|
||||
uint8_t SPIClass::initialized = 0;
|
||||
|
||||
SPIClass::SPIClass() {
|
||||
if (!bcm2835_init()) {
|
||||
mys_log(LOG_ERR, "Failed to initialized bcm2835.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
SPIClass::~SPIClass() {}
|
||||
|
||||
uint8_t SPIClass::isInitialized() {
|
||||
uint8_t SPIClass::is_initialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
|
||||
+2
-9
@@ -18,6 +18,7 @@
|
||||
*
|
||||
* Based on TMRh20 RF24 library, Copyright (c) 2015 Charles-Henri Hallard <tmrh20@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _SPI_H_
|
||||
#define _SPI_H_
|
||||
|
||||
@@ -122,20 +123,12 @@ private:
|
||||
static uint8_t initialized; //!< @brief SPI initialized flag.
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief SPIClass constructor.
|
||||
*/
|
||||
SPIClass();
|
||||
/**
|
||||
* @brief SPIClass destructor.
|
||||
*/
|
||||
virtual ~SPIClass();
|
||||
/**
|
||||
* @brief Checks if SPI was initialized.
|
||||
*
|
||||
* @return 0 if wasn't initialized, else 1 or more.
|
||||
*/
|
||||
static uint8_t isInitialized();
|
||||
static uint8_t is_initialized();
|
||||
/**
|
||||
* @brief Send and receive a byte.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
TwoWire.h - TWI/I2C library for Arduino & Wiring
|
||||
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
|
||||
Modified December 2014 by Ivan Grokhotkov (ivan@esp8266.com) - esp8266 support
|
||||
Modified April 2015 by Hrsto Gochkov (ficeto@ficeto.com) - alternative esp8266 support
|
||||
Modified October 2016 by Marcelo Aquino <marceloaqno@gmail.org> for Raspberry Pi
|
||||
*/
|
||||
|
||||
#include "Wire.h"
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include "bcm2835.h"
|
||||
#include "log.h"
|
||||
|
||||
static pthread_mutex_t i2cMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
|
||||
uint8_t TwoWire::rxBufferIndex = 0;
|
||||
uint8_t TwoWire::rxBufferLength = 0;
|
||||
|
||||
uint8_t TwoWire::txAddress = 0;
|
||||
uint8_t TwoWire::txBuffer[BUFFER_LENGTH];
|
||||
uint8_t TwoWire::txBufferIndex = 0;
|
||||
uint8_t TwoWire::txBufferLength = 0;
|
||||
|
||||
uint8_t TwoWire::transmitting = 0;
|
||||
|
||||
void TwoWire::begin()
|
||||
{
|
||||
if (!bcm2835_i2c_begin()) {
|
||||
mys_log(LOG_ERR, "You need to be root to use I2C.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void TwoWire::begin(uint8_t address)
|
||||
{
|
||||
begin();
|
||||
bcm2835_i2c_setSlaveAddress(address);
|
||||
}
|
||||
|
||||
void TwoWire::begin(int address)
|
||||
{
|
||||
begin(static_cast<uint8_t>(address));
|
||||
}
|
||||
|
||||
void TwoWire::end()
|
||||
{
|
||||
bcm2835_i2c_end();
|
||||
}
|
||||
|
||||
void TwoWire::setClock(uint32_t clock)
|
||||
{
|
||||
bcm2835_i2c_set_baudrate(clock);
|
||||
}
|
||||
|
||||
void TwoWire::beginTransmission(uint8_t address)
|
||||
{
|
||||
pthread_mutex_lock(&i2cMutex);
|
||||
// indicate that we are transmitting
|
||||
transmitting = 1;
|
||||
// set address of targeted slave
|
||||
txAddress = address;
|
||||
// reset tx buffer iterator vars
|
||||
txBufferIndex = 0;
|
||||
txBufferLength = 0;
|
||||
}
|
||||
|
||||
void TwoWire::beginTransmission(int address)
|
||||
{
|
||||
beginTransmission(static_cast<uint8_t>(address));
|
||||
}
|
||||
|
||||
uint8_t TwoWire::endTransmission(void)
|
||||
{
|
||||
// transmit buffer
|
||||
bcm2835_i2c_setSlaveAddress(txAddress);
|
||||
uint8_t ret = bcm2835_i2c_write(reinterpret_cast<const char *>(txBuffer), txBufferLength);
|
||||
|
||||
// reset tx buffer iterator vars
|
||||
txBufferIndex = 0;
|
||||
txBufferLength = 0;
|
||||
// indicate that we are done transmitting
|
||||
transmitting = 0;
|
||||
|
||||
pthread_mutex_unlock(&i2cMutex);
|
||||
|
||||
if (ret == BCM2835_I2C_REASON_OK) {
|
||||
return 0; // success
|
||||
} else if (ret == BCM2835_I2C_REASON_ERROR_NACK) {
|
||||
return 3; // error: data send, nack received
|
||||
}
|
||||
return 4; // other error
|
||||
}
|
||||
|
||||
size_t TwoWire::requestFrom(uint8_t address, size_t quantity)
|
||||
{
|
||||
// clamp to buffer length
|
||||
if (quantity > BUFFER_LENGTH) {
|
||||
quantity = BUFFER_LENGTH;
|
||||
}
|
||||
|
||||
rxBufferIndex = 0;
|
||||
rxBufferLength = 0;
|
||||
|
||||
bcm2835_i2c_setSlaveAddress(address);
|
||||
uint8_t ret = bcm2835_i2c_read(reinterpret_cast<char *>(rxBuffer), quantity);
|
||||
if (ret == BCM2835_I2C_REASON_OK) {
|
||||
rxBufferLength = quantity;
|
||||
}
|
||||
|
||||
return rxBufferLength;
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
|
||||
{
|
||||
return requestFrom(address, static_cast<size_t>(quantity));
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(int address, int quantity)
|
||||
{
|
||||
return requestFrom(static_cast<uint8_t>(address), static_cast<size_t>(quantity));
|
||||
}
|
||||
|
||||
size_t TwoWire::write(uint8_t data)
|
||||
{
|
||||
if (transmitting) {
|
||||
// in master transmitter mode
|
||||
// don't bother if buffer is full
|
||||
if (txBufferLength >= BUFFER_LENGTH) {
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
// put byte in tx buffer
|
||||
txBuffer[txBufferIndex] = data;
|
||||
++txBufferIndex;
|
||||
// update amount in buffer
|
||||
txBufferLength = txBufferIndex;
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
return write(&data, 1);
|
||||
}
|
||||
}
|
||||
|
||||
size_t TwoWire::write(const uint8_t *data, size_t quantity)
|
||||
{
|
||||
if (transmitting) {
|
||||
// in master transmitter mode
|
||||
for (size_t i = 0; i < quantity; ++i) {
|
||||
write(data[i]);
|
||||
}
|
||||
} else {
|
||||
uint8_t rc = bcm2835_i2c_write(reinterpret_cast<const char *>(data), quantity);
|
||||
if (rc != BCM2835_I2C_REASON_OK) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return quantity;
|
||||
}
|
||||
|
||||
int TwoWire::available()
|
||||
{
|
||||
return rxBufferLength - rxBufferIndex;
|
||||
}
|
||||
|
||||
int TwoWire::read()
|
||||
{
|
||||
int value = -1;
|
||||
|
||||
if (rxBufferIndex < rxBufferLength) {
|
||||
value = rxBuffer[rxBufferIndex];
|
||||
++rxBufferIndex;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int TwoWire::peek()
|
||||
{
|
||||
if (rxBufferIndex < rxBufferLength) {
|
||||
return rxBuffer[rxBufferIndex];
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void TwoWire::flush()
|
||||
{
|
||||
rxBufferIndex = 0;
|
||||
rxBufferLength = 0;
|
||||
txBufferIndex = 0;
|
||||
txBufferLength = 0;
|
||||
}
|
||||
|
||||
TwoWire Wire = TwoWire();
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
TwoWire.h - TWI/I2C library for Arduino & Wiring
|
||||
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
|
||||
Modified December 2014 by Ivan Grokhotkov (ivan@esp8266.com) - esp8266 support
|
||||
Modified April 2015 by Hrsto Gochkov (ficeto@ficeto.com) - alternative esp8266 support
|
||||
Modified October 2016 by Marcelo Aquino <marceloaqno@gmail.org> for Raspberry Pi
|
||||
*/
|
||||
|
||||
#ifndef Wire_h
|
||||
#define Wire_h
|
||||
|
||||
#if !DOXYGEN
|
||||
#include <stdint.h>
|
||||
#include "Stream.h"
|
||||
|
||||
#define BUFFER_LENGTH 32
|
||||
|
||||
class TwoWire : public Stream {
|
||||
|
||||
private:
|
||||
static uint8_t rxBuffer[];
|
||||
static uint8_t rxBufferIndex;
|
||||
static uint8_t rxBufferLength;
|
||||
|
||||
static uint8_t txAddress;
|
||||
static uint8_t txBuffer[];
|
||||
static uint8_t txBufferIndex;
|
||||
static uint8_t txBufferLength;
|
||||
|
||||
static uint8_t transmitting;
|
||||
|
||||
public:
|
||||
void begin();
|
||||
void begin(uint8_t address);
|
||||
void begin(int address);
|
||||
void end();
|
||||
void setClock(uint32_t clock);
|
||||
|
||||
void beginTransmission(uint8_t address);
|
||||
void beginTransmission(int address);
|
||||
uint8_t endTransmission(void);
|
||||
|
||||
size_t requestFrom(uint8_t address, size_t size);
|
||||
uint8_t requestFrom(uint8_t address, uint8_t quantity);
|
||||
uint8_t requestFrom(int address, int quantity);
|
||||
|
||||
size_t write(uint8_t data);
|
||||
size_t write(const uint8_t *data, size_t quantity);
|
||||
int available();
|
||||
int read();
|
||||
int peek();
|
||||
void flush();
|
||||
|
||||
inline size_t write(unsigned long n) { return write((uint8_t)n); }
|
||||
inline size_t write(long n) { return write((uint8_t)n); }
|
||||
inline size_t write(unsigned int n) { return write((uint8_t)n); }
|
||||
inline size_t write(int n) { return write((uint8_t)n); }
|
||||
using Print::write;
|
||||
};
|
||||
|
||||
extern TwoWire Wire;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -167,7 +167,7 @@ void rpi_util::pinMode(uint8_t physPin, uint8_t mode) {
|
||||
return;
|
||||
}
|
||||
// Check if SPI is in use and target pin is related to SPI
|
||||
if (SPIClass::isInitialized() && gpioPin >= RPI_GPIO_P1_26 && gpioPin <= RPI_GPIO_P1_23) {
|
||||
if (SPIClass::is_initialized() && gpioPin >= RPI_GPIO_P1_26 && gpioPin <= RPI_GPIO_P1_23) {
|
||||
return;
|
||||
} else {
|
||||
bcm2835_gpio_fsel(gpioPin, mode);
|
||||
@@ -181,7 +181,7 @@ void rpi_util::digitalWrite(uint8_t physPin, uint8_t value) {
|
||||
return;
|
||||
}
|
||||
// Check if SPI is in use and target pin is related to SPI
|
||||
if (SPIClass::isInitialized() && gpioPin >= RPI_GPIO_P1_26 && gpioPin <= RPI_GPIO_P1_23) {
|
||||
if (SPIClass::is_initialized() && gpioPin >= RPI_GPIO_P1_26 && gpioPin <= RPI_GPIO_P1_23) {
|
||||
if (value == LOW && (gpioPin == RPI_GPIO_P1_24 || gpioPin == RPI_GPIO_P1_26)) {
|
||||
SPI.chipSelect(gpioPin);
|
||||
}
|
||||
@@ -199,7 +199,7 @@ uint8_t rpi_util::digitalRead(uint8_t physPin) {
|
||||
return 0;
|
||||
}
|
||||
// Check if SPI is in use and target pin is related to SPI
|
||||
if (SPIClass::isInitialized() && gpioPin >= RPI_GPIO_P1_26 && gpioPin <= RPI_GPIO_P1_23) {
|
||||
if (SPIClass::is_initialized() && gpioPin >= RPI_GPIO_P1_26 && gpioPin <= RPI_GPIO_P1_23) {
|
||||
return 0;
|
||||
} else {
|
||||
return bcm2835_gpio_lev(gpioPin);
|
||||
|
||||
Reference in New Issue
Block a user