I2C und SPI
Serielle Busse über Systemgeräte oder bereitgestellte Services nutzen.
I2C und SPI werden in zwei Schritten betrachtet:
- Der Device Tree beschreibt Bus, angeschlossenes Gerät, Chip-Select, Interrupts und weitere Hardwareparameter.
- Die Anwendung nutzt das bereitgestellte Userspace-Gerät oder den Service.
Die Busse sind über [I2C-GERÄT] und [SPI-GERÄT] verfügbar. Vor dem Zugriff müssen Busnummer,
Chip-Select, Frequenz und elektrische Randbedingungen geprüft werden.
Für die Python-Beispiele werden smbus2 [SMBUS2-VERSION] und spidev [SPIDEV-VERSION]
verwendet.
I2C: [I2C-GERÄT], Adresse [I2C-ADRESSE], [I2C-FREQUENZ]
SPI: [SPI-GERÄT], Chip-Select [CHIP-SELECT], [SPI-FREQUENZ][PLATZHALTER: Freigegebene Geräte, Frequenzgrenzen und Beispielzugriffe]
I2C aus eigenen Programmen verwenden
Voraussetzung ist ein aktivierter I2C-Bus und ein Geräteknoten [I2C-GERÄT]. Die Geräteadresse
[I2C-ADRESSE] und die Register sind bausteinspezifisch.
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <unistd.h>
int i2c_read_register(const char *device_path, int address, unsigned char reg)
{
unsigned char value = 0U;
const int fd = open(device_path, O_RDWR);
if (fd < 0 || ioctl(fd, I2C_SLAVE, address) < 0) {
if (fd >= 0) {
(void)close(fd);
}
return -1;
}
if (write(fd, ®, sizeof(reg)) != (ssize_t)sizeof(reg) ||
read(fd, &value, sizeof(value)) != (ssize_t)sizeof(value)) {
(void)close(fd);
return -1;
}
(void)close(fd);
return (int)value;
}
/* Beispiel: i2c_read_register("/dev/i2c-1", [I2C-ADRESSE], [REGISTER]); */SPI aus eigenen Programmen verwenden
SPI benötigt den richtigen Chip-Select, Modus, Takt und die maximale Übertragungsfrequenz.
#include <fcntl.h>
#include <linux/spi/spidev.h>
#include <sys/ioctl.h>
#include <unistd.h>
int spi_transfer(const char *device_path, unsigned char *buffer, unsigned int length)
{
const int fd = open(device_path, O_RDWR);
struct spi_ioc_transfer transfer = {
.tx_buf = (unsigned long)buffer,
.rx_buf = (unsigned long)buffer,
.len = length,
.speed_hz = [SPI-TAKT-HZ],
.bits_per_word = 8U
};
if (fd < 0 || ioctl(fd, SPI_IOC_MESSAGE(1), &transfer) < 0) {
if (fd >= 0) {
(void)close(fd);
}
return -1;
}
(void)close(fd);
return 0;
}
/* Beispiel: spi_transfer("/dev/spidev0.0", buffer, buffer_length); */Für Python werden in diesen Beispielen smbus2 und spidev verwendet. Die Bibliotheken müssen
Bestandteil des Images oder der Anwendungslieferung sein.