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.Core; 10 using Antmicro.Renode.Logging; 11 using Antmicro.Renode.Peripherals.Bus; 12 13 namespace Antmicro.Renode.Peripherals.GPIOPort 14 { 15 [AllowedTranslations(AllowedTranslation.WordToDoubleWord)] 16 17 public class STM32F4GPIOPort : BaseGPIOPort, IDoubleWordPeripheral 18 { STM32F4GPIOPort(IMachine machine, uint modeResetValue = 0, uint outputSpeedResetValue = 0, uint pullUpPullDownResetValue = 0)19 public STM32F4GPIOPort(IMachine machine, uint modeResetValue = 0, uint outputSpeedResetValue = 0, uint pullUpPullDownResetValue = 0) : base(machine, 16) 20 { 21 this.modeResetValue = modeResetValue; 22 this.outputSpeedResetValue = outputSpeedResetValue; 23 this.pullUpPullDownResetValue = pullUpPullDownResetValue; 24 Reset(); 25 } 26 ReadDoubleWord(long offset)27 public uint ReadDoubleWord(long offset) 28 { 29 uint returnValue = 0; 30 switch((Registers)offset) 31 { 32 case Registers.GPIOx_MODE: // GPIO port mode register 33 returnValue = gpiox_mode; 34 break; 35 case Registers.GPIOx_OTYPER: // GPIO port output type register 36 returnValue = gpiox_otyper; 37 break; 38 case Registers.GPIOx_OSPEEDR: // GPIO port output speed register 39 returnValue = gpiox_ospeedr; 40 break; 41 case Registers.GPIOx_PUPDR: // GPIO port pull-up/pull-down register register 42 returnValue = gpiox_pupdr; 43 break; 44 case Registers.GPIOx_IDR: // GPIO port input data register 45 var value = 0u; 46 for(var i = 0; i < State.Length; i++) 47 { 48 if(State[i]) 49 { 50 value |= 1u << i; 51 } 52 } 53 returnValue = value; 54 break; 55 case Registers.GPIOx_ODR: // GPIO port output data register 56 returnValue = gpiox_odr & 0xFFFF; 57 break; 58 case Registers.GPIOx_LCKR: // GPIO port lock register 59 returnValue = gpiox_lckr & 0x1FFFF; 60 break; 61 case Registers.GPIOx_BSRR: // GPIO port bit set/reset register 62 returnValue = gpiox_afrl; 63 break; 64 case Registers.GPIOx_AFRL: // GPIO alternate function low register 65 returnValue = gpiox_afrh; 66 break; 67 case Registers.GPIOx_AFRH: // GPIO alternate function high register 68 returnValue = 0; 69 break; 70 default: 71 this.LogUnhandledRead(offset); 72 returnValue = 0; 73 break; 74 } 75 return returnValue; 76 } 77 WriteDoubleWord(long offset, uint value)78 public void WriteDoubleWord(long offset, uint value) 79 { 80 switch((Registers)offset) 81 { 82 case Registers.GPIOx_MODE: // GPIO port mode register 83 gpiox_mode = value; 84 break; 85 case Registers.GPIOx_OTYPER: // GPIO port output type register 86 gpiox_otyper = value; 87 break; 88 case Registers.GPIOx_OSPEEDR: // GPIO port output speed register 89 gpiox_ospeedr = value; 90 break; 91 case Registers.GPIOx_PUPDR: // GPIO port pull-up/pull-down register register 92 gpiox_pupdr = value; 93 break; 94 case Registers.GPIOx_IDR: // GPIO port input data register 95 break; 96 case Registers.GPIOx_ODR: // GPIO port output data register 97 gpiox_odr = value; 98 SetConnectionsStateUsingBits(gpiox_odr); 99 break; 100 case Registers.GPIOx_LCKR: // GPIO port lock register 101 gpiox_lckr = value; 102 break; 103 case Registers.GPIOx_BSRR: // GPIO port bit set/reset register 104 gpiox_bsrr = value; 105 for(var i = 0; i < 16; ++i) 106 { 107 if((gpiox_bsrr & 1u << i) != 0) 108 { 109 Connections[i].Set(); 110 State[i] = true; 111 } 112 } 113 for(var i = 16; i < 32; ++i) 114 { 115 if((gpiox_bsrr & 1u << i) != 0) 116 { 117 Connections[i - 16].Unset(); 118 State[i - 16] = false; 119 } 120 } 121 break; 122 case Registers.GPIOx_AFRL: // GPIO alternate function low register 123 gpiox_afrl = value; 124 break; 125 case Registers.GPIOx_AFRH: // GPIO alternate function high register 126 gpiox_afrh = value; 127 break; 128 default: 129 this.LogUnhandledWrite(offset, value); 130 break; 131 } 132 return; 133 } 134 OnGPIO(int number, bool value)135 public override void OnGPIO(int number, bool value) 136 { 137 base.OnGPIO(number, value); 138 Connections[number].Set(value); 139 } 140 Reset()141 public override void Reset() 142 { 143 base.Reset(); 144 gpiox_mode = modeResetValue; 145 gpiox_otyper = 0; 146 gpiox_ospeedr = outputSpeedResetValue; 147 gpiox_pupdr = pullUpPullDownResetValue; 148 gpiox_odr = 0; 149 gpiox_bsrr = 0; 150 gpiox_lckr = 0; 151 gpiox_afrl = 0; 152 gpiox_afrh = 0; 153 154 } 155 156 private uint gpiox_mode; 157 private uint gpiox_otyper; 158 private uint gpiox_ospeedr; 159 private uint gpiox_pupdr; 160 private uint gpiox_odr; 161 private uint gpiox_bsrr; 162 private uint gpiox_lckr; 163 private uint gpiox_afrl; 164 private uint gpiox_afrh; 165 166 private readonly uint modeResetValue; 167 private readonly uint outputSpeedResetValue; 168 private readonly uint pullUpPullDownResetValue; 169 170 // Source: Chapter 7.4 in RM0090 Cortex M4 Reference Manual (Doc ID 018909 Rev 4) 171 // for STM32F40xxx, STM32F41xxx, STM32F42xxx, STM32F43xxx advanced ARM-based 32-bit MCUs 172 private enum Registers 173 { 174 GPIOx_MODE = 0x00, // GPIO port mode register - Read-Write 175 GPIOx_OTYPER = 0x04, // GPIO port output type register - Read-Write 176 GPIOx_OSPEEDR = 0x08, // GPIO port output speed register - Read-Write 177 GPIOx_PUPDR = 0x0C, // GPIO port pull-up/pull-down register - Read-Write 178 GPIOx_IDR = 0x10, // GPIO port input data register - Read-only 179 GPIOx_ODR = 0x14, // GPIO port output data register - Read-Write 180 GPIOx_BSRR = 0x18, // GPIO port bit set/reset register - Write-Only 181 GPIOx_LCKR = 0x1C, // GPIO port configuration lock register - Read-Write 182 GPIOx_AFRL = 0x20, // GPIO alternate function low register - Read-Write 183 GPIOx_AFRH = 0x24 // GPIO alternate function high register - Read-Write 184 } 185 } 186 } 187 188