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