90 lines
1.9 KiB
C
90 lines
1.9 KiB
C
#include "io.h"
|
|
|
|
void serial_set_baud(unsigned short port, unsigned short div)
|
|
{
|
|
outb(COM_LINE_CONTROL(port), DLAB_BYTE);
|
|
outb(COM_DATA(port), (div >> 8) & 0x00FF);
|
|
outb(COM_INTERRUPT(port), div & 0x00FF);
|
|
outb(COM_LINE_CONTROL(port), 0);
|
|
}
|
|
|
|
void serial_config(unsigned short port)
|
|
{
|
|
/* configuration de la façon d'envoyer des données. Ici, on envoie des
|
|
caractères de 8 bits, avec 1 bit de stop et aucune parité. */
|
|
outb(COM_LINE_CONTROL(port), 0x03);
|
|
|
|
/* configuration de la file FIFO. Lorsqu'on essaie d'envoyer trop de
|
|
* caractères et que la vitesse du port ne suit pas, les caractères en trop
|
|
* sont stockés dans cette file. Ici, on vide la file de réception et
|
|
* d'envoie, on stocke 14 bytes dans les files et on l'active. cf. FCR (FIFO
|
|
* Control Register) : https://www.sci.muni.cz/docs/pc/serport.txt
|
|
*/
|
|
outb(COM_FIFO(port), 0xC7);
|
|
|
|
/* configuration du modem, on active la réception et l'envoie de données */
|
|
outb(COM_MODEM_CONTROL(port), 0x03);
|
|
}
|
|
|
|
int serial_is_fifo_empty(unsigned short port)
|
|
{
|
|
return inb(COM_LINE_STATUS(port)) & 0x20;
|
|
}
|
|
|
|
unsigned int serial_write(unsigned short port, char *buf, unsigned int len)
|
|
{
|
|
unsigned int ret;
|
|
char tmp;
|
|
|
|
ret = 0;
|
|
|
|
while (ret < len)
|
|
{
|
|
tmp = *(buf + ret);
|
|
|
|
/* pas ouf, à trouver un meilleur moyen d'attendre lorsque la file est
|
|
* pleine */
|
|
while (!serial_is_fifo_empty(port));
|
|
outb(COM_DATA(port), tmp);
|
|
|
|
ret++;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int serial_test_configuration(unsigned short port)
|
|
{
|
|
char *tmp;
|
|
char t;
|
|
int i, ret;
|
|
|
|
serial_set_baud(port, 5);
|
|
serial_config(port);
|
|
/* activation du retour pour pouvoir tester */
|
|
outb(COM_MODEM_CONTROL(port), 0x13);
|
|
|
|
i = 0;
|
|
tmp = "coucou";
|
|
|
|
do
|
|
{
|
|
outb(COM_DATA(port), *(tmp + i));
|
|
i++;
|
|
}
|
|
while (*(tmp + i) != '\0');
|
|
|
|
ret = 0;
|
|
i = 0;
|
|
|
|
do
|
|
{
|
|
t = inb(COM_DATA(port));
|
|
if (t != *(tmp + i)) ret++;
|
|
i++;
|
|
}
|
|
while (t != '\0');
|
|
|
|
return ret;
|
|
}
|