/************************************************ Configura a porta serial UART com interrupcao LabProc 2009-2 Marcos Augusto Stemmer *************************************************/ #include #include "vic_cpsr.h" #include "uart.h" /* TAMFILA deve ser ((2^n)-1) */ #define TAMFILA 0x100 char filarx[TAMFILA]; /* Fila de recebimento */ char filatx[TAMFILA]; /* Fila de transmissao */ volatile int rx_ini, rx_fim, tx_ini, tx_fim; /* Declara que a funcao uart_irq e' um atendimento de IRQ */ void uart_irq(void) __attribute__ ((interrupt("IRQ"))); /* Atendimento da IRQ 6 (UART0) */ void uart_irq(void) { int iir; iir = U0IIR; /* Caractere recebido: Le e coloca no fim da fila RX */ if(iir & 4) while(U0LSR & 1) { /* Pega todos os caracteres recebidos na FIFO */ filarx[rx_fim++] = U0RBR; if(rx_fim == TAMFILA) rx_fim = 0; } /* Transmissor livre e caractere na fila TX: Pega da fila e transmite */ if(iir & 2) while((U0LSR & 0x20) && (tx_fim != tx_ini)) { U0THR = filatx[tx_ini++]; if(tx_ini == TAMFILA) tx_ini = 0; } #ifdef DEBUG FIO4PIN0 = ~rx_fim; /* Mostra contagem nos LEDs [para debugging] */ #endif VICVectAddr = 0; /* Limpa IRQ no VIC */ } /* Configuracao da Porta Serial 0 com interrupcao */ void U0init(int baudrate) { int divisor; PINSEL0 |= 0x50; /* Seleciona pinos TxD0 e RxD0 */ U0FCR = 0x87; /* Habilita as FIFOs e reset. Interrompe com 8 chars */ U0LCR = 0x83; /* Habilita acesso ao divisor de baud-rate (DLAB) */ divisor = (SYSCLK/baudrate + 8) >> 4; U0DLL = divisor & 0xff; U0DLM = (divisor >> 8); U0LCR = 0x03; /* Configura UART0 como 8N1 */ /* Habilita a interrupcao 6 da UART0 no VIC */ desabilitaIRQ(); /* Definida no #include "vic_cpsr.h" */ rx_fim = rx_ini = 0; tx_fim = tx_ini = 0; VICIntSelect &= ~(1<< 6); /* UART bit 6 como IRQ */ VICIntEnable = (1<< 6); /* Habilita int 6 */ VICVectAddr6 = (int)uart_irq; /* Vetor para a rotina de atendimento */ U0IER = 3; /* Hbilita irq por recebimento e transmissao na UART0 */ habilitaIRQ(); /* Definida no #include "vic_cpsr.h" */ } /* Recebe um caractere da porta serial */ int U0getchar(void) { int c; while(rx_ini == rx_fim); /* Fila vazia: espera */ c = filarx[rx_ini++]; /* Pega c da fila */ if(rx_ini == TAMFILA) rx_ini = 0; return c; } /* Envia um caractere */ void U0putchar(int c) { filatx[tx_fim]=c; /* Coloca caractere na fila */ tx_fim = (tx_fim + 1) & TAMFILA; if(U0LSR & 0x20) { /* Se transmissor livre, transmite */ U0THR = filatx[tx_ini++]; if(tx_ini == TAMFILA) tx_ini = 0; } } /* Informa quantos caracteres tem na fila de recebimento */ int U0tem(void) { return ((rx_fim - rx_ini) & TAMFILA); } /* Envia uma mensagem pela UART0 */ void U0puts(char *txt) { while(*txt) U0putchar(*txt++); } /* Escreve um digito hexadecimal */ void U0prdig(int dig) { dig &= 0xf; if(dig > 9) dig+='A'-'9'-1; U0putchar(dig+'0'); } /* Escreve um byte como 2 digitos hexadecimais */ void U0prbyte(int c) { U0prdig(c>>4); U0prdig(c); }