// busp.cc // buzz - Programme du robot Efrei Robotique I1-I2 2003 // Copyright (C) 2003 Nicolas Schodet // #include "busp.h" #include "kernel/pbus.h" #include "erreur/erreur.h" #include #include #include #include //Debug #define BUSP_FILE "/dev/robotbusp" // Pointeur vers l'instance unique. Busp *Busp::m_instance = 0; // Initialise le busp, open (), signal (). Busp::Busp () { // Sauvegarde le pointeur d'instance. m_instance = this; // Ouvre le périphérique. m_fd = open (BUSP_FILE, O_RDONLY); if (m_fd == -1) throw ErreurFatale ("Impossible d'ouvrir le périphérique du bus" " parallèle.\n"); // Paramètre le handler de signaux. struct sigaction sa; sa.sa_handler = irq; sigemptyset (&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction (SIGUSR1, &sa, 0); // Il n'y aura pas d'erreur, cf doc. // Active les interruptions. sti (); } // Destructeur. Busp::~Busp () { // Désactive les interruptions. cli (); // Ignore les signaux, on sait jammais. struct sigaction sa; sa.sa_handler = SIG_IGN; sigemptyset (&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction (SIGUSR1, &sa, 0); // Ferme le périphérique. close (m_fd); // Efface le pointeur d'instance. m_instance = 0; } // Active les interruptions. void Busp::sti (void) { ioctl (m_fd, PBUS_INTENABLE); } // Désactive les interruptions. void Busp::cli (void) { ioctl (m_fd, PBUS_INTDISABLE); } // Traite le signal envoyé par le kernel lors d'une interruption. void Busp::irq (int sig) { Busp &busp = Busp::getInstance (); // Désactivation des interuptions automatique. // Récupère le numéro d'intéruption. struct pbus_io io; ioctl (busp.m_fd, PBUS_INTREAD, &io); cout << "irq " << (int) io.ints << endl; // Sous-traite l'interruption. if (io.ints & BuspIr::m_irqMask) busp.m_ir.irq (); // Active à nouveau. busp.sti (); } // Ecrire sur le bus. void Busp::write (int addr, int data) { struct pbus_io io; io.addr = addr; io.data = data; ioctl (m_fd, PBUS_WRITE, &io); cout << "write " << addr << " " << data << endl; } // Lire sur le bus. int Busp::read (int addr) { struct pbus_io io; io.addr = addr; ioctl (m_fd, PBUS_READ, &io); cout << "read " << addr << " = " << (int) io.data << endl; return io.data; }