\subsection{Cahier des charges}

Voici les contraintes du bloc de d'entrées / sorties :

\begin{itemize}
\item{Bloc de 8 entrées / sorties}
\item{Chaque fils est configurable soit en entrée, soit en sortie}
\item{Chaque fils est configurable pour générer ou non, une interruption lors
d'un changement d'état}
\item{Un signal de RAZ}
\end{itemize}


% en gros c'est comment est vu le module côté userland.
\subsection{Vue comportementale}

Les blocs d'entrées / sorties ont plusieurs utilités. La première est de
pouvoir brancher des capteurs renvoyant une entrée binaire, par exemple la
sortie d'un comparateur. Ce bloc permettra aussi de commander, des sorties
comme par exemple l'allumage de LEDs. 

Finalement la troisième fonction de ce bloc sera de simuler un bus parallèle.
En effet, l'année dernière, nous utilisions un bus parallèle pour lequel nous
avons développé un certain nombre de cartes. A partir de blocs d'entrées /
sorties, on peut donc réutiliser les modules précédements développés.

On pourra voir la figure \ref{entity_gpio} page
\pageref{entity_gpio} pour avoir une vue globale du module.

\begin{figure}[htbp]
\caption{Entity du bloc de gestion des interruptions}
\begin{center}
\scalebox{0.6}{
\includegraphics {./gpio/images/entity.pdf}
%\includegraphics[width=\textwidth]{./interrupt/images/entity.pdf}
}
\end{center}
\label{entity_gpio}
\end{figure}

Du point de vue comportemental son fonctionnement est le suivant. Au début,
le PC configure le bloc après avoir envoyé un signal de remise à zéro. Il
commence par configurer les différentes pins du bloc soit en entrées, soit en
sorties. Ensuite le PC configure quelles pins pourront générer une interruption.
Une fois cela fait, il peut lire et écrire des données sur les entrées et
sorties. La configuration du bloc gpio est réalisées en écrivant dans des
registres. 

On remarque que ce module possède quatres signaux "chip select" :
cs\_reg\_data, cs\_reg\_direction, cs\_reg\_it\_mask et cs\_read\_output.
Le signal cs\_read\_output permet de lire l'états de 8 broches d'entrées /
sorties. Les autres signaux permettent d'accéder aux registres contenant
respectivement, le masque des directions, le masque d'interruption et les
données à mettre sur les lignes en sorties. 

Ces trois registres ont la particularité de pouvoir être écrit mais aussi lu.
En effet, pour la phase de teste il nous semble utile que les registres
puissent être relus. Ainsi on pourra s'assurer que la configuration est bien
celle désirée. 

Voici comment se déroule les procédures d'écriture et de lecture dans les
registres. La procédure d'écriture est la suivante. Tout d'abord, le module
dirigeant le bloc écrit sur le bus de donnés l'octet lui permettant de
configurer tel ou tel registre.

Simultanément, il positionne le signal $R\bar{W}$ en mode écriture (Write).
Finalement, il sélectionne à l'aide d'un des signal CS (Chip select) le
registre dans lequel il veut écrire.

La procédure de lecture s'effectue en positionnant le signal $R\bar{W}$ en
lecture (Read), puis en sélectionnant le chip select du registre auquel on
désire accéder. 

On notera que pour interfacer ce bloc et le bus ISA, il faut un module dont le
rôle sera de convertir les signaux du bus ISA en les signaux $R\bar{W}$ et les
signaux de "chip select" (CS).

Pour résumer, voici quelques informations utiles :
\begin{itemize}
\item{La lecture (signal $R\bar{W}$) : active pour un état haut}
\item{La écriture (signal $R\bar{W}$) : active pour un état bas}
\item{Le masque d'interruptions : interruption active pour un état haut,
	inactive pour un état bas}
\item{Le masque de directions : en sortie pour un état haut, en entrée pour un
	état bas}
\end{itemize}

\subsection{Exemple d'utilisation du module}

Voici un exemple pour illustrer les discours précédents. On pourra se reporter
aux chronogrammes de la figure \ref{gpio_behav_simul} page
\pageref{gpio_behav_simul}. Ce chronogramme représente la simulation
comportementale du bloc d'entrées sorties.


%% TODO : Se débrouiller pour inclure l'image

% Commande sympas : convert -rotate -90 fichier.tiff fichier.pdf
\begin{figure}[htbp]
\begin{center}
%\scalebox{0.6}{
%\includegraphics {./gpio/sim/gpio_behavior_simul.pdf}
%}
\includegraphics[height=0.7\textwidth,angle=90]{./gpio/sim/gpio_behavior_simul.pdf}
\end{center}
\label{gpio_behav_simul}
\end{figure}

% Ajouter le chronogramme du test des gpio.
% Copier la suite dans le fichier de la gestion des interruptions !

Dans cet exemple, nous allons configurer puis utiliser le bloc d'entrée /
sorties. La première action à effectuer est une remise-à-zéro du bloc à l'aide
de son signal reset. C'est ce que l'on remarque lorsque le signal rst est à 1.
Ce signal doit garder un état haut durant au moins une prériode d'horloge du
bus ISA (clk\_i).

On remarque que sur les entrées /sorties, on simule le fait d'avoir branché
des capteurs sur les cinq lignes de poid fort. On voit donc apparaître sur la
la sortie les valeurs $00001ZZZ$. Cela signifie que l'on laisse les trois pins
de poid fort dans un état de haute impédance.

Une fois cela fait, on configure alors le bloc. Pour ce faire, l'ordinateur
place tout d'abord sur le bus de données le masque de direction. Dans
l'exemple, le masque est $00000111$, ce qui signifie que l'on désire
positionner les 3 pins de poid faible en sorties. On peut alors constater que
les trois pins du bloc qui sont en sortie, prennent la valeur $0$. Cela vient
du fait que lors du reset, on a remis le bloc à zéro, et par défaut, les
sorties sont à zéro d'ou les signaux obtenus.

On remarquera aussi que la ligne $R\bar{W}$ est en écriture. Ainsi, dès que
la ligne de validation du registre de configuration des directions (ligne chip
select : cs\_reg\_direction ) est à un état haut et qu'il y a un front
montant de l'horloge (clk\_i) du bus ISA, on configure le bloc avec les
signaux sur le bus de données.

De la même manière, on configure ensuite le masque d'interruption pour lequel
on conserve la valeur $11111000$. On remarque que cet octet est le
complémentaire du masque de direction. Dans cette configuration, on vient
d'autoriser les interruptions sur les pins en entrée du bloc. Ainsi, dès qu'il
y aura un changement d'état sur l'une des cinq pins de poid fort, une
interruption sera générée.

Ensuite, on transmet au bloc les signaux que l'on désire voir sur les lignes
en sortie du bloc. Dans notre cas on transmet $00000001$. Comme seules les
trois pins de poid faible sont en sortie, on recopie en sortie $ZZZZZ001$ sans
tenir compte des bits de poid fort. Comme les "capteurs simulés" sur les cinq
bits de poid fort génèrent les valeurs $00001ZZZ$, on retrouve sur la sortie
un mélange de ces signaux, d'où la valeur de $00001001$.

Dans la suite, on se propose de relire les valeurs affectées. C'est ce que
l'on fait. On vérifie successivement le masque d'interruption, le registre de
direction puis le registre de données. Finalement le PC veut lire les valeurs
situées sur les entrées sorties, ce qui est réalisé grâce au signal
cs\_read\_output.

On remarquera aussi le signal d'interruption. Celui-ci passe à l'état haut
lorsque l'état des "capteurs" change. Le bloc d'entrées /sorties attend alors
que le PC demande à lire les entrées / sorties pour achever l'interruption.
