first commit

This commit is contained in:
Lazarewicz Julien
2025-07-22 15:27:00 +02:00
commit 6c6451c92c
205 changed files with 44418 additions and 0 deletions

264
RHutil_pigpio/RasPi.cpp Normal file
View File

@@ -0,0 +1,264 @@
// RasPi.cpp
//(9/22/2019) Contributed by Brody M. This file is based off RHutil\RasPi.cpp
// but modified for the pigpio library instead of BCM2835. Original
// code maintained where possible. Unused code commented out and
// left in place.
// Routines for implementing RadioHead on Raspberry Pi
// using BCM2835 library for GPIO
//
// Contributed by Mike Poublon and used with permission
#include <RadioHead.h>
#if (RH_PLATFORM == RH_PLATFORM_RASPI)
#include <sys/time.h>
#include <time.h>
#include "RasPi.h"
#include <stdio.h>
int spiHandle;
//Initialize the values for sanity
timeval RHStartTime;
void SPIClass::begin()
{
//Set SPI Defaults
//Retaining BCM2835 macros for compatibility with RadioHead
uint16_t divider = BCM2835_SPI_CLOCK_DIVIDER_256;
uint8_t bitorder = BCM2835_SPI_BIT_ORDER_MSBFIRST;
uint8_t datamode = BCM2835_SPI_MODE0;
begin(divider, bitorder, datamode);
}
//void SPIClass::begin(uint32_t spiChannel, uint32_t spiBaud, uint32_t spiFlags)
void SPIClass::begin(uint16_t divider, uint8_t bitOrder, uint8_t dataMode)
{
//Set CS pins polarity to low
//bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, 0);
//pigpio SPI Defailts
//SPI Speed
//BCM2835 divider of 256 is approx 1MHz SCLK, depending on model
//uint32_t spiBaud = 1000000;
//Spi Flag Settings
//21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
//b b b b b b R T n n n n W A u2 u1 u0 p2 p1 p0 m m
//m m bits = mode
//Mode 0 = 0 0
uint32_t spiBaud = convertClockDivider(divider);
//datamode is 0 to 3 on BCM2835
uint32_t spiFlags = 0; //Zero is a good default start.
//on pigpio, the least sig 2 bits set datamode, which will probably be zero.
spiFlags = 0x00000000 | (uint32_t) dataMode;
//According to documentation, bitOrder for SPI MAIN in pigpio is always MSBFIRST. So bitOrder ignored.
printf("\nSPI Settings:\nBaud rate=%d\nFlags=%d\n\n", spiBaud, spiFlags);
spiHandle = spiOpen(0, spiBaud, spiFlags); //spiChannel assumed to be zero.
//Initialize a timestamp for millis calculation
gettimeofday(&RHStartTime, NULL);
}
void SPIClass::end()
{
//End the SPI
//bcm2835_spi_end();
spiClose(spiHandle);
}
uint32_t SPIClass::convertClockDivider(uint16_t rate)
{
//Simple divide default RPi SPI clock by divider amount.
//Nominal clock at 250MHz for Zero.
return 250000000/rate;
}
/*
//Thes functions aren't necessary
void SPIClass::setBitOrder(uint8_t bitOrder)
{
//Set the SPI bit Order
bcm2835_spi_setBitOrder(bitOrder);
}
void SPIClass::setDataMode(uint8_t mode)
{
//Set SPI data mode
bcm2835_spi_setDataMode(mode);
}
void SPIClass::setClockDivider(uint16_t rate)
{
//Set SPI clock divider
bcm2835_spi_setClockDivider(rate);
}
*/
byte SPIClass::transfer(byte _data)
{
char txByte[1] = {(char)_data};
char rxByte[1];
//For RF Compatibility, just transfer 1 byte
spiXfer(spiHandle, txByte, rxByte, 1);
return (byte)rxByte[0];
}
//void pinMode(unsigned char pin, unsigned char mode)
void pinMode(uint8_t pin, WiringPinMode mode)
{
if (mode == OUTPUT)
{
gpioSetMode(pin, PI_OUTPUT);
//bcm2835_gpio_fsel(pin,BCM2835_GPIO_FSEL_OUTP);
}
else if (mode == INPUT)
{
gpioSetMode(pin, PI_INPUT);
//bcm2835_gpio_fsel(pin,BCM2835_GPIO_FSEL_INPT);
}
else if (mode == INPUT_PULLUP)
{
gpioSetMode(pin, PI_INPUT);
gpioSetPullUpDown(pin, PI_PUD_UP);
}
else if (mode == INPUT_PULLDOWN)
{
gpioSetMode(pin, PI_INPUT);
gpioSetPullUpDown(pin, PI_PUD_DOWN);
}
else
{
//For safety
gpioSetMode(pin, PI_INPUT);
}
}
void digitalWrite(unsigned char pin, unsigned char value)
{
//bcm2835_gpio_write(pin,value);
//Could have just written gpioWrite(pin, value)
if(value == HIGH)
{
gpioWrite(pin, PI_ON);
}
else
{
gpioWrite(pin, PI_OFF);
}
}
unsigned long millis()
{
//Declare a variable to store current time
struct timeval RHCurrentTime;
//Get current time
gettimeofday(&RHCurrentTime,NULL);
//Calculate the difference between our start time and the end time
unsigned long difference = ((RHCurrentTime.tv_sec - RHStartTime.tv_sec) * 1000);
difference += ((RHCurrentTime.tv_usec - RHStartTime.tv_usec)/1000);
//Return the calculated value
return difference;
}
void delay (unsigned long ms)
{
//Implement Delay function
struct timespec ts;
ts.tv_sec=0;
ts.tv_nsec=(ms * 1000);
nanosleep(&ts,&ts);
}
long random(long min, long max)
{
long diff = max - min;
long ret = diff * rand() + min;
return ret;
}
//******************************
//* Attach Interupt
//* Emulate Arduino Function
//******************************
void attachInterrupt(unsigned char pin, void (*handler)(void), int mode)
{
switch(mode)
{
case CHANGE:
gpioSetISRFunc(pin, EITHER_EDGE, 0, (void (*)(int,int,unsigned int))handler);
break;
case RISING:
gpioSetISRFunc(pin, RISING_EDGE, 0, (void (*)(int,int,unsigned int))handler);
break;
case FALLING:
gpioSetISRFunc(pin, FALLING_EDGE, 0, (void (*)(int,int,unsigned int))handler);
break;
default:
break;
}
}
void SerialSimulator::begin(int baud)
{
//No implementation neccesary - Serial emulation on Linux = standard console
//
//Initialize a timestamp for millis calculation - we do this here as well in case SPI
//isn't used for some reason
gettimeofday(&RHStartTime, NULL);
}
size_t SerialSimulator::println(const char* s)
{
size_t charsPrinted = 0;
charsPrinted = print(s);
printf("\n");
return charsPrinted + 1;
}
size_t SerialSimulator::print(const char* s)
{
return (size_t)printf(s);
}
size_t SerialSimulator::print(unsigned int n, int base)
{
if (base == DEC)
return (size_t)printf("%d", n);
else if (base == HEX)
return (size_t)printf("%02x", n);
else if (base == OCT)
return (size_t)printf("%o", n);
// TODO: BIN
else
return 0;
}
size_t SerialSimulator::print(char ch)
{
return (size_t)printf("%c", ch);
}
size_t SerialSimulator::println(char ch)
{
return (size_t)printf("%c\n", ch);
}
size_t SerialSimulator::print(unsigned char ch, int base)
{
return print((unsigned int)ch, base);
}
size_t SerialSimulator::println(unsigned char ch, int base)
{
size_t charsPrinted = 0;
charsPrinted = print((unsigned int)ch, base);
printf("\n");
return charsPrinted + 1;
}
#endif

214
RHutil_pigpio/RasPi.h Normal file
View File

@@ -0,0 +1,214 @@
// RasPi.h
//(9/22/2019) Contributed by Brody M. This file is based off RHutil\RasPi.h
// but modified for the pigpio library instead of BCM2835. Original
// code maintained where possible. Unused code commented out and
// left in place. WiringPinMode enumeration declaration borrowed from
// STM32ArduinoCompat\wirish.h. Also some enumeration declarations
// "borrowed" from bcm2835.h to maintain original code and for simplicity.
// Routines for implementing RadioHead on Raspberry Pi
// using BCM2835 library for GPIO
// Contributed by Mike Poublon and used with permission
#ifndef RASPI_h
#define RASPI_h
#include <pigpio.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stdint.h>
typedef unsigned char byte;
#ifndef NULL
#define NULL 0
#endif
#define HIGH 0x1
#define LOW 0x0
#define CHANGE 1
#define FALLING 2
#define RISING 3
#define memcpy_P memcpy
//#ifndef OUTPUT
// #define OUTPUT BCM2835_GPIO_FSEL_OUTP
//#endif
class SPIClass
{
public:
//pigpio SPI ID
//We need to make sure this handle can be accessed by all SPI Functions
static byte transfer(byte _data);
// SPI Configuration methods
static void begin(); // Default
//static void begin(uint32_t,uint32_t,uint32_t);
static void begin(uint16_t, uint8_t, uint8_t);
static void end();
//static void setBitOrder(uint8_t);
//static void setDataMode(uint8_t);
//static void setClockDivider(uint16_t);
static uint32_t convertClockDivider(uint16_t);
};
extern SPIClass SPI;
class SerialSimulator
{
public:
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
// TODO: move these from being inlined
static void begin(int baud);
static size_t println(const char* s);
static size_t print(const char* s);
static size_t print(unsigned int n, int base = DEC);
static size_t print(char ch);
static size_t println(char ch);
static size_t print(unsigned char ch, int base = DEC);
static size_t println(unsigned char ch, int base = DEC);
};
extern SerialSimulator Serial;
void RasPiSetup();
//The WiringPinMode enumeration declaration is borrowed from STM32ArduinoCompat\wirish.h
typedef enum WiringPinMode {
OUTPUT, /**< Basic digital output: when the pin is HIGH, the
voltage is held at +3.3v (Vcc) and when it is LOW, it
is pulled down to ground. */
OUTPUT_OPEN_DRAIN, /**< In open drain mode, the pin indicates
"low" by accepting current flow to ground
and "high" by providing increased
impedance. An example use would be to
connect a pin to a bus line (which is pulled
up to a positive voltage by a separate
supply through a large resistor). When the
pin is high, not much current flows through
to ground and the line stays at positive
voltage; when the pin is low, the bus
"drains" to ground with a small amount of
current constantly flowing through the large
resistor from the external supply. In this
mode, no current is ever actually sourced
from the pin. */
INPUT, /**< Basic digital input. The pin voltage is sampled; when
it is closer to 3.3v (Vcc) the pin status is high, and
when it is closer to 0v (ground) it is low. If no
external circuit is pulling the pin voltage to high or
low, it will tend to randomly oscillate and be very
sensitive to noise (e.g., a breath of air across the pin
might cause the state to flip). */
INPUT_ANALOG, /**< This is a special mode for when the pin will be
used for analog (not digital) reads. Enables ADC
conversion to be performed on the voltage at the
pin. */
INPUT_PULLUP, /**< The state of the pin in this mode is reported
the same way as with INPUT, but the pin voltage
is gently "pulled up" towards +3.3v. This means
the state will be high unless an external device
is specifically pulling the pin down to ground,
in which case the "gentle" pull up will not
affect the state of the input. */
INPUT_PULLDOWN, /**< The state of the pin in this mode is reported
the same way as with INPUT, but the pin voltage
is gently "pulled down" towards 0v. This means
the state will be low unless an external device
is specifically pulling the pin up to 3.3v, in
which case the "gentle" pull down will not
affect the state of the input. */
INPUT_FLOATING, /**< Synonym for INPUT. */
PWM, /**< This is a special mode for when the pin will be used for
PWM output (a special case of digital output). */
PWM_OPEN_DRAIN, /**< Like PWM, except that instead of alternating
cycles of LOW and HIGH, the voltage on the pin
consists of alternating cycles of LOW and
floating (disconnected). */
} WiringPinMode;
void pinMode(uint8_t pin, WiringPinMode mode);
//void pinMode(unsigned char pin, unsigned char mode);
void digitalWrite(unsigned char pin, unsigned char value);
unsigned long millis();
void delay (unsigned long delay);
long random(long min, long max);
void attachInterrupt(unsigned char pin, void (*handler)(void), int mode);
//The following lines are borrowed from bcm2835.h, which is part of the BCM2835 library
//(https://www.airspayce.com/mikem/bcm2835/). The original RadioHead library expects
//BCM2835. We could eliminate this by modifying more RadioHead code, but this leaves
//the library more "original". Another option would be to include bcm2835.h directly,
//but this method is easier.
typedef enum
{
BCM2835_SPI_BIT_ORDER_LSBFIRST = 0,
BCM2835_SPI_BIT_ORDER_MSBFIRST = 1
}bcm2835SPIBitOrder;
typedef enum
{
BCM2835_SPI_MODE0 = 0,
BCM2835_SPI_MODE1 = 1,
BCM2835_SPI_MODE2 = 2,
BCM2835_SPI_MODE3 = 3
}bcm2835SPIMode;
typedef enum
{
BCM2835_SPI_CS0 = 0,
BCM2835_SPI_CS1 = 1,
BCM2835_SPI_CS2 = 2,
BCM2835_SPI_CS_NONE = 3
} bcm2835SPIChipSelect;
typedef enum
{
BCM2835_SPI_CLOCK_DIVIDER_65536 = 0,
BCM2835_SPI_CLOCK_DIVIDER_32768 = 32768,
BCM2835_SPI_CLOCK_DIVIDER_16384 = 16384,
BCM2835_SPI_CLOCK_DIVIDER_8192 = 8192,
BCM2835_SPI_CLOCK_DIVIDER_4096 = 4096,
BCM2835_SPI_CLOCK_DIVIDER_2048 = 2048,
BCM2835_SPI_CLOCK_DIVIDER_1024 = 1024,
BCM2835_SPI_CLOCK_DIVIDER_512 = 512,
BCM2835_SPI_CLOCK_DIVIDER_256 = 256,
BCM2835_SPI_CLOCK_DIVIDER_128 = 128,
BCM2835_SPI_CLOCK_DIVIDER_64 = 64,
BCM2835_SPI_CLOCK_DIVIDER_32 = 32,
BCM2835_SPI_CLOCK_DIVIDER_16 = 16,
BCM2835_SPI_CLOCK_DIVIDER_8 = 8,
BCM2835_SPI_CLOCK_DIVIDER_4 = 4,
BCM2835_SPI_CLOCK_DIVIDER_2 = 2,
BCM2835_SPI_CLOCK_DIVIDER_1 = 1
} bcm2835SPIClockDivider;
#endif