diff --git a/cMIPS/include/handlers.s b/cMIPS/include/handlers.s index 4f90c23d1a681e35fdf269ca872861c101ca8672..59d06e1840b31098c09430f1f0b12fe89c070f2c 100644 --- a/cMIPS/include/handlers.s +++ b/cMIPS/include/handlers.s @@ -116,9 +116,9 @@ UARTinterr: .include "../tests/handlerUART.s" #---------------------------------- - andi $a1, $k1, UART_rx_irq # Is this reception? - beq $a1, $zero, UARTret # no, ignore it and return - nop + #andi $a1, $k1, UART_rx_irq # Is this reception? + #beq $a1, $zero, UARTret # no, ignore it and return + #nop # handle reception #lw $a1, 4($a0) # Read data from device diff --git a/cMIPS/include/main.c b/cMIPS/include/main.c index 3ba007c2148cf2991a989db1e0aff62763a52100..bc328f1f69293e4f95ed6da8b0ab07845aa411a8 100644 --- a/cMIPS/include/main.c +++ b/cMIPS/include/main.c @@ -1,29 +1,22 @@ #include "cMIPS.h" #include "vetorFib.h" +#include "structUart.h" #define MAXPOW 7 +#define SPEED 3 +#define COUNT ((SPEED+1)*100) -typedef struct UARTdriver { -int rx_hd ; // reception queue head index -int rx_tl ; // reception queue tail index -char rx_q [16]; // reception queue -int tx_hd ; // transmission queue head index -int tx_tl ; // transmission queue tail index -char tx_q [16]; // transmission queue -int nrx ; // number of characters in rx_queue -int ntx ; // number of spaces in tx_queue -} UARTdriver ; -extern UARTdriver Ud ; +extern UARTdriver Ud; +Tcontrol ctrl; +volatile Tserial *uart; -int Strlen(char *c) -{ +int Strlen (char *c) { int i= 0; while(c[i++]-10); return i-1; } -int pow16(int ex) -{ +int pow16 (int ex) { int i, ret=1; for (i= 0; i< ex/2; i++) ret*=16; @@ -31,8 +24,7 @@ int pow16(int ex) return (ex%2?ret*16:ret); } -int hex2int(char *hex) -{ +int hex2int (char *hex) { int s= Strlen(hex), i, ans= 0; for (i= 0; i< s; i++) { hex[i]-= 48; @@ -45,8 +37,7 @@ int hex2int(char *hex) return ans; } -int int2hex(char *c, int i) -{ +int int2hex (char *c, int i) { int j= 0, val; int p; p = pow16(MAXPOW); @@ -67,10 +58,32 @@ int int2hex(char *c, int i) return j-1; } -int main() -{ +int Putc (char c) { + if (Ud.ntx == 0) + return 0; + if (Ud.ntx == 16 && uart->cs.stat.txEmpty) // Empty Q && Tx + uart->d.tx = (int) c; // 32-bits + else { // Sending smthng + disableInterr(); + ud.ntx--; + Ud.tx_q[Ud.tx_tl] = c; + Ud.tx_tl = (Ud.tx_tl + 1)&0xF; // modulo 16 + enableInterr(); + } + return 1; +} + +int main () { + uart= IO_UART_ADDR; char n[16], f[16], c; - int fib, j, s; + int fib, j, s, val; + // initialize UART control + ctrl.rts= 1; + ctrl.intTX= 1; // Both interruption + ctrl.intRX= 1; + ctrl.speed= SPEED; + uart->cs.ctl = ctrl; + while (1) { j= 0; while ((n[j++]= getFila()) != '\n'); @@ -82,7 +95,7 @@ int main() fib = buf[fib]; s= int2hex(f, fib); //retorna strlen de f for (j= 0; j< s; j++) - putc(f[j]); + Putc(f[j]); } else { to_stdout('v'); to_stdout('a'); @@ -105,6 +118,9 @@ int main() to_stdout('\n'); } } + startCounter (COUNT , 0); + while ((val= (readCounter() && 0x3FFFFFFF)) < COUNT); // sleep?? - return 0; + // yes, baby! + return val; } diff --git a/cMIPS/include/putc.c b/cMIPS/include/putc.c new file mode 100644 index 0000000000000000000000000000000000000000..a98da00650d81e6c7a88224db7c4948cf53649cd --- /dev/null +++ b/cMIPS/include/putc.c @@ -0,0 +1,13 @@ +int Putc(char c) +{ + void *Tx = IO_UART_ADDR + if (Ud.ntx == 16) // Empty Q + *Tx = (int) c; // 32-bits + else { + Ud.tx_tl = (Ud.tx_tl + 1)&0xF; // modulo 16 + disableInterr(); + Ud.tx_q[Ud.tx_tl] = c; + enableInterr(); + } + return 1; +} diff --git a/cMIPS/include/structUart.h b/cMIPS/include/structUart.h new file mode 100644 index 0000000000000000000000000000000000000000..1572b41bb2163200db5108e248deb13e9574967e --- /dev/null +++ b/cMIPS/include/structUart.h @@ -0,0 +1,56 @@ +#ifndef __STRUCTUART__ +#define __STRUCTUART__ + +typedef struct UARTdriver { +int rx_hd ; // reception queue head index +int rx_tl ; // reception queue tail index +char rx_q [16]; // reception queue +int tx_hd ; // transmission queue head index +int tx_tl ; // transmission queue tail index +char tx_q [16]; // transmission queue +int nrx ; // number of characters in rx_queue +int ntx ; // number of spaces in tx_queue +} UARTdriver; + +typedef struct control { // control register fields (uses only ls byte) + int ign : 24, // ignore uppermost bits + rts : 1, // Request to Send output (bit 7) + ign2 : 2, // bits 6,5 ignored + intTX : 1, // interrupt on TX buffer empty (bit 4) + intRX : 1, // interrupt on RX buffer full (bit 3) + speed : 3; // 4,8,16..256 tx-rx clock data rates (bits 0..2) +} Tcontrol; + +typedef struct status { // status register fields (uses only ls byte) + int ign : 24, // ignore uppermost bits + ign7 : 1, // ignored (bit 7) + txEmpty : 1, // TX register is empty (bit 6) + rxFull : 1, // octet available from RX register (bit 5) + int_TX_empt: 1, // interrupt pending on TX empty (bit 4) + int_RX_full: 1, // interrupt pending on RX full (bit 3) + ign2 : 1, // ignored (bit 2) + framing : 1, // framing error (bit 1) + overun : 1; // overun error (bit 0) +} Tstatus; + +typedef union ctlStat { // control + status on same address + Tcontrol ctl; // write-only + Tstatus stat; // read-only +} TctlStat; + +typedef union data { // data registers on same address + int tx; // write-only + int rx; // read-only +} Tdata; + +/***************************************************** +?typedef struct serial { ** +? TctlStat cs; // @ (int *)IO_UART_ADDR ** +?} ** +*****************************************************/ + +typedef struct serial { + TctlStat cs; // @ (int *)IO_UART_ADDR + Tdata d; // @ (int *)(IO_UART_ADDR+1) +} Tserial; +#endif diff --git a/cMIPS/tests/handlerUART.s b/cMIPS/tests/handlerUART.s index 27ecb4e39bb8a9f8639ac00906ebb59717b50922..c5b3f9bff300fe72b3dc3e934fcd829ddb0ab707 100644 --- a/cMIPS/tests/handlerUART.s +++ b/cMIPS/tests/handlerUART.s @@ -10,8 +10,7 @@ sw $a3, 8*4($k0) sw $v0, 9*4($k0) - jal disableInterr - nop + di andi $a1, $k1, UART_rx_irq # Is this reception? beq $a1, $zero, UARTrxinter # no, maybe transmission? @@ -37,28 +36,24 @@ lui $a1, %hi(tx_hd) ori $a1, $a1, %lo(tx_hd) lw $a3, 0($a1) - addi $a3, $a3, 1 + nop + add $a2, $a2, $a3 # a2 <- &(tx_q[tx_hd]) + lb $a3, 0($a2) # get char from Q head + nop + addi $a3, $a3, 1 #increment Q head andi $a3, $a3, 0xf # modulo 16 sw $a3, 0(a1) # store new head index - add $a2, $a2, $a3 - lb $a3, 0($a2) # get char from Q head - sw $a2, 0(a0) # write char in txreg -overrun: - - # do something if rx queue is full or tx is empty - #... (doing absolutely nothing besides stacking and unstacking regs) - #Precisa coisar o nrx (incrementar) - jal enableInterr - nop - lw $v0, 9*4($k0) - lw $a3, 8*4($k0) - lw $a2, 7*4($k0) +endHU: + + lw $v0, 9*4($k0) + lw $a3, 8*4($k0) + lw $a2, 7*4($k0) b UARTret - nop + ei UARTrxinter: #handle reception @@ -99,21 +94,17 @@ UARTrxinter: nop sb $7, 0($6) # and store it! - jal enableInterr + b endUH nop - #### process rx_tl -- update tail - #lw $7, 0($5) - #nop - -#UARTinterr2: -# andi $a1, $k1, UART_tx_irq # Is this transmission? -# beq $a1, $zero, UARTret # no, ignore it and return -# nop - - #handle transmission - # ... TODO - - # Lembrar de inicializar os hd e tl com 0 no comeco do main +overrun: + # do something if rx queue is full or tx is empty + # set overrun bit on uart statusReg + #... (doing absolutely nothing besides stacking and unstacking regs) + lw $a1, 0*4($k0) # get status from memory + nop + andi $a1, $a1, 0xFFFFFFF1 # set overun bit to 1 + # sw $a1, ??? ---+ Dunno where to save Status + b endUH # | + nop # <--+ -#UARTret: