@@ -281,13 +281,33 @@ static void doLoad (int argc, char *argv []) | |||||
if (!moduleLoaded (module1)) | if (!moduleLoaded (module1)) | ||||
{ | { | ||||
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ; | sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ; | ||||
system (cmd) ; | |||||
int ret = system(cmd); | |||||
if (ret == -1) { | |||||
perror("Error executing command"); | |||||
} else if (WIFEXITED(ret)) { | |||||
int exit_status = WEXITSTATUS(ret); | |||||
if (exit_status != 0) { | |||||
fprintf(stderr, "Command failed with exit status %d\n", exit_status); | |||||
} | |||||
} else { | |||||
fprintf(stderr, "Command terminated by signal\n"); | |||||
} | |||||
} | } | ||||
if (!moduleLoaded (module2)) | if (!moduleLoaded (module2)) | ||||
{ | { | ||||
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ; | sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ; | ||||
system (cmd) ; | |||||
int ret = system(cmd); | |||||
if (ret == -1) { | |||||
perror("Error executing command"); | |||||
} else if (WIFEXITED(ret)) { | |||||
int exit_status = WEXITSTATUS(ret); | |||||
if (exit_status != 0) { | |||||
fprintf(stderr, "Command failed with exit status %d\n", exit_status); | |||||
} | |||||
} else { | |||||
fprintf(stderr, "Command terminated by signal\n"); | |||||
} | |||||
} | } | ||||
if (!moduleLoaded (module2)) | if (!moduleLoaded (module2)) | ||||
@@ -341,13 +361,33 @@ static void doUnLoad (int argc, char *argv []) | |||||
if (moduleLoaded (module1)) | if (moduleLoaded (module1)) | ||||
{ | { | ||||
sprintf (cmd, "%s %s", findExecutable (RMMOD), module1) ; | sprintf (cmd, "%s %s", findExecutable (RMMOD), module1) ; | ||||
system (cmd) ; | |||||
int ret = system(cmd); | |||||
if (ret == -1) { | |||||
perror("Error executing command"); | |||||
} else if (WIFEXITED(ret)) { | |||||
int exit_status = WEXITSTATUS(ret); | |||||
if (exit_status != 0) { | |||||
fprintf(stderr, "Command failed with exit status %d\n", exit_status); | |||||
} | |||||
} else { | |||||
fprintf(stderr, "Command terminated by signal\n"); | |||||
} | |||||
} | } | ||||
if (moduleLoaded (module2)) | if (moduleLoaded (module2)) | ||||
{ | { | ||||
sprintf (cmd, "%s %s", findExecutable (RMMOD), module2) ; | sprintf (cmd, "%s %s", findExecutable (RMMOD), module2) ; | ||||
system (cmd) ; | |||||
int ret = system(cmd); | |||||
if (ret == -1) { | |||||
perror("Error executing command"); | |||||
} else if (WIFEXITED(ret)) { | |||||
int exit_status = WEXITSTATUS(ret); | |||||
if (exit_status != 0) { | |||||
fprintf(stderr, "Command failed with exit status %d\n", exit_status); | |||||
} | |||||
} else { | |||||
fprintf(stderr, "Command terminated by signal\n"); | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -416,15 +456,14 @@ static volatile int globalCounter ; | |||||
void printgpioflush(const char* text) { | void printgpioflush(const char* text) { | ||||
if (gpioDebug) { | if (gpioDebug) { | ||||
printf(text); | |||||
printf("%s", text); | |||||
fflush(stdout); | fflush(stdout); | ||||
} | } | ||||
} | } | ||||
void printgpio(const char* text) { | void printgpio(const char* text) { | ||||
if (gpioDebug) { | if (gpioDebug) { | ||||
printf(text); | |||||
fflush(stdout); | |||||
printf("%s", text); | |||||
} | } | ||||
} | } | ||||
@@ -474,7 +513,7 @@ void doWfi (int argc, char *argv []) | |||||
exit (1) ; | exit (1) ; | ||||
} | } | ||||
printgpio("wait for interrupt function call \n"); | |||||
printgpio("wait for interrupt function call\n"); | |||||
for (int Sec=0; Sec<timeoutSec; ++Sec) { | for (int Sec=0; Sec<timeoutSec; ++Sec) { | ||||
printgpioflush("."); | printgpioflush("."); | ||||
delay (999); | delay (999); | ||||
@@ -1112,7 +1151,10 @@ static void doVersion (char *argv []) | |||||
{ | { | ||||
if ((fd = fopen ("/proc/device-tree/model", "r")) != NULL) | if ((fd = fopen ("/proc/device-tree/model", "r")) != NULL) | ||||
{ | { | ||||
fgets (name, 80, fd) ; | |||||
if (fgets(name, sizeof(name), fd) == NULL) { | |||||
// Handle error or end of file condition | |||||
perror("Error reading /proc/device-tree/model"); | |||||
} | |||||
fclose (fd) ; | fclose (fd) ; | ||||
printf (" Model: %s\n", name) ; | printf (" Model: %s\n", name) ; | ||||
} | } | ||||
@@ -43,15 +43,20 @@ | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void waitForConversion (int fd, unsigned char *buffer, int n) | |||||
void waitForConversion(int fd, unsigned char *buffer, int n) | |||||
{ | { | ||||
for (;;) | |||||
{ | |||||
read (fd, buffer, n) ; | |||||
if ((buffer [n-1] & 0x80) == 0) | |||||
break ; | |||||
delay (1) ; | |||||
} | |||||
for (;;) { | |||||
ssize_t bytes_read = read(fd, buffer, n); | |||||
if (bytes_read != n) { | |||||
perror("Error reading from file descriptor"); | |||||
return; | |||||
} | |||||
if ((buffer[n - 1] & 0x80) == 0) | |||||
break; | |||||
delay(1); | |||||
} | |||||
} | } | ||||
/* | /* | ||||
@@ -24,6 +24,7 @@ | |||||
*/ | */ | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <stdio.h> | |||||
#include "wiringPi.h" | #include "wiringPi.h" | ||||
#include "wiringPiI2C.h" | #include "wiringPiI2C.h" | ||||
@@ -41,7 +42,10 @@ static void myAnalogWrite (struct wiringPiNodeStruct *node, UNU int pin, int val | |||||
unsigned char b [2] ; | unsigned char b [2] ; | ||||
b [0] = 0x40 ; | b [0] = 0x40 ; | ||||
b [1] = value & 0xFF ; | b [1] = value & 0xFF ; | ||||
write (node->fd, b, 2) ; | |||||
ssize_t bytes_written = write(node->fd, b, 2); | |||||
if (bytes_written != 2) { | |||||
perror("Error writing to file descriptor"); | |||||
} | |||||
} | } | ||||
@@ -35,9 +35,12 @@ | |||||
#define SHARED_NAME "wiringPiPseudoPins" | #define SHARED_NAME "wiringPiPseudoPins" | ||||
#define PSEUDO_PINS 64 | #define PSEUDO_PINS 64 | ||||
#include <stdio.h> | |||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/mman.h> | #include <sys/mman.h> | ||||
#include <fcntl.h> | |||||
#include <stdint.h> | |||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
@@ -45,21 +48,20 @@ | |||||
#include "pseudoPins.h" | #include "pseudoPins.h" | ||||
static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) | |||||
static int myAnalogRead(struct wiringPiNodeStruct *node, int pin) | |||||
{ | { | ||||
int *ptr = (int *)node->data0 ; | |||||
int myPin = pin - node->pinBase ; | |||||
int *ptr = (int *)(intptr_t)node->data0; // Cast to intptr_t to handle pointer-to-integer conversion | |||||
int myPin = pin - node->pinBase; | |||||
return *(ptr + myPin) ; | |||||
return *(ptr + myPin); | |||||
} | } | ||||
static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) | |||||
static void myAnalogWrite(struct wiringPiNodeStruct *node, int pin, int value) | |||||
{ | { | ||||
int *ptr = (int *)node->data0 ; | |||||
int myPin = pin - node->pinBase ; | |||||
int *ptr = (int *)(intptr_t)node->data0; | |||||
int myPin = pin - node->pinBase; | |||||
*(ptr + myPin) = value ; | |||||
*(ptr + myPin) = value; | |||||
} | } | ||||
@@ -69,27 +71,39 @@ static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
int pseudoPinsSetup (const int pinBase) | |||||
{ | |||||
struct wiringPiNodeStruct *node ; | |||||
void *ptr ; | |||||
node = wiringPiNewNode (pinBase, PSEUDO_PINS) ; | |||||
node->fd = shm_open (SHARED_NAME, O_CREAT | O_RDWR, 0666) ; | |||||
if (node->fd < 0) | |||||
return FALSE ; | |||||
if (ftruncate (node->fd, PSEUDO_PINS * sizeof (int)) < 0) | |||||
return FALSE ; | |||||
ptr = mmap (NULL, PSEUDO_PINS * sizeof (int), PROT_READ | PROT_WRITE, MAP_SHARED, node->fd, 0) ; | |||||
node->data0 = (unsigned int)ptr ; | |||||
node->analogRead = myAnalogRead ; | |||||
node->analogWrite = myAnalogWrite ; | |||||
return TRUE ; | |||||
int pseudoPinsSetup(const int pinBase) | |||||
{ | |||||
struct wiringPiNodeStruct *node; | |||||
void *ptr; | |||||
node = wiringPiNewNode(pinBase, PSEUDO_PINS); | |||||
if (node == NULL) { | |||||
fprintf(stderr, "Error creating new wiringPi node"); | |||||
return FALSE; | |||||
} | |||||
node->fd = shm_open(SHARED_NAME, O_CREAT | O_RDWR, 0666); | |||||
if (node->fd < 0) { | |||||
perror("Error opening shared memory"); | |||||
return FALSE; | |||||
} | |||||
if (ftruncate(node->fd, PSEUDO_PINS * sizeof(int)) < 0) { | |||||
perror("Error resizing shared memory"); | |||||
return FALSE; | |||||
} | |||||
ptr = mmap(NULL, PSEUDO_PINS * sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, node->fd, 0); | |||||
if (ptr == MAP_FAILED) { | |||||
perror("Error mapping shared memory"); | |||||
return FALSE; | |||||
} | |||||
node->data0 = (unsigned int)(uintptr_t)ptr; | |||||
node->analogRead = myAnalogRead; | |||||
node->analogWrite = myAnalogWrite; | |||||
return TRUE; | |||||
} | } |
@@ -558,8 +558,8 @@ int GetMaxPin() { | |||||
} | } | ||||
#define RETURN_ON_MODEL5 if (PI_MODEL_5 == RaspberryPiModel) { if (wiringPiDebug) printf("Function not supported on Pi5\n"); return; } | |||||
#define RETURN_ON_MODEL5 if (PI_MODEL_5 == RaspberryPiModel) { if (wiringPiDebug) printf("Function not supported on Pi5\n"); return; } | |||||
int FailOnModel5() { | int FailOnModel5() { | ||||
if (PI_MODEL_5 == RaspberryPiModel) { | if (PI_MODEL_5 == RaspberryPiModel) { | ||||
return wiringPiFailure (WPI_ALMOST, "Function not supported on Raspberry Pi 5.\n" | return wiringPiFailure (WPI_ALMOST, "Function not supported on Raspberry Pi 5.\n" | ||||
@@ -831,12 +831,12 @@ static void usingGpioMemCheck (const char *what) | |||||
void PrintSystemStdErr () { | void PrintSystemStdErr () { | ||||
struct utsname sys_info; | struct utsname sys_info; | ||||
if (uname(&sys_info) == 0) { | if (uname(&sys_info) == 0) { | ||||
fprintf (stderr, " wiringpi = %d.%d\n", VERSION_MAJOR, VERSION_MINOR); | |||||
fprintf (stderr, " system name = %s\n", sys_info.sysname); | |||||
//fprintf (stderr, " node name = %s\n", sys_info.nodename); | |||||
fprintf (stderr, " release = %s\n", sys_info.release); | |||||
fprintf (stderr, " version = %s\n", sys_info.version); | |||||
fprintf (stderr, " machine = %s\n", sys_info.machine); | |||||
fprintf (stderr, " WiringPi : %d.%d\n", VERSION_MAJOR, VERSION_MINOR); | |||||
fprintf (stderr, " system name : %s\n", sys_info.sysname); | |||||
//fprintf (stderr, " node name : %s\n", sys_info.nodename); | |||||
fprintf (stderr, " release : %s\n", sys_info.release); | |||||
fprintf (stderr, " version : %s\n", sys_info.version); | |||||
fprintf (stderr, " machine : %s\n", sys_info.machine); | |||||
if (strstr(sys_info.machine, "arm") == NULL && strstr(sys_info.machine, "aarch")==NULL) { | if (strstr(sys_info.machine, "arm") == NULL && strstr(sys_info.machine, "aarch")==NULL) { | ||||
fprintf (stderr, " -> This is not an ARM architecture; it cannot be a Raspberry Pi.\n") ; | fprintf (stderr, " -> This is not an ARM architecture; it cannot be a Raspberry Pi.\n") ; | ||||
} | } | ||||
@@ -1200,16 +1200,16 @@ void setPadDrive (int group, int value) | |||||
if (PI_MODEL_5 == RaspberryPiModel) { | if (PI_MODEL_5 == RaspberryPiModel) { | ||||
if (-1==group) { | if (-1==group) { | ||||
printf ("Pad register:\n"); | printf ("Pad register:\n"); | ||||
for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) { | |||||
for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) { | |||||
unsigned int drive = (pads[1+pin] & RP1_PAD_DRIVE_MASK)>>4; | unsigned int drive = (pads[1+pin] & RP1_PAD_DRIVE_MASK)>>4; | ||||
printf (" Pin %2d: 0x%08X drive: 0x%d = %2dmA\n", pin, pads[1+pin], drive, 0==drive ? 2 : drive*4) ; | printf (" Pin %2d: 0x%08X drive: 0x%d = %2dmA\n", pin, pads[1+pin], drive, 0==drive ? 2 : drive*4) ; | ||||
} | |||||
} | |||||
} | } | ||||
if (group !=0) { // only GPIO range @RP1 | if (group !=0) { // only GPIO range @RP1 | ||||
return ; | return ; | ||||
} | |||||
} | |||||
switch(value) { | switch(value) { | ||||
default: | |||||
default: | |||||
/* bcm*/ // RP1 | /* bcm*/ // RP1 | ||||
case 0: /* 2mA*/ value=0; break; // 2mA | case 0: /* 2mA*/ value=0; break; // 2mA | ||||
case 1: /* 4mA*/ | case 1: /* 4mA*/ | ||||
@@ -1220,9 +1220,9 @@ void setPadDrive (int group, int value) | |||||
case 6: /*14mA*/ | case 6: /*14mA*/ | ||||
case 7: /*16mA*/ value=3; break; //12mA | case 7: /*16mA*/ value=3; break; //12mA | ||||
} | } | ||||
wrVal = (value << 4); //Drive strength 0-3 | |||||
wrVal = (value << 4); //Drive strength 0-3 | |||||
//set for all pins even when it's avaiable for each pin separately | //set for all pins even when it's avaiable for each pin separately | ||||
for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) { | |||||
for (int pin=0, maxpin=GetMaxPin(); pin<=maxpin; ++pin) { | |||||
pads[1+pin] = (pads[1+pin] & RP1_INV_PAD_DRIVE_MASK) | wrVal; | pads[1+pin] = (pads[1+pin] & RP1_INV_PAD_DRIVE_MASK) | wrVal; | ||||
} | } | ||||
rdVal = pads[1+17]; // only pin 17 readback, for logging | rdVal = pads[1+17]; // only pin 17 readback, for logging | ||||
@@ -1234,7 +1234,7 @@ void setPadDrive (int group, int value) | |||||
if ((group < 0) || (group > 2)) | if ((group < 0) || (group > 2)) | ||||
return ; | return ; | ||||
wrVal = BCM_PASSWORD | 0x18 | value; //Drive strength 0-7 | |||||
wrVal = BCM_PASSWORD | 0x18 | value; //Drive strength 0-7 | |||||
*(pads + group + 11) = wrVal ; | *(pads + group + 11) = wrVal ; | ||||
rdVal = *(pads + group + 11); | rdVal = *(pads + group + 11); | ||||
} | } | ||||
@@ -1620,7 +1620,7 @@ void pinModeAlt (int pin, int mode) | |||||
if (PI_MODEL_5 == RaspberryPiModel) { | if (PI_MODEL_5 == RaspberryPiModel) { | ||||
//confusion! diffrent to to BCM! this is taking directly the value for the register | |||||
//confusion! diffrent to to BCM! this is taking directly the value for the register | |||||
/* | /* | ||||
"alt0" 0b100 | "alt0" 0b100 | ||||
"alt1" 0b101 | "alt1" 0b101 | ||||
@@ -1728,7 +1728,7 @@ void pinMode (int pin, int mode) | |||||
shift = gpioToShift [pin] ; | shift = gpioToShift [pin] ; | ||||
if (mode == INPUT) { | if (mode == INPUT) { | ||||
if (PI_MODEL_5 == RaspberryPiModel) { | |||||
if (PI_MODEL_5 == RaspberryPiModel) { | |||||
pads[1+pin] = (pin<=8) ? RP1_PAD_DEFAULT_0TO8 : RP1_PAD_DEFAULT_FROM9; | pads[1+pin] = (pin<=8) ? RP1_PAD_DEFAULT_0TO8 : RP1_PAD_DEFAULT_FROM9; | ||||
gpio[2*pin+1] = RP1_FSEL_GPIO | RP1_DEBOUNCE_DEFAULT; // GPIO | gpio[2*pin+1] = RP1_FSEL_GPIO | RP1_DEBOUNCE_DEFAULT; // GPIO | ||||
rio[RP1_RIO_OE + RP1_CLR_OFFSET] = 1<<pin; // Input | rio[RP1_RIO_OE + RP1_CLR_OFFSET] = 1<<pin; // Input | ||||
@@ -2060,7 +2060,7 @@ void digitalWrite (int pin, int value) | |||||
rio[RP1_RIO_OUT + RP1_CLR_OFFSET] = 1<<pin; | rio[RP1_RIO_OUT + RP1_CLR_OFFSET] = 1<<pin; | ||||
} else { | } else { | ||||
//printf("Set pin %d >>0x%08x<< to high\n", pin, 1<<pin); | //printf("Set pin %d >>0x%08x<< to high\n", pin, 1<<pin); | ||||
rio[RP1_RIO_OUT + RP1_SET_OFFSET] = 1<<pin; | |||||
rio[RP1_RIO_OUT + RP1_SET_OFFSET] = 1<<pin; | |||||
} | } | ||||
} else { | } else { | ||||
if (value == LOW) | if (value == LOW) | ||||
@@ -2316,7 +2316,7 @@ unsigned int digitalReadByte2 (void) | |||||
int waitForInterrupt (int pin, int mS) | int waitForInterrupt (int pin, int mS) | ||||
{ | { | ||||
int fd, ret; | |||||
int fd, ret; | |||||
struct pollfd polls ; | struct pollfd polls ; | ||||
struct gpioevent_data evdata; | struct gpioevent_data evdata; | ||||
//struct gpio_v2_line_request req2; | //struct gpio_v2_line_request req2; | ||||
@@ -2339,7 +2339,7 @@ int waitForInterrupt (int pin, int mS) | |||||
if (ret <= 0) { | if (ret <= 0) { | ||||
fprintf(stderr, "wiringPi: ERROR: poll returned=%d\n", ret); | fprintf(stderr, "wiringPi: ERROR: poll returned=%d\n", ret); | ||||
} else { | } else { | ||||
//if (polls.revents & POLLIN) | |||||
//if (polls.revents & POLLIN) | |||||
if (wiringPiDebug) { | if (wiringPiDebug) { | ||||
printf ("wiringPi: IRQ line %d received %d, fd=%d\n", pin, ret, isrFds[pin]) ; | printf ("wiringPi: IRQ line %d received %d, fd=%d\n", pin, ret, isrFds[pin]) ; | ||||
} | } | ||||
@@ -2427,7 +2427,7 @@ int waitForInterruptClose (int pin) { | |||||
if (isrFds[pin]>0) { | if (isrFds[pin]>0) { | ||||
if (wiringPiDebug) { | if (wiringPiDebug) { | ||||
printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; | printf ("wiringPi: waitForInterruptClose close thread 0x%lX\n", (unsigned long)isrThreads[pin]) ; | ||||
} | |||||
} | |||||
if (pthread_cancel(isrThreads[pin]) == 0) { | if (pthread_cancel(isrThreads[pin]) == 0) { | ||||
if (wiringPiDebug) { | if (wiringPiDebug) { | ||||
printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ; | printf ("wiringPi: waitForInterruptClose thread canceled successfuly\n") ; | ||||
@@ -2527,7 +2527,7 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) | |||||
if(waitForInterruptInit (pin, mode)<0) { | if(waitForInterruptInit (pin, mode)<0) { | ||||
if (wiringPiDebug) { | if (wiringPiDebug) { | ||||
fprintf (stderr, "wiringPi: waitForInterruptInit failed\n") ; | fprintf (stderr, "wiringPi: waitForInterruptInit failed\n") ; | ||||
} | |||||
} | |||||
}; | }; | ||||
if (wiringPiDebug) { | if (wiringPiDebug) { | ||||
@@ -3087,7 +3087,7 @@ int wiringPiSetupGpioDevice (enum WPIPinType pinType) { | |||||
* wiringPiSetupSys: | * wiringPiSetupSys: | ||||
* GPIO Sysfs Interface for Userspace is deprecated | * GPIO Sysfs Interface for Userspace is deprecated | ||||
* https://www.kernel.org/doc/html/v5.5/admin-guide/gpio/sysfs.html | * https://www.kernel.org/doc/html/v5.5/admin-guide/gpio/sysfs.html | ||||
* | |||||
* | |||||
* Switched to new GPIO driver Interface in version 3.3 | * Switched to new GPIO driver Interface in version 3.3 | ||||
*/ | */ | ||||
@@ -153,9 +153,12 @@ void serialClose (const int fd) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void serialPutchar (const int fd, const unsigned char c) | |||||
void serialPutchar(const int fd, const unsigned char c) | |||||
{ | { | ||||
write (fd, &c, 1) ; | |||||
ssize_t bytes_written = write(fd, &c, 1); | |||||
if (bytes_written != 1) { | |||||
perror("Error writing to file descriptor"); | |||||
} | |||||
} | } | ||||
@@ -165,9 +168,13 @@ void serialPutchar (const int fd, const unsigned char c) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
void serialPuts (const int fd, const char *s) | |||||
void serialPuts(const int fd, const char *s) | |||||
{ | { | ||||
write (fd, s, strlen (s)) ; | |||||
size_t len = strlen(s); | |||||
ssize_t bytes_written = write(fd, s, len); | |||||
if (bytes_written != (ssize_t)len) { | |||||
perror("Error writing to file descriptor"); | |||||
} | |||||
} | } | ||||
/* | /* | ||||