aboutsummaryrefslogtreecommitdiff
path: root/src/UART.bs
blob: f83794937dba36e106c4f684cb46a3c34a5da53e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package UART where

import GetPut
import Util

interface Clock =
  clk :: Bool

defaultClock :: Clock
defaultClock =
  interface Clock
    clk = True

mkDivider :: Integer -> Clock -> Module Clock
mkDivider divisor clockIn =
  module
    count <- mkReg 0

    rules
      "increment_divider": when clockIn.clk ==> do
        if count == fromInteger divisor then do
          count := 0
        else
          count := count + 1

    interface Clock
      clk = count == 0
  
interface ShiftRegister =
  get :: Get (Bit 1)
  put :: Put (Bit 1)

mkShiftRegister :: Module ShiftRegister
mkShiftRegister =
  module
    reg :: Reg (Bit 8) <- mkReg 0

    interface ShiftRegister
      get = interface Get
              get = return 0
      put = interface Put
              put bit = do
                return ()

-- An 8n1 UART.
interface UART =
  -- The RX pin.
  rxPin :: Bit 1 -> Action
  -- The TX pin.
  txPin :: Bit 1

  -- Reads a byte from the UART.
  rxByte :: Get (Bit 8)
  -- Writes a byte to the UART.
  txByte :: Put (Bit 8)

mkUART :: Integer -> Module UART
mkUART baudDivisor =
  module
    baud <- mkDivider baudDivisor defaultClock

    count :: Reg (Bit 4) <- mkReg 0
    rules
      "increment_count": when baud.clk ==> do
        count := count + 1

    let start = 0
        d0 = 1
        d1 = 0
        d2 = 0
        d3 = 0
        d4 = 1
        d5 = 0
        d6 = 0
        d7 = 0
        stop = 1

    interface UART
      rxPin _bit = when_ baud.clk $ do
        return () -- TODO
      txPin = case count of
                0 -> start
                1 -> d0
                2 -> d1
                3 -> d2
                4 -> d3
                5 -> d4
                6 -> d5
                7 -> d6
                8 -> d7
                9 -> stop
                _ -> 1

      rxByte = interface Get
                 get = return 0 when False
      txByte = interface Put
                 put _ = do
                   -- TODO
                   return ()

-- vim: set ft=haskell :