1 //
2 // Copyright (c) 2010-2018 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using Antmicro.Renode.Logging;
10 using Antmicro.Renode.Peripherals.Bus;
11 using Antmicro.Renode.Peripherals.UART;
12 
13 namespace Antmicro.Renode.Peripherals.UART
14 {
15     public class AppUart : IDoubleWordPeripheral, IUART
16     {
AppUart()17         public AppUart()
18         {
19             Reset();
20         }
21 
ReadDoubleWord(long offset)22         public uint ReadDoubleWord(long offset)
23         {
24             uint val;
25             switch((Register)offset)
26             {
27             case Register.RecvCtrl:
28                 val = recvControl;
29                 break;
30             case Register.TransCtrl:
31                 val = transControl;
32                 break;
33             case Register.Control:
34                 val = control;
35                 break;
36             case Register.LineCtrl:
37                 val = lineControl;
38                 break;
39             case Register.InterruptReg:
40                 val = 0;//state.Interrupt;
41                 break;
42             case Register.StatusReg:
43                 val = 0x08000000;//state.Status;
44                 break;
45             default:
46                 this.LogUnhandledRead(offset);
47                 return 0;
48             }
49             return val;
50         }
51 
WriteDoubleWord(long offset, uint value)52         public void WriteDoubleWord(long offset, uint value)
53         {
54             switch((Register)offset)
55             {
56             case Register.RecvCtrl:
57                 recvControl = value;
58                 break;
59             case Register.RecvCtrlSet:
60                 recvControl |= value;
61                 break;
62             case Register.RecvCtrlClr:
63                 recvControl &= ~value;
64                 break;
65             case Register.Control:
66                 control = value;
67                 break;
68             case Register.ControlSet:
69                 control |= value;
70                 break;
71             case Register.ControlClr:
72                 control &= ~value;
73                 break;
74             case Register.LineCtrl:
75                 lineControl = value;
76                 break;
77             case Register.LineCtrlSet:
78                 lineControl |= value;
79                 break;
80             case Register.LineCtrlClr:
81                 lineControl &= ~value;
82                 break;
83             case Register.InterruptReg:
84                 interrupt = value;
85                 break;
86             case Register.InterruptRegSet:
87                 interrupt |= value;
88                 break;
89             case Register.InterruptRegClr:
90                 interrupt &= ~value;
91                 break;
92             case Register.StatusReg:
93                 status = value;
94                 break;
95             case Register.StatusRegSet:
96                 status |= value;
97                 break;
98             default:
99                 this.LogUnhandledWrite(offset, value);
100                 break;
101             }
102         }
103 
Reset()104         public void Reset()
105         {
106             recvControl = 1 << 31 & 1 << 30 & 3 << 16;
107             transControl = 0; //TODO: verify if buggy
108             control = 2 << 20 & 2 << 16 & 1 << 9 & 1 << 8;
109             Status = 1 << 31 & 1 << 30 & 1 << 27 & 1 << 24 & 0xF << 20;
110         }
111 
112         public event Action<byte> CharReceived
113         {
114             add {}
115             remove {}
116         }
117 
WriteChar(byte value)118         public void WriteChar(byte value)
119         {
120             throw new NotImplementedException();
121         }
122 
123         private uint recvControl;
124         private uint control;
125         private uint lineControl;
126         private uint interrupt;
127         private uint status;
128         private uint transControl;
129 
130         private uint Status
131         {
132             get
133             {
134                 return status;
135             }
136             set
137             {
138                 status = value & (0xF << 20 & 1 << 18 & 1 << 17 & 1 << 16);
139             }
140         }
141 
142         private enum Register
143         {
144             RecvCtrl = 0x00,
145             RecvCtrlSet = 0x04,
146             RecvCtrlClr = 0x08,
147             RecvCtrlTog = 0x0C,
148             TransCtrl = 0x10,
149             TransCtrlSet = 0x14,
150             TransCtrlClr = 0x18,
151             TransCtrlTog = 0x1C,
152             Control = 0x20,
153             ControlSet = 0x24,
154             ControlClr = 0x28,
155             ControlTog = 0x2C,
156             LineCtrl = 0x30,
157             LineCtrlSet = 0x34,
158             LineCtrlClr = 0x38,
159             LineCtrlTog = 0x3C,
160             InterruptReg = 0x50,
161             InterruptRegSet = 0x54,
162             InterruptRegClr = 0x58,
163             InterruptRegTohg = 0x5C,
164             StatusReg = 0x70,
165             StatusRegSet = 0x74,
166             StatusRegClr = 0x78,
167             StatusRegTog = 0x7C
168         }
169 
170         public uint BaudRate
171         {
172             get
173             {
174                 var divFrac = ((lineControl >> 8) & 0x3F);
175                 var divInt = (lineControl >> 16);
176                 var divisor = ((divInt << 6) + divFrac);
177                 return divisor == 0 ? 0 : (UARTClockFrequency * 32) / divisor;
178             }
179         }
180 
181         public Bits StopBits { get { return (lineControl & 8u) == 0 ? Bits.One : Bits.Two; } }
182 
183         public Parity ParityBit
184         {
185             get
186             {
187                 var pen = lineControl & (1u << 1);
188                 if(pen == 0)
189                 {
190                     return Parity.None;
191                 }
192                 else
193                 {
194                     var eps = lineControl & (1u << 2);
195                     var sps = lineControl & (1u << 7);
196 
197                     if(eps == 0)
198                     {
199                         return sps == 0 ? Parity.Odd : Parity.Forced1;
200                     }
201                     else
202                     {
203                         return sps == 0 ? Parity.Even : Parity.Forced0;
204                     }
205                 }
206             }
207         }
208 
209         private const uint UARTClockFrequency = 24000000;
210         // 24 Mhz
211     }
212 }
213 
214