summaryrefslogtreecommitdiff
path: root/2003/i/buzz/src/busp/busp.cc
blob: 0e90475844349e17d5602262134ed2809563b128 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// 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 <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <iostream>	//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;
}