/** @file serial.h * Fichier d'en-tête pour les ports séries. * * Références: * - documentation sur les ports séries : * - https://wiki.osdev.org/Serial_Ports * - https://devse.wiki/x86_64/p%C3%A9riph%C3%A9riques/com * - https://www.sci.muni.cz/docs/pc/serport.txt * - `LCR (Line Control Register)` * - `FCR (FIFO Control Register)` * - `Excursion: Why and how to use the FIFOs (by Scott C. Sadow)` */ #ifndef SERIAL_H #define SERIAL_H #define COM1_PORT 0x03F8 #define COM_DATA(base) (base) #define COM_INTERRUPT(base) (base + 1) #define COM_FIFO(base) (base + 2) #define COM_LINE_CONTROL(base) (base + 3) #define COM_MODEM_CONTROL(base) (base + 4) #define COM_LINE_STATUS(base) (base + 5) #define COM_MODEM_STATUS(base) (base + 6) #define COM_SCRATCH(base) (base + 7) #define DLAB_BYTE 0x80 /** * Fonction pour définir la vitesse de transmission du port série. * * L'UART (le controleur de série) a une horloge interne tournant à 115200 * ticks par seconde. On peut modifier cette vitesse en la divisant. Cela se * fait en activant le DLAB. * * @param port le port série à configurer * @param div le diviseur du nombre de tick */ void serial_set_baud(unsigned short port, unsigned short div); /** * Configuration du port série. * * On configure le port série via le canal de controle de ligne. Il prend un * byte découpé en plusieurs sous parties : (7) DBPPPSTT (0). * * - D = bit pour activer le DLAB; * - B = active le break (cf. section `LCR (Line Control Register)` de * https://www.sci.muni.cz/docs/pc/serport.txt); * - P = parité (cf. https://wiki.osdev.org/Serial_Ports#Parity); * - S = nombre de bits de stop (0 = 1, 1 = 1.5/2); * - T = taille de la communication (0 = 5; 3 = 8) * * Notre configuration étant basique, nous nous contentons d'utiliser la taille * maximale de données, sans parité et avec un bit de stop. * * @param port le port à configurer */ void serial_config(unsigned short port); /** * Vérifie si la file d'envoie est vide. * * @param port le port à vérifier * @return 1 si la file est vide, 0 sinon */ int serial_is_fifo_empty(unsigned short port); /** * Envoie une chaine de caractère à un port série. * * La fonction fait une attente active lorsque la chaine est trop grosse. À * corriger dans le futur. * * @param port le port où envoyer la chaine. Il doit être configuré avant. * @param buf la chaine de caractère * @param len la longueur de la chaine * @return la taille de la chaine envoyée */ unsigned int serial_write(unsigned short port, char *buf, unsigned int len); /** * Vérifie si le port série marche bien. * * Configure le port avec un diviseur de 5 et active le drapeau de boucle du * modem. * * @param port le port où tester la configuration * @return 0 si tout est OK, un chiffre positif sinon */ int serial_test_configuration(unsigned short port); #endif