1 //
2 // Copyright (c) 2010-2024 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 
8 using System;
9 using System.IO;
10 using System.Collections.Generic;
11 using Antmicro.Renode.Exceptions;
12 using Antmicro.Renode.Logging;
13 using Antmicro.Renode.Peripherals.Sensor;
14 using Antmicro.Renode.Peripherals.I2C;
15 
16 namespace Antmicro.Renode.Peripherals.Sensors
17 {
18     public class HiMaxHM01B0 : I2CPeripheralBase<HiMaxHM01B0.Registers>, ICPIPeripheral, ISensor
19     {
HiMaxHM01B0()20         public HiMaxHM01B0() : base(16)
21         {
22             frames = new List<byte[]>();
23             framesLock = new Object();
24             currentFrameIndex = 0;
25         }
26 
Reset()27         public override void Reset()
28         {
29             base.Reset();
30             currentFrameIndex = 0;
31         }
32 
ReadFrame()33         public byte[] ReadFrame()
34         {
35             var output = new byte[0];
36             lock(framesLock)
37             {
38                 if (frames.Count > 0)
39                 {
40                         output = frames[currentFrameIndex];
41                         currentFrameIndex = (currentFrameIndex + 1) % frames.Count;
42                 }
43                 else
44                 {
45                     this.Log(LogLevel.Warning, "No frames available. Returning empty array");
46                 }
47             }
48 
49             return output;
50         }
51 
AddFrame(string path)52         public void AddFrame(string path)
53         {
54             byte[] imageData;
55             try
56             {
57                 imageData = File.ReadAllBytes(path);
58                 this.NoisyLog("Loaded {0} bytes of image data as frame number {1}", imageData.Length, frames.Count);
59             }
60             catch(Exception e)
61             {
62                 throw new RecoverableException($"Could not load image from path {path}: {(e.Message)}");
63             }
64 
65             lock(framesLock)
66             {
67                 frames.Add(imageData);
68             }
69         }
70 
DropFrames()71         public void DropFrames()
72         {
73             currentFrameIndex = 0;
74             frames.Clear();
75         }
76 
DefineRegisters()77         protected override void DefineRegisters()
78         {
79         }
80 
81         private readonly List<byte[]> frames;
82         private readonly Object framesLock;
83         private int currentFrameIndex;
84 
85         // based on https://github.com/sparkfun/SparkFun_Apollo3_AmbiqSuite_BSPs/blob/master/common/third_party/hm01b0/HM01B0.h
86         public enum Registers
87         {
88             ModelIdHigh = 0x0000,
89             ModelIdLow = 0x0001,
90             SiliconRevision = 0x0002,
91             FrameCount = 0x0005,
92             PixelOrder = 0x0006,
93 
94             ModeSelect = 0x0100,
95             ImageOrientation = 0x0101,
96             SoftwareReset = 0x0103,
97             GRP_ParamHold = 0x0104,
98 
99             IntegrationHigh = 0x0202,
100             IntegrationLow = 0x0203,
101             AnalogGain = 0x0205,
102             DigitalGainHigh = 0x020E,
103             DigitalGainLow = 0x020F,
104 
105             AE_TargetMean = 0x2101,
106             AE_MinMean = 0x2102,
107             ConvergeInThreshold = 0x2103,
108             ConvergeOutThreshold = 0x2104,
109 
110             I2C_IdSelection = 0x3400,
111             I2C_Id = 0x3401,
112 
113             PMU_ProgrammableFrameCount = 0x3020,
114         }
115     }
116 }
117