uart: RX support
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 7 Feb 2012 13:12:23 +0000 (14:12 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 7 Feb 2012 13:12:23 +0000 (14:12 +0100)
milkymist/uart/__init__.py

index 12ad58550922623a3f078ee5208bf07edcf93f1c..3d052619c7d0f91e19a265c54cc09dd5445b63f2 100644 (file)
@@ -9,7 +9,8 @@ class UART:
                self._divisor = RegisterField("divisor", 16, reset=int(clk_freq/baud/16))
                
                self._tx_event = EventSourceLevel()
-               self.events = EventManager(self._tx_event)
+               self._rx_event = EventSourcePulse()
+               self.events = EventManager(self._tx_event, self._rx_event)
                self.bank = csrgen.Bank([self._rxtx, self._divisor] + self.events.get_registers(),
                        address=address)
 
@@ -28,10 +29,11 @@ class UART:
                                enable16_counter.eq(self._divisor.field.r - 1))
                ]
                
+               # TX
                tx_reg = Signal(BV(8))
                tx_bitcount = Signal(BV(4))
                tx_count16 = Signal(BV(4))
-               tx_busy = Signal()
+               tx_busy = self._tx_event.trigger
                sync += [
                        If(self._rxtx.re,
                                tx_reg.eq(self._rxtx.r),
@@ -55,7 +57,53 @@ class UART:
                                )
                        )
                ]
-               comb.append(self._tx_event.trigger.eq(tx_busy))
+               
+               # RX
+               rx0 = Signal() # sychronize
+               rx = Signal()
+               sync += [
+                       rx0.eq(self.rx),
+                       rx.eq(rx0)
+               ]
+               rx_r = Signal()
+               rx_reg = Signal(BV(8))
+               rx_bitcount = Signal(BV(4))
+               rx_count16 = Signal(BV(4))
+               rx_busy = Signal()
+               rx_done = self._rx_event.trigger
+               rx_data = self._rxtx.w
+               sync += [
+                       rx_done.eq(0),
+                       If(enable16,
+                               rx_r.eq(rx),
+                               If(~rx_busy,
+                                       If(~rx & rx_r, # look for start bit
+                                               rx_busy.eq(1),
+                                               rx_count16.eq(7),
+                                               rx_bitcount.eq(0)
+                                       )
+                               ).Else(
+                                       rx_count16.eq(rx_count16 + 1),
+                                       If(rx_count16 == 0,
+                                               rx_bitcount.eq(rx_bitcount + 1),
+
+                                               If(rx_bitcount == 0,
+                                                       If(rx, # verify start bit
+                                                               rx_busy.eq(0)
+                                                       )
+                                               ).Elif(rx_bitcount == 9,
+                                                       rx_busy.eq(0),
+                                                       If(rx, # verify stop bit
+                                                               rx_data.eq(rx_reg),
+                                                               rx_done.eq(1)
+                                                       )
+                                               ).Else(
+                                                       rx_reg.eq(Cat(rx_reg[1:], rx))
+                                               )
+                                       )
+                               )
+                       )
+               ]
                
                return self.bank.get_fragment() \
                        + self.events.get_fragment() \