Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge master to rpi_gpiod branch #271

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,39 @@ echo "Building OpenSprinkler..."
if [ "$1" == "demo" ]; then
echo "Installing required libraries..."
apt-get install -y libmosquitto-dev
echo "Compiling firmware..."
echo "Compiling demo firmware..."
g++ -o OpenSprinkler -DDEMO -std=c++14 main.cpp OpenSprinkler.cpp program.cpp opensprinkler_server.cpp utils.cpp weather.cpp gpio.cpp etherport.cpp mqtt.cpp -lpthread -lmosquitto
elif [ "$1" == "osbo" ]; then
echo "Installing required libraries..."
apt-get install -y libmosquitto-dev
echo "Compiling firmware..."
echo "Compiling osbo firmware..."
g++ -o OpenSprinkler -DOSBO -std=c++14 main.cpp OpenSprinkler.cpp program.cpp opensprinkler_server.cpp utils.cpp weather.cpp gpio.cpp etherport.cpp mqtt.cpp -lpthread -lmosquitto
else
echo "Installing required libraries..."
apt-get update
apt-get install -y libmosquitto-dev
apt-get install -y raspi-gpio
apt-get install -y libi2c-dev
apt-get install -y libssl-dev
apt-get install -y libgpiod-dev
if ! command -v raspi-gpio &> /dev/null
then
echo "Command raspi-gpio is required and is not installed"
exit 0
fi
echo "Compiling firmware..."
g++ -o OpenSprinkler -DOSPI -std=c++14 main.cpp OpenSprinkler.cpp program.cpp opensprinkler_server.cpp utils.cpp weather.cpp gpio.cpp etherport.cpp mqtt.cpp -lpthread -lmosquitto

USEGPIO=""
GPIOLIB=""


if [ -h "/sys/class/gpio/gpiochip512" ]; then
echo "using libgpiod"
USEGPIO="-DLIBGPIOD"
GPIOLIB="-lgpiod"
fi

echo "Compiling ospi firmware..."
g++ -o OpenSprinkler -DOSPI $USEGPIO -std=c++14 main.cpp OpenSprinkler.cpp program.cpp opensprinkler_server.cpp utils.cpp weather.cpp gpio.cpp etherport.cpp mqtt.cpp -lpthread -lmosquitto $GPIOLIB
fi

if [ ! "$SILENT" = true ] && [ -f OpenSprinkler.launch ] && [ ! -f /etc/init.d/OpenSprinkler.sh ]; then
Expand Down
2 changes: 1 addition & 1 deletion defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ typedef unsigned long ulong;
// if this number is different from the one stored in non-volatile memory
// a device reset will be automatically triggered

#define OS_FW_MINOR 3 // Firmware minor version
#define OS_FW_MINOR 4 // Firmware minor version

/** Hardware version base numbers */
#define OS_HW_VERSION_BASE 0x00 // OpenSprinkler
Expand Down
134 changes: 134 additions & 0 deletions gpio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ byte digitalReadExt(byte pin) {

#elif defined(OSPI) || defined(OSBO)

#if !defined(LIBGPIOD) // use classic sysfs

#include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>
Expand Down Expand Up @@ -442,6 +444,138 @@ void attachInterrupt(int pin, const char* mode, void (*isr)(void)) {
delay(1) ;
pthread_mutex_unlock (&pinMutex) ;
}
#else // use GPIOD

/**
* NEW GPIO Implementation for Raspberry Pi OS 12 (bookworm)
*
* Thanks to Jason Balonso
* https://github.com/jbalonso/
*
*
*/

#include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <poll.h>
#include <pthread.h>
#include <gpiod.h>

#include "utils.h"

#define BUFFER_MAX 64
#define GPIO_MAX 64

// GPIO interfaces
const char *gpio_chipname = "gpiochip0";
const char *gpio_consumer = "opensprinkler";

struct gpiod_chip *chip = NULL;
struct gpiod_line* gpio_lines[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
};

int assert_gpiod_chip() {
if( !chip ) {
chip = gpiod_chip_open_by_name(gpio_chipname);
if( !chip ) {
DEBUG_PRINTLN("failed to open gpio chip");
return -1;
} else {
DEBUG_PRINTLN("gpio chip opened");
return 0;
}
}
return 0;
}

int assert_gpiod_line(int pin) {
if( !gpio_lines[pin] ) {
if( assert_gpiod_chip() ) { return -1; }
gpio_lines[pin] = gpiod_chip_get_line(chip, pin);
if( !gpio_lines[pin] ) {
DEBUG_PRINT("failed to open gpio line ");
DEBUG_PRINTLN(pin);
return -1;
} else {
DEBUG_PRINT("opened gpio line ");
DEBUG_PRINT(pin);
return 0;
}
}
return 0;
}

/** Set pin mode, in or out */
void pinMode(int pin, byte mode) {
if( assert_gpiod_line(pin) ) { return; }
switch(mode) {
case INPUT:
gpiod_line_request_input(gpio_lines[pin], gpio_consumer);
break;
case INPUT_PULLUP:
gpiod_line_request_input_flags(gpio_lines[pin], gpio_consumer, GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP);
break;
case OUTPUT:
gpiod_line_request_output(gpio_lines[pin], gpio_consumer, LOW);
break;
default:
DEBUG_PRINTLN("invalid pin direction");
break;
}

return;
}

/** Read digital value */
byte digitalRead(int pin) {
if( !gpio_lines[pin] ) {
DEBUG_PRINT("tried to read uninitialized pin ");
DEBUG_PRINTLN(pin);
return 0;
}
int val = gpiod_line_get_value(gpio_lines[pin]);
if( val < 0 ) {
DEBUG_PRINT("failed to read value on pin ");
DEBUG_PRINTLN(pin);
return 0;
}
return val;
}

/** Write digital value */
void digitalWrite(int pin, byte value) {
if( !gpio_lines[pin] ) {
DEBUG_PRINT("tried to write uninitialized pin ");
DEBUG_PRINTLN(pin);
return;
}

int res;
res = gpiod_line_set_value(gpio_lines[pin], value);
if( res ) {
DEBUG_PRINT("failed to write value on pin ");
DEBUG_PRINTLN(pin);
}
}

void attachInterrupt(int pin, const char* mode, void (*isr)(void)) {}
void gpio_write(int fd, byte value) {}
int gpio_fd_open(int pin, int mode) {return 0;}
void gpio_fd_close(int fd) {}

#endif

#else

void pinMode(int pin, byte mode) {}
Expand Down
32 changes: 18 additions & 14 deletions opensprinkler_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2091,20 +2091,24 @@ void on_ap_upload() { on_sta_upload(); }

void start_server_client() {
if(!otf) return;

otf->on("/", server_home); // handle home page
otf->on("/index.html", server_home);
otf->on("/update", on_sta_update, OTF::HTTP_GET); // handle firmware update
update_server->on("/update", HTTP_POST, on_sta_upload_fin, on_sta_upload);

// set up all other handlers
char uri[4];
uri[0]='/';
uri[3]=0;
for(byte i=0;i<sizeof(urls)/sizeof(URLHandler);i++) {
uri[1]=pgm_read_byte(_url_keys+2*i);
uri[2]=pgm_read_byte(_url_keys+2*i+1);
otf->on(uri, urls[i]);
static bool callback_initialized = false;

if(!callback_initialized) {
otf->on("/", server_home); // handle home page
otf->on("/index.html", server_home);
otf->on("/update", on_sta_update, OTF::HTTP_GET); // handle firmware update
update_server->on("/update", HTTP_POST, on_sta_upload_fin, on_sta_upload);

// set up all other handlers
char uri[4];
uri[0]='/';
uri[3]=0;
for(byte i=0;i<sizeof(urls)/sizeof(URLHandler);i++) {
uri[1]=pgm_read_byte(_url_keys+2*i);
uri[2]=pgm_read_byte(_url_keys+2*i+1);
otf->on(uri, urls[i]);
}
callback_initialized = true;
}
update_server->begin();
}
Expand Down
Loading