RPi: Add support for I2C

Add MyHw file for RaspberryPi.

Fix compilation warnings in x86.

Fix some error messages.
This commit is contained in:
Marcelo Aquino
2016-10-16 13:40:23 -02:00
parent 3d51b31e71
commit 69ac4b759a
21 changed files with 817 additions and 147 deletions
+25 -2
View File
@@ -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
/**
+2 -2
View File
@@ -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, ... ) {
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+151
View File
@@ -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);
}
+34
View File
@@ -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
+2
View File
@@ -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
View File
@@ -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;
}