I hate to bug people with my problems, but I have wracked my brains around this for several days. I'm sure I am missing something that somebody else will pick up easily! Any help appreciated.I have successfully used lib bcm2835 before to turn on a relay, which opens a garage door, and the code I am using is a copy of that code, which I needed to modify for ten GPIO outputs rather than just one. Naturally I have done apt-get update and apt-get upgrade.I am using a Pi model B V2.0, same as the one I was using on the system that is working with one relay. Pinout gives:
Revision : 000e
SoC : BCM2835
RAM : 512MB
Storage : SD
USB ports : 2 (of which 0 USB3)
Ethernet ports : 1 (100Mbps max. speed)
Wi-fi : False
Bluetooth : False
Camera ports (CSI) : 1
Display ports (DSI): 1
#include <bcm2835.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#define _POSIX_SOURCE 1 /* POSIX compliant source */
//#define PN RPI_V2_GPIO_P1_19
void pulse (void);
char debug =0;
char Assigns[10][70];
void init(void);
char Pins[10][18];
char* PinsPtr=Pins[0];
char PN;
int main(int argc, char* argv[])
{
init();
bcm2835_init();
for (int i=0;i<10;i++)
{
strncpy(&PN,&PinsPtr[i*18],17);
printf("Pin = %s\n\r",&PN);
bcm2835_gpio_fsel(PN,BCM2835_GPIO_FSEL_OUTP);
// bcm2835_gpio_fsel(RPI_V2_GPIO_P1_19,BCM2835_GPIO_FSEL_OUTP);
}
pulse();
}
void pulse(void)
{
for (int i=0;i<10;i++)
{
strncpy(&PN,&PinsPtr[i*18],17);
printf("PN=%s\n\r",&PN);
bcm2835_gpio_write(PN, LOW);
// bcm2835_gpio_write(RPI_V2_GPIO_P1_19,LOW);
sleep(1);
bcm2835_gpio_write(PN, HIGH);
sleep(1);
// bcm2835_gpio_write(RPI_V2_GPIO_P1_19,HIGH);
}
}
void init(void)
{
strcpy(Assigns[0],"GPIO02 on P1-3 using RLA1-1 driving CAT5A-BLU for Pi-Star");
strcpy(Assigns[1],"GPIO03 on P1-5 using RLA1-2 driving CAT5A-ORG for Pi-Quisk");
strcpy(Assigns[2],"GPIO04 on P1-7 using RLA1-3 driving CAT5A-GRN for Pi-Marine");
strcpy(Assigns[3],"GPIO17 on P1-11 using RLA1-4 driving CAT5A-BRN for Pi-APRS");
strcpy(Assigns[4],"GPIO27 on P1-13 using RLA2-1 driving CAT5A-BLU for Pi-LiveATC");
strcpy(Assigns[5],"GPIO22 on P1-16 using RLA2-2 driving CAT5A-ORG for Spare");
strcpy(Assigns[6],"GPIO10 on P1-19 using RLA2-3 driving CAT5A-GRN for Pi-Boil-Mon");
strcpy(Assigns[7],"GPIO09 on P1-21 using RLA2-4 driving CAT5A-BRN for Pi-Aware");
strcpy(Assigns[8],"GPIO11 on P1-8 using SSR-1 driving GRN-BLK for IC900");
strcpy(Assigns[9],"GPIO14 on P1-23 using SSR-2 driving WHI-BLK for TK981");
strcpy(Pins[0],"RPI_V2_GPIO_P1_03");
strcpy(Pins[1],"RPI_V2_GPIO_P1_05");
strcpy(Pins[2],"RPI_V2_GPIO_P1_07");
strcpy(Pins[3],"RPI_V2_GPIO_P1_11");
strcpy(Pins[4],"RPI_V2_GPIO_P1_13");
strcpy(Pins[5],"RPI_V2_GPIO_P1_16");
strcpy(Pins[6],"RPI_V2_GPIO_P1_19");
strcpy(Pins[7],"RPI_V2_GPIO_P1_21");
strcpy(Pins[8],"RPI_V2_GPIO_P1_08");
strcpy(Pins[9],"RPI_V2_GPIO_P1_23");
}
If I embed the full name of the I/O pin, e.g.
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_19,BCM2835_GPIO_FSEL_OUTP);
then
bcm2835_gpio_write(RPI_V2_GPIO_P1_19,LOW);
sleep(1);
bcm2835_gpio_write(PN, HIGH);
bcm2835_gpio_write(RPI_V2_GPIO_P1_19,HIGH);
For the init and actual I/O, it works fine. Relay on the pin clicks. But if I load it using a variable from a table (one of the ten pins, un-commented in code) it gives me a diagnostic from lib BCM2835 with an address which is outside the published range:
PN=RPI_V2_GPIO_P1_03
bcm2835_peri_write paddr 0xb5040030, value 00040000
bcm2835_peri_write paddr 0xb5040024, value 00040000
bcm2835_peri_write paddr 0xb504001c, value 00000400
I put in the printf to show what the value is being passed.
NOW, if I use the full name of the pin, but leave the printf uncommented, it fails again, even though I can't see how the printf could change the access to the peripheral!
So my thoughts are that I am messing up memory somewhere!
I tried running it through gdb, but after 3 single-steps I am getting 'file not found' under /proc/device-tree/soc/ranges, which I understand may be that gdb doesn't know how to handle the dynamic location there, so maybe not an error.
Any help really appreciated! I'd hate to duplicate code for each relay individually, but it is looking like that may be my only hope!
cheers,
Nigel Johnson