Skip to content

Instantly share code, notes, and snippets.

@rm-hull
Last active December 18, 2022 15:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rm-hull/5862591 to your computer and use it in GitHub Desktop.
Save rm-hull/5862591 to your computer and use it in GitHub Desktop.
// How to access GPIO registers from C-code on the Raspberry-Pi
// Example program
// 15-January-2012
// Dom and Gert
//
/*
$ wget http://www.open.com.au/mikem/bcm2835/bcm2835-1.8.tar.gz
$ tar -zxvf bcm2835-1.8.tar.gz
$ cd bcm2835-1.8
$ ./configure
$ make
$ sudo make install
Then compile the Adafruit_DHT program with
gcc DHT.c -l bcm2835 -std=gnu99 -o DHT
*/
// Access from ARM Running Linux
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <bcm2835.h>
#include <unistd.h>
#define MAXTIMINGS 100
//#define DEBUG
#define DHT11 11
#define DHT22 22
#define AM2302 22
int readDHT(int type, int pin);
int main(int argc, char **argv)
{
if (!bcm2835_init())
return 1;
if (argc != 3) {
printf("usage: %s [11|22|2302] GPIOpin#\n", argv[0]);
printf("example: %s 2302 4 - Read from an AM2302 connected to GPIO #4\n", argv[0]);
return 2;
}
int type = 0;
if (strcmp(argv[1], "11") == 0) type = DHT11;
if (strcmp(argv[1], "22") == 0) type = DHT22;
if (strcmp(argv[1], "2302") == 0) type = AM2302;
if (type == 0) {
printf("Select 11, 22, 2302 as type!\n");
return 3;
}
int dhtpin = atoi(argv[2]);
if (dhtpin <= 0) {
printf("Please select a valid GPIO pin #\n");
return 3;
}
printf("Using pin #%d\n", dhtpin);
readDHT(type, dhtpin);
return 0;
} // main
int bits[250], data[100];
int bitidx = 0;
int readDHT(int type, int pin) {
int counter = 0;
int laststate = HIGH;
int j=0;
// Set GPIO pin to output
bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_write(pin, HIGH);
usleep(500000); // 500 ms
bcm2835_gpio_write(pin, LOW);
usleep(20000);
bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
// wait for pin to drop?
while (bcm2835_gpio_lev(pin) == 1) {
usleep(1);
}
// read data!
for (int i=0; i< MAXTIMINGS; i++) {
counter = 0;
while ( bcm2835_gpio_lev(pin) == laststate) {
counter++;
//nanosleep(1); // overclocking might change this?
if (counter == 1000)
break;
}
laststate = bcm2835_gpio_lev(pin);
if (counter == 1000) break;
bits[bitidx++] = counter;
if ((i>3) && (i%2 == 0)) {
// shove each bit into the storage bytes
data[j/8] <<= 1;
if (counter > 200)
data[j/8] |= 1;
j++;
}
}
#ifdef DEBUG
for (int i=3; i<bitidx; i+=2) {
printf("bit %d: %d\n", i-3, bits[i]);
printf("bit %d: %d (%d)\n", i-2, bits[i+1], bits[i+1] > 200);
}
#endif
printf("Data (%d): 0x%x 0x%x 0x%x 0x%x 0x%x\n", j, data[0], data[1], data[2], data[3], data[4]);
if ((j >= 39) &&
(data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) {
// yay!
if (type == DHT11)
printf("Temp = %d *C, Hum = %d \%\n", data[2], data[0]);
if (type == DHT22) {
float f, h;
h = data[0] * 256 + data[1];
h /= 10;
f = (data[2] & 0x7F)* 256 + data[3];
f /= 10.0;
if (data[2] & 0x80) f *= -1;
printf("Temp = %.1f *C, Hum = %.1f \%\n", f, h);
}
return 1;
}
return 0;
}

PiBOT Setup

First steps

$ raspi-config

  • expand filesystem
  • i18n locale & timezone
  • advanced options / memory split / 32M (16M doesn't work? confirm)
  • advanced options / change hostname

$ sudo apt-get update

$ sudo apt-get upgrade

$ sudo BRANCH=next rpi-update

Standard installs

$ sudo apt-get install htop ipython vim-gtk tree locate python-dev python-pip ctags libi2c-dev

$ sudo pip install psutil

Config file changes

/boot/config.txt

hdmi_safe=1
gpu_mem=32

/etc/wpa_supplicant/wpa_supplicant.conf

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
  ssid="xxx"
  scan_ssid=1
  key_mgmt=WPA-PSK
  psk="xxx"
}

Disable pi user, add others

$ adduser xxx

$ visudo

xxx ALL=(ALL) NOPASSWD: ALL

$ ssh-keygen -t dsa

$ cat other_host.pub >> ~/.ssh/authorized_keys2

$ chown og-rwx ~/.ssh/authorized_keys2

$ sudo usermod --lock pi

GPIOs / PWM

Build and install https://github.com/sarfata/pi-blaster

I2C Setup

Edit /etc/modules and add the following entries:

i2c-bcm2708
i2c-dev

and reboot. Alternatively, modprobe them in. Either way, confirm the driver has loaded properly:

$ dmesg | grep i2c
[   18.310467] bcm2708_i2c bcm2708_i2c.0: BSC0 Controller at 0x20205000 (irq 79) (baudrate 100k)
[   18.332292] bcm2708_i2c bcm2708_i2c.1: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100k)
[   18.480593] i2c /dev entries driver

Then add your user to the i2c group:

$ sudo adduser pi i2c

Install some packages:

$ sudo apt-get install i2c-tools python-smbus

Check to see if the chip has registered (revision 2 RPi's should use icbus 1, whereas earlier revisions use 0):

$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --    

SPI Setup

Edit /etc/modules and add the following entry:

spi-bcm2708

and reboot. Alternatively, modprobe them in. Either way, confirm the driver has loaded properly:

$ dmesg | grep spi
[  480.856103] bcm2708_spi bcm2708_spi.0: master is unqueued, this is deprecated
[  480.856146] bcm2708_spi bcm2708_spi.0: SPI Controller at 0x20204000 (irq 80)

$ ls -l /dev/spi* 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment