1 // 2 // Copyright (c) 2010-2022 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.Collections.Generic; 8 using Antmicro.Renode.Peripherals.Bus; 9 using Antmicro.Renode.Core.Structure.Registers; 10 using Antmicro.Renode.Core; 11 using Antmicro.Renode.Logging; 12 13 namespace Antmicro.Renode.Peripherals.UART 14 { 15 public class USBSerialPort_S3B : UARTBase, IDoubleWordPeripheral, IKnownSize 16 { USBSerialPort_S3B(IMachine machine)17 public USBSerialPort_S3B(IMachine machine) : base(machine) 18 { 19 var registersMap = new Dictionary<long, DoubleWordRegister> 20 { 21 {(long)Registers.DeviceId, new DoubleWordRegister(this) 22 .WithValueField(0, 32, FieldMode.Read, valueProviderCallback: _ => DeviceId) 23 }, 24 {(long)Registers.UsbPid, new DoubleWordRegister(this) 25 .WithValueField(0, 16, FieldMode.Read, valueProviderCallback: _ => UsbPid) 26 }, 27 {(long)Registers.RevisionNumber, new DoubleWordRegister(this) 28 .WithValueField(0, 32, FieldMode.Read, valueProviderCallback: _ => RevisionNumber) 29 }, 30 {(long)Registers.UsbToM4FifoFlags, new DoubleWordRegister(this) 31 // this is a simplification - as along as queue is not empty we say it has exactly one byte 32 .WithEnumField<DoubleWordRegister, FifoPopFlags>(0, 4, FieldMode.Read, valueProviderCallback: _ => Count != 0 ? FifoPopFlags.EntryCout1 : FifoPopFlags.Empty) 33 .WithReservedBits(4, 28) 34 }, 35 {(long)Registers.UsbToM4FifoReadData, new DoubleWordRegister(this) 36 .WithValueField(0, 8, FieldMode.Read, valueProviderCallback: _ => 37 { 38 if(!TryGetCharacter(out var character)) 39 { 40 this.Log(LogLevel.Warning, "Trying to read from an empty Rx FIFO."); 41 return 0; 42 } 43 return character; 44 }) 45 .WithReservedBits(8, 24) 46 }, 47 {(long)Registers.M4ToUsbFifoFlags, new DoubleWordRegister(this) 48 .WithEnumField<DoubleWordRegister, FifoPushFlags>(0, 4, FieldMode.Read, valueProviderCallback: _ => FifoPushFlags.Empty) // tx is always empty 49 .WithReservedBits(4, 28) 50 }, 51 {(long)Registers.M4ToUsbFifoWriteData, new DoubleWordRegister(this) 52 .WithValueField(0, 8, FieldMode.Write, writeCallback: (_, value) => this.TransmitCharacter((byte)value)) 53 .WithReservedBits(8, 24) 54 }, 55 }; 56 57 registers = new DoubleWordRegisterCollection(this, registersMap); 58 } 59 ReadDoubleWord(long offset)60 public uint ReadDoubleWord(long offset) 61 { 62 return registers.Read(offset); 63 } 64 Reset()65 public override void Reset() 66 { 67 base.Reset(); 68 registers.Reset(); 69 } 70 WriteDoubleWord(long offset, uint value)71 public void WriteDoubleWord(long offset, uint value) 72 { 73 registers.Write(offset, value); 74 } 75 76 public long Size => 0x100; 77 78 private uint DeviceId => 0xA5BD; 79 private uint RevisionNumber => 0x0200; 80 private uint UsbPid => 0x6141; 81 82 public override Bits StopBits => Bits.One; 83 84 public override Parity ParityBit => Parity.None; 85 86 public override uint BaudRate => 115200; 87 CharWritten()88 protected override void CharWritten() 89 { 90 // intentionally left blank 91 } 92 QueueEmptied()93 protected override void QueueEmptied() 94 { 95 // intentionally left blank 96 } 97 98 private readonly DoubleWordRegisterCollection registers; 99 100 private enum FifoPopFlags 101 { 102 Empty = 0b0000, 103 EntryCout1 = 0b0001, 104 AtLeast2Entries = 0b0010, 105 AtLeast4Entries = 0b0011, 106 AtLeast8Entries = 0b0100, 107 AtLeast16Entries = 0b0101, 108 AtLeast32Entries = 0b0110, 109 LessThan1_4To64Entries = 0b1000, 110 Fill1_4OrMore = 0b1101, 111 Fill1_2OrMore = 0b1110, 112 Full = 0b1111, 113 // others - reserved 114 } 115 116 private enum FifoPushFlags 117 { 118 Full = 0b0000, 119 Empty = 0b0001, 120 RoomForMoreThan1_2 = 0b0010, 121 RoomForMoreThan1_4 = 0b0011, 122 RoomForLessThan1_4To64 = 0b0100, 123 RoomFor32To63 = 0b1010, 124 RoomFor16To31 = 0b1011, 125 RoomFor8To15 = 0b1100, 126 RoomFor4to7 = 0b1101, 127 RoomForAtLeast2 = 0b1110, 128 RoomForAtLeast1 = 0b1111, 129 // others -reserved 130 } 131 132 private enum Registers : long 133 { 134 DeviceId = 0x00, 135 RevisionNumber = 0x04, 136 UsbPid = 0x10, 137 UsbToM4FifoFlags = 0x40, 138 UsbToM4FifoReadData = 0x44, 139 M4ToUsbFifoFlags = 0x80, 140 M4ToUsbFifoWriteData = 0x84, 141 } 142 } 143 } 144