pit.c (2876B)
1 #include <module.h> 2 #include <types.h> 3 #include <algo/math/math.h> 4 #include <pc/irq/irq.h> 5 #include <pc/pit/pit.h> 6 #include <pc/io/io.h> 7 8 #include <interfaceUtilisateur/console/console.h> /* DEBUG */ 9 10 MODULE(Pit); 11 12 DEPENDANCE_MODULE(Pit, Irq); 13 DEPENDANCE_MODULE(Pit, Io); 14 DEPENDANCE_MODULE(Pit, Math); 15 DEPENDANCE_MODULE(Pit, Console); /* DEBUG */ 16 17 void gestionnaireRequeteInterruptionPit() { 18 etatPit->gestionnairePit(); 19 } 20 21 void gestionnairePitVide() { 22 } 23 24 void definirCompteurCanal(uint16 compteur, PitCanal canal) { 25 uint8 haut = (compteur >> 8) & 0xff; 26 uint8 bas = compteur & 0xff; 27 int port = PORT_PIT_CANAUX + canal; 28 /* TODO : lorsqu'on fait les outb avec un entier dans une variable 29 * pour le port, il y a un problème. */ 30 port = port; 31 32 if ((etatPit->modeAcces == PIT_OCTET_BAS) || 33 (etatPit->modeAcces == PIT_OCTETS_HAUT_BAS)) 34 outb(PORT_PIT_CANAUX, bas); 35 36 if ((etatPit->modeAcces == PIT_OCTET_HAUT) || 37 (etatPit->modeAcces == PIT_OCTETS_HAUT_BAS)) 38 outb(PORT_PIT_CANAUX, haut); 39 } 40 41 void definirModeCanal(PitModeCanal mode, PitCanal canal) { 42 PitCommandeMode commande; 43 commande.bcd = FALSE; 44 commande.mode = mode; 45 commande.acces = etatPit->modeAcces; 46 commande.canal = canal; 47 48 outb(PORT_PIT_COMMANDE, commande); 49 } 50 51 /* freq en 1/1000 hz [~18000..FREQUENCE_PIT_KHZ] */ 52 uint32 definirFrequenceCanal(uint32 freq, PitCanal canal) { 53 uint32 diviseur = FREQUENCE_PIT_MILI_HZ / freq; 54 55 if (diviseur > 65536) { 56 return 0; 57 } else if (diviseur == 65536) { 58 definirCompteurCanal(0, canal); 59 return FREQUENCE_PIT_MILI_HZ / 65536; 60 } else if (diviseur == 0) { 61 definirCompteurCanal(1, canal); 62 return FREQUENCE_PIT_MILI_HZ; 63 } else { 64 definirCompteurCanal(diviseur, canal); 65 return FREQUENCE_PIT_MILI_HZ / diviseur; 66 } 67 } 68 69 /* delai en ns [1..10^8] */ 70 uint32 definirDelaiCanal(uint32 delai, PitCanal canal) { 71 //afficherEntierVirguleEnDecimal(delai, 9); 72 uint64 fd = (uint64)FREQUENCE_PIT_MILI_HZ * (uint64)delai; 73 Div64 r = div64 (fd, 1000000000000); 74 uint64 diviseur = r.quotient; 75 76 if (diviseur >= 65536) { 77 definirCompteurCanal(0, canal); 78 diviseur = 65536; 79 } else if (diviseur == 0) { 80 definirCompteurCanal(1, canal); 81 diviseur = 1; 82 } else { 83 definirCompteurCanal(diviseur, canal); 84 } 85 86 Div64 delaiEffectif = div64(diviseur * 1000000000000L, FREQUENCE_PIT_MILI_HZ); 87 88 return (uint32)delaiEffectif.quotient; 89 } 90 91 void definirGestionnairePit(GestionnairePit gestionnairePit) { 92 etatPit->gestionnairePit = gestionnairePit; 93 } 94 95 void initPit (void** etat) { 96 *etat = etatPit; 97 98 etatPit->gestionnairePit = gestionnairePitVide; 99 100 definirGestionnaireRequeteInterruption(LIGNE_IRQ_PIT, gestionnaireRequeteInterruptionPit); 101 activerLigneRequeteInterruption(LIGNE_IRQ_PIT); 102 103 etatPit->modeAcces = PIT_OCTETS_HAUT_BAS; 104 definirModeCanal(PIT_MODE_GENERATEUR_FREQUENCE, 0); 105 definirCompteurCanal(0, 0); 106 } 107 108 void deinitPit (void** etat) { 109 *etat = NULL; 110 }