Article Index

 

Programs

Raspberry Pi IoT in C Third Edition

 

piciot3e360

We have decided not to make the programs available as a download because this is not the point of the book - the programs are not finished production code but something you should type in and study.

The best solution is to provide the source code of the programs in a form that can be copied and pasted into a VS Code project.  

Note: The VS Code task listings are in Appendix II.

The only downside is that you have to create a project to paste the code into.

To do this follow the instructions in the book - in particular remember to add the bcm2835 library and also any library references that may be needed. The majority of the programs also need to be run with root permissions.

All of the programs below were copy and pasted from working programs in the IDE.

If anything you consider important is missing or if you have any requests or comments  contact me

This email address is being protected from spambots. You need JavaScript enabled to view it.


Chapter  2

Page 28

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
    printf("Hello C World");
    int test = 42;
    printf("%d\n", test);
    return (EXIT_SUCCESS);
}
 

Chapter  3

Page 47

#include <bcm2835.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    while (1)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_delay(500);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
        bcm2835_delay(500);
    }
    bcm2835_close();
    return 0;
}

Chapter  4

Page 50

#include <bcm2835.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    for (;;)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
    }
    bcm2835_close();
    return 0;
}
 

Page 62

#define _DEFAULT_SOURCE
#include <bcm2835.h>
#include <stdio.h>
#include <time.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    volatile int i;
    struct timespec delay = {0, 10 * 1000};
    for (;;)
    {
        bcm2835_gpio_set(RPI_BPLUS_GPIO_J8_07);
        nanosleep(&delay, NULL);
        bcm2835_gpio_clr(RPI_BPLUS_GPIO_J8_07);
        nanosleep(&delay, NULL);
    }
    bcm2835_close();
    return 0;
}
 

Page 64

#include <bcm2835.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    volatile int i;
    int n = 10;
    for (;;)
    {
        for (i = 0; i < n; i++)
        {
        };
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        for (i = 0; i < n; i++)
        {
        };
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
    }
    bcm2835_close();
    return 0;
}
 

Page 65

 
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <time.h> 

#define BILLION 1000000000L 

int main(int argc, char** argv) {
    struct timespec btime, etime;

    volatile int i;
    clock_gettime(CLOCK_REALTIME, &btime);
    for (i = 0; i < 10000000; i++) {
    };
    clock_gettime(CLOCK_REALTIME, &etime);
    double nseconds =  (double) ((etime.tv_sec - btime.tv_sec)* BILLION)+(double) (etime.tv_nsec - btime.tv_nsec);
    int n = (int) 10 /nseconds * BILLION + 0.5;
    printf("time = %f (s)  \n \r",nseconds / BILLION);
    printf("n= %d \n\r", n);
    return (EXIT_SUCCESS);
}

Page 66

 
#include <bcm2835.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07,
                      BCM2835_GPIO_FSEL_OUTP);
    for (;;)
    {
        bcm2835_gpio_set(RPI_BPLUS_GPIO_J8_07);
        bcm2835_delayMicroseconds(1);
        bcm2835_gpio_clr(RPI_BPLUS_GPIO_J8_07);
        bcm2835_delayMicroseconds(1);
    }
    bcm2835_close();
    return 0;
}
 

Page 67

 
#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07,BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11,BCM2835_GPIO_FSEL_OUTP);
    volatile int i;
    for (;;)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
    }
    return (EXIT_SUCCESS);
}
 

Page 68

 
#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);
    uint32_t mask = (1 << RPI_BPLUS_GPIO_J8_07) | (1 << RPI_BPLUS_GPIO_J8_11);
    for (;;)
    {
        bcm2835_gpio_set_multi(mask);
        bcm2835_gpio_clr_multi(mask);
    }

    return (EXIT_SUCCESS);
}
 

Chapter 6

 Page 89

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);

    while (1)
    {
        if (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
        {
            printf("Line Low \n\r");
            fflush(stdout);
        };
    }
    return 0;
}
 

Page 90

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);

    while (1)
    {
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07));
        bcm2835_delayMicroseconds(1000);
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07));
        bcm2835_delayMicroseconds(1000);
        printf("Button Push \n\r");
        fflush(stdout);
    }
    return 0;
}
 

Page 91

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    uint64_t t;
    while (1)
    {
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07)) ;
        t = bcm2835_st_read();
        bcm2835_delayMicroseconds(1000);
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07)) ;
        t = bcm2835_st_read() - t;
        bcm2835_delayMicroseconds(1000);
        if (t > 5000000)
        {
            printf("Putton held \n\r");
        }
        else
        {
            printf("Button Push \n\r");
        }
        fflush(stdout);
    }
    return 0;
}
 

Page 92

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{

    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);

    volatile int i;
    while (1)
    {
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07)) ;
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07)) ;
        for (i = 0; i < 5000; i++)
        {
            if (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
                break;
        }
        printf("%d\n\r", i);
        fflush(stdout);
    }
    return (EXIT_SUCCESS);
}
 

Page 93

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    volatile int i;
    uint64_t t;
    while (1)
    {
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07)) ;
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07)) ;
        t = bcm2835_st_read();
        for (i = 0; i < 5000; i++)
        {
            if (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
                break;
        }
        t = bcm2835_st_read() - t;
        printf("%d,%llu\n\r", i, t);
        fflush(stdout);
    }
    return (EXIT_SUCCESS);
}
 

Page 94

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);

    uint64_t t;
    while (1)
    {
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07));
        t = bcm2835_st_read();
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07));
        t = bcm2835_st_read() - t;
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
    }
    return (EXIT_SUCCESS);
}
 

 Page 97 

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    uint64_t t;
    int s = 0;
    int i;
    while (1)
    {
        t = bcm2835_st_read();
        i = bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07);
        switch (s)
        {
        case 0: //Button not pushed
            if (!i)
            {
                s = 1;
                printf("Button Push \n\r");
                fflush(stdout);
            }
            break;
        case 1: //Button pushed
            if (i)
            {
                s = 0;
            }
            break;
        default:
            s = 0;
        }
        t = bcm2835_st_read() - t;
        bcm2835_delayMicroseconds(1000 - t);
    }
    return 0;
}

Page 99

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    uint64_t t, tpush = 0;
    int s = 0, i;
    while (1)
    {
        t = bcm2835_st_read();
        i = bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07);
        switch (s)
        {
        case 0: //Button not pushed
            if (!i)
            {
                s = 1;
                tpush = t;
            }
            break;
        case 1: //Button pushed
            if (i)
            {
                s = 0;
                if ((t - tpush) > 5000000)
                {
                    printf("Button held \n\r");
                }
                else
                {
                    printf("Button pushed \n\r");
                }
                fflush(stdout);
            }
            break;
        default:
            s = 0;
        }
        t = bcm2835_st_read() - t;
        bcm2835_delayMicroseconds(1000 - t);
    }
    return 0;
}
 

Page 100

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_13, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_15, BCM2835_GPIO_FSEL_OUTP);

    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_13, LOW);
    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_15, LOW);

    uint64_t t;
    int buttonState = bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07);

    int state = 0;
    while (1)
    {
        t = bcm2835_st_read();
        int buttonNow = bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07);
        int edge = buttonState - buttonNow;
        buttonState = buttonNow;

        switch (state)
        {
        case 0:
            if (edge)
            {
                state = 1;
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_13, HIGH);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_15, LOW);
            }
            break;
        case 1:
            if (edge)
            {
                state = 2;
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_13, LOW);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_15, HIGH);
            }
            break;
        case 2:
            if (edge)
            {
                state = 0;
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_13, LOW);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_15, LOW);
            }
            break;
        }

        t = bcm2835_st_read() - t;
        bcm2835_delayMicroseconds(1000 - t);
    }
    return 0;
}
 

Chapter 7

 

Page 111

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>

int main(int argc, char **argv)
{
    int fd;
    struct gpiochip_info info;

    fd = open("/dev/gpiochip0", O_RDONLY);

    int ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &info);
    close(fd);
    printf("label: %s\n name: %s\n number of lines: %u\n", info.label, info.name, info.lines);
    return 0;
}
 

Page 114

#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>

int main(int argc, char **argv)
{
    int fd, ret;

    struct gpiohandle_request req;
    req.lineoffsets[0] = 4;
    req.lineoffsets[1] = 17;
    req.flags = GPIOHANDLE_REQUEST_OUTPUT;
    req.default_values[0] = 0;
    req.default_values[1] = 0;
    strcpy(req.consumer_label, "Output test");
    req.lines = 2;

    fd = open("/dev/gpiochip0", O_RDONLY);
    ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
    close(fd);

    struct gpiohandle_data data;
    data.values[0] = 0;
    data.values[1] = 1;
    while (1)
    {
        data.values[0] = !data.values[0];
        data.values[1] = !data.values[1];
        ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
    }
    return 0;
}
 

Page 116

#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>

int main(int argc, char **argv)
{
    int fd, ret;

    struct gpiohandle_request req;
    req.lineoffsets[0] = 4;
    req.lineoffsets[1] = 17;
    req.flags = GPIOHANDLE_REQUEST_INPUT;
    strcpy(req.consumer_label, "Input test");
    req.lines = 2;

    fd = open("/dev/gpiochip0", O_RDONLY);
    ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
    close(fd);

    struct gpiohandle_data data;
    ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
    printf("%hhu , %hhu", data.values[0], data.values[1]);
    close(req.fd);
    return 0;
}

Chapter 8

Page 122

Not a full program just a function definition
 
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

void checkIRQ()
{
    FILE *fp = popen("sudo dtparam -l", "r");
    if (fp == NULL)
    {
        printf("Failed to run command\n\r");
        exit(1);
    }
    char output[1024];
    int txfound = 0;
    while (fgets(output, sizeof(output), fp) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, "gpio-no-irq") != NULL)
        {
            txfound = 1;
        }
    }
    pclose(fp);

    if (txfound == 0)
    {
        fp = popen("sudo dtoverlay gpio-no-irq", "r");
        if (fp == NULL)
        {
            printf("Failed to run command\n\r");
            exit(1);
        }
        pclose(fp);
    }
}
 

Page 126

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_ren(RPI_BPLUS_GPIO_J8_07);

    volatile int i;
    uint64_t t;
    while (1)
    {
        bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
        while (0 == bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07)) ;
        t = bcm2835_st_read();
        bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
        for (i = 0; i < 5000; i++)
        {
            if (1 == bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07))
                break;
        }
        t = bcm2835_st_read() - t;
        printf("%d,%llu\n\r", i, t);
        fflush(stdout);
    }
    return (EXIT_SUCCESS);
}
 

Page 127

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_clr_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);

    uint64_t t;
    while (1)
    {
        bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
        t = bcm2835_st_read();
        for (;;)
        {
            if (1 == bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07))
                break;
        }
        t = bcm2835_st_read() - t;
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
    }
    return (EXIT_SUCCESS);
}
 

 Page 128

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    printf("Press button \n\r");
    fflush(stdout);
    sleep(20);
    if (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
    {
        printf("Button pressed \n\r");
    }
    else
    {
        printf("No Button press\n\r");
    };
    return 0;
}
 

Page 129

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    bcm2835_gpio_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
    printf("Press button \n\r");
    fflush(stdout);
    sleep(20);
    if (bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07))
    {
        printf("Button pressed \n\r");
    }
    else
    {
        printf("No Button press\n\r");
    };
    return 0;
}
 

 Page 132

 
#include <string.h>
#include <stdio.h> 
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>
#include <sys/epoll.h>

int main(int argc, char **argv) {
    int fd, ret;

    struct gpioevent_request req;
    req.lineoffset = 4;
    req.handleflags = GPIOHANDLE_REQUEST_INPUT;
    req.eventflags = GPIOEVENT_REQUEST_RISING_EDGE;
    strcpy(req.consumer_label, "Event test");

    fd = open("/dev/gpiochip0", O_RDONLY);
    ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &req);
    close(fd);

    static struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = req.fd;
    int epfd = epoll_create(1);
    int res = epoll_ctl(epfd, EPOLL_CTL_ADD, req.fd, &ev);

    int nfds = epoll_wait(epfd, &ev, 1, 20000);
    if (nfds != 0) {
        struct gpioevent_data edata;
        read(req.fd, &edata, sizeof edata);
        printf("%u,%llu", edata.id, edata.timestamp);
    }
}
 

Page 137 

#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>
#include <sys/epoll.h>

#include <pthread.h>
uint64_t t[20];
typedef void (*eventHandler)(int);

typedef struct
{
    int epfd;
    int fd;
    eventHandler func;
} intVec;

void myHandler(int fd)
{
    struct gpioevent_data edata;
    read(fd, &edata, sizeof edata);
    printf("%u,%llu \n\r", edata.id, edata.timestamp);
    fflush(stdout);
}
void *waitInterrupt(void *arg)
{
    intVec *intData = (intVec *)arg;
    struct epoll_event ev;
    for (;;)
    {
        int nfds = epoll_wait(intData->epfd, &ev, 1, 20000);

        if (nfds != 0)
        {
            intData->func(intData->fd);
        }
    }
}
int main(int argc, char **argv)
{
    int fd, ret;
    struct gpioevent_request req;
    req.lineoffset = 4;
    req.handleflags = GPIOHANDLE_REQUEST_INPUT;
    req.eventflags = GPIOEVENT_REQUEST_RISING_EDGE;
    strcpy(req.consumer_label, "Event test");

    fd = open("/dev/gpiochip0", O_RDONLY);
    ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &req);
    close(fd);
    static struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = req.fd;
    int epfd = epoll_create(1);
    int res = epoll_ctl(epfd, EPOLL_CTL_ADD, req.fd, &ev);
    intVec intData;
    intData.epfd = epfd;
    intData.fd = req.fd;
    intData.func = &myHandler;
    pthread_t intThread;
    if (pthread_create(&intThread, NULL, waitInterrupt,
                       (void *)&intData))
    {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }
    for (;;)
    {
        printf("Working\n\r");
        fflush(stdout);
        sleep(2);
    }
}
 

page 140

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <bcm2835.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>

#define BUFFER_MAX 50

typedef void (*eventHandler)();

int openGPIO(int pin, int direction);
int writeGPIO(int gpio, int value);
int readGPIO(int gpio);
int setEdgeGPIO(int gpio, char *edge);
void *waitInterrupt(void *arg);
int attachGPIO(int gpio, char *edge, eventHandler func);

int fd[32] = {0};
typedef struct
{
    int fd;
    int gpio;
    eventHandler func;
} intVec;

intVec intData;
static int count;

void myIntHandler()
{
    count++;
};
int main(int argc, char **argv)
{
    attachGPIO(4, "both", myIntHandler);
    for (;;)
    {
        printf("Interrupt %d\n\r", count);
        fflush(stdout);
    };
    return 0;
}

int openGPIO(int gpio, int direction)
{
    if (gpio < 0 || gpio > 31)
        return -1;
    if (direction < 0 || direction > 1)
        return -2;
    int len;
    char buf[BUFFER_MAX];
    if (fd[gpio] != 0)
    {
        close(fd[gpio]);
        fd[gpio] = open("/sys/class/gpio/unexport", O_WRONLY);
        len = snprintf(buf, BUFFER_MAX, "%d", gpio);
        write(fd[gpio], buf, len);
        close(fd[gpio]);
        fd[gpio] = 0;
    }

    fd[gpio] = open("/sys/class/gpio/export", O_WRONLY);
    len = snprintf(buf, BUFFER_MAX, "%d", gpio);
    write(fd[gpio], buf, len);
    close(fd[gpio]);
    len = snprintf(buf, BUFFER_MAX,
                   "/sys/class/gpio/gpio%d/direction", gpio);
    fd[gpio] = open(buf, O_WRONLY);
    if (direction == 1)
    {
        write(fd[gpio], "out", 4);
        close(fd[gpio]);
        len = snprintf(buf, BUFFER_MAX,
                       "/sys/class/gpio/gpio%d/value", gpio);
        fd[gpio] = open(buf, O_WRONLY);
    }
    else
    {
        write(fd[gpio], "in", 3);
        close(fd[gpio]);
        len = snprintf(buf, BUFFER_MAX,
                       "/sys/class/gpio/gpio%d/value", gpio);
        fd[gpio] = open(buf, O_RDONLY);
    }
    return 0;
}

int writeGPIO(int gpio, int b)
{
    if (b == 0)
    {
        write(fd[gpio], "0", 1);
    }
    else
    {
        write(fd[gpio], "1", 1);
    }

    lseek(fd[gpio], 0, SEEK_SET);
    return 0;
}

int readGPIO(int gpio)
{
    char value_str[3];
    int c = read(fd[gpio], value_str, 3);
    lseek(fd[gpio], 0, SEEK_SET);

    if (value_str[0] == '0')
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

int setEdgeGPIO(int gpio, char *edge)
{
    char buf[BUFFER_MAX];
    int len = snprintf(buf, BUFFER_MAX,
                       "/sys/class/gpio/gpio%d/edge", gpio);
    int fd = open(buf, O_WRONLY);
    write(fd, edge, strlen(edge) + 1);
    close(fd);
    return 0;
}

int attachGPIO(int gpio, char *edge, eventHandler func)
{
    openGPIO(gpio, 0);
    setEdgeGPIO(gpio, edge);
    readGPIO(gpio);
    intData.fd = fd[gpio];
    intData.gpio = gpio;
    intData.func = func;
    pthread_t intThread;
    if (pthread_create(&intThread,
                       NULL, waitInterrupt, (void *)&intData))
    {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }
    return 0;
}
void *waitInterrupt(void *arg)
{

    intVec *intData = (intVec *)arg;
    int gpio = intData->gpio;
    struct pollfd fdset[1];
    fdset[0].fd = intData->fd;
    fdset[0].events = POLLPRI;
    fdset[0].revents = 0;
    for (;;)
    {
        int rc = poll(fdset, 1, -1);
        if (fdset[0].revents & POLLPRI)
        {
            intData->func();
            lseek(fdset[0].fd, 0, SEEK_SET);
            readGPIO(gpio);
        }
    }
    pthread_exit(0);
}

Chapter 9

Page 151

#include <bcm2835.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 2);
    bcm2835_pwm_set_data(0, 1);
    return (0);
}
 

Page 152

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_gpio_fsel(13, BCM2835_GPIO_FSEL_ALT0);
    bcm2835_pwm_set_clock(2);

    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 2);
    bcm2835_pwm_set_data(0, 1);

    bcm2835_pwm_set_mode(1, 1, 1);
    bcm2835_pwm_set_range(1, 8);
    bcm2835_pwm_set_data(1, 2);
    return (EXIT_SUCCESS);
}
 

Page 153

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 256);
    for (;;)
    {
        bcm2835_pwm_set_data(0, 16);
        bcm2835_delayMicroseconds((int)26.666 * 8);
        bcm2835_pwm_set_data(0, 128);
        bcm2835_delayMicroseconds((int)26.666 * 8);
    }
    return (EXIT_SUCCESS);
}
 

Page 155

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char** argv) {
    if (!bcm2835_init())
        return 1;


    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 256);
    for (;;) {
        for (int i = 0; i < 256; i = i + 10) {
            bcm2835_pwm_set_data(0, i);
            bcm2835_delayMicroseconds(100);
        }
    }
    return (EXIT_SUCCESS);
}
 

Page 156

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    int C = 34091;
    bcm2835_pwm_set_range(0, C);
    bcm2835_pwm_set_data(0, C / 2);
    return (EXIT_SUCCESS);
}

Page 158

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv){
    if (!bcm2835_init())
            return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);
    int w = 1;
    int inc = 1;
    for (;;)
    {
        bcm2835_pwm_set_data(0, w);
        w = w + inc;
        if (w > 1024 || w <= 0)
            inc = -inc;
        bcm2835_delayMicroseconds(5000);
    }
    return (EXIT_SUCCESS);
}
    bcm2835_delayMicroseconds(5000);
    }
    return (EXIT_SUCCESS);
}
 

Page 159

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);
    int w = 0;
    int inc = 1;
    for (;;)
    {
        bcm2835_pwm_set_data(0, w * w * w);
        w = w + inc;
        if (w > 10 || w <= 0)
            inc = -inc;
        bcm2835_delayMicroseconds(50000);
    }
    return (EXIT_SUCCESS);
}
 

Page 160

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);
    int w = 0;
    int inc = 1;

    for (;;)
    {
        bcm2835_pwm_set_data(0, (w * w * w) >> 3);
        w = w + inc;
        if (w > 20 || w <= 0)
            inc = -inc;
        bcm2835_delayMicroseconds(50000);
    }
    return (EXIT_SUCCESS);
}
 

Page 163 

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(375);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);

    for (;;)
    {
        bcm2835_pwm_set_data(0, 25);
        bcm2835_delayMicroseconds(2000000);
        bcm2835_pwm_set_data(0, 50);
        bcm2835_delayMicroseconds(2000000);
        bcm2835_pwm_set_data(0, 128);
        bcm2835_delayMicroseconds(2000000);
    }
    return (EXIT_SUCCESS);
}
 

Page 164 

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(375);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);

    for (;;)
    {
        bcm2835_pwm_set_data(0, 52 * 0 / 180 + 920);
        bcm2835_delayMicroseconds(2000000);
        bcm2835_pwm_set_data(0, 52 * 90 / 180 + 920);
        bcm2835_delayMicroseconds(2000000);
        bcm2835_pwm_set_data(0, 52 * 180 / 180 + 920);
        bcm2835_delayMicroseconds(2000000);
    }
    return (EXIT_SUCCESS);
}

Page 166

Function only - needs to run as root.
 
void bcm2835_pwm_set_clock_source(
    uint32_t source,
    uint32_t divisorI,
    uint32_t divisorF)
{
    divisorI &= 0xfff;
    divisorF &= 0xfff;
    source &= 0xf;
    uint8_t mask = bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0xffffffef;
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | mask);
    while ((bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0x80) != 0)
    {
    };
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_DIV, BCM2835_PWM_PASSWRD | (divisorI << 12) | divisorF);
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | source | 0x200);
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x210 | source);
}
 

Page 168

 This needs to be run as root.
 
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <bcm2835.h>

void bcm2835_pwm_set_clock_source(uint32_t source,uint32_t divisorI,uint32_t divisorF)
{
    divisorI &= 0xfff;
    divisorF &= 0xfff;
    source &= 0xf;
    uint8_t mask = bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) &  0xffffffef;
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL,  BCM2835_PWM_PASSWRD | mask);
    while ((bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0x80) != 0)
    {
    };
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_DIV, BCM2835_PWM_PASSWRD | (divisorI << 12) | divisorF);
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | source | 0x200);
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x210 | source);
}

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock_source(6, 2, 0);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 256);
    int i;
    for (;;)
    {
        for (i = 0; i < 256; i = i + 10)
        {
            bcm2835_pwm_set_data(0, i);
            bcm2835_delayMicroseconds(2);
        }
    }
    return (EXIT_SUCCESS);
}
 

Chapter 10

Page 184 

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    char buf[] = {0xE7};
    bcm2835_i2c_begin();
    bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_148);
    bcm2835_i2c_setSlaveAddress(0x40);
    bcm2835_i2c_write(buf, 1);
    bcm2835_i2c_read(buf, 1);
    printf("User Register = %X \r\n", buf[0]);
    bcm2835_i2c_end();
    return (EXIT_SUCCESS);
}
 

 Page 186

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

void setTimeout(uint32_t timeout) {
    volatile uint32_t* stimeout = bcm2835_bsc1 + BCM2835_BSC_CLKT / 4;
    bcm2835_peri_write(stimeout, timeout);
}

int main(int argc, char** argv) {
    if (!bcm2835_init())
        return 1;

    bcm2835_i2c_begin();
    bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_150);
    setTimeout(0);
    char buf[4] = {0xE3};
    uint8_t status = bcm2835_i2c_read_register_rs(buf, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    printf("msb %d \n\r lsb %d \n\r checksum %d \n\r", msb, lsb, check);
    bcm2835_i2c_end();
    return (EXIT_SUCCESS);
}
 

Page 188 

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

void setTimeout(uint32_t timeout)
{
    volatile uint32_t *stimeout = bcm2835_bsc1 + BCM2835_BSC_CLKT / 4;
    bcm2835_peri_write(stimeout, timeout);
}

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_i2c_begin();
    bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_2500);
    setTimeout(20000);
    char buf[3] = {0xE3};
    uint8_t status = bcm2835_i2c_read_register_rs(buf, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    printf("msb %d \n\r lsb %d \n\r checksum %d \n\r", msb, lsb, check);
    bcm2835_i2c_end();
    return (EXIT_SUCCESS);
}
 

Page 192

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

void setTimeout(uint16_t timeout);
uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check);
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_i2c_begin();
    bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_2500);
    setTimeout(20000);
    char buf[4] = {0xE3};
    uint8_t status = bcm2835_i2c_read_register_rs(buf, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];

    printf("crc = %d\n\r", crcCheck(msb, lsb, check));
    unsigned int data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
    float temp = (float)(-46.85 + (175.72 * data16 / (float)65536));
    printf("Temperature %f C \n\r", temp);

    buf[0] = 0xF5;
    bcm2835_i2c_write(buf, 1);
    while (bcm2835_i2c_read(buf, 3) == BCM2835_I2C_REASON_ERROR_NACK)
    {
        bcm2835_delayMicroseconds(500);
    };
    msb = buf[0];
    lsb = buf[1];
    check = buf[2];
    printf("crc = %d\n\r", crcCheck(msb, lsb, check));
    data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
    float hum = -6 + (125.0 * (float)data16) / 65536;
    printf("Humidity %f %% \n\r", hum);
    bcm2835_i2c_end();

    return (EXIT_SUCCESS);
}

void setTimeout(uint16_t timeout)
{
    volatile uint32_t *stimeout = bcm2835_bsc1 + BCM2835_BSC_CLKT / 4;
    bcm2835_peri_write(stimeout, timeout);
}

uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check)
{
    uint32_t data32 = ((uint32_t)msb << 16) | ((uint32_t)lsb << 8) | (uint32_t)check;
    uint32_t divisor = 0x988000;
    for (int i = 0; i < 16; i++)
    {
        if (data32 & (uint32_t)1 << (23 - i))
            data32 ^= divisor;
        divisor >>= 1;
    };
    return (uint8_t)data32;
}
 

Chapter 11

Page 203 

#include <bcm2835.h>
#include <stdio.h>
#include <sched.h>
#include <sys/mman.h>

uint8_t getByte(int b, int buf[]);
void GetDHT22data(uint8_t pin);

int main(int argc, char **argv)
{
    const struct sched_param priority = {1};
    sched_setscheduler(0, SCHED_FIFO, &priority);
    mlockall(MCL_CURRENT | MCL_FUTURE);
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(1000);
    GetDHT22data(RPI_BPLUS_GPIO_J8_07);
    return 0;
}

void GetDHT22data(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(1000);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    int i;
    for (i = 1; i < 2000; i++)
    {
        if (bcm2835_gpio_lev(pin) == 0)
            break;
    };
    uint64_t t;
    int buf[41];
    int j;
    bcm2835_delayMicroseconds(1);
    for (j = 0; j < 41; j++)
    {
        for (i = 1; i < 2000; i++)
        {
            if (bcm2835_gpio_lev(pin) == 1)
                break;
        };
        t = bcm2835_st_read();
        for (i = 1; i < 2000; i++)
        {
            if (bcm2835_gpio_lev(pin) == 0)
                break;
        }
        buf[j] = (bcm2835_st_read() - t) > 50;
    }

    int byte1 = getByte(1, buf);
    int byte2 = getByte(2, buf);
    int byte3 = getByte(3, buf);
    int byte4 = getByte(4, buf);
    int byte5 = getByte(5, buf);
    printf("Checksum %d %d \n\r", byte5, (byte1 + byte2 + byte3 + byte4) & 0xFF);
    float humidity = (float)(byte1 << 8 | byte2) / 10.0;
    printf("Humidity= %f \n\r", humidity);
    float temperature;
    int neg = byte3 & 0x80;
    byte3 = byte3 & 0x7F;
    temperature = (float)(byte3 << 8 | byte4) / 10.0;
    if (neg > 0)
        temperature = -temperature;
    printf("Temperature= %f \n\r", temperature);
    return;
}

uint8_t getByte(int b, int buf[])
{
    int i;
    uint8_t result = 0;
    b = (b - 1) * 8 + 1;
    for (i = b; i <= b + 7; i++)
    {
        result = result << 1;
        result = result | buf[i];
    }
    return result;
}

Chapter 13 

Page 223

#include <bcm2835.h>
#include <stdio.h>
#include <sched.h>
#include <sys/mman.h>

int presence(uint8_t pin);
void writeByte(uint8_t pin, int byte);
uint8_t crc8(uint8_t *data, uint8_t len);
int readByte(uint8_t pin);
int readiButton(uint8_t pin, uint8_t *data);

int main(int argc, char **argv)
{
    const struct sched_param priority = {1};
    sched_setscheduler(0, SCHED_FIFO, &priority);
    mlockall(MCL_CURRENT | MCL_FUTURE);

    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);

    int i;
    uint8_t code[8];
    for (;;)
    {
        int p = readiButton(RPI_BPLUS_GPIO_J8_07, code);
        if (p == 1)
        {
            for (i = 0; i < 8; i++)
            {
                printf("%hhX ", code[i]);
            }
            printf("\n\r");
            fflush(stdout);
        }
        bcm2835_delayMicroseconds(100000);
    };
    bcm2835_close();
    return 0;
}

int presence(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(480);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(70);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(410);
    return b;
}

void writeBit(uint8_t pin, int b)
{

    int delay1, delay2;
    if (b == 1)
    {
        delay1 = 6;
        delay2 = 64;
    }
    else
    {
        delay1 = 80;
        delay2 = 10;
    }
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(delay1);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(delay2);
}

uint8_t readBit(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(6);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(9);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(55);
    return b;
}

void writeByte(uint8_t pin, int byte)
{
    int i;
    for (i = 0; i < 8; i++)
    {
        if (byte & 1)
        {
            writeBit(pin, 1);
        }
        else
        {
            writeBit(pin, 0);
        }
        byte = byte >> 1;
    }
}

int readByte(uint8_t pin)
{
    int byte = 0;
    int i;
    for (i = 0; i < 8; i++)
    {
        byte = byte | readBit(pin) << i;
    };
    return byte;
}
uint8_t crc8(uint8_t *data, uint8_t len)
{

    uint8_t i;
    uint8_t j;
    uint8_t temp;
    uint8_t databyte;
    uint8_t crc = 0;
    for (i = 0; i < len; i++)
    {
        databyte = data[i];
        for (j = 0; j < 8; j++)
        {
            temp = (crc ^ databyte) & 0x01;
            crc >>= 1;
            if (temp)
                crc ^= 0x8C;

            databyte >>= 1;
        }
    }

    return crc;
}

int readiButton(uint8_t pin, uint8_t *data)
{
    int b = presence(pin);
    if (b != 0)
        return 0;
    writeByte(pin, 0x33);
    int i;
    for (i = 0; i < 8; i++)
    {
        data[i] = readByte(pin);
    }
    uint8_t crc = crc8(data, 8);
    if (crc == 0)
        return 1;
    return 0;
}

Chapter 14

 Page 233

#include <bcm2835.h>
#include <stdio.h>

int presence(uint8_t pin);
void writeBit(uint8_t pin, int b);
void writeByte(uint8_t pin, int byte);
uint8_t readBit(uint8_t pin);
int convert(uint8_t pin);
int readByte(uint8_t pin);
float getTemperature(uint8_t pin);
uint8_t crc8(uint8_t *data, uint8_t len);

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    if (presence(RPI_BPLUS_GPIO_J8_07) == 1)
    {
        printf("No device \n");
    }
    else
    {
        printf("Device present \n");
    }
    fflush(stdout);
    float t;
    for (;;)
    {
        do
        {
            t = getTemperature(RPI_BPLUS_GPIO_J8_07);
        } while (t < -999);
        printf("%f\r\n", t);
        fflush(stdout);
    };
    bcm2835_close();

    return 0;
}

int presence(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(480);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(70);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(410);
    return b;
}

void writeBit(uint8_t pin, int b)
{
    int delay1, delay2;
    if (b == 1)
    {
        delay1 = 6;
        delay2 = 64;
    }
    else
    {

        delay1 = 60;
        delay2 = 10;
    }
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(delay1);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(delay2);
}

void writeByte(uint8_t pin, int byte)
{
    int i;
    for (i = 0; i < 8; i++)
    {
        if (byte & 1)
        {
            writeBit(pin, 1);
        }
        else
        {

            writeBit(pin, 0);
        }
        byte = byte >> 1;
    }
}

uint8_t readBit(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(8);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(2);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(60);
    return b;
}

int convert(uint8_t pin)
{
    int i;
    writeByte(pin, 0x44);
    for (i = 0; i < 5000; i++)
    {
        bcm2835_delayMicroseconds(100000);
        if (readBit(pin) == 1)
            break;
    }
    return i;
}

float getTemperature(uint8_t pin)
{
    if (presence(pin) == 1)
        return -1000;
    writeByte(pin, 0xCC);
    if (convert(pin) == 5000)
        return -3000;
    presence(pin);
    writeByte(pin, 0xCC);
    writeByte(pin, 0xBE);
    int i;
    uint8_t data[9];
    for (i = 0; i < 9; i++)
    {
        data[i] = readByte(pin);
    }
    uint8_t crc = crc8(data, 9);
    if (crc != 0)
        return -2000;
    int t1 = data[0];
    int t2 = data[1];
    int16_t temp1 = (t2 << 8 | t1);
    float temp = (float)temp1 / 16;
    return temp;
}

int readByte(uint8_t pin)
{
    int byte = 0;
    int i;
    for (i = 0; i < 8; i++)
    {
        byte = byte | readBit(pin) << i;
    };
    return byte;
}

uint8_t crc8(uint8_t *data, uint8_t len)
{
    uint8_t i;
    uint8_t j;
    uint8_t temp;
    uint8_t databyte;
    uint8_t crc = 0;
    for (i = 0; i < len; i++)
    {
        databyte = data[i];
        for (j = 0; j < 8; j++)
        {
            temp = (crc ^ databyte) & 0x01;
            crc >>= 1;
            if (temp)
                crc ^= 0x8C;
            databyte >>= 1;
        }
    }
    return crc;
}

Chapter 15

Page 246

function only - needs a main program to call it

int oneWireScan(uint8_t pin, uint64_t serial[])
{
    static int bitcount = 0;
    static int deviceCount = 0;

    if (bitcount > 63)
    {
        bitcount = 0;
        deviceCount++;
        return deviceCount;
    }

    if (bitcount == 0)
    {
        if (presence(pin) == 1)
        {
            bitcount = 0;
            return deviceCount;
        }
        deviceCount = 0;
        serial[deviceCount] = 0;
        writeByte(pin, 0xF0);
    };

    int b1 = readBit(pin);
    int b2 = readBit(pin);

    if (b1 == 0 && b2 == 1)
    {
        serial[deviceCount] >>= 1;
        writeBit(pin, 0);
        bitcount++;
        oneWireScan(pin, serial);
    };

    if (b1 == 1 && b2 == 0)
    {
        serial[deviceCount] >>= 1;
        serial[deviceCount] |= 0x8000000000000000LL;
        writeBit(pin, 1);
        bitcount++;
        oneWireScan(pin, serial);
    };

    if (b1 == 1 && b2 == 1)
    {
        bitcount = 0;
        return deviceCount;
    };
    if (b1 == 0 && b2 == 0)
    {
        serial[deviceCount] >>= 1;
        writeBit(pin, 0);
        int bitposition = bitcount;
        bitcount++;
        oneWireScan(pin, serial);

        bitcount = bitposition;
        if (presence(pin) == 1)
        {
            bitposition = 0;
            return 0;
        }

        writeByte(pin, 0xF0);
        uint64_t temp = serial[deviceCount - 1] | (0x1LL << (bitcount));
        int i;
        uint64_t bit;
        for (i = 0; i < bitcount + 1; i++)
        {
            bit = temp & 0x01LL;
            temp >>= 1;
            b1 = readBit(pin);
            b2 = readBit(pin);
            writeBit(pin, bit);
            serial[deviceCount] >>= 1;
            serial[deviceCount] |= (bit << 63);
        }
        bitcount++;
        oneWireScan(pin, serial);
    };

    return deviceCount;
}

Chapter 16

Page 268

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

#include <unistd.h>

#include <fcntl.h>

#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main(int argc, char **argv)
{
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    return 0;
}
 

Page 268

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

This loopback most likely wont work unless the serial port is already configured - see next program.

 

#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    char buf[] = "hello world";
    char buf2[11];
    int count = write(sfd, buf, 11);
    count = read(sfd, buf2, 11);
    buf2[11] = 0;
    printf("%s", buf2);
    close(sfd);
    return 0;
}

Page 278

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/ioctl.h>

int main(int argc, char **argv)
{
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B9600);
    cfmakeraw(&options);
    options.c_cflag &= ~CSTOPB;
    options.c_cflag |= CLOCAL;
    options.c_cflag |= CREAD;
    options.c_cc[VTIME] = 0;
    options.c_cc[VMIN] = 1;
    tcsetattr(sfd, TCSANOW, &options);
    char buf[] = "hello world";
    char buf2[11];
    int count = write(sfd, buf, 11);
    count = read(sfd, buf2, 11);
    buf2[11] = 0;
    printf("%s", buf2);
    close(sfd);
    return 0;
}
 

Page 279

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

 
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/ioctl.h>

int main(int argc, char **argv)
{
    system("sudo systemctl stop serial-getty@serial0 .service");
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B9600);
    cfmakeraw(&options);
    options.c_cflag &= ~CSTOPB;
    options.c_cflag |= CLOCAL;
    options.c_cflag |= CREAD;
    options.c_cc[VTIME] = 1;
    options.c_cc[VMIN] = 100;
    tcsetattr(sfd, TCSANOW, &options);
    char buf[] = "hello world";
    char buf2[100];
    int count = write(sfd, buf, strlen(buf));
    usleep(100000);
    int bytes;
    ioctl(sfd, FIONREAD, &bytes);
    if (bytes != 0)
    {
        count = read(sfd, buf2, 100);
    }
    printf("%s\n\r", buf2);
    close(sfd);
    return (EXIT_SUCCESS);
}
 

Page 281

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

 
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>

int main(int argc, char **argv)
{
    system("sudo systemctl stop serial-getty@serial0 .service");
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };

    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B9600);
    cfmakeraw(&options);
    options.c_cflag &= ~CSTOPB;
    options.c_cflag |= CLOCAL;
    options.c_cflag |= CREAD;
    options.c_cc[VTIME] = 0;
    options.c_cc[VMIN] = 0;
    tcsetattr(sfd, TCSANOW, &options);

    char buf[] = "hello world";
    char buf2[100];
    char c;
    int count = write(sfd, buf, strlen(buf) + 1);

    int i = 0;
    while (1)
    {
        count = read(sfd, &c, 1);
        if (count != 0)
        {
            buf2[i] = c;
            i++;
            if (c == 0)
                break;
        };
    };
    printf("%s\n\r", buf2);
    close(sfd);
    return (EXIT_SUCCESS);
}
 

Page 287

 

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

 
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <stdint.h>

int openPort(char port[]);
int presence(int sfd);
void writeBit(int sfd, int b);
uint8_t readBit(int sfd);
void writeByte(int sfd, int byte);
int readByte(int sfd);
int readByte(int sfd);
float getTemperature(int sfd);
int convert(int sfd);

uint8_t crc8(uint8_t *data, uint8_t len);

int main(int argc, char **argv)
{
    int sfd = openPort("/dev/ttyAMA1");
    if (presence(sfd) == 0)
    {
        printf("Device Present\n\r");
    }
    else
    {
        printf("No Device\n\r");
    }
    for (;;)
    {
        float temp = getTemperature(sfd);
        printf("%f \n\r", temp);

        fflush(stdout);
    }
    close(sfd);
    return 0;
}

int openPort(char port[])
{
    int sfd = open(port, O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B115200);
    cfmakeraw(&options);
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    options.c_cflag |= PARENB;
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag |= CLOCAL;
    options.c_cflag |= CREAD;
    options.c_cc[VTIME] = 0;
    options.c_cc[VMIN] = 1;
    tcsetattr(sfd, TCSADRAIN, &options);
    return sfd;
}

int presence(int sfd)
{
    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B9600);
    tcsetattr(sfd, TCSADRAIN, &options);

    char buf = 0xF0;
    int count = write(sfd, &buf, 1);
    count = read(sfd, &buf, 1);

    tcgetattr(sfd, &options);
    cfsetspeed(&options, B115200);
    tcsetattr(sfd, TCSADRAIN, &options);
    if (buf == 0xF0)
        return -1;
    return 0;
}

void writeBit(int sfd, int b)
{
    char buf;
    if (b == 0)
    {
        buf = 0x00;
    }
    else
    {
        buf = 0xFF;
    }
    int count = write(sfd, &buf, 1);
    count = read(sfd, &buf, 1);
}

uint8_t readBit(int sfd)
{
    char buf;
    buf = 0xFF;
    int count = write(sfd, &buf, 1);
    count = read(sfd, &buf, 1);
    if (buf == 0xFF)
        return 1;
    return 0;
}

void writeByte(int sfd, int byte)
{
    for (int i = 0; i < 8; i++)
    {
        if (byte & 1)
        {
            writeBit(sfd, 1);
        }
        else
        {
            writeBit(sfd, 0);
        }
        byte = byte >> 1;
    }
}

int readByte(int sfd)
{
    int byte = 0;
    for (int i = 0; i < 8; i++)
    {
        byte = byte | readBit(sfd) << i;
    };
    return byte;
}

int convert(int sfd)
{
    int i;
    writeByte(sfd, 0x44);
    for (i = 0; i < 5000; i++)
    {
        usleep(100000);
        if (readBit(sfd) != 0)
            break;
    }
    return i;
}

uint8_t crc8(uint8_t *data, uint8_t len)
{
    uint8_t i;
    uint8_t j;
    uint8_t temp;
    uint8_t databyte;
    uint8_t crc = 0;
    for (i = 0; i < len; i++)
    {
        databyte = data[i];
        for (j = 0; j < 8; j++)
        {
            temp = (crc ^ databyte) & 0x01;
            crc >>= 1;
            if (temp)
                crc ^= 0x8C;
            databyte >>= 1;
        }
    }
    return crc;
}

float getTemperature(int sfd)
{
    if (presence(sfd) == -1)
        return -1000;
    writeByte(sfd, 0xCC);
    if (convert(sfd) == 5000)
        return -3000;

    presence(sfd);
    writeByte(sfd, 0xCC);
    writeByte(sfd, 0xBE);

    uint8_t data[9];
    for (int i = 0; i < 9; i++)
    {
        data[i] = readByte(sfd);
    }

    uint8_t crc = crc8(data, 9);
    if (crc != 0)
        return -2000;
    int t1 = data[0];
    int t2 = data[1];
    int16_t temp1 = (t2 << 8 | t1);
    float temp = (float)temp1 / 16;
    return temp;
}

Chapter 17

Page 303 

#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
    {
        return 1;
    }
    if (!bcm2835_spi_begin())
    {
        return 1;
    }

    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_65536);
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
    uint8_t read_data = bcm2835_spi_transfer(0xAA);
    if (read_data == 0xAA)
    {
        printf("data received correctly");
    }
    else
    {
        printf("data error");
    };
    bcm2835_spi_end();
    bcm2835_close();
    return (EXIT_SUCCESS);
}

Chapter 18

 Page 312

 
#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
    {
        return 1;
    }
    if (!bcm2835_spi_begin())
    {
        return 1;
    }
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_8192);
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);

    char buf[] = {0x01, 0x80, 0x00};
    char readBuf[3];
    bcm2835_spi_transfernb(buf, readBuf, 3);
    int data = ((int)readBuf[1] & 0x03) << 8 | (int)readBuf[2];
    float volts = (float)data * 3.3f / 1023.0f;

    printf("%f", volts);
    bcm2835_spi_end();
    bcm2835_close();
    return (EXIT_SUCCESS);
}

 

Chapter 19

Page 324

#include <stdio.h>
#include <stdlib.h>

#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(80);
    addr.sin_addr.s_addr = 0x22d8b85d;
    if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
        return -1;
    char header[] = "GET /index.html HTTP/1.1\r\nHost:example.org\r\n\r\n";
    int n = write(sockfd, header, strlen(header));
    char buffer[2048];
    n = read(sockfd, buffer, 2048);
    printf("%s", buffer);
    return (EXIT_SUCCESS);
}
 

Page 326

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <netdb.h>

int main(int argc, char **argv)
{
    struct addrinfo hints;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    struct addrinfo *servinfo;
    int status = getaddrinfo("www.example.com", "80", &hints, &servinfo);
    int sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
    connect(sockfd, servinfo->ai_addr, servinfo->ai_addrlen);
    char header[] = "GET /index.html HTTP/1.1\r\nHost:example.org\r\n\r\n";
    int n = write(sockfd, header, strlen(header));
    char buffer[2048];
    n = read(sockfd, buffer, 2048);
    printf("%s", buffer);
    return (EXIT_SUCCESS);
}
 

Page 331

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <time.h>

int main(int argc, char **argv)
{
    struct addrinfo hints, *server;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    getaddrinfo(NULL, "80", &hints, &server);
    int sockfd = socket(server->ai_family, server->ai_socktype | SOCK_NONBLOCK, server->ai_protocol);
    bind(sockfd, server->ai_addr, server->ai_addrlen);
    listen(sockfd, 10);

    char buffer[2048];
    char html[] = "<html><head><title>Temperature</title></head><body><p>{\"humidity\":81%, \"airtemperature\":23.5C}</p></body></html>\r\n";

    char headers[1024] = {0};

    char Status[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\nServer:CPi\r\n";

    char Date[100];
    time_t now = time(NULL);
    struct tm *t = gmtime(&now);
    strftime(Date, sizeof(Date), "Date: %a, %d %b %Y %k:%M:%S %Z\r\n", t);

    char ContLen[100] = {0};
    snprintf(ContLen, sizeof ContLen, "Content-Length:%d \r\n", strlen(html));

    snprintf(headers, sizeof headers, "%s%s%s\r\n", Status, Date, ContLen);

    char data[2048] = {0};
    snprintf(data, sizeof data, "%s%s", headers, html);

    for (;;)
    {
        struct sockaddr_storage client_addr;
        socklen_t addr_size = sizeof client_addr;

        int client_fd = accept(sockfd, (struct sockaddr *)&client_addr, &addr_size);
        if (client_fd > 0)
        {
            int n = read(client_fd, buffer, 2048);
            printf("%s", buffer);
            fflush(stdout);
            n = write(client_fd, data, strlen(data));
            close(client_fd);
        }
    }
    return (EXIT_SUCCESS);
}

Chapter 20

Page 350

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    int memfd = open("/dev/mem", O_RDWR | O_SYNC);
    uint32_t *map = (uint32_t *)mmap(
        NULL,
        4 * 1024,
        (PROT_READ | PROT_WRITE),
        MAP_SHARED,
        memfd,
        (off_t)bcm2835_peripherals_base + BCM2835_GPIO_BASE);
    if (map == MAP_FAILED)
        printf("mmap failed: %s\n", strerror(errno));
    close(memfd);
    volatile uint32_t *paddr = map;
    *paddr = 0x1000;
    volatile uint32_t *paddr1 = map + 0x1C / 4;
    volatile uint32_t *paddr2 = map + 0x28 / 4;
    for (;;)
    {
        *paddr1 = 0x10;
        *paddr2 = 0x10;
    };
    return (EXIT_SUCCESS);
}
 

Page 355

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    uint32_t *gpioBASE = bcm2835_regbase(BCM2835_REGBASE_GPIO);
    bcm2835_peri_write(gpioBASE, 0x1000);
    for (;;)
    {
        bcm2835_peri_write(gpioBASE + BCM2835_GPSET0 / 4, 0x10);
        bcm2835_peri_write(gpioBASE + BCM2835_GPCLR0 / 4, 0x10);
    }
    return 0;
}
 

Page 360

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

#define CLK_GP0_CTL 28
#define CLK_GP0_DIV 29
void bcm2835_GPIO4_set_clock_source(uint32_t, uint32_t, uint32_t);

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(4, BCM2835_GPIO_FSEL_ALT0);
    bcm2835_GPIO4_set_clock_source(6, 50, 0);
}

void bcm2835_GPIO4_set_clock_source(
    uint32_t source,
    uint32_t divisorI,
    uint32_t divisorF)
{
    divisorI &= 0xfff;
    divisorF &= 0xfff;
    source &= 0xf;

    uint8_t mask = bcm2835_peri_read(bcm2835_clk + CLK_GP0_CTL) & 0xffffffef;

    bcm2835_peri_write(bcm2835_clk + CLK_GP0_CTL, BCM2835_PWM_PASSWRD | mask);

    while ((bcm2835_peri_read(bcm2835_clk + CLK_GP0_CTL) & 0x80) != 0)
    {
    };

    bcm2835_peri_write(bcm2835_clk + CLK_GP0_DIV, BCM2835_PWM_PASSWRD | (divisorI << 12) | divisorF);
    bcm2835_peri_write(bcm2835_clk + CLK_GP0_CTL, BCM2835_PWM_PASSWRD | source | 0x200);
    bcm2835_peri_write(bcm2835_clk + CLK_GP0_CTL, BCM2835_PWM_PASSWRD | 0x0210 | source);
}
 

Page 362 

#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>

#define BCM2835_SPI6_BASE 0x204C00
volatile uint32_t *bcm2835_spiOLD;

int bcm2835_spi6_begin(void)
{
    volatile uint32_t *paddr;
    bcm2835_spiOLD = bcm2835_spi0;
    bcm2835_spi0 = bcm2835_peripherals + BCM2835_SPI6_BASE / 4;

    bcm2835_gpio_fsel(27, BCM2835_GPIO_FSEL_ALT3); /* CE1 */
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT3); /* CE0 */
    bcm2835_gpio_fsel(19, BCM2835_GPIO_FSEL_ALT3); /* MISO */
    bcm2835_gpio_fsel(20, BCM2835_GPIO_FSEL_ALT3); /* MOSI */
    bcm2835_gpio_fsel(21, BCM2835_GPIO_FSEL_ALT3); /* CLK */

    paddr = bcm2835_spi0 + BCM2835_SPI0_CS / 4;
    bcm2835_peri_write(paddr, 0); /* All 0s */

    bcm2835_peri_write_nb(paddr, BCM2835_SPI0_CS_CLEAR);
    return 1;
}

void bcm2835_spi6_end(void)
{
    bcm2835_spi0 = bcm2835_spiOLD;
    /* Set all the SPI0 pins back to input */
    bcm2835_gpio_fsel(27, BCM2835_GPIO_FSEL_INPT); /* CE1 */
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_INPT); /* CE0 */
    bcm2835_gpio_fsel(19, BCM2835_GPIO_FSEL_INPT); /* MISO */
    bcm2835_gpio_fsel(20, BCM2835_GPIO_FSEL_INPT); /* MOSI */
    bcm2835_gpio_fsel(21, BCM2835_GPIO_FSEL_INPT); /* CLK */
}

int main(int argc, char **argv)
{
    if (!bcm2835_init())
    {
        return 1;
    }

    if (!bcm2835_spi6_begin())
    {
        return 1;
    }

    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_8192);
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);

    char buf[] = {0x01, 0x80, 0x00};
    char readBuf[3];
    bcm2835_spi_transfernb(buf, readBuf, 3);
    int data = ((int)readBuf[1] & 0x03) << 8 | (int)readBuf[2];
    float volts = (float)data * 3.3f / 1023.0f;

    printf("%f \n \r", volts);
    bcm2835_spi6_end();
    bcm2835_close();
    return (EXIT_SUCCESS);
}
 

Page 370

 
#include <bcm2835.h>
#include <stdio.h>
#include <sched.h>
int main(int argc, char **argv)
{
    const struct sched_param priority = {1};
    sched_setscheduler(0, SCHED_FIFO, &priority);
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    while (1)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
    }
    bcm2835_close();
    return 0;
}

Chapter 21

Page  372

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>

typedef struct{
    uint32_t status;
    uint32_t ctrl;
}GPIOregs;

#define GPIO ((GPIOregs*)GPIOBase)

typedef struct
{
    uint32_t Out;
    uint32_t OE;
    uint32_t In;
    uint32_t InSync;
} rioregs;

#define rio ((rioregs *)RIOBase)
#define rioXOR ((rioregs *)(RIOBase + 0x1000 / 4))
#define rioSET ((rioregs *)(RIOBase + 0x2000 / 4))
#define rioCLR ((rioregs *)(RIOBase + 0x3000 / 4))


int main(int argc, char **argv)
{
    int memfd = open("/dev/mem", O_RDWR | O_SYNC);
    uint32_t *map = (uint32_t *)mmap(
        NULL,
        64 * 1024 * 1024,
        (PROT_READ | PROT_WRITE),
        MAP_SHARED,
        memfd,
        0x1f00000000
    );
    if (map == MAP_FAILED)
    {
        printf("mmap failed: %s\n", strerror(errno));
        return (-1);
    };
    close(memfd);

    uint32_t *PERIBase = map;
    uint32_t *GPIOBase = PERIBase + 0xD0000 / 4;
    uint32_t *RIOBase = PERIBase + 0xe0000 / 4;
    uint32_t *PADBase = PERIBase + 0xf0000 / 4;
    uint32_t *pad = PADBase + 1;  
   
    uint32_t pin = 2;
    uint32_t fn = 5;

    GPIO[pin].ctrl=fn;
    pad[pin] = 0x10;
    rioSET->OE = 0x01<<pin;
    rioSET->Out = 0x01<<pin;
   
    for (;;)
    {
        rioXOR->Out = 0x04;
    }
    return (EXIT_SUCCESS);
}
 

Page  378

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>

typedef struct
{
    uint32_t status;
    uint32_t ctrl;
} GPIOregs;

#define GPIO ((GPIOregs *)GPIOBase)

typedef struct{
    uint32_t Ctrl;
    uint32_t Range;
    uint32_t Phase;
    uint32_t Duty;
} PWMregs;

#define PWM ((PWMregs *) (PWMBase+0x14/4))

typedef struct
{
    uint32_t Out;
    uint32_t OE;
    uint32_t In;
    uint32_t InSync;
} rioregs;

#define rio ((rioregs *)RIOBase)
#define rioXOR ((rioregs *)(RIOBase + 0x1000 / 4))
#define rioSET ((rioregs *)(RIOBase + 0x2000 / 4))
#define rioCLR ((rioregs *)(RIOBase + 0x3000 / 4))

uint32_t *PERIBase;
uint32_t *GPIOBase;
uint32_t *RIOBase;
uint32_t *PADBase;
uint32_t *pad;
uint32_t *PWMBase;


int rp1_Init()
{
    int memfd = open("/dev/mem", O_RDWR | O_SYNC);
    uint32_t *map = (uint32_t *)mmap(
        NULL,
        64 * 1024 * 1024,
        (PROT_READ | PROT_WRITE),
        MAP_SHARED,
        memfd,
        0x1f00000000);
    if (map == MAP_FAILED)
    {

        return (-1);
    };
    close(memfd);
    PERIBase = map;
    GPIOBase = PERIBase + 0xD0000 / 4;
    RIOBase = PERIBase + 0xe0000 / 4;
    PADBase = PERIBase + 0xf0000 / 4;
    PWMBase = PERIBase + 0x98000 / 4;
    pad = PADBase + 1;
    return 0;
};


int main(int argc, char **argv)
{
    if (rp1_Init())
        return (1);
    GPIO[12].ctrl = 0x0;
    pad[12] = 0x10;
    PWM[0].Ctrl=0x1;
    PWM[0].Range=0xFFFFF;
    PWM[0].Duty=0x8FFFF;
    PWM[0].Phase=0x0;
    *PWMBase=0x80000001;
    return (EXIT_SUCCESS);
}

Chapter 22

Page  395

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <linux/sched.h>
#include <pthread.h>
#include <stdint.h>

struct sched_attr
{
    uint32_t size;
    uint32_t sched_policy;
    uint64_t sched_flags;
    int32_t sched_nice;
    uint32_t sched_priority;
    uint64_t sched_runtime;
    uint64_t sched_deadline;
    uint64_t sched_period;
};

int sched_setattr(pid_t pid, const struct sched_attr *attr,
                  unsigned int flags)
{
    return syscall(__NR_sched_setattr, pid, attr, flags);
}

void *threadA(void *p)
{
    struct sched_attr attr = {
        .size = sizeof(attr),
        .sched_policy = SCHED_DEADLINE,
        .sched_runtime = 10 * 1000 * 1000,
        .sched_period = 2 * 1000 * 1000 * 1000,
        .sched_deadline = 11 * 1000 * 1000};
    sched_setattr(0, &attr, 0);
    for (;;)
    {
        printf("sensor\n");
        fflush(0);
        sched_yield();
    };
}

int main(int argc, char **argv)
{
    pthread_t pthreadA;
    pthread_create(&pthreadA, NULL, threadA, NULL);
    pthread_exit(0);
    return (EXIT_SUCCESS);
}
 

Page 399

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>

#include <pthread.h>
#include <sched.h>
#include <unistd.h>

volatile int j;
volatile int i;

void *threadA(void *p)
{
    for (i = 0;; i++)
    {
    };
}

void *threadB(void *p)
{
    for (j = 0;; j++)
    {
    };
}

int main(int argc, char **argv)
{
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    CPU_SET(1, &cpuset);

    pthread_t pthreadA;
    pthread_create(&pthreadA, NULL, threadA, NULL);
    pthread_setaffinity_np(pthreadA, sizeof(cpu_set_t), &cpuset);

    CPU_ZERO(&cpuset);
    CPU_SET(2, &cpuset);
    pthread_t pthreadB;
    pthread_create(&pthreadB, NULL, threadB, NULL);
    pthread_setaffinity_np(pthreadB, sizeof(cpu_set_t), &cpuset);

    sleep(5);

    printf("%d %d", i, j);
    return (EXIT_SUCCESS);
}
 

 Page 402

 
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <unistd.h>
#include <bcm2835.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    CPU_SET(3, &cpuset);
    int res = sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset);

    const struct sched_param priority = {1};
    sched_setscheduler(0, SCHED_FIFO, &priority);
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    while (1)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
    }
    bcm2835_close();
    return 0;
}

Appendix I

 

Page 406

#include <stdio.h>
#include <string.h>
 int main(int argc, char** argv) {
    int gpio = 4;
    FILE* fd = fopen("/sys/class/gpio/export", "w");
    fprintf(fd, "%d", gpio);
    fclose(fd);
    return 0;
}
 

Page 407


#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
    int gpio = 4;
    char buf[100];

    FILE *fd = fopen("/sys/class/gpio/export", "w");
    fprintf(fd, "%d", gpio);
    fclose(fd);

    sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);
    fd = fopen(buf, "w");
    fprintf(fd, "out");
    fclose(fd);

    sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
    fd = fopen(buf, "w");

    for (;;)
    {
        fd = fopen(buf, "w");
        fprintf(fd, "1");
        fclose(fd);
        fd = fopen(buf, "w");
        fprintf(fd, "0");
        fclose(fd);
    }
    return 0;
}

Appendix II

All files have to be stored in the .vscode folder

settings,json (typical) 

{
    "sshUser": "root",
    "sshEndpoint": "192.168.11.151",
    "remoteDirectory": "/home/pi/Documents/${workspaceFolderBasename}",
    "std": "c99",
    "libs":"-lbcm2835",
    "header":"/usr/local/include/bcm2835.h"
}
 

launch.json 

{
    "configurations": [
     
        {
            "name": "Remote C Debug",
            "type": "cppdbg",
            "request": "launch",
            "program": "${config:remoteDirectory}/${relativeFileDirname}/${fileBasenameNoExtension}",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${config:remoteDirectory}/${relativeFileDirname}",
            "environment": [],
            "externalConsole": false,
            "pipeTransport": {
                "debuggerPath": "/usr/bin/gdb",
                "pipeProgram": "C:/Windows/System32/OpenSSH/ssh",
                "pipeArgs": [
                    "${config:sshUser}@${config:sshEndpoint}"
                ],
                "pipeCwd": "${workspaceFolder}"
            },
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "sourceFileMap": {
                "${config:remoteDirectory}/${relativeFileDirname}": "${fileDirname}"
            },
            "preLaunchTask": "CopyBuildRemote",
        }
    ]
}
 

c_cpp_properties.json for Mingw

 
{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "C:/MinGW/include"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "cStandard":"c99",
            "intelliSenseMode":"gcc-arm" 
                }
    ],
    "version": 4
}
 
 

tasks.json

 
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "copyToRemote",
            "type": "shell",
            "command": "scp -r ${fileDirname} ${config:sshUser}@${config:sshEndpoint}:${config:remoteDirectory}/",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
                "clear": true
            }
        },
        {
            "label": "copyHeader",
            "type": "shell",
            "command": "mkdir ${workspaceFolder}/headers/ ;scp -r  ${config:sshUser}@${config:sshEndpoint}:${config:header} ${workspaceFolder}/headers/ ",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
                "clear": true
            }
        },
        {
            "label": "buildRemote",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} 'gcc  -g -std=${config:std} ${config:remoteDirectory}/${relativeFileDirname}/${fileBasename} ${config:libs}  -o${config:remoteDirectory}/${relativeFileDirname}/${fileBasenameNoExtension}.exe'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
                "clear": false
            }
        },
        {
            "label": "runRemote",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} '${config:remoteDirectory}/${relativeFileDirname}/${fileBasenameNoExtension}'",
            "problemMatcher": [
                "$gcc"
            ],
            "presentation": {
                "showReuseMessage": true,
                "clear": false
            }
        },
        {
            "label": "CopyBuildRunRemote",
            "dependsOrder": "sequence",
            "dependsOn": [
                "copyToRemote",
                "buildRemote",
                "runRemote"
            ],
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "CopyBuildRemote",
            "dependsOrder": "sequence",
            "dependsOn": [
                "copyToRemote",
                "buildRemote",
            ],
            "problemMatcher": [],
        },
        {
            "label": "StopREmoteC",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} ;'pkill ${fileBasenameNoExtension}'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": true,
            }
        },
        {
            "label": "copyARMheaders",
            "type": "shell",
            "command": "mkdir ${workspaceFolder}/include/;scp -r  ${config:sshUser}@${config:sshEndpoint}:/usr/include ${workspaceFolder}/include/ ",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": true,
                "clear": true
            }
        },
    ],
}
"presentation": {
"showReuseMessage": true,
}
},
{
"label": "copyARMheaders",
"type": "shell",
"command": "mkdir ${workspaceFolder}/include/;scp -r  ${config:sshUser}@${config:sshEndpoint}:/usr/include ${workspaceFolder}/include/ ",
"problemMatcher": [],
"presentation": {
"showReuseMessage": true,
"clear": true
}
},
],
}