Interface logicielle (API) - Driver GPIO

De Wiki Techno-Innov
< Technique‎ | Logiciel‎ | API‎ | Use‎ | Drivers
Révision datée du 2 septembre 2020 à 05:47 par Nathael (discussion | contributions) (Page créée avec « {{DISPLAYTITLE:Interface logicielle (API) - Driver GPIO}} == Présentation == #include "drivers/gpio.h" Le driver "GPIO" (General Purpose Input / Output) donne accès au... »)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à la navigation Aller à la recherche


Présentation

#include "drivers/gpio.h"

Le driver "GPIO" (General Purpose Input / Output) donne accès aux fonctions d'entrée / sortie "génériques" (General Purpose) pour les pins du micro-contrôleur.

La sélection de la fonction "GPIO" pour une pin est fait à l'aide de la fonction config_pio() décrite à la page "Configuration des fonctions des ports d'entrée/sortie" de cette documentation. L'appel à cette fonction est fait automatiquement lors de l'appel aux fonction config_gpio() ou set_gpio_callback() décrites dans les sections suivantes.

Le nombre de ports et le nombre de pins disponibles sur chaque port dépends du micro-contrôleur utilisé, et parfois même du nombre de pattes physiques du boîtier utilisé. Le fichier d'entête fournit les définitions du nombre de pins disponibles pour chaque port, indépendamment du type de boîtier utilisé.

#define PORT0_NB_PINS
#define PORT1_NB_PINS
#define PORT2_NB_PINS
...

Activation

void gpio_on(void);
void gpio_off(void);

Les sous-systèmes (modules) du micro-contrôleurs permettant l'accès à la configuration et à l'état des GPIO peuvent être activés ou désactivés pour limiter la consommation du micro-contrôleur. Cette désactivation est faite en coupant l'horloge du sous-système concerné.
Cette activation ou désactivation peut se faire port par port sur certains micro-contrôleurs, cependant l'implémentation actuelle active ou désactive tous les ports en même temps.
Lorsqu'ils sont désactivés, les sorties conservent leur état, mais l'état des entrées n'est plus mis à jour et il n'est plus possible de changer l'état des sorties sans réactiver les ports d'entrée sortie.

Configuration : GPIO

void config_gpio(const struct pio* gpio, uint32_t mode, uint8_t dir, uint8_t ini_val);

La fonction config_gpio() permet de configurer une pin du micro-contrôleur en fonction GPIO, et de spécifier son mode de fonctionnement, sa direction ' dir' (GPIO_DIR_IN ou GPIO_DIR_OUT) et son état par défaut 'ini_val' (0 ou 1).
Le paramètre 'mode' est passé à la fonction config_pio() en ajoutant le bit "LPC_IO_DIGITAL".

Utilisation : Entrées/Sorties, accès séparé

Les fonctions présentées ci-dessous n'utilisent pas d'appel de fonction, mais des définitions, à l'exception de gpio_read() qui utilise une fonction "inline".

void gpio_dir_in(const struct pio gpio);
void gpio_dir_out(const struct pio gpio);

Les fonctions gpio_dir_in() et gpio_dir_out() permettent de changer la direction d'une GPIO après sa configuration initiale.

void gpio_set(const struct pio gpio);
void gpio_clear(const struct pio gpio);
void gpio_toggle(const struct pio gpio);

La fonction gpio_set() permet de changer l'état d'une GPIO configurée en sortie en la mettant au niveau logique "1", indépendamment de son état actuel, et sans changer l'état des autres pins du même port.
La fonction gpio_clear() permet de changer l'état d'une GPIO configurée en sortie en la mettant au niveau logique "0", indépendamment de son état actuel, et sans changer l'état des autres pins du même port.
La fonction gpio_toggle() permet de changer l'état d'une GPIO configurée en sortie en inversant son niveau logique, sans avoir besoin de lire au préalable son état actuel, et sans changer l'état des autres pins du même port.

uint32_t gpio_read(const struct pio gpio);

La fonction gpio_read() renvoie 0 si l'entrée correspondante est à l'état logique "0", et autre chose (dépendant du micro-contrôleur) si l'entrée correspondante est à l'état logique "1".

Utilisation : Entrées/Sorties, accès groupé

Cette partie est extrêmement spécifique à chaque micro-contrôleur et il est nécessaire de se référer à la documentation du micro-contrôleur pour l'utiliser. Les éléments présentés ici ne sont que des indications générales aidant à comprendre le fonctionnement.

Lorsqu'il est nécessaire de mettre à jour plusieurs sorties simultanément, ou de lire plusieurs entrées en une seule fois, il est possible de passer directement par la structure donnant accès aux registres correspondants.

Cette structure est définie dans le fichier d'entête "drivers/gpio.h", et contient plusieurs champs en fonction du micro-contrôleur, permettant différents modes d'accès aux entrées/sorties correspondantes.

enum gpio_ports {
   GPIO_PORT0,
   GPIO_PORT1,
   /* [....] */
};
struct lpc_gpio
{
    /* [....] */
};
#define LPC_GPIO_REGS(x)

Il existe une structure "lpc_gpio" pour chaque port du micro-contrôleur (indépendemment du nombre de pins de chaque port).
Pour accéder à un port donné, il faut déclarer un pointeur vers la structure correspondante au port (par exemple le port 0) :

struct lpc_gpio* gpio_port = LPC_GPIO_REGS(GPIO_PORT0);

Chaque champ de cette structure donne un type d'accès particulier à l'état des pins du micro-contrôleur. Les différents champs suivants peuvent être disponibles en fonction du micro-contrôleur. (Tous ne sont pas présents, se référer au fichier d'entête "drivers/gpio.h" correspondant au micro-contrôleur concerné pour connaître les champs existants).
Pour la plupart des champs, un mot de 32 bits représente les 32 pins d'un port donné. (Le bit 0 correspond à la pin 0, le bit 1 à la pin 1, ...).

  • 'in', 'out', 'val' ou 'mval' : Valeur de l'ensemble des pins du port sur un mot de 32 bits
  • 'set', 'clear' et 'toggle' : Permet de ne changer que l'état de certaines sorties, sans modifier l'état des autres sorties.
  • 'data_dir' : Change la direction des GPIO du port.
  • 'mask' : Permet de définir un masque d'accès aux bits des autres champs. Affecte différents champs en fonction du micro-contrôleur.

Champs particuliers :

  • 'bval[32]' : Valeur de la pin sur un octet, le plus souvent sous la forme d'un tableau
  • 'wval[32]' : Valeur de la pin sur un entier de 32 bits, le plus souvent sous la forme d'un tableau

Utilisation : Interruptions

int set_gpio_callback(void (*callback) (uint32_t), const struct pio* gpio, uint8_t sense);
void remove_gpio_callback(const struct pio* gpio);
void remove_gpio_callback(unsigned int irq);

La fonction set_gpio_callback() sert à enregistrer une routine (paramètre 'callback') qui sera appelée lorsque l'événement 'sense' sur la GPIO 'gpio' générera une interruption.
La configuration de le GPIO correspondante en entrée et l'enregistrement et la configuration de l'interruption sont faits par la fonction set_gpio_callback().
Le fichier d'entête "drivers/gpio.h" définit une énumération d'événements et d'états pouvant déclencher une interruption.

EDGES_BOTH   /* Fronts montants et descendants */
EDGE_FALLING  /* Fronts descendants */
EDGE_RISING   /* Front montants */
LEVEL_HIGH  /* Niveau haut */
LEVEL_LOW   /* Niveau bas */

Note : un "front" est un changement d'état d'une entrée. Un front montant est donc le passage de l'entrée du niveau logique "0" au niveau logique "1".
Deux types de valeurs de retour sont possibles pour la fonction set_gpio_callback() en fonction du micro-contrôleur et du fonctionnement des interruptions GPIO pour ce micro-contrôleur (voir les spécificités par micro-contrôleur ci-dessous) :

  • Dans le cas de l'enregistrement par GPIO, la valeur de retour est un code d'erreur (valeur négative en cas d'erreur, ou 0 si tout c'est bien déroulé).
  • Pour l'enregistrement par numéro d'interruption, la valeur de retour est soit un code d'erreur (valeur négative), soit le numéro de l'interruption allouée à cette GPIO (valeur supérieure ou égale à 0).

La fonction remove_gpio_callback() sert à désactiver une interruption précédemment enregistrée par la fonction set_gpio_callback().
Selon le type de fonctionnement de l'enregistrement des interruptions (par GPIO ou par numéro d'interruption) le paramètre est soit la GPIO utilisée pour enregistrer l'interruption, soit le numéro d'interruption alloué par la fonction set_gpio_callback().
Se référer à la section "Spécificités par micro-contrôleur" ci-dessous pour déterminer le type du paramètre pour le micro-contrôleur utilisé.

Spécificités par micro-contrôleur

LPC82x

  • Nombre de ports : 1
  • Nombre de pins sur port 0 :
  • Fonctionnement des interruptions :
Enregistrement par numéro d'interruption.
8 interruptions individuelles disponibles.
N'importe quelle pin peut être reliée à n'importe quelles interruption.
2 interruptions "groupées" (pattern match).

LPC11A04

LPC122x

  • Nombre de ports : 3
  • Nombre de pins sur port 0 : 32
  • Nombre de pins sur port 1 : 7
  • Nombre de pins sur port 2 : 16 (Uniquement présentes sur les boîtiers avec 64 pins)
  • Fonctionnement des interruptions :
Enregistrement par GPIO (struct pio).
Une interruption par port.
Pas de limitation du nombre de pins pouvant être configurées pour générer des interruptions.

LPC176x