#include "heha_print.h" // print() mit Kommastellen an Integerzahlen
#include <bcm2835.h>
#include <unistd.h> // usleep()
#include <signal.h> // signal()
#include <semaphore.h>
/* I²C-Abfrage- und Steuerprogramm für
Fernbedien-Adapter der BGA-Fahrzeuge mit ATmega328 (etwa Arduino Uno)
Nicht in Python, sondern C++.
221219 heha
+230413 Systemglobale Semaphore als Mutex
*/
static volatile bool wantAbort;
static void onSigInt(int) {
wantAbort=true;
}
int main() {
if (!bcm2835_init()) {
heha::print("bcm2835_init() versagt, \"sudo\" vergessen?\n");
return 1;
}
uint32_t*const gpio_base=bcm2835_regbase(BCM2835_REGBASE_GPIO);//(uint32_t*)0x7E20'0000;
heha::print("%p mode0=%#o\n",gpio_base,bcm2835_peri_read(gpio_base+0));
if (!bcm2835_i2c_begin()) {
heha::print("bcm2835_%s() versagt\n","i2c_begin");
return 2;
}
const unsigned i2cslave = 0x5d; // 7-Bit-Adresse in Linux-Schreibweise
bcm2835_i2c_set_baudrate(400000);
bcm2835_i2c_setSlaveAddress(i2cslave);
char semname[32];
// Die 3 (als I²C-Busnummer) ist eigentlich Quatsch, auch bei fba2 und fba3.
// Denn gesperrt werden muss die Ressource bezüglich Portpins;
// im Prinzip 2 Mutexe, für jedes Portpin eins.
// Pin 3 = GPIO2 = SDA0, Pin 5 = GPIO3 = SCL0
// Was für ein Posix-Mumpitz: sem ist kein Handle, auf das man mit
// WaitForMultipleObjects() aka select() warten könnte.
heha::snprint(semname,sizeof semname,"/i2c%u.%02x",3,i2cslave);
sem_t*sem = sem_open(semname,O_CREAT,0660,1);
signal(SIGINT,onSigInt); //^C abfangen und Hauptschleife definiert beenden
do {
char cmd[1]={0};
char buf[6];
sem_wait(sem);
// BUG: I²C-Hardware unterstützt ohnehin Clock-Stretch nur fehlerhaft, also nicht.
bcm2835_i2c_write_read_rs(cmd,sizeof cmd,buf,sizeof buf);
sem_post(sem);
heha::print("%,3u\n",*(uint32_t*)(buf));
if (wantAbort) break;
usleep(250000);
}while(!wantAbort);
sem_unlink(semname);
bcm2835_i2c_end();
heha::print("r0=%#o\n",bcm2835_peri_read(gpio_base+0));
bcm2835_close();
}
Detected encoding: UTF-8 | 0
|