Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 7 commits
  • 16 files changed
  • 0 commit comments
  • 1 contributor
23 boards/milkymist-one/rtl/system.v
View
@@ -720,8 +720,7 @@ fmlbrg #(
//---------------------------------------------------------------------------
// Interrupts
//---------------------------------------------------------------------------
-wire uartrx_irq;
-wire uarttx_irq;
+wire uart_irq;
wire gpio_irq;
wire timer0_irq;
wire timer1_irq;
@@ -734,17 +733,15 @@ wire tmu_irq;
wire ethernetrx_irq;
wire ethernettx_irq;
wire videoin_irq;
-wire midirx_irq;
-wire miditx_irq;
+wire midi_irq;
wire ir_irq;
wire usb_irq;
wire [31:0] cpu_interrupt;
-assign cpu_interrupt = {14'd0,
+assign cpu_interrupt = {16'd0,
usb_irq,
ir_irq,
- miditx_irq,
- midirx_irq,
+ midi_irq,
videoin_irq,
ethernettx_irq,
ethernetrx_irq,
@@ -757,8 +754,7 @@ assign cpu_interrupt = {14'd0,
timer1_irq,
timer0_irq,
gpio_irq,
- uarttx_irq,
- uartrx_irq
+ uart_irq
};
//---------------------------------------------------------------------------
@@ -876,8 +872,7 @@ uart #(
.csr_di(csr_dw),
.csr_do(csr_dr_uart),
- .rx_irq(uartrx_irq),
- .tx_irq(uarttx_irq),
+ .irq(uart_irq),
.uart_rx(uart_rx),
.uart_tx(uart_tx),
@@ -1383,16 +1378,14 @@ uart #(
.csr_di(csr_dw),
.csr_do(csr_dr_midi),
- .rx_irq(midirx_irq),
- .tx_irq(miditx_irq),
+ .irq(midi_irq),
.uart_rx(midi_rx),
.uart_tx(midi_tx)
);
`else
assign csr_dr_midi = 32'd0;
-assign midirx_irq = 1'b0;
-assign miditx_irq = 1'b0;
+assign midi_irq = 1'b0;
assign midi_tx = 1'b1;
`endif
182 cores/monitor/rtl/gdbstub.rom
View
@@ -12,7 +12,7 @@ e0000005
581d0000
f8000034
5b9f0080
-f80001c9
+f80001cf
e000008f
98000000
78001000
@@ -20,7 +20,7 @@ e000008f
581d0000
f800002c
5b9e0080
-f80001c1
+f80001c7
e0000079
98000000
78001000
@@ -28,7 +28,7 @@ e0000079
581d0000
f8000024
5b9f0080
-f80001b9
+f80001bf
e000007f
98000000
78001000
@@ -36,7 +36,7 @@ e000007f
581d0000
f800001c
5b9e0080
-f80001b1
+f80001b7
e0000069
98000000
78001000
@@ -44,7 +44,7 @@ e0000069
581d0000
f8000014
5b9e0080
-f80001a9
+f80001af
e0000061
98000000
78001000
@@ -52,7 +52,7 @@ e0000061
581d0000
f800000c
5b9e0080
-f80001a1
+f80001a7
e0000059
98000000
78001000
@@ -60,7 +60,7 @@ e0000059
581d0000
f8000004
5b9e0080
-f8000199
+f800019f
e0000051
3400ff64
58010004
@@ -179,11 +179,17 @@ c3e00000
34210004
e3fffffd
c3a00000
-90400800
-20210001
-4420fffe
-34010001
-d0410000
+78021000
+38420fb8
+28410000
+28220000
+20420002
+4440fffe
+78031000
+38630fb8
+28610000
+34020002
+58220000
7801e000
28210000
b0200800
@@ -191,11 +197,11 @@ c3a00000
7802e000
58410000
78021000
-38420f90
+38420fb8
28410000
28220000
-20420002
-5c40fffe
+20420001
+4440fffe
c3a00000
b8201000
3421ff9f
@@ -216,7 +222,7 @@ c3a00000
3441ffc9
c3a00000
78041000
-38840fe0
+3884100c
e000000d
40250000
3463ffff
@@ -307,7 +313,7 @@ c3a00000
b8205800
29620084
78011000
-38210fd8
+38211004
20420007
b4220800
10230000
@@ -317,7 +323,7 @@ b4220800
14640004
30410000
78011000
-38210fe0
+3821100c
2063000f
2084000f
b4242000
@@ -368,7 +374,7 @@ c3a00000
780d1000
780b1000
39ad1804
-396b0f98
+396b0fc4
3410002b
34010024
fbffff49
@@ -392,7 +398,7 @@ b56c6000
fbffff37
11810000
fbffff35
-fbffff2b
+fbffff25
5c30ffe9
2b9d0004
2b8b001c
@@ -460,10 +466,10 @@ b4823800
e0000002
fbffff20
78011000
-38210fac
+38210fd8
e0000003
78011000
-38210fb0
+38210fdc
fbffffc3
2b9d0004
2b8b0008
@@ -488,33 +494,35 @@ c3a00000
5b9b0008
5b9d0004
78021000
-38420f90
+38420fbc
b8206800
28410000
78031000
-38630f94
+38630fc0
58200000
28610000
28220000
5c400004
34020001
58220000
-fbfffeb7
+fbfffeb1
78081000
-39080f90
+39080fb8
29010000
28220000
-20420002
-5c40fffe
-9040d800
+20420001
+4440fffe
+78021000
+38420fb8
+28410000
+283b0000
78011000
38211800
10210000
-237b0002
-44220004
+44200004
b9a00800
-fbffff2a
-fbffff63
+fbffff28
+fbffff61
78101000
780c1000
78171000
@@ -529,20 +537,20 @@ fbffff63
398c1b28
3af71800
3ad61b2b
-39ef0fb0
-3ab50fb8
-3a730fac
+39ef0fdc
+3ab50fe4
+3a730fd8
396b1e50
39ce1e4c
3a521e64
32000000
34190024
34180023
-fbfffe99
+fbfffe91
5c39ffff
34110000
34140000
-fbfffe95
+fbfffe8d
b8201000
4439fffc
44380008
@@ -550,35 +558,35 @@ b681a000
b5910800
30220000
36310001
-3401031f
+3403031f
229400ff
-4c31fff6
+4c71fff6
b5918800
32200000
5c58ffef
-fbfffe87
+fbfffe7f
202100ff
-fbfffe97
+fbfffe95
3c210004
203100ff
-fbfffe82
+fbfffe7a
202100ff
-fbfffe92
+fbfffe90
b6210800
202100ff
46810004
3401002d
-fbfffe84
+fbfffe82
e3ffffe1
3401002b
-fbfffe81
+fbfffe7f
11820002
3401003a
5c410005
11810000
-fbfffe7c
-11810001
fbfffe7a
+11810001
+fbfffe78
11830000
34010001
32e10000
@@ -625,7 +633,7 @@ e000000c
5c610149
e0000071
b9a00800
-fbfffeba
+fbfffeb8
e0000145
b9a00800
ba001000
@@ -641,7 +649,7 @@ e0000040
5b810050
3782004c
37810050
-fbfffe8a
+fbfffe88
4c010121
2b810050
10220000
@@ -651,43 +659,43 @@ fbfffe8a
5c41011b
37810050
37820048
-fbfffe80
+fbfffe7e
4c010117
2b830048
3401018f
54610114
2b81004c
ba001000
-fbfffe45
+fbfffe43
5c200124
78011000
-38210fb4
-e000014a
+38210fe0
+e000014c
34010000
e0000002
34010001
-fbffff04
+fbffff02
e000011c
78011000
38211b29
5b810050
3782004c
37810050
-fbfffe6a
+fbfffe68
4c010101
2b81004c
ba001000
34030004
3c210002
b5a10800
-fbfffe2f
+fbfffe2d
e000010e
78011000
38211b29
5b810050
3782004c
37810050
-fbfffe5c
+fbfffe5a
4c0100f3
2b810050
3402003d
@@ -699,7 +707,7 @@ fbfffe5c
34030004
3c420002
b5a21000
-fbfffe2f
+fbfffe2d
e00000e3
d1000000
d2000000
@@ -712,16 +720,16 @@ d2600000
34010044
5c6100f3
78011000
-38210fac
-fbfffeca
-fbfffe9b
+38210fd8
+fbfffec8
+fbfffe99
e00000ee
78011000
38211b29
5b810050
3782004c
37810050
-fbfffe3a
+fbfffe38
4c010003
2b81004c
59a10080
@@ -742,7 +750,7 @@ e00000da
5e2100c0
37810050
3782004c
-fbfffe25
+fbfffe23
4c0100bc
2b820050
10410000
@@ -751,7 +759,7 @@ fbfffe25
5c3100b7
37810050
37820048
-fbfffe1c
+fbfffe1a
4c0100b3
11820001
34010032
@@ -928,11 +936,11 @@ e0000009
3c840002
e3ffffeb
ba600800
-e0000040
+e0000042
baa00800
-e000003e
+e0000040
b9e00800
-e000003c
+e000003e
7802e000
34010001
3842103c
@@ -941,17 +949,17 @@ e000000e
78021000
78031000
38421b29
-38630fbc
+38630fe8
40440000
40610000
5c810007
78081000
39081b31
-4448002b
+4448002d
34420001
34630001
e3fffff8
-fbfffdae
+fbfffdac
e3fffe5f
d0600000
34000000
@@ -963,12 +971,14 @@ d0800000
34000000
34000000
34000000
-5f600003
-34010002
-d0410000
78031000
-38630f90
+38630fb8
28610000
+78081000
+23620004
+39080fbc
+58220000
+29010000
34020001
58220000
2b9d0004
@@ -991,10 +1001,11 @@ d0410000
379c0050
c3a00000
78011000
-38210fc8
-fbfffdb3
-e3ffffd6
-e000000c
+38210ff4
+fbfffdaf
+e3ffffd4
+e0000008
+e0000010
e0001030
30313233
34353637
@@ -1019,18 +1030,7 @@ e0001030
38396162
63646566
00000000
-02ef8670
-00000000
-00000000
-00000000
-00000000
-00000000
-00000000
-00000000
-00000000
-00000000
-00000000
-00000000
+69f0c80b
00000000
00000000
00000000
57 cores/uart/doc/uart.tex
View
@@ -34,21 +34,68 @@ \section{Registers}
\hline
\bf{Offset} & \bf{Read/Write} & \bf{Default} & \bf{Description} \\
\hline
-0x0 & RW & 0x00 & Data register. Received bytes and bytes to transmit are read/written from/to this register. \\
+0x00 & RW & 0x00 & Data register. Received bytes and bytes to transmit are read/written from/to this register. \\
\hline
-0x4 & RW & for default bitrate & Divisor register (for bitrate selection). \\
+0x04 & RW & for default bitrate & Divisor register (for bitrate selection). \\
+\hline
+0x08 & R, W1C & 0x01 & Status and event register. Events are cleared by writing 1. \\
+\hline
+0x0c & RW & 0x00 & Control register. \\
+\hline
+0x10 & RW & configurable & Debug register. \\
\hline
\end{tabularx}\\
+\subsection{Status and event register, offset 0x08}
+\begin{tabularx}{\textwidth}{|l|l|l|X|}
+\hline
+\bf Bits & \bf Access & \bf Default & \bf Description \\
+\hline
+0 & R & 1 & (Transmit Holding Register Empty). If this bit is set, the transmit holding register is empty, eg. transmission is finished. \\
+\hline
+1 & R, W1C & 0 & (RX Event). See below. \\
+\hline
+2 & R, W1C & 0 & (TX Event). See below. \\
+\hline
+\end{tabularx}
+
+\subsection{Control register, offset 0x0c}
+\begin{tabularx}{\textwidth}{|l|l|l|X|}
+\hline
+\bf Bits & \bf Access & \bf Default & \bf Description \\
+\hline
+0 & RW & 1 & (RX IRQ Enable). If this bit is set, a pending RX event will assert the interrupt output. \\
+\hline
+1 & RW & 1 & (TX IRQ Enable). If this bit is set, a pending TX event will assert the interrupt output. \\
+\hline
+2 & RW & 1 & (THRU). If this bit is set, MIDI thru mode is enabled. \\
+\hline
+\end{tabularx}
+
+\subsection{Debug control register, offset 0x10}
+\begin{tabularx}{\textwidth}{|l|l|l|X|}
+\hline
+\bf Bits & \bf Access & \bf Default & \bf Description \\
+\hline
+0 & RW & 1 & (Break Enable). If this bit is set and the UART core receives a BREAK symbol, the break output will be pulsed and this bit is cleared automatically. \\
+\hline
+\end{tabularx}
+
\section{Interrupts}
-The core has two active-high edge-sensitive interrupts outputs.
+The core has one active-high level-sensitive interrupt output.
+
+Whenever an event bit is set and the corresponding event is enabled in the control register, the interrupt output is asserted.
-The ``RX'' interrupt is sent whenever a new character is received. The CPU should then read the data register immediately. If a new character is sent before the CPU has had time to read it, the first character will be lost.
+\section{Events}
+The ``RX'' event is sent whenever a new character is received. The CPU should then read the data register immediately. If a new character is sent before the CPU has had time to read it, the first character will be lost.
The ``TX'' interrupt is sent as soon as the UART finished transmitting a character. When the CPU has written to the data register, it must wait for the interrupt before writing again.
+\section{MIDI thru mode}
+TBD.
+
\section{Using the core}
-Connect the CSR signals and the interrupts to the system bus and the interrupt controller. The \verb!uart_tx! and \verb!uart_rx! signals should go to the FPGA pads. You must also provide the desired default baudrate and the system clock frequency in Hz using the parameters.
+Connect the CSR signals and the interrupt to the system bus and the interrupt controller. The \verb!uart_tx! and \verb!uart_rx! signals should go to the FPGA pads. You must also provide the desired default baudrate and the system clock frequency in Hz using the parameters. The \verb!break! signal may be connected to your CPU debug unit to raise an exception on BREAK.
\section*{Copyright notice}
Copyright \copyright 2007-2010 S\'ebastien Bourdeauducq. \\
72 cores/uart/rtl/uart.v
View
@@ -29,8 +29,7 @@ module uart #(
input [31:0] csr_di,
output reg [31:0] csr_do,
- output rx_irq,
- output tx_irq,
+ output irq,
input uart_rx,
output uart_tx,
@@ -55,58 +54,85 @@ uart_transceiver transceiver(
.divisor(divisor),
.rx_data(rx_data),
- .rx_done(rx_irq),
+ .rx_done(rx_done),
.tx_data(tx_data),
.tx_wr(tx_wr),
- .tx_done(tx_irq),
+ .tx_done(tx_done),
.break(break_transceiver)
);
-assign uart_tx = thru ? uart_rx : uart_tx_transceiver;
+assign uart_tx = thru_en ? uart_rx : uart_tx_transceiver;
assign break = break_en & break_transceiver;
/* CSR interface */
wire csr_selected = csr_a[13:10] == csr_addr;
+assign irq = (tx_event & tx_irq_en) | (rx_event & rx_irq_en);
+
assign tx_data = csr_di[7:0];
-assign tx_wr = csr_selected & csr_we & (csr_a[1:0] == 2'b00);
+assign tx_wr = csr_selected & csr_we & (csr_a[2:0] == 3'b000);
parameter default_divisor = clk_freq/baud/16;
-reg thru;
+reg thru_en;
reg break_en;
-reg tx_pending;
+reg tx_irq_en;
+reg rx_irq_en;
+reg rx_event;
+reg tx_event;
+reg thre;
always @(posedge sys_clk) begin
if(sys_rst) begin
divisor <= default_divisor;
csr_do <= 32'd0;
- thru <= 1'b0;
+ thru_en <= 1'b0;
break_en <= break_en_default;
- tx_pending <= 1'b0;
+ rx_irq_en <= 1'b0;
+ tx_irq_en <= 1'b0;
+ tx_event <= 1'b0;
+ rx_event <= 1'b0;
+ thre <= 1'b1;
end else begin
csr_do <= 32'd0;
if(break)
break_en <= 1'b0;
- if(tx_irq)
- tx_pending <= 1'b0;
+ if(tx_done) begin
+ tx_event <= 1'b1;
+ thre <= 1'b1;
+ end
if(tx_wr)
- tx_pending <= 1'b1;
+ thre <= 1'b0;
+ if(rx_done) begin
+ rx_event <= 1'b1;
+ end
if(csr_selected) begin
- case(csr_a[1:0])
- 2'b00: csr_do <= rx_data;
- 2'b01: csr_do <= divisor;
- 2'b10: csr_do <= thru;
- 2'b11: csr_do <= {tx_pending, break_en};
+ case(csr_a[2:0])
+ 3'b000: csr_do <= rx_data;
+ 3'b001: csr_do <= divisor;
+ 3'b010: csr_do <= {tx_event, rx_event, thre};
+ 3'b011: csr_do <= {thru_en, tx_irq_en, rx_irq_en};
+ 3'b100: csr_do <= {break_en};
endcase
if(csr_we) begin
- case(csr_a[1:0])
- 2'b00:; /* handled by transceiver */
- 2'b01: divisor <= csr_di[15:0];
- 2'b10: thru <= csr_di[0];
- 2'b11: break_en <= csr_di[0];
+ case(csr_a[2:0])
+ 3'b000:; /* handled by transceiver */
+ 3'b001: divisor <= csr_di[15:0];
+ 3'b010: begin
+ /* write one to clear */
+ if(csr_di[1])
+ rx_event <= 1'b0;
+ if(csr_di[2])
+ tx_event <= 1'b0;
+ end
+ 3'b011: begin
+ rx_irq_en <= csr_di[0];
+ tx_irq_en <= csr_di[1];
+ thru_en <= csr_di[2];
+ end
+ 3'b100: break_en <= csr_di[0];
endcase
end
end
6 software/bios/isr.c
View
@@ -28,10 +28,8 @@ void isr()
irqs = irq_pending() & irq_getmask();
- if(irqs & IRQ_UARTRX)
- uart_isr_rx();
- if(irqs & IRQ_UARTTX)
- uart_isr_tx();
+ if(irqs & IRQ_UART)
+ uart_isr();
if(irqs & IRQ_TMU)
tmu_isr();
6 software/demo/isr.c
View
@@ -35,10 +35,8 @@ void isr()
irqs = irq_pending() & irq_getmask();
- if(irqs & IRQ_UARTRX)
- uart_isr_rx();
- if(irqs & IRQ_UARTTX)
- uart_isr_tx();
+ if(irqs & IRQ_UART)
+ uart_isr();
if(irqs & IRQ_TIMER0)
time_isr();
10 software/demo/shell.c
View
@@ -780,16 +780,16 @@ static void irtest()
static void midiprint()
{
unsigned int r;
- if(irq_pending() & IRQ_MIDIRX) {
+ if(CSR_MIDI_STAT & MIDI_STAT_RX_EVT) {
r = CSR_MIDI_RXTX;
- irq_ack(IRQ_MIDIRX);
+ CSR_MIDI_STAT = MIDI_STAT_RX_EVT;
printf("RX: %02x\n", r);
}
}
static void midirx()
{
- irq_ack(IRQ_MIDIRX);
+ CSR_MIDI_STAT = MIDI_STAT_RX_EVT;
while(!readchar_nonblock()) midiprint();
}
@@ -797,9 +797,9 @@ static void midisend(int c)
{
printf("TX: %02x\n", c);
CSR_MIDI_RXTX = c;
- while(!(irq_pending() & IRQ_MIDITX));
+ while(!(CSR_MIDI_STAT & MIDI_STAT_TX_EVT));
printf("TX done\n");
- irq_ack(IRQ_MIDITX);
+ CSR_MIDI_STAT = MIDI_STAT_TX_EVT;
midiprint();
}
33 software/gdbstub/gdbstub.c
View
@@ -109,17 +109,16 @@ static int memcmp(const void *cs, const void *ct, size_t count)
static char get_debug_char(void)
{
- while (!(irq_pending() & IRQ_UARTRX));
- irq_ack(IRQ_UARTRX);
+ while (!(CSR_UART_STAT & UART_STAT_RX_EVT));
+ CSR_UART_STAT = UART_STAT_RX_EVT;
return (char)CSR_UART_RXTX;
}
static void put_debug_char(char c)
{
CSR_UART_RXTX = c;
- /* Blocking on UART pending bit is intended here! Have a
- * look at the end of handle_exception() too. */
- while (CSR_UART_BREAK & UART_TX_PENDING);
+ /* loop on THRE, TX_EVT must not be cleared */
+ while (!(CSR_UART_STAT & UART_STAT_THRE));
}
/*
@@ -671,8 +670,8 @@ static void cmd_query(void)
*/
void handle_exception(unsigned int *registers)
{
- int irq;
-
+ unsigned int stat;
+
/*
* make sure break is disabled.
* we can enter the stub with break enabled when the application calls it.
@@ -681,7 +680,7 @@ void handle_exception(unsigned int *registers)
* applications should disable debug exceptions before jumping to debug
* ROM.
*/
- CSR_UART_BREAK = 0;
+ CSR_UART_DEBUG = 0;
/* clear BSS there was a board reset */
if (!CSR_DBG_SCRATCHPAD) {
@@ -689,11 +688,11 @@ void handle_exception(unsigned int *registers)
clear_bss();
}
- /* wait until TX transaction is finished */
- while (CSR_UART_BREAK & UART_TX_PENDING);
-
- /* remember if irq was set */
- irq = irq_pending() & IRQ_UARTTX;
+ /* wait until TX transaction is finished. If there was a transmission in
+ * progress, the event bit will be set. In this case, the gdbstub won't clear
+ * it after it is terminated. */
+ while(!(CSR_UART_STAT & UART_STAT_THRE));
+ stat = CSR_UART_STAT;
/* reply to host that an exception has occured */
if (gdb_connected) {
@@ -768,11 +767,9 @@ void handle_exception(unsigned int *registers)
out:
flush_cache();
- /* ack TX IRQ only if it wasn't set before */
- if (!irq) {
- irq_ack(IRQ_UARTTX);
- }
+ /* clear TX event if there was no transmission in progress */
+ CSR_UART_STAT = stat & UART_STAT_TX_EVT;
/* reenable break */
- CSR_UART_BREAK = UART_BREAK_EN;
+ CSR_UART_DEBUG = UART_DEBUG_BREAK_EN;
}
3  software/include/base/uart.h
View
@@ -19,8 +19,7 @@
#define __UART_H
void uart_init();
-void uart_isr_rx();
-void uart_isr_tx();
+void uart_isr();
void uart_force_sync(int f);
void uart_write(char c);
34 software/include/hw/interrupts.h
View
@@ -18,23 +18,21 @@
#ifndef __HW_INTERRUPTS_H
#define __HW_INTERRUPTS_H
-#define IRQ_UARTRX (0x00000001) /* 0 */
-#define IRQ_UARTTX (0x00000002) /* 1 */
-#define IRQ_GPIO (0x00000004) /* 2 */
-#define IRQ_TIMER0 (0x00000008) /* 3 */
-#define IRQ_TIMER1 (0x00000010) /* 4 */
-#define IRQ_AC97CRREQUEST (0x00000020) /* 5 */
-#define IRQ_AC97CRREPLY (0x00000040) /* 6 */
-#define IRQ_AC97DMAR (0x00000080) /* 7 */
-#define IRQ_AC97DMAW (0x00000100) /* 8 */
-#define IRQ_PFPU (0x00000200) /* 9 */
-#define IRQ_TMU (0x00000400) /* 10 */
-#define IRQ_ETHRX (0x00000800) /* 11 */
-#define IRQ_ETHTX (0x00001000) /* 12 */
-#define IRQ_VIDEOIN (0x00002000) /* 13 */
-#define IRQ_MIDIRX (0x00004000) /* 14 */
-#define IRQ_MIDITX (0x00008000) /* 15 */
-#define IRQ_IR (0x00010000) /* 16 */
-#define IRQ_USB (0x00020000) /* 17 */
+#define IRQ_UART (0x00000001) /* 0 */
+#define IRQ_GPIO (0x00000002) /* 1 */
+#define IRQ_TIMER0 (0x00000004) /* 2 */
+#define IRQ_TIMER1 (0x00000008) /* 3 */
+#define IRQ_AC97CRREQUEST (0x00000010) /* 4 */
+#define IRQ_AC97CRREPLY (0x00000020) /* 5 */
+#define IRQ_AC97DMAR (0x00000040) /* 6 */
+#define IRQ_AC97DMAW (0x00000080) /* 7 */
+#define IRQ_PFPU (0x00000100) /* 8 */
+#define IRQ_TMU (0x00000200) /* 9 */
+#define IRQ_ETHRX (0x00000400) /* 10 */
+#define IRQ_ETHTX (0x00000800) /* 11 */
+#define IRQ_VIDEOIN (0x00001000) /* 12 */
+#define IRQ_MIDI (0x00002000) /* 13 */
+#define IRQ_IR (0x00004000) /* 14 */
+#define IRQ_USB (0x00008000) /* 15 */
#endif /* __HW_INTERRUPTS_H */
11 software/include/hw/midi.h
View
@@ -22,6 +22,15 @@
#define CSR_MIDI_RXTX MMPTR(0xe000b000)
#define CSR_MIDI_DIVISOR MMPTR(0xe000b004)
-#define CSR_MIDI_THRU MMPTR(0xe000b008)
+#define CSR_MIDI_STAT MMPTR(0xe000b008)
+#define CSR_MIDI_CTRL MMPTR(0xe000b00c)
+
+#define MIDI_STAT_THRE (0x1)
+#define MIDI_STAT_RX_EVT (0x2)
+#define MIDI_STAT_TX_EVT (0x4)
+
+#define MIDI_CTRL_RX_INT (0x1)
+#define MIDI_CTRL_TX_INT (0x2)
+#define MIDI_CTRL_THRU (0x4)
#endif /* __HW_MIDI_H */
16 software/include/hw/uart.h
View
@@ -22,12 +22,18 @@
#define CSR_UART_RXTX MMPTR(0xe0000000)
#define CSR_UART_DIVISOR MMPTR(0xe0000004)
-#define CSR_UART_THRU MMPTR(0xe0000008)
-#define CSR_UART_BREAK MMPTR(0xe000000c)
+#define CSR_UART_STAT MMPTR(0xe0000008)
+#define CSR_UART_CTRL MMPTR(0xe000000c)
+#define CSR_UART_DEBUG MMPTR(0xe0000010)
-#define UART_THRU (0x1)
+#define UART_STAT_THRE (0x1)
+#define UART_STAT_RX_EVT (0x2)
+#define UART_STAT_TX_EVT (0x4)
-#define UART_BREAK_EN (0x1)
-#define UART_TX_PENDING (0x2)
+#define UART_CTRL_RX_INT (0x1)
+#define UART_CTRL_TX_INT (0x2)
+#define UART_CTRL_THRU (0x4)
+
+#define UART_DEBUG_BREAK_EN (0x1)
#endif /* __HW_UART_H */
4 software/libbase/console.c
View
@@ -65,7 +65,7 @@ int puts(const char *s)
unsigned int oldmask;
oldmask = irq_getmask();
- irq_setmask(IRQ_UARTRX); // HACK: prevent UART data loss
+ irq_setmask(IRQ_UART); // HACK: prevent UART data loss
while(*s) {
writechar(*s);
@@ -82,7 +82,7 @@ void putsnonl(const char *s)
unsigned int oldmask;
oldmask = irq_getmask();
- irq_setmask(IRQ_UARTRX); // HACK: prevent UART data loss
+ irq_setmask(IRQ_UART); // HACK: prevent UART data loss
while(*s) {
writechar(*s);
67 software/libbase/uart.c
View
@@ -34,11 +34,36 @@ static char rx_buf[UART_RINGBUFFER_SIZE_RX];
static volatile unsigned int rx_produce;
static volatile unsigned int rx_consume;
-void uart_isr_rx()
+#define UART_RINGBUFFER_SIZE_TX 131072
+#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1)
+
+static char tx_buf[UART_RINGBUFFER_SIZE_TX];
+static unsigned int tx_produce;
+static unsigned int tx_consume;
+static volatile int tx_cts;
+
+static int force_sync;
+
+
+void uart_isr()
{
- irq_ack(IRQ_UARTRX);
- rx_buf[rx_produce] = CSR_UART_RXTX;
- rx_produce = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX;
+ unsigned int stat = CSR_UART_STAT;
+
+ if(stat & UART_STAT_RX_EVT) {
+ rx_buf[rx_produce] = CSR_UART_RXTX;
+ rx_produce = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX;
+ }
+
+ if(stat & UART_STAT_TX_EVT) {
+ if(tx_produce != tx_consume) {
+ CSR_UART_RXTX = tx_buf[tx_consume];
+ tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX;
+ } else
+ tx_cts = 1;
+ }
+
+ CSR_UART_STAT = stat;
+ irq_ack(IRQ_UART);
}
/* Do not use in interrupt handlers! */
@@ -57,36 +82,16 @@ int uart_read_nonblock()
return (rx_consume != rx_produce);
}
-#define UART_RINGBUFFER_SIZE_TX 131072
-#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1)
-
-static char tx_buf[UART_RINGBUFFER_SIZE_TX];
-static unsigned int tx_produce;
-static unsigned int tx_consume;
-static volatile int tx_cts;
-
-static int force_sync;
-
-void uart_isr_tx()
-{
- irq_ack(IRQ_UARTTX);
- if(tx_produce != tx_consume) {
- CSR_UART_RXTX = tx_buf[tx_consume];
- tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX;
- } else
- tx_cts = 1;
-}
-
void uart_write(char c)
{
unsigned int oldmask;
oldmask = irq_getmask();
irq_setmask(0);
+
if(force_sync) {
CSR_UART_RXTX = c;
- while(!(irq_pending() & IRQ_UARTTX));
- irq_ack(IRQ_UARTTX);
+ while(!(CSR_UART_STAT & UART_STAT_THRE));
} else {
if(tx_cts) {
tx_cts = 0;
@@ -109,10 +114,16 @@ void uart_init()
tx_consume = 0;
tx_cts = 1;
- irq_ack(IRQ_UARTRX|IRQ_UARTTX);
+ irq_ack(IRQ_UART);
+
+ /* ack any events */
+ CSR_UART_STAT = CSR_UART_STAT;
+
+ /* enable interrupts */
+ CSR_UART_CTRL = UART_CTRL_TX_INT | UART_CTRL_RX_INT;
mask = irq_getmask();
- mask |= IRQ_UARTRX|IRQ_UARTTX;
+ mask |= IRQ_UART;
irq_setmask(mask);
}
4 software/libhal/vga.c
View
@@ -360,10 +360,10 @@ static void scroll_callback(struct tmu_td *td)
unsigned int oldmask;
unsigned int ie;
- /* HACK: allow nested UART RX interrupts to prevent data loss */
+ /* HACK: allow nested UART interrupts to prevent data loss */
ie = irq_getie();
oldmask = irq_getmask();
- irq_setmask(IRQ_UARTRX);
+ irq_setmask(IRQ_UART);
irq_enable(1);
flush_cpu_dcache();
39 software/libhpdmc/libhpdmc.S
View
@@ -342,16 +342,18 @@ boot:
*
* inputs: none
* outputs: r1 - character
- * clobbers: r1
+ * clobbers: r1, r2
*/
getkey:
- rcsr r1, IP
- andi r1, r1, IRQ_UARTRX
- be r1, r0, getkey
- wcsr IP, r1
- mvhi r1, hi(CSR_UART_RXTX)
- ori r1, r1, lo(CSR_UART_RXTX)
- lw r1, (r1+0)
+ mvhi r2, hi(CSR_UART_RXTX)
+ ori r2, r2, lo(CSR_UART_RXTX)
+getkeywait:
+ lw r1, (r2+8)
+ andi r1, r1, UART_STAT_RX_EVT
+ be r1, r0, getkeywait
+ mvi r1, UART_STAT_RX_EVT
+ sw (r2+8), r1
+ lw r1, (r2+0)
ret
#endif /* FEAT_MANUAL_CALIBRATION */
@@ -416,8 +418,8 @@ printint:
mvu r3, '-'
sw (r2+0), r3
writeintwait0:
- rcsr r3, IP
- andi r3, r3, IRQ_UARTTX
+ lw r3, (r2+8)
+ andi r3, r3, UART_STAT_THRE
be r3, r0, writeintwait0
wcsr IP, r3
@@ -428,8 +430,8 @@ positive:
addi r3, r3, '0'
sw (r2+0), r3
writeintwait1:
- rcsr r3, IP
- andi r3, r3, IRQ_UARTTX
+ lw r3, (r2+8)
+ andi r3, r3, UART_STAT_THRE
be r3, r0, writeintwait1
wcsr IP, r3
@@ -439,16 +441,16 @@ writeintwait1:
addi r3, r3, '0'
sw (r2+0), r3
writeintwait2:
- rcsr r3, IP
- andi r3, r3, IRQ_UARTTX
+ lw r3, (r2+8)
+ andi r3, r3, UART_STAT_THRE
be r3, r0, writeintwait2
wcsr IP, r3
addi r3, r1, '0'
sw (r2+0), r3
writeintwait3:
- rcsr r3, IP
- andi r3, r3, IRQ_UARTTX
+ lw r3, (r2+8)
+ andi r3, r3, UART_STAT_THRE
be r3, r0, writeintwait3
wcsr IP, r3
@@ -468,10 +470,9 @@ writeloop:
be r3, r0, print_endloop
sw (r2+0), r3
writewait:
- rcsr r3, IP
- andi r3, r3, IRQ_UARTTX
+ lw r3, (r2+8)
+ andi r3, r3, UART_STAT_THRE
be r3, r0, writewait
- wcsr IP, r3
addi r1, r1, 1
bi writeloop
print_endloop:

No commit comments for this range

Something went wrong with that request. Please try again.