GPIO
A GPIO may have multiple functions. The active function can be selected using the GPFSEL register.
Base Address>: 0x7e20'0000
Can be found in the PDF on section 5.2 (Register View)
Register
| Register | Anwendung | Bits | 
|---|---|---|
| GPFSEL | Function selection for GPIO | 3 | 
| GPSET | Set Value for GPIO | 1 | 
| GPCLR | Clear Value for GPIO (Set to 0x00) | 1 | 
| GPLEV | Read Pin Level | 1 | 
Access

Kommandozeilen Befehl um die GPIOChip Nummern für Zugriff über pseudo Filesystem
ls gpiochip*/device/driver
Pseudo Filesystem
GPIO can be accessed using the pseudo file system mapped at "/sys/class/gpio"
- Requires driver for GPIO
 - Portable to other HW, works everywere
 - Less hassle with addressses
 
Enable GPIO
echo <gpio-pin> > /sys/class/gpio/export
Set Direction of GPIO
| Direction | Value to Write | 
|---|---|
| Read pin | in | 
| set pin | out | 
XX => GPIO-PIN-Number
echo "direction" >> /sys/class/gpio/gpioXX/direction
Value of GPIO
| State | Value to Write | 
|---|---|
| HIGH | 1 | 
| LOW | 0 | 
Set Value
echo "1" >> /sys/class/gpio/gpioXX/value
Read Value
cat /sys/class/gpio/gpioXX/value
C-Code
Export GPIO
FILE *fp;
fp = fopen("/sys/class/gpio/export", "w");
if (fp == NULL) {
	printf("Error opening file in gpio_init %s\n", str);
	return 1;
}
fprintf(fp, "%i", gpio);
fflush(fp);
fclose(fp);
Set Value
void fs_gpio_set (int gpio, int val)
{
	FILE *fp;
	char str[100];
	sprintf(str, "/sys/class/gpio/gpio%i/value", gpio);
	fp = fopen(str, "w");
	if (fp== NULL) {
		printf("Error opening file in gpio_set %s\n", str);
		return -1;
	}
	fprintf(fp, "%i", val);
	fflush(fp);
	fclose(fp);
}
Read Value
int fs_gpio_get (int gpio)
{
	FILE *fp;
	char str[100];
	int ret;
	sprintf(str, "/sys/class/gpio/gpio%i/value", gpio);
	fp = fopen(str, "r");
	if (fp == NULL) {
		printf("Error opening file in gpio_read %s\n", str);
		return -1;
	}
	fread(str, 101, 1, fp);
	sscanf(str, "%i", &ret);
	fclose(fp);
	return ret;
}
Memory Mapped
When using Memory Mapped / DMA (Direct Memory Access), the gpio location must be translated to the memory address.
The Physical Address is 35bit!
void *virtual_gpio_base; //define global pointer
int mmap_virtual_base()
{
	int m_mfd;
	if ((m_mfd = open("/dev/mem", O_RDWR)) < 0)
	{
		printf("FAIL by open /dev/mem\n");
		return m_mfd;
	}
	virtual_gpio_base = (void*) mmap(NULL, sysconf(_SC_PAGE_SIZE),
	PROT_READ|PROT_WRITE, MAP_SHARED, m_mfd, GPIO_BASE_ADDR);
	close(m_mfd);
	
	if (virtual_gpio_base == MAP_FAILED) {
		return errno;
	}
	return 0;
}
Setting and clearing of single gpio pins
#define GPIO_SET0 (0x0000001c) // GPIOSET0 offset
#define GPIO_CLR0 (0x00000028) // GPIOCLR0 offset
void *virtual_gpio_base; //define global pointer
static void mmap_gpio_set(int gpio, int value)
{
	uint32_t *gpio_reg;
	if (value == 1){
		gpio_reg = (uint32_t *) (virtual_gpio_base + GPIO_SET0);
	}
	else {
		gpio_reg = (uint32_t *) (virtual_gpio_base + GPIO_CLR0);
	}
	*gpio_reg = (0x1 << gpio);
	
}
I2C
Read / Write Cycle

Writing / Reading Data

- 
For more details checkout CT2 I2C
 - 
Only one driver can open the bus
 
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
int fd;
char *filename = "/dev/i2c-1";
if ((fd = open(filename, O_RDWR)) < 0) {
	/* ERROR HANDLING: you can check errno to see what went wrong */
	perror("Failed to open the i2c bus");
	exit(1);
}
// Sets up the I2C controller with I2C-bus mode and I2C slave address
int addr = 0x20;
if ( ioctl(fd, I2C_SLAVE, addr ) < 0) {
	printf("Failed to acquire I2C bus access and/or talk to slave.\n");
	exit(1);
}
// WRITE
uint8_t wr_buf[2];
wr_buf[0] = register_address;
wr_buf[1] = register_data;
if ( write(fd, wr_buf, 2) != 2 ) {
	printf("Failed to write to the i2c bus.\n");
}
//READ
uint8_t data = 0;
uint8_t wr_buf[1];
uint8_t rd_buf[1];
wr_buf[0] = register_addr;
if ( write(fd, wr_buf, 1) != 1 ) {
	printf("Failed to write to the i2c bus.\n");
}
if ( read(fd, rd_buf, 1) != 1 ) {
	printf("Failed to read from the i2c bus.\n");
} else {
	data = rd_buf[0];
}