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

Implement support for Raspberry Pi 5 using lgpio library #499

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
47 changes: 45 additions & 2 deletions RCSwitch.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

#include "RCSwitch.h"

#ifdef RaspberryPi
#if defined( RaspberryPi ) || defined( RaspberryPi5 )
// PROGMEM and _P functions are for AVR based microprocessors,
// so we must normalize these for the ARM processor:
#define PROGMEM
Expand Down Expand Up @@ -121,6 +121,12 @@ RCSwitch::RCSwitch() {
#endif
}

#if defined( RaspberryPi5 )
RCSwitch::~RCSwitch() {
RCSwitch::setLgGpioHandle(0);
}
#endif

/**
* Sets the protocol to send.
*/
Expand Down Expand Up @@ -174,6 +180,16 @@ void RCSwitch::setReceiveTolerance(int nPercent) {
}
#endif

#if defined( RaspberryPi5 )
void RCSwitch::setLgGpioHandle(int gpiochip) {
if (gpiochip) {
RCSwitch::nLgGpioHandle = lgGpiochipOpen(gpiochip);
} else if (RCSwitch::nLgGpioHandle) {
lgGpiochipClose(RCSwitch::nLgGpioHandle);
RCSwitch::nLgGpioHandle = 0;
}
}
#endif

/**
* Enable transmissions
Expand All @@ -182,7 +198,11 @@ void RCSwitch::setReceiveTolerance(int nPercent) {
*/
void RCSwitch::enableTransmit(int nTransmitterPin) {
this->nTransmitterPin = nTransmitterPin;
#if defined( RaspberryPi5 )
lgGpioClaimOutput(this->nLgGpioHandle, 0, this->nTransmitterPin, 0);
#else
pinMode(this->nTransmitterPin, OUTPUT);
#endif
}

/**
Expand Down Expand Up @@ -518,7 +538,11 @@ void RCSwitch::send(unsigned long code, unsigned int length) {
}

// Disable transmit after sending (i.e., for inverted protocols)
#if defined( RaspberryPi5 )
lgGpioWrite(this->nLgGpioHandle, this->nTransmitterPin, LOW);
#else
digitalWrite(this->nTransmitterPin, LOW);
#endif

#if not defined( RCSwitchDisableReceiving )
// enable receiver again if we just disabled it
Expand All @@ -535,10 +559,17 @@ void RCSwitch::transmit(HighLow pulses) {
uint8_t firstLogicLevel = (this->protocol.invertedSignal) ? LOW : HIGH;
uint8_t secondLogicLevel = (this->protocol.invertedSignal) ? HIGH : LOW;

#if defined( RaspberryPi5 )
lgGpioWrite(this->nLgGpioHandle, this->nTransmitterPin, firstLogicLevel);
lguSleep( (float)this->protocol.pulseLength * pulses.high / 1000000);
lgGpioWrite(this->nLgGpioHandle, this->nTransmitterPin, secondLogicLevel);
lguSleep( (float)this->protocol.pulseLength * pulses.low / 1000000);
#else
digitalWrite(this->nTransmitterPin, firstLogicLevel);
delayMicroseconds( this->protocol.pulseLength * pulses.high);
digitalWrite(this->nTransmitterPin, secondLogicLevel);
delayMicroseconds( this->protocol.pulseLength * pulses.low);
#endif
}


Expand All @@ -557,6 +588,10 @@ void RCSwitch::enableReceive() {
RCSwitch::nReceivedBitlength = 0;
#if defined(RaspberryPi) // Raspberry Pi
wiringPiISR(this->nReceiverInterrupt, INT_EDGE_BOTH, &handleInterrupt);
#elif defined(RaspberryPi5) // Raspberry Pi 5
static int userdata = 1;
lgGpioSetAlertsFunc(this->nLgGpioHandle, this->nReceiverInterrupt, handleInterrupt, &userdata);
lgGpioClaimAlert(this->nLgGpioHandle, 0, LG_BOTH_EDGES, this->nReceiverInterrupt, -1);
#else // Arduino
attachInterrupt(this->nReceiverInterrupt, handleInterrupt, CHANGE);
#endif
Expand All @@ -567,7 +602,7 @@ void RCSwitch::enableReceive() {
* Disable receiving data
*/
void RCSwitch::disableReceive() {
#if not defined(RaspberryPi) // Arduino
#if not defined(RaspberryPi) and not defined(RaspberryPi5) // Arduino
detachInterrupt(this->nReceiverInterrupt);
#endif // For Raspberry Pi (wiringPi) you can't unregister the ISR
this->nReceiverInterrupt = -1;
Expand Down Expand Up @@ -668,13 +703,21 @@ bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCoun
return false;
}

#if defined( RaspberryPi5 )
void RECEIVE_ATTR RCSwitch::handleInterrupt(int e, lgGpioAlert_p evt, void *data) {
#else
void RECEIVE_ATTR RCSwitch::handleInterrupt() {
#endif

static unsigned int changeCount = 0;
static unsigned long lastTime = 0;
static unsigned int repeatCount = 0;

#if defined( RaspberryPi5 )
const long time = lguTimestamp();
#else
const long time = micros();
#endif
const unsigned int duration = time - lastTime;

if (duration > RCSwitch::nSeparationLimit) {
Expand Down
23 changes: 21 additions & 2 deletions RCSwitch.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,20 @@
#elif defined(ENERGIA) // LaunchPad, FraunchPad and StellarPad specific
#include "Energia.h"
#elif defined(RPI) // Raspberry Pi
#define RaspberryPi

// Include libraries for RPi:
#include <string.h> /* memcpy */
#include <stdlib.h> /* abs */

#if (RPI==5)
#define RaspberryPi5
#define LOW LG_LOW
#define HIGH LG_HIGH
#include <lgpio.h>
#else
#define RaspberryPi
#include <wiringPi.h>
#endif

#elif defined(SPARK)
#include "application.h"
#else
Expand All @@ -64,6 +72,9 @@ class RCSwitch {

public:
RCSwitch();
#if defined( RaspberryPi5 )
~RCSwitch();
#endif

void switchOn(int nGroupNumber, int nSwitchNumber);
void switchOff(int nGroupNumber, int nSwitchNumber);
Expand Down Expand Up @@ -101,6 +112,9 @@ class RCSwitch {
#if not defined( RCSwitchDisableReceiving )
void setReceiveTolerance(int nPercent);
#endif
#if defined( RaspberryPi5 )
void setLgGpioHandle(int nLgGpioHandle);
#endif

/**
* Description of a single pule, which consists of a high signal
Expand Down Expand Up @@ -156,7 +170,12 @@ class RCSwitch {
void transmit(HighLow pulses);

#if not defined( RCSwitchDisableReceiving )
#if defined( RaspberryPi5 )
static void handleInterrupt(int e, lgGpioAlert_p evt, void *data);
int nLgGpioHandle;
#else
static void handleInterrupt();
#endif
static bool receiveProtocol(const int p, unsigned int changeCount);
int nReceiverInterrupt;
#endif
Expand Down