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.Peripherals.Bus; 9 using Antmicro.Renode.Peripherals.Sensor; 10 using Antmicro.Renode.Peripherals.I2C; 11 using Antmicro.Renode.Utilities; 12 using Antmicro.Renode.Logging; 13 using Antmicro.Renode.Core.Structure.Registers; 14 15 namespace Antmicro.Renode.Peripherals.Sensors 16 { 17 public class LSM330_Gyroscope : ST_I2CSensorBase<LSM330_Gyroscope.Registers> 18 { LSM330_Gyroscope()19 public LSM330_Gyroscope() 20 { 21 Reset(); 22 } 23 Reset()24 public override void Reset() 25 { 26 base.Reset(); 27 UpdateSensitivity(0); 28 } 29 30 public decimal AngularRateX { get; set; } 31 32 public decimal AngularRateY { get; set; } 33 34 public decimal AngularRateZ { get; set; } 35 DefineRegisters()36 protected override void DefineRegisters() 37 { 38 Registers.Control4.Define(this) 39 .WithTaggedFlag("SIM", 0) 40 .WithReservedBits(1, 3) 41 .WithValueField(4, 2, name: "FS: Full-scale selection", writeCallback: (_, val) => UpdateSensitivity((uint)val)) 42 .WithTaggedFlag("BLE", 6) 43 .WithTaggedFlag("BDU", 7) 44 ; 45 46 Registers.OutputXLow.Define(this) 47 .WithValueField(0, 8, FieldMode.Read, name: "OUT_X_L_G", valueProviderCallback: _ => GetScaledValue(AngularRateX, sensitivity, false)) 48 ; 49 50 Registers.OutputXHigh.Define(this) 51 .WithValueField(0, 8, FieldMode.Read, name: "OUT_X_H_G", valueProviderCallback: _ => GetScaledValue(AngularRateX, sensitivity, true)) 52 ; 53 54 Registers.OutputYLow.Define(this) 55 .WithValueField(0, 8, FieldMode.Read, name: "OUT_Y_L_G", valueProviderCallback: _ => GetScaledValue(AngularRateY, sensitivity, false)) 56 ; 57 58 Registers.OutputYHigh.Define(this) 59 .WithValueField(0, 8, FieldMode.Read, name: "OUT_Y_H_G", valueProviderCallback: _ => GetScaledValue(AngularRateY, sensitivity, true)) 60 ; 61 62 Registers.OutputZLow.Define(this) 63 .WithValueField(0, 8, FieldMode.Read, name: "OUT_Z_L_G", valueProviderCallback: _ => GetScaledValue(AngularRateZ, sensitivity, false)) 64 ; 65 66 Registers.OutputZHigh.Define(this) 67 .WithValueField(0, 8, FieldMode.Read, name: "OUT_Z_H_G", valueProviderCallback: _ => GetScaledValue(AngularRateZ, sensitivity, true)) 68 ; 69 } 70 UpdateSensitivity(uint val)71 private void UpdateSensitivity(uint val) 72 { 73 var range = 0; 74 switch(val) 75 { 76 case 0: 77 range = 250; 78 break; 79 case 1: 80 range = 500; 81 break; 82 // yes, both cases 0b10 and 0b11 encodes scale of 2000 dps 83 case 2: 84 case 3: 85 range = 2000; 86 break; 87 default: 88 this.Log(LogLevel.Warning, "Tried to set an unsupported sensitivity value: {0}", val); 89 return; 90 } 91 92 sensitivity = CalculateScale(-range, range, OutputWidth); 93 } 94 95 private short sensitivity; 96 97 private const int OutputWidth = 16; 98 99 public enum Registers 100 { 101 WhoaAmI = 0x0F, 102 103 Control1 = 0x20, 104 Control2 = 0x21, 105 Control3 = 0x22, 106 Control4 = 0x23, 107 Control5 = 0x24, 108 109 Reference = 0x25, 110 TemperatureOutput = 0x26, 111 Status = 0x27, 112 113 OutputXLow = 0x28, 114 OutputXHigh = 0x29, 115 OutputYLow = 0x2A, 116 OutputYHigh = 0x2B, 117 OutputZLow = 0x2C, 118 OutputZHigh = 0x2D, 119 120 FifoControl = 0x2E, 121 FifoSource = 0x2F, 122 123 InterruptConfig = 0x30, 124 InterruptSource = 0x31, 125 InterruptThresholdXHigh = 0x32, 126 InterruptThresholdXLow = 0x33, 127 InterruptThresholdYHigh = 0x34, 128 InterruptThresholdYLow = 0x35, 129 InterruptThresholdZHigh = 0x36, 130 InterruptThresholdZLow = 0x37, 131 InterruptDuration = 0x38, 132 } 133 } 134 } 135