1 //
2 // Copyright (c) 2010-2023 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 using System;
8 using Antmicro.Renode.Logging;
9 using Antmicro.Renode.Peripherals.Bus;
10 using Antmicro.Renode.Core;
11 using System.Collections.Generic;
12 using System.Collections.ObjectModel;
13 using Antmicro.Renode.Core.CAN;
14 using Antmicro.Renode.Peripherals.UART;
15 using Antmicro.Renode.Exceptions;
16 using System.Linq;
17 using Antmicro.Renode.Core.Structure.Registers;
18 
19 namespace Antmicro.Renode.Peripherals.UART
20 {
21     public class BCM2711_AUX_UART : UARTBase, IDoubleWordPeripheral, IProvidesRegisterCollection<DoubleWordRegisterCollection>, IKnownSize
22     {
BCM2711_AUX_UART(IMachine machine)23         public BCM2711_AUX_UART(IMachine machine) : base(machine)
24         {
25             IRQ = new GPIO();
26             RegistersCollection = new DoubleWordRegisterCollection(this);
27             DefineRegisters();
28         }
29 
Reset()30         public override void Reset()
31         {
32             base.Reset();
33             RegistersCollection.Reset();
34         }
35 
ReadDoubleWord(long offset)36         public uint ReadDoubleWord(long offset)
37         {
38            return RegistersCollection.Read(offset);
39         }
40 
WriteDoubleWord(long offset, uint val)41         public void WriteDoubleWord(long offset, uint val)
42         {
43             RegistersCollection.Write(offset, val);
44         }
45 
46         public DoubleWordRegisterCollection RegistersCollection { get; }
47 
48         public override Bits StopBits => Bits.One;
49 
50         public override Parity ParityBit => Parity.None;
51 
52         public override uint BaudRate => 115200;
53 
54         public long Size => 0x40;
55 
56         public GPIO IRQ { get; }
57 
CharWritten()58         protected override void CharWritten()
59         {
60             // intentionally left empty
61         }
62 
QueueEmptied()63         protected override void QueueEmptied()
64         {
65             // intentionally left empty
66         }
67 
DefineRegisters()68         private void DefineRegisters()
69         {
70             Registers.MiniUart_IO.Define(this)
71                 .WithValueField(0, 8, name: "Receive data read/write",
72                     valueProviderCallback: _ =>
73                     {
74                         if(!TryGetCharacter(out var b))
75                         {
76                             this.Log(LogLevel.Warning, "Tried to read from an empty FIFO");
77                             return 0;
78                         }
79                         return b;
80                     },
81                     writeCallback: (_, v) =>
82                     {
83                         TransmitCharacter((byte)v);
84                     })
85                 .WithReservedBits(8, 24);
86 
87             Registers.MiniUart_LineStatus.Define(this)
88                 .WithFlag(0, FieldMode.Read, name: "Data ready", valueProviderCallback: _ => Count > 0)
89                 .WithFlag(1, FieldMode.Read | FieldMode.WriteOneToClear, name: "Receiver overrun", valueProviderCallback: _ => false)
90                 .WithReservedBits(2, 2)
91                 .WithFlag(5, FieldMode.Read, name: "Transmitter empty", valueProviderCallback: _ => true)
92                 .WithFlag(6, FieldMode.Read, name: "Transmitter idle", valueProviderCallback: _ => true)
93                 .WithReservedBits(7, 25);
94         }
95 
96         private enum Registers
97         {
98             MiniUart_IO = 0x0, // AUX_MU_IO_REG, Mini UART I/O Data
99             MiniUart_InterruptEnable = 0x4, // AUX_MU_IER_REG, Mini UART Interrupt Enable
100             MiniUart_InterruptIdentify = 0x8, // AUX_MU_IIR_REG, Mini UART Interrupt Identify
101             MiniUart_LineControl = 0xc, // AUX_MU_LCR_REG, Mini UART Line Control
102             MiniUart_ModemControl = 0x10, // AUX_MU_MCR_REG, Mini UART Modem Control
103             MiniUart_LineStatus = 0x14, // AUX_MU_LSR_REG, Mini UART Line Status
104             MiniUart_ModemStatus = 0x18, // AUX_MU_MSR_REG, Mini UART Modem Status
105             MiniUart_Scratch = 0x1c, // AUX_MU_SCRATCH, Mini UART Scratch
106             MiniUart_ExtraControl = 0x20, // AUX_MU_CNTL_REG, Mini UART Extra Control
107             MiniUart_Status = 0x24, // AUX_MU_STAT_REG, Mini UART Extra Status
108             MiniUart_Baudrate = 0x28, // AUX_MU_BAUD_REG, Mini UART Baudrate
109         }
110     }
111 }
112