diff --git a/src/MMALSharp/Config/BayerOrder.cs b/src/MMALSharp/Config/BayerOrder.cs new file mode 100644 index 00000000..e0f3ec34 --- /dev/null +++ b/src/MMALSharp/Config/BayerOrder.cs @@ -0,0 +1,13 @@ + +namespace MMALSharp.Config +{ + public enum BayerOrder + { + //Carefully ordered so that an hflip is ^1, + //and a vflip is ^2. + BAYER_ORDER_BGGR, + BAYER_ORDER_GBRG, + BAYER_ORDER_GRBG, + BAYER_ORDER_RGGB + } +} diff --git a/src/MMALSharp/Config/ModeDefs/Imx219ModeDefs.cs b/src/MMALSharp/Config/ModeDefs/Imx219ModeDefs.cs new file mode 100644 index 00000000..3bf8295c --- /dev/null +++ b/src/MMALSharp/Config/ModeDefs/Imx219ModeDefs.cs @@ -0,0 +1,150 @@ +using MMALSharp.Config.SensorRegs; +using System; +using System.Collections.Generic; +using System.Text; + +namespace MMALSharp.Config.ModeDefs +{ + public static class Imx219ModeDefs + { + public static readonly List ModeDefs = new List + { + new ModeDef + { + Regs = Imx219SensorRegs.Imx219Regs, + NumRegs = Imx219SensorRegs.Imx219Regs.Count, + Width = 3280, + Height = 2464, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_BGGR, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 2504, + LineTimeNs = 18904, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 66 + }, + new ModeDef + { + Regs = Imx219SensorRegs.Imx219Mode1Regs, + NumRegs = Imx219SensorRegs.Imx219Mode1Regs.Count, + Width = 1920, + Height = 1080, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_BGGR, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 1084, + LineTimeNs = 18904, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 66 + }, + new ModeDef + { + Regs = Imx219SensorRegs.Imx219Mode2Regs, + NumRegs = Imx219SensorRegs.Imx219Mode2Regs.Count, + Width = 3280, + Height = 2464, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_BGGR, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 2468, + LineTimeNs = 18904, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 66 + }, + new ModeDef + { + Regs = Imx219SensorRegs.Imx219Mode3Regs, + NumRegs = Imx219SensorRegs.Imx219Mode3Regs.Count, + Width = 3280, + Height = 2464, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_BGGR, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 2468, + LineTimeNs = 18904, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 66 + }, + new ModeDef + { + Regs = Imx219SensorRegs.Imx219Mode4Regs, + NumRegs = Imx219SensorRegs.Imx219Mode4Regs.Count, + Width = 1640, + Height = 1232, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_BGGR, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 1236, + LineTimeNs = 18904, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 66 + }, + new ModeDef + { + Regs = Imx219SensorRegs.Imx219Mode5Regs, + NumRegs = Imx219SensorRegs.Imx219Mode5Regs.Count, + Width = 1640, + Height = 922, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_BGGR, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 926, + LineTimeNs = 18904, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 66 + }, + new ModeDef + { + Regs = Imx219SensorRegs.Imx219Mode6Regs, + NumRegs = Imx219SensorRegs.Imx219Mode6Regs.Count, + Width = 1280, + Height = 720, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_BGGR, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 724, + LineTimeNs = 19517, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 66 + }, + new ModeDef + { + Regs = Imx219SensorRegs.Imx219Mode7Regs, + NumRegs = Imx219SensorRegs.Imx219Mode7Regs.Count, + Width = 640, + Height = 480, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_BGGR, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 484, + LineTimeNs = 19517, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 66 + } + }; + } +} diff --git a/src/MMALSharp/Config/ModeDefs/ModeDef.cs b/src/MMALSharp/Config/ModeDefs/ModeDef.cs new file mode 100644 index 00000000..6468030d --- /dev/null +++ b/src/MMALSharp/Config/ModeDefs/ModeDef.cs @@ -0,0 +1,23 @@ +using MMALSharp.Config.SensorRegs; +using System.Collections.Generic; + +namespace MMALSharp.Config +{ + public class ModeDef + { + public List Regs { get; set; } + public int NumRegs { get; set; } + public int Width { get; set; } + public int Height { get; set; } + public int Encoding { get; set; } + public BayerOrder Order { get; set; } + public int NativeBitDepth { get; set; } + public int ImageId { get; set; } + public int DataLanes { get; set; } + public int MinVts { get; set; } + public int LineTimeNs { get; set; } + public int[] Timing { get; set; } + public int[] Term { get; set; } + public int BlackLevel { get; set; } + } +} diff --git a/src/MMALSharp/Config/ModeDefs/Ov5647ModeDefs.cs b/src/MMALSharp/Config/ModeDefs/Ov5647ModeDefs.cs new file mode 100644 index 00000000..d9c528d2 --- /dev/null +++ b/src/MMALSharp/Config/ModeDefs/Ov5647ModeDefs.cs @@ -0,0 +1,148 @@ +using MMALSharp.Config.SensorRegs; +using System.Collections.Generic; + +namespace MMALSharp.Config.ModeDefs +{ + public static class Ov5647ModeDefs + { + public static readonly List ModeDefs = new List + { + new ModeDef + { + Regs = Ov5647SensorRegs.Ov5647Regs, + NumRegs = Ov5647SensorRegs.Ov5647Regs.Count, + Width = 2592, + Height = 1944, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_GBRG, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 1968, + LineTimeNs = 32503, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 16 + }, + new ModeDef + { + Regs = Ov5647SensorRegs.Ov5647Mode1Regs, + NumRegs = Ov5647SensorRegs.Ov5647Mode1Regs.Count, + Width = 1920, + Height = 1080, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_GBRG, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 1104, + LineTimeNs = 29584, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 16 + }, + new ModeDef + { + Regs = Ov5647SensorRegs.Ov5647Mode2Regs, + NumRegs = Ov5647SensorRegs.Ov5647Mode2Regs.Count, + Width = 2592, + Height = 1944, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_GBRG, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 1968, + LineTimeNs = 32503, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 16 + }, + new ModeDef + { + Regs = Ov5647SensorRegs.Ov5647Mode3Regs, + NumRegs = Ov5647SensorRegs.Ov5647Mode3Regs.Count, + Width = 2592, + Height = 1944, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_GBRG, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 1968, + LineTimeNs = 183789, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 16 + }, + new ModeDef + { + Regs = Ov5647SensorRegs.Ov5647Mode4Regs, + NumRegs = Ov5647SensorRegs.Ov5647Mode4Regs.Count, + Width = 1296, + Height = 976, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_GBRG, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 996, + LineTimeNs = 23216, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 16 + }, + new ModeDef + { + Regs = Ov5647SensorRegs.Ov5647Mode5Regs, + NumRegs = Ov5647SensorRegs.Ov5647Mode5Regs.Count, + Width = 1296, + Height = 730, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_GBRG, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 754, + LineTimeNs = 23216, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 16 + }, + new ModeDef + { + Regs = Ov5647SensorRegs.Ov5647Mode6Regs, + NumRegs = Ov5647SensorRegs.Ov5647Mode6Regs.Count, + Width = 640, + Height = 480, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_GBRG, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 484, + LineTimeNs = 31749, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 16 + }, + new ModeDef + { + Regs = Ov5647SensorRegs.Ov5647Mode7Regs, + NumRegs = Ov5647SensorRegs.Ov5647Mode7Regs.Count, + Width = 640, + Height = 480, + Encoding = 0, + Order = BayerOrder.BAYER_ORDER_GBRG, + NativeBitDepth = 10, + ImageId = 0x2B, + DataLanes = 2, + MinVts = 484, + LineTimeNs = 21165, + Timing = new int[] { 0, 0, 0, 0 }, + Term = new int[] { 0, 0 }, + BlackLevel = 16 + } + }; + } +} diff --git a/src/MMALSharp/Config/SensorDefs/Imx219SensorDef.cs b/src/MMALSharp/Config/SensorDefs/Imx219SensorDef.cs new file mode 100644 index 00000000..1daad969 --- /dev/null +++ b/src/MMALSharp/Config/SensorDefs/Imx219SensorDef.cs @@ -0,0 +1,37 @@ +using MMALSharp.Config.ModeDefs; +using MMALSharp.Config.SensorRegs; + +namespace MMALSharp.Config.SensorDefs +{ + public static class Imx219SensorDefs + { + public static SensorDef Imx219SensorDef = new SensorDef + { + Name = "imx219", + Modes = Imx219ModeDefs.ModeDefs, + NumModes = Imx219ModeDefs.ModeDefs.Count, + StopReg = Imx219SensorRegs.Imx219StopRegs, + NumStopRegs = Imx219SensorRegs.Imx219StopRegs.Count, + + I2CAddr = 0x10, + I2CAddressing = 2, + I2CIdentLength = 2, + I2CIdentReg = 0x0000, + I2CIdentValue = 0x1902, // 0x0219 bytes reversed. + + VFlipReg = 0x172, + VFlipRegBit = 1, + HFlipReg = 0x172, + HFlipRegBit = 0, + + ExposureReg = 0x015A, + ExposureRegNumBits = 16, + + VtsReg = 0x0160, + VtsRegNumBits = 16, + + GainReg = 0x0157, + GainRegNumBits = 8 // Only valid up to 230. + }; + } +} diff --git a/src/MMALSharp/Config/SensorDefs/Ov5647SensorDefs.cs b/src/MMALSharp/Config/SensorDefs/Ov5647SensorDefs.cs new file mode 100644 index 00000000..65b0e857 --- /dev/null +++ b/src/MMALSharp/Config/SensorDefs/Ov5647SensorDefs.cs @@ -0,0 +1,37 @@ +using MMALSharp.Config.ModeDefs; +using MMALSharp.Config.SensorRegs; + +namespace MMALSharp.Config.SensorDefs +{ + public static class Ov5647SensorDefs + { + public static SensorDef Ov5647SensorDef = new SensorDef + { + Name = "ov5647", + Modes = Ov5647ModeDefs.ModeDefs, + NumModes = Ov5647ModeDefs.ModeDefs.Count, + StopReg = Ov5647SensorRegs.Ov5647StopRegs, + NumStopRegs = Ov5647SensorRegs.Ov5647StopRegs.Count, + + I2CAddr = 0x36, + I2CAddressing = 2, + I2CIdentLength = 2, + I2CIdentReg = 0x300A, + I2CIdentValue = 0x4756, + + VFlipReg = 0x3820, + VFlipRegBit = 0, + HFlipReg = 0x3821, + HFlipRegBit = 0, + + ExposureReg = 0x3500, + ExposureRegNumBits = 20, + + VtsReg = 0x380E, + VtsRegNumBits = 16, + + GainReg = 0x350A, + GainRegNumBits = 10 + }; + } +} diff --git a/src/MMALSharp/Config/SensorDefs/SensorDef.cs b/src/MMALSharp/Config/SensorDefs/SensorDef.cs new file mode 100644 index 00000000..68cdcfb2 --- /dev/null +++ b/src/MMALSharp/Config/SensorDefs/SensorDef.cs @@ -0,0 +1,37 @@ +using MMALSharp.Config.SensorRegs; +using System.Collections.Generic; + +namespace MMALSharp.Config.SensorDefs +{ + public class SensorDef + { + public string Name { get; set; } + public List Modes { get; set; } + public int NumModes { get; set; } + public List StopReg { get; set; } + public int NumStopRegs { get; set; } + + public int I2CAddr { get; set; } + public int I2CAddressing { get; set; } + public int I2CDataSize { get; set; } + + public int I2CIdentLength { get; set; } + public int I2CIdentReg { get; set; } + public int I2CIdentValue { get; set; } + + public int VFlipReg { get; set; } + public int VFlipRegBit { get; set; } + public int HFlipReg { get; set; } + public int HFlipRegBit { get; set; } + public int FlipsDontChangeBayerOrder { get; set; } + + public int ExposureReg { get; set; } + public int ExposureRegNumBits { get; set; } + + public int VtsReg { get; set; } + public int VtsRegNumBits { get; set; } + + public int GainReg { get; set; } + public int GainRegNumBits { get; set; } + } +} diff --git a/src/MMALSharp/Config/SensorRegs/Imx219SensorRegs.cs b/src/MMALSharp/Config/SensorRegs/Imx219SensorRegs.cs new file mode 100644 index 00000000..59c1a4b0 --- /dev/null +++ b/src/MMALSharp/Config/SensorRegs/Imx219SensorRegs.cs @@ -0,0 +1,540 @@ +using System.Collections.Generic; + +namespace MMALSharp.Config.SensorRegs +{ + public static class Imx219SensorRegs + { + public static readonly List Imx219Regs = new List + { + /* 3280x2464@15 FPS */ + new SensorReg(0x0100, 0x00), // 0=OFF, 1=Stream, 2=MAX + new SensorReg(0x30EB, 0x05), + new SensorReg(0x30EB, 0x0C), + new SensorReg(0x300A, 0xFF), + new SensorReg(0x300B, 0xFF), + new SensorReg(0x30EB, 0x05), + new SensorReg(0x30EB, 0x09), + new SensorReg(0x0114, 0x01), // CSI MIPI Lanes [1:0] (0x01=2, 0x03=4) + new SensorReg(0x0128, 0x00), // DPHY_CNTRL + new SensorReg(0x012A, 0x18), // EXCK_FREQ [15:8] + new SensorReg(0x012B, 0x00), // EXCK_FREQ [7:0] + new SensorReg(0x0157, 0x00), // Analog Gain + new SensorReg(0x0158, 0x01), // Digital Gain [15:8] + new SensorReg(0x0159, 0x00), // Digital Gain [7:0] + new SensorReg(0x015A, 0x01), // Shutter/Integration Time [15:8] + new SensorReg(0x015B, 0x00), // Shutter/Integration Time [7:0] + new SensorReg(0x0160, 0x09), // Frame Length [15:8] + new SensorReg(0x0161, 0xC8), // Frame Length [7:0] + new SensorReg(0x0162, 0x0D), // Line Length [15:8] + new SensorReg(0x0163, 0x78), // Line Length [7:0] + new SensorReg(0x0164, 0x00), + new SensorReg(0x0165, 0x00), + new SensorReg(0x0166, 0x0C), + new SensorReg(0x0167, 0xCF), + new SensorReg(0x0168, 0x00), + new SensorReg(0x0169, 0x00), + new SensorReg(0x016A, 0x09), + new SensorReg(0x016B, 0x9F), + new SensorReg(0x016C, 0x0C), + new SensorReg(0x016D, 0xD0), + new SensorReg(0x016E, 0x09), + new SensorReg(0x016F, 0xA0), + new SensorReg(0x0170, 0x01), // X_ODD_INC [2:0] + new SensorReg(0x0171, 0x01), // Y_ODD_INC [2:0] + new SensorReg(0x0172, 0x03), + new SensorReg(0x0174, 0x00), // Binning Mode H_A + new SensorReg(0x0175, 0x00), // Binning Mode V_A + new SensorReg(0x018C, 0x0A), // CSI Data Format [15:8] + new SensorReg(0x018D, 0x0A), // CSI Data Format [7:0] + new SensorReg(0x0301, 0x05), // VTPXCK_DIV + new SensorReg(0x0303, 0x01), // VTSYCK_DIV + new SensorReg(0x0304, 0x03), // PREPLLCK_VT_DIV [3:0] + new SensorReg(0x0305, 0x03), // PREPLLCK_OP_DIV [3:0] + new SensorReg(0x0306, 0x00), // PLL_VT_MPY [10:8] + new SensorReg(0x0307, 0x2B), // PLL_VT_MPY [7:0] + new SensorReg(0x0309, 0x0A), // OPPXCK_DIV [4:0] + new SensorReg(0x030B, 0x01), // OPSYCK_DIV + new SensorReg(0x030C, 0x00), // PLL_OP_MPY [10:8] + new SensorReg(0x030D, 0x55), // PLL_OP_MPY [7:0] + new SensorReg(0x455E, 0x00), // CIS Tuning ? + new SensorReg(0x471E, 0x4B), // CIS Tuning ? + new SensorReg(0x4767, 0x0F), // CIS Tuning ? + new SensorReg(0x4750, 0x14), // CIS Tuning ? + new SensorReg(0x4540, 0x00), // CIS Tuning ? + new SensorReg(0x47B4, 0x14), // CIS Tuning ? + new SensorReg(0x4713, 0x30), // CIS Tuning ? + new SensorReg(0x478B, 0x10), // CIS Tuning ? + new SensorReg(0x478F, 0x10), // CIS Tuning ? + new SensorReg(0x4797, 0x0E), // CIS Tuning ? + new SensorReg(0x479B, 0x0E), // CIS Tuning ? + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Imx219Mode1Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x30eb, 0x0c), + new SensorReg(0x300a, 0xff), + new SensorReg(0x300b, 0xff), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x30eb, 0x09), + new SensorReg(0x0114, 0x01), + new SensorReg(0x0128, 0x00), + new SensorReg(0x012a, 0x18), + new SensorReg(0x012b, 0x00), + new SensorReg(0x0162, 0x0d), + new SensorReg(0x0163, 0x78), + new SensorReg(0x0164, 0x02), + new SensorReg(0x0165, 0xa8), + new SensorReg(0x0166, 0x0a), + new SensorReg(0x0167, 0x27), + new SensorReg(0x0168, 0x02), + new SensorReg(0x0169, 0xb4), + new SensorReg(0x016a, 0x06), + new SensorReg(0x016b, 0xeb), + new SensorReg(0x016c, 0x07), + new SensorReg(0x016d, 0x80), + new SensorReg(0x016e, 0x04), + new SensorReg(0x016f, 0x38), + new SensorReg(0x0170, 0x01), + new SensorReg(0x0171, 0x01), + new SensorReg(0x0174, 0x00), + new SensorReg(0x0175, 0x00), + new SensorReg(0x018c, 0x0a), + new SensorReg(0x018d, 0x0a), + new SensorReg(0x0301, 0x05), + new SensorReg(0x0303, 0x01), + new SensorReg(0x0304, 0x03), + new SensorReg(0x0305, 0x03), + new SensorReg(0x0306, 0x00), + new SensorReg(0x0307, 0x39), + new SensorReg(0x0309, 0x0a), + new SensorReg(0x030b, 0x01), + new SensorReg(0x030c, 0x00), + new SensorReg(0x030d, 0x72), + new SensorReg(0x455e, 0x00), + new SensorReg(0x471e, 0x4b), + new SensorReg(0x4767, 0x0f), + new SensorReg(0x4750, 0x14), + new SensorReg(0x4540, 0x00), + new SensorReg(0x47b4, 0x14), + new SensorReg(0x4713, 0x30), + new SensorReg(0x478b, 0x10), + new SensorReg(0x478f, 0x10), + new SensorReg(0x4793, 0x10), + new SensorReg(0x4797, 0x0e), + new SensorReg(0x479b, 0x0e), + + new SensorReg(0x0172, 0x03), + new SensorReg(0x0157, 0x00), + new SensorReg(0x0160, 0x06), + new SensorReg(0x0161, 0xe3), + new SensorReg(0x0162, 0x0d), + new SensorReg(0x0163, 0x78), + new SensorReg(0x015a, 0x00), + new SensorReg(0x015b, 0x31), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Imx219Mode2Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x30eb, 0x0c), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x300a, 0xff), + new SensorReg(0x300b, 0xff), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x30eb, 0x09), + new SensorReg(0x0114, 0x01), + new SensorReg(0x0128, 0x00), + new SensorReg(0x012a, 0x18), + new SensorReg(0x012b, 0x00), + new SensorReg(0x0164, 0x00), + new SensorReg(0x0165, 0x00), + new SensorReg(0x0166, 0x0c), + new SensorReg(0x0167, 0xcf), + new SensorReg(0x0168, 0x00), + new SensorReg(0x0169, 0x00), + new SensorReg(0x016a, 0x09), + new SensorReg(0x016b, 0x9f), + new SensorReg(0x016c, 0x0c), + new SensorReg(0x016d, 0xd0), + new SensorReg(0x016e, 0x09), + new SensorReg(0x016f, 0xa0), + new SensorReg(0x0170, 0x01), + new SensorReg(0x0171, 0x01), + new SensorReg(0x0174, 0x00), + new SensorReg(0x0175, 0x00), + new SensorReg(0x018c, 0x0a), + new SensorReg(0x018d, 0x0a), + new SensorReg(0x0301, 0x05), + new SensorReg(0x0303, 0x01), + new SensorReg(0x0304, 0x03), + new SensorReg(0x0305, 0x03), + new SensorReg(0x0306, 0x00), + new SensorReg(0x0307, 0x39), + new SensorReg(0x0309, 0x0a), + new SensorReg(0x030b, 0x01), + new SensorReg(0x030c, 0x00), + new SensorReg(0x030d, 0x72), + new SensorReg(0x0624, 0x0c), + new SensorReg(0x0625, 0xd0), + new SensorReg(0x0626, 0x09), + new SensorReg(0x0627, 0xa0), + new SensorReg(0x455e, 0x00), + new SensorReg(0x471e, 0x4b), + new SensorReg(0x4767, 0x0f), + new SensorReg(0x4750, 0x14), + new SensorReg(0x4540, 0x00), + new SensorReg(0x47b4, 0x14), + new SensorReg(0x4713, 0x30), + new SensorReg(0x478b, 0x10), + new SensorReg(0x478f, 0x10), + new SensorReg(0x4793, 0x10), + new SensorReg(0x4797, 0x0e), + new SensorReg(0x479b, 0x0e), + + new SensorReg(0x0172, 0x03), + new SensorReg(0x0157, 0x00), + new SensorReg(0x0160, 0x0d), + new SensorReg(0x0161, 0xc6), + new SensorReg(0x0162, 0x0d), + new SensorReg(0x0163, 0x78), + new SensorReg(0x015a, 0x00), + new SensorReg(0x015b, 0x31), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Imx219Mode3Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x30eb, 0x0c), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x300a, 0xff), + new SensorReg(0x300b, 0xff), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x30eb, 0x09), + new SensorReg(0x0114, 0x01), + new SensorReg(0x0128, 0x00), + new SensorReg(0x012a, 0x18), + new SensorReg(0x012b, 0x00), + new SensorReg(0x0164, 0x00), + new SensorReg(0x0165, 0x00), + new SensorReg(0x0166, 0x0c), + new SensorReg(0x0167, 0xcf), + new SensorReg(0x0168, 0x00), + new SensorReg(0x0169, 0x00), + new SensorReg(0x016a, 0x09), + new SensorReg(0x016b, 0x9f), + new SensorReg(0x016c, 0x0c), + new SensorReg(0x016d, 0xd0), + new SensorReg(0x016e, 0x09), + new SensorReg(0x016f, 0xa0), + new SensorReg(0x0170, 0x01), + new SensorReg(0x0171, 0x01), + new SensorReg(0x0174, 0x00), + new SensorReg(0x0175, 0x00), + new SensorReg(0x018c, 0x0a), + new SensorReg(0x018d, 0x0a), + new SensorReg(0x0301, 0x05), + new SensorReg(0x0303, 0x01), + new SensorReg(0x0304, 0x03), + new SensorReg(0x0305, 0x03), + new SensorReg(0x0306, 0x00), + new SensorReg(0x0307, 0x39), + new SensorReg(0x0309, 0x0a), + new SensorReg(0x030b, 0x01), + new SensorReg(0x030c, 0x00), + new SensorReg(0x030d, 0x72), + new SensorReg(0x0624, 0x0c), + new SensorReg(0x0625, 0xd0), + new SensorReg(0x0626, 0x09), + new SensorReg(0x0627, 0xa0), + new SensorReg(0x455e, 0x00), + new SensorReg(0x471e, 0x4b), + new SensorReg(0x4767, 0x0f), + new SensorReg(0x4750, 0x14), + new SensorReg(0x4540, 0x00), + new SensorReg(0x47b4, 0x14), + new SensorReg(0x4713, 0x30), + new SensorReg(0x478b, 0x10), + new SensorReg(0x478f, 0x10), + new SensorReg(0x4793, 0x10), + new SensorReg(0x4797, 0x0e), + new SensorReg(0x479b, 0x0e), + + new SensorReg(0x0172, 0x03), + new SensorReg(0x0157, 0x00), + new SensorReg(0x0160, 0x0d), + new SensorReg(0x0161, 0xc6), + new SensorReg(0x0162, 0x0d), + new SensorReg(0x0163, 0x78), + new SensorReg(0x015a, 0x00), + new SensorReg(0x015b, 0x31), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Imx219Mode4Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x30eb, 0x0c), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x300a, 0xff), + new SensorReg(0x300b, 0xff), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x30eb, 0x09), + new SensorReg(0x0114, 0x01), + new SensorReg(0x0128, 0x00), + new SensorReg(0x012a, 0x18), + new SensorReg(0x012b, 0x00), + new SensorReg(0x0164, 0x00), + new SensorReg(0x0165, 0x00), + new SensorReg(0x0166, 0x0c), + new SensorReg(0x0167, 0xcf), + new SensorReg(0x0168, 0x00), + new SensorReg(0x0169, 0x00), + new SensorReg(0x016a, 0x09), + new SensorReg(0x016b, 0x9f), + new SensorReg(0x016c, 0x06), + new SensorReg(0x016d, 0x68), + new SensorReg(0x016e, 0x04), + new SensorReg(0x016f, 0xd0), + new SensorReg(0x0170, 0x01), + new SensorReg(0x0171, 0x01), + new SensorReg(0x0174, 0x01), + new SensorReg(0x0175, 0x01), + new SensorReg(0x018c, 0x0a), + new SensorReg(0x018d, 0x0a), + new SensorReg(0x0301, 0x05), + new SensorReg(0x0303, 0x01), + new SensorReg(0x0304, 0x03), + new SensorReg(0x0305, 0x03), + new SensorReg(0x0306, 0x00), + new SensorReg(0x0307, 0x39), + new SensorReg(0x0309, 0x0a), + new SensorReg(0x030b, 0x01), + new SensorReg(0x030c, 0x00), + new SensorReg(0x030d, 0x72), + new SensorReg(0x455e, 0x00), + new SensorReg(0x471e, 0x4b), + new SensorReg(0x4767, 0x0f), + new SensorReg(0x4750, 0x14), + new SensorReg(0x4540, 0x00), + new SensorReg(0x47b4, 0x14), + new SensorReg(0x4713, 0x30), + new SensorReg(0x478b, 0x10), + new SensorReg(0x478f, 0x10), + new SensorReg(0x4793, 0x10), + new SensorReg(0x4797, 0x0e), + new SensorReg(0x479b, 0x0e), + + new SensorReg(0x0172, 0x03), + new SensorReg(0x0157, 0x00), + new SensorReg(0x0160, 0x05), + new SensorReg(0x0161, 0x2a), + new SensorReg(0x0162, 0x0d), + new SensorReg(0x0163, 0x78), + new SensorReg(0x015a, 0x00), + new SensorReg(0x015b, 0x31), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Imx219Mode5Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x30eb, 0x0c), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x300a, 0xff), + new SensorReg(0x300b, 0xff), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x30eb, 0x09), + new SensorReg(0x0114, 0x01), + new SensorReg(0x0128, 0x00), + new SensorReg(0x012a, 0x18), + new SensorReg(0x012b, 0x00), + new SensorReg(0x0164, 0x00), + new SensorReg(0x0165, 0x00), + new SensorReg(0x0166, 0x0c), + new SensorReg(0x0167, 0xcf), + new SensorReg(0x0168, 0x01), + new SensorReg(0x0169, 0x36), + new SensorReg(0x016a, 0x08), + new SensorReg(0x016b, 0x69), + new SensorReg(0x016c, 0x06), + new SensorReg(0x016d, 0x68), + new SensorReg(0x016e, 0x03), + new SensorReg(0x016f, 0x9a), + new SensorReg(0x0170, 0x01), + new SensorReg(0x0171, 0x01), + new SensorReg(0x0174, 0x01), + new SensorReg(0x0175, 0x01), + new SensorReg(0x018c, 0x0a), + new SensorReg(0x018d, 0x0a), + new SensorReg(0x0301, 0x05), + new SensorReg(0x0303, 0x01), + new SensorReg(0x0304, 0x03), + new SensorReg(0x0305, 0x03), + new SensorReg(0x0306, 0x00), + new SensorReg(0x0307, 0x39), + new SensorReg(0x0309, 0x0a), + new SensorReg(0x030b, 0x01), + new SensorReg(0x030c, 0x00), + new SensorReg(0x030d, 0x72), + new SensorReg(0x455e, 0x00), + new SensorReg(0x471e, 0x4b), + new SensorReg(0x4767, 0x0f), + new SensorReg(0x4750, 0x14), + new SensorReg(0x4540, 0x00), + new SensorReg(0x47b4, 0x14), + new SensorReg(0x4713, 0x30), + new SensorReg(0x478b, 0x10), + new SensorReg(0x478f, 0x10), + new SensorReg(0x4793, 0x10), + new SensorReg(0x4797, 0x0e), + new SensorReg(0x479b, 0x0e), + new SensorReg(0x0172, 0x03), + new SensorReg(0x0157, 0x00), + new SensorReg(0x0160, 0x05), + new SensorReg(0x0161, 0x2a), + new SensorReg(0x0162, 0x0d), + new SensorReg(0x0163, 0x78), + new SensorReg(0x015a, 0x00), + new SensorReg(0x015b, 0x31), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Imx219Mode6Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x30eb, 0x0c), + new SensorReg(0x300a, 0xff), + new SensorReg(0x300b, 0xff), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x30eb, 0x09), + new SensorReg(0x0114, 0x01), + new SensorReg(0x0128, 0x00), + new SensorReg(0x012a, 0x18), + new SensorReg(0x012b, 0x00), + new SensorReg(0x0164, 0x01), + new SensorReg(0x0165, 0x68), + new SensorReg(0x0166, 0x0b), + new SensorReg(0x0167, 0x67), + new SensorReg(0x0168, 0x02), + new SensorReg(0x0169, 0x00), + new SensorReg(0x016a, 0x07), + new SensorReg(0x016b, 0x9f), + new SensorReg(0x016c, 0x05), + new SensorReg(0x016d, 0x00), + new SensorReg(0x016e, 0x02), + new SensorReg(0x016f, 0xd0), + new SensorReg(0x0170, 0x01), + new SensorReg(0x0171, 0x01), + new SensorReg(0x0174, 0x03), + new SensorReg(0x0175, 0x03), + new SensorReg(0x018c, 0x0a), + new SensorReg(0x018d, 0x0a), + new SensorReg(0x0301, 0x05), + new SensorReg(0x0303, 0x01), + new SensorReg(0x0304, 0x03), + new SensorReg(0x0305, 0x03), + new SensorReg(0x0306, 0x00), + new SensorReg(0x0307, 0x39), + new SensorReg(0x0309, 0x0a), + new SensorReg(0x030b, 0x01), + new SensorReg(0x030c, 0x00), + new SensorReg(0x030d, 0x72), + new SensorReg(0x455e, 0x00), + new SensorReg(0x471e, 0x4b), + new SensorReg(0x4767, 0x0f), + new SensorReg(0x4750, 0x14), + new SensorReg(0x4540, 0x00), + new SensorReg(0x47b4, 0x14), + new SensorReg(0x4713, 0x30), + new SensorReg(0x478b, 0x10), + new SensorReg(0x478f, 0x10), + new SensorReg(0x4793, 0x10), + new SensorReg(0x4797, 0x0e), + new SensorReg(0x479b, 0x0e), + new SensorReg(0x0172, 0x03), + new SensorReg(0x0157, 0x00), + new SensorReg(0x0160, 0x02), + new SensorReg(0x0161, 0x39), + new SensorReg(0x0162, 0x0d), + new SensorReg(0x0163, 0xe7), + new SensorReg(0x015a, 0x00), + new SensorReg(0x015b, 0x2f), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Imx219Mode7Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x30eb, 0x0c), + new SensorReg(0x300a, 0xff), + new SensorReg(0x300b, 0xff), + new SensorReg(0x30eb, 0x05), + new SensorReg(0x30eb, 0x09), + new SensorReg(0x0114, 0x01), + new SensorReg(0x0128, 0x00), + new SensorReg(0x012a, 0x18), + new SensorReg(0x012b, 0x00), + new SensorReg(0x0164, 0x03), + new SensorReg(0x0165, 0xe8), + new SensorReg(0x0166, 0x08), + new SensorReg(0x0167, 0xe7), + new SensorReg(0x0168, 0x02), + new SensorReg(0x0169, 0xf0), + new SensorReg(0x016a, 0x06), + new SensorReg(0x016b, 0xaf), + new SensorReg(0x016c, 0x02), + new SensorReg(0x016d, 0x80), + new SensorReg(0x016e, 0x01), + new SensorReg(0x016f, 0xe0), + new SensorReg(0x0170, 0x01), + new SensorReg(0x0171, 0x01), + new SensorReg(0x0174, 0x03), + new SensorReg(0x0175, 0x03), + new SensorReg(0x018c, 0x0a), + new SensorReg(0x018d, 0x0a), + new SensorReg(0x0301, 0x05), + new SensorReg(0x0303, 0x01), + new SensorReg(0x0304, 0x03), + new SensorReg(0x0305, 0x03), + new SensorReg(0x0306, 0x00), + new SensorReg(0x0307, 0x39), + new SensorReg(0x0309, 0x0a), + new SensorReg(0x030b, 0x01), + new SensorReg(0x030c, 0x00), + new SensorReg(0x030d, 0x72), + new SensorReg(0x455e, 0x00), + new SensorReg(0x471e, 0x4b), + new SensorReg(0x4767, 0x0f), + new SensorReg(0x4750, 0x14), + new SensorReg(0x4540, 0x00), + new SensorReg(0x47b4, 0x14), + new SensorReg(0x4713, 0x30), + new SensorReg(0x478b, 0x10), + new SensorReg(0x478f, 0x10), + new SensorReg(0x4793, 0x10), + new SensorReg(0x4797, 0x0e), + new SensorReg(0x479b, 0x0e), + new SensorReg(0x0172, 0x03), + new SensorReg(0x0157, 0x00), + new SensorReg(0x0160, 0x02), + new SensorReg(0x0161, 0x39), + new SensorReg(0x0162, 0x0d), + new SensorReg(0x0163, 0xe7), + new SensorReg(0x015a, 0x00), + new SensorReg(0x015b, 0x2f), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Imx219StopRegs = new List + { + new SensorReg(0x0100, 0x00) + }; + } +} diff --git a/src/MMALSharp/Config/SensorRegs/Ov5647SensorRegs.cs b/src/MMALSharp/Config/SensorRegs/Ov5647SensorRegs.cs new file mode 100644 index 00000000..69a9cfe1 --- /dev/null +++ b/src/MMALSharp/Config/SensorRegs/Ov5647SensorRegs.cs @@ -0,0 +1,797 @@ +using System.Collections.Generic; + +namespace MMALSharp.Config.SensorRegs +{ + public static class Ov5647SensorRegs + { + public static readonly List Ov5647Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x0103, 0x01), + new SensorReg(0x3034, 0x1a), + new SensorReg(0x3035, 0x21), + new SensorReg(0x3036, 0x69), + new SensorReg(0x303c, 0x11), + new SensorReg(0x3106, 0xf5), + new SensorReg(0x3827, 0xec), + new SensorReg(0x370c, 0x03), + new SensorReg(0x3612, 0x5b), + new SensorReg(0x3618, 0x04), + new SensorReg(0x5000, 0x06), + new SensorReg(0x5002, 0x40), + new SensorReg(0x5003, 0x08), + new SensorReg(0x5a00, 0x08), + new SensorReg(0x3000, 0x00), + new SensorReg(0x3001, 0x00), + new SensorReg(0x3002, 0x00), + new SensorReg(0x3016, 0x08), + new SensorReg(0x3017, 0xe0), + new SensorReg(0x3018, 0x44), + new SensorReg(0x301c, 0xf8), + new SensorReg(0x301d, 0xf0), + new SensorReg(0x3a18, 0x00), + new SensorReg(0x3a19, 0xf8), + new SensorReg(0x3c01, 0x80), + new SensorReg(0x3b07, 0x0c), + new SensorReg(0x380c, 0x0b), + new SensorReg(0x380d, 0x1c), + new SensorReg(0x380e, 0x07), + new SensorReg(0x380f, 0xb0), + new SensorReg(0x3814, 0x11), + new SensorReg(0x3815, 0x11), + new SensorReg(0x3708, 0x64), + new SensorReg(0x3709, 0x12), + new SensorReg(0x3808, 0x0a), + new SensorReg(0x3809, 0x20), + new SensorReg(0x380a, 0x07), + new SensorReg(0x380b, 0x98), + new SensorReg(0x3800, 0x00), + new SensorReg(0x3801, 0x00), + new SensorReg(0x3802, 0x00), + new SensorReg(0x3803, 0x00), + new SensorReg(0x3804, 0x0a), + new SensorReg(0x3805, 0x3f), + new SensorReg(0x3806, 0x07), + new SensorReg(0x3807, 0xa3), + new SensorReg(0x3811, 0x10), + new SensorReg(0x3813, 0x06), + new SensorReg(0x3630, 0x2e), + new SensorReg(0x3632, 0xe2), + new SensorReg(0x3633, 0x23), + new SensorReg(0x3634, 0x44), + new SensorReg(0x3636, 0x06), + new SensorReg(0x3620, 0x64), + new SensorReg(0x3621, 0xe0), + new SensorReg(0x3600, 0x37), + new SensorReg(0x3704, 0xa0), + new SensorReg(0x3703, 0x5a), + new SensorReg(0x3715, 0x78), + new SensorReg(0x3717, 0x01), + new SensorReg(0x3731, 0x02), + new SensorReg(0x370b, 0x60), + new SensorReg(0x3705, 0x1a), + new SensorReg(0x3f05, 0x02), + new SensorReg(0x3f06, 0x10), + new SensorReg(0x3f01, 0x0a), + new SensorReg(0x3a08, 0x01), + new SensorReg(0x3a09, 0x28), + new SensorReg(0x3a0a, 0x00), + new SensorReg(0x3a0b, 0xf6), + new SensorReg(0x3a0d, 0x08), + new SensorReg(0x3a0e, 0x06), + new SensorReg(0x3a0f, 0x58), + new SensorReg(0x3a10, 0x50), + new SensorReg(0x3a1b, 0x58), + new SensorReg(0x3a1e, 0x50), + new SensorReg(0x3a11, 0x60), + new SensorReg(0x3a1f, 0x28), + new SensorReg(0x4001, 0x02), + new SensorReg(0x4004, 0x04), + new SensorReg(0x4000, 0x09), + new SensorReg(0x4837, 0x16), + new SensorReg(0x4800, 0x24), + new SensorReg(0x3503, 0x03), + new SensorReg(0x3820, 0x41), + new SensorReg(0x3821, 0x03), + + new SensorReg(0x350A, 0x00), + new SensorReg(0x350B, 0x23), + new SensorReg(0x3212, 0x00), + new SensorReg(0x3500, 0x00), + new SensorReg(0x3501, 0x04), + new SensorReg(0x3502, 0x60), + new SensorReg(0x3212, 0x10), + new SensorReg(0x3212, 0xA0), + + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Ov5647Mode1Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x0103, 0x01), + new SensorReg(0x3034, 0x1A), + new SensorReg(0x3035, 0x21), + new SensorReg(0x3036, 0x62), + new SensorReg(0x303C, 0x11), + new SensorReg(0x3106, 0xF5), + new SensorReg(0x3827, 0xEC), + new SensorReg(0x370C, 0x03), + new SensorReg(0x3612, 0x5B), + new SensorReg(0x3618, 0x04), + new SensorReg(0x5000, 0x06), + new SensorReg(0x5002, 0x40), + new SensorReg(0x5003, 0x08), + new SensorReg(0x5A00, 0x08), + new SensorReg(0x3000, 0x00), + new SensorReg(0x3001, 0x00), + new SensorReg(0x3002, 0x00), + new SensorReg(0x3016, 0x08), + new SensorReg(0x3017, 0xE0), + new SensorReg(0x3018, 0x44), + new SensorReg(0x301C, 0xF8), + new SensorReg(0x301D, 0xF0), + new SensorReg(0x3A18, 0x00), + new SensorReg(0x3A19, 0xF8), + new SensorReg(0x3C01, 0x80), + new SensorReg(0x3B07, 0x0C), + new SensorReg(0x380C, 0x09), + new SensorReg(0x380D, 0x70), + new SensorReg(0x3814, 0x11), + new SensorReg(0x3815, 0x11), + new SensorReg(0x3708, 0x64), + new SensorReg(0x3709, 0x12), + new SensorReg(0x3808, 0x07), + new SensorReg(0x3809, 0x80), + new SensorReg(0x380A, 0x04), + new SensorReg(0x380B, 0x38), + new SensorReg(0x3800, 0x01), + new SensorReg(0x3801, 0x5C), + new SensorReg(0x3802, 0x01), + new SensorReg(0x3803, 0xB2), + new SensorReg(0x3804, 0x08), + new SensorReg(0x3805, 0xE3), + new SensorReg(0x3806, 0x05), + new SensorReg(0x3807, 0xF1), + new SensorReg(0x3811, 0x04), + new SensorReg(0x3813, 0x02), + new SensorReg(0x3630, 0x2E), + new SensorReg(0x3632, 0xE2), + new SensorReg(0x3633, 0x23), + new SensorReg(0x3634, 0x44), + new SensorReg(0x3636, 0x06), + new SensorReg(0x3620, 0x64), + new SensorReg(0x3621, 0xE0), + new SensorReg(0x3600, 0x37), + new SensorReg(0x3704, 0xA0), + new SensorReg(0x3703, 0x5A), + new SensorReg(0x3715, 0x78), + new SensorReg(0x3717, 0x01), + new SensorReg(0x3731, 0x02), + new SensorReg(0x370B, 0x60), + new SensorReg(0x3705, 0x1A), + new SensorReg(0x3F05, 0x02), + new SensorReg(0x3F06, 0x10), + new SensorReg(0x3F01, 0x0A), + new SensorReg(0x3A08, 0x01), + new SensorReg(0x3A09, 0x4B), + new SensorReg(0x3A0A, 0x01), + new SensorReg(0x3A0B, 0x13), + new SensorReg(0x3A0D, 0x04), + new SensorReg(0x3A0E, 0x03), + new SensorReg(0x3A0F, 0x58), + new SensorReg(0x3A10, 0x50), + new SensorReg(0x3A1B, 0x58), + new SensorReg(0x3A1E, 0x50), + new SensorReg(0x3A11, 0x60), + new SensorReg(0x3A1F, 0x28), + new SensorReg(0x4001, 0x02), + new SensorReg(0x4004, 0x04), + new SensorReg(0x4000, 0x09), + new SensorReg(0x4837, 0x19), + new SensorReg(0x4800, 0x34), + new SensorReg(0x3503, 0x03), + new SensorReg(0x3820, 0x00), + new SensorReg(0x3821, 0x02), + new SensorReg(0x380E, 0x04), + new SensorReg(0x380F, 0x66), + new SensorReg(0x350A, 0x00), + new SensorReg(0x350B, 0x10), + new SensorReg(0x3500, 0x00), + new SensorReg(0x3501, 0x15), + new SensorReg(0x3502, 0x20), + new SensorReg(0x3212, 0xA0), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Ov5647Mode2Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x0103, 0x01), + new SensorReg(0x3034, 0x1A), + new SensorReg(0x3035, 0x21), + new SensorReg(0x3036, 0x69), + new SensorReg(0x303C, 0x11), + new SensorReg(0x3106, 0xF5), + new SensorReg(0x3827, 0xEC), + new SensorReg(0x370C, 0x03), + new SensorReg(0x3612, 0x5B), + new SensorReg(0x3618, 0x04), + new SensorReg(0x5000, 0x06), + new SensorReg(0x5002, 0x40), + new SensorReg(0x5003, 0x08), + new SensorReg(0x5A00, 0x08), + new SensorReg(0x3000, 0x00), + new SensorReg(0x3001, 0x00), + new SensorReg(0x3002, 0x00), + new SensorReg(0x3016, 0x08), + new SensorReg(0x3017, 0xE0), + new SensorReg(0x3018, 0x44), + new SensorReg(0x301C, 0xF8), + new SensorReg(0x301D, 0xF0), + new SensorReg(0x3A18, 0x00), + new SensorReg(0x3A19, 0xF8), + new SensorReg(0x3C01, 0x80), + new SensorReg(0x3B07, 0x0C), + new SensorReg(0x380C, 0x0B), + new SensorReg(0x380D, 0x1C), + new SensorReg(0x3814, 0x11), + new SensorReg(0x3815, 0x11), + new SensorReg(0x3708, 0x64), + new SensorReg(0x3709, 0x12), + new SensorReg(0x3808, 0x0A), + new SensorReg(0x3809, 0x20), + new SensorReg(0x380A, 0x07), + new SensorReg(0x380B, 0x98), + new SensorReg(0x3800, 0x00), + new SensorReg(0x3801, 0x00), + new SensorReg(0x3802, 0x00), + new SensorReg(0x3803, 0x00), + new SensorReg(0x3804, 0x0A), + new SensorReg(0x3805, 0x3F), + new SensorReg(0x3806, 0x07), + new SensorReg(0x3807, 0xA3), + new SensorReg(0x3811, 0x10), + new SensorReg(0x3813, 0x06), + new SensorReg(0x3630, 0x2E), + new SensorReg(0x3632, 0xE2), + new SensorReg(0x3633, 0x23), + new SensorReg(0x3634, 0x44), + new SensorReg(0x3636, 0x06), + new SensorReg(0x3620, 0x64), + new SensorReg(0x3621, 0xE0), + new SensorReg(0x3600, 0x37), + new SensorReg(0x3704, 0xA0), + new SensorReg(0x3703, 0x5A), + new SensorReg(0x3715, 0x78), + new SensorReg(0x3717, 0x01), + new SensorReg(0x3731, 0x02), + new SensorReg(0x370B, 0x60), + new SensorReg(0x3705, 0x1A), + new SensorReg(0x3F05, 0x02), + new SensorReg(0x3F06, 0x10), + new SensorReg(0x3F01, 0x0A), + new SensorReg(0x3A08, 0x01), + new SensorReg(0x3A09, 0x28), + new SensorReg(0x3A0A, 0x00), + new SensorReg(0x3A0B, 0xF6), + new SensorReg(0x3A0D, 0x08), + new SensorReg(0x3A0E, 0x06), + new SensorReg(0x3A0F, 0x58), + new SensorReg(0x3A10, 0x50), + new SensorReg(0x3A1B, 0x58), + new SensorReg(0x3A1E, 0x50), + new SensorReg(0x3A11, 0x60), + new SensorReg(0x3A1F, 0x28), + new SensorReg(0x4001, 0x02), + new SensorReg(0x4004, 0x04), + new SensorReg(0x4000, 0x09), + new SensorReg(0x4837, 0x16), + new SensorReg(0x4800, 0x24), + new SensorReg(0x3503, 0x03), + new SensorReg(0x3820, 0x00), + new SensorReg(0x3821, 0x02), + new SensorReg(0x380E, 0x08), + new SensorReg(0x380F, 0x03), + new SensorReg(0x350A, 0x00), + new SensorReg(0x350B, 0x10), + new SensorReg(0x3500, 0x00), + new SensorReg(0x3501, 0x13), + new SensorReg(0x3502, 0x40), + new SensorReg(0x3212, 0xA0), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Ov5647Mode3Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x0103, 0x01), + new SensorReg(0x3034, 0x1A), + new SensorReg(0x3035, 0x21), + new SensorReg(0x3036, 0x34), + new SensorReg(0x303C, 0x11), + new SensorReg(0x3106, 0xF5), + new SensorReg(0x3827, 0xEC), + new SensorReg(0x370C, 0x03), + new SensorReg(0x3612, 0x5B), + new SensorReg(0x3618, 0x04), + new SensorReg(0x5000, 0x06), + new SensorReg(0x5002, 0x40), + new SensorReg(0x5003, 0x08), + new SensorReg(0x5A00, 0x08), + new SensorReg(0x3000, 0x00), + new SensorReg(0x3001, 0x00), + new SensorReg(0x3002, 0x00), + new SensorReg(0x3016, 0x08), + new SensorReg(0x3017, 0xE0), + new SensorReg(0x3018, 0x44), + new SensorReg(0x301C, 0xF8), + new SensorReg(0x301D, 0xF0), + new SensorReg(0x3A18, 0x00), + new SensorReg(0x3A19, 0xF8), + new SensorReg(0x3C01, 0x80), + new SensorReg(0x3B07, 0x0C), + new SensorReg(0x380C, 0x1F), + new SensorReg(0x380D, 0x1B), + new SensorReg(0x3814, 0x11), + new SensorReg(0x3815, 0x11), + new SensorReg(0x3708, 0x64), + new SensorReg(0x3709, 0x12), + new SensorReg(0x3808, 0x0A), + new SensorReg(0x3809, 0x20), + new SensorReg(0x380A, 0x07), + new SensorReg(0x380B, 0x98), + new SensorReg(0x3800, 0x00), + new SensorReg(0x3801, 0x00), + new SensorReg(0x3802, 0x00), + new SensorReg(0x3803, 0x00), + new SensorReg(0x3804, 0x0A), + new SensorReg(0x3805, 0x3F), + new SensorReg(0x3806, 0x07), + new SensorReg(0x3807, 0xA3), + new SensorReg(0x3811, 0x10), + new SensorReg(0x3813, 0x06), + new SensorReg(0x3630, 0x2E), + new SensorReg(0x3632, 0xE2), + new SensorReg(0x3633, 0x23), + new SensorReg(0x3634, 0x44), + new SensorReg(0x3636, 0x06), + new SensorReg(0x3620, 0x64), + new SensorReg(0x3621, 0xE0), + new SensorReg(0x3600, 0x37), + new SensorReg(0x3704, 0xA0), + new SensorReg(0x3703, 0x5A), + new SensorReg(0x3715, 0x78), + new SensorReg(0x3717, 0x01), + new SensorReg(0x3731, 0x02), + new SensorReg(0x370B, 0x60), + new SensorReg(0x3705, 0x1A), + new SensorReg(0x3F05, 0x02), + new SensorReg(0x3F06, 0x10), + new SensorReg(0x3F01, 0x0A), + new SensorReg(0x3A08, 0x01), + new SensorReg(0x3A09, 0x28), + new SensorReg(0x3A0A, 0x00), + new SensorReg(0x3A0B, 0xF6), + new SensorReg(0x3A0D, 0x08), + new SensorReg(0x3A0E, 0x06), + new SensorReg(0x3A0F, 0x58), + new SensorReg(0x3A10, 0x50), + new SensorReg(0x3A1B, 0x58), + new SensorReg(0x3A1E, 0x50), + new SensorReg(0x3A11, 0x60), + new SensorReg(0x3A1F, 0x28), + new SensorReg(0x4001, 0x02), + new SensorReg(0x4004, 0x04), + new SensorReg(0x4000, 0x09), + new SensorReg(0x4837, 0x16), + new SensorReg(0x4800, 0x24), + new SensorReg(0x3503, 0x03), + new SensorReg(0x3820, 0x00), + new SensorReg(0x3821, 0x02), + new SensorReg(0x380E, 0x15), + new SensorReg(0x380F, 0x56), + new SensorReg(0x350A, 0x00), + new SensorReg(0x350B, 0x10), + new SensorReg(0x3500, 0x00), + new SensorReg(0x3501, 0x03), + new SensorReg(0x3502, 0x60), + new SensorReg(0x3212, 0xA0), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Ov5647Mode4Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x0103, 0x01), + new SensorReg(0x3034, 0x1A), + new SensorReg(0x3035, 0x21), + new SensorReg(0x3036, 0x62), + new SensorReg(0x303C, 0x11), + new SensorReg(0x3106, 0xF5), + new SensorReg(0x3827, 0xEC), + new SensorReg(0x370C, 0x03), + new SensorReg(0x3612, 0x59), + new SensorReg(0x3618, 0x00), + new SensorReg(0x5000, 0x06), + new SensorReg(0x5002, 0x40), + new SensorReg(0x5003, 0x08), + new SensorReg(0x5A00, 0x08), + new SensorReg(0x3000, 0x00), + new SensorReg(0x3001, 0x00), + new SensorReg(0x3002, 0x00), + new SensorReg(0x3016, 0x08), + new SensorReg(0x3017, 0xE0), + new SensorReg(0x3018, 0x44), + new SensorReg(0x301C, 0xF8), + new SensorReg(0x301D, 0xF0), + new SensorReg(0x3A18, 0x00), + new SensorReg(0x3A19, 0xF8), + new SensorReg(0x3C01, 0x80), + new SensorReg(0x3B07, 0x0C), + new SensorReg(0x3800, 0x00), + new SensorReg(0x3801, 0x00), + new SensorReg(0x3802, 0x00), + new SensorReg(0x3803, 0x00), + new SensorReg(0x3804, 0x0A), + new SensorReg(0x3805, 0x3F), + new SensorReg(0x3806, 0x07), + new SensorReg(0x3807, 0xA3), + new SensorReg(0x3808, 0x05), + new SensorReg(0x3809, 0x10), + new SensorReg(0x380A, 0x03), + new SensorReg(0x380B, 0xCC), + new SensorReg(0x380C, 0x07), + new SensorReg(0x380D, 0x68), + new SensorReg(0x3811, 0x10), + new SensorReg(0x3813, 0x06), + new SensorReg(0x3814, 0x31), + new SensorReg(0x3815, 0x31), + new SensorReg(0x3630, 0x2E), + new SensorReg(0x3632, 0xE2), + new SensorReg(0x3633, 0x23), + new SensorReg(0x3634, 0x44), + new SensorReg(0x3636, 0x06), + new SensorReg(0x3620, 0x64), + new SensorReg(0x3621, 0xE0), + new SensorReg(0x3600, 0x37), + new SensorReg(0x3704, 0xA0), + new SensorReg(0x3703, 0x5A), + new SensorReg(0x3715, 0x78), + new SensorReg(0x3717, 0x01), + new SensorReg(0x3731, 0x02), + new SensorReg(0x370B, 0x60), + new SensorReg(0x3705, 0x1A), + new SensorReg(0x3F05, 0x02), + new SensorReg(0x3F06, 0x10), + new SensorReg(0x3F01, 0x0A), + new SensorReg(0x3A08, 0x01), + new SensorReg(0x3A09, 0x28), + new SensorReg(0x3A0A, 0x00), + new SensorReg(0x3A0B, 0xF6), + new SensorReg(0x3A0D, 0x08), + new SensorReg(0x3A0E, 0x06), + new SensorReg(0x3A0F, 0x58), + new SensorReg(0x3A10, 0x50), + new SensorReg(0x3A1B, 0x58), + new SensorReg(0x3A1E, 0x50), + new SensorReg(0x3A11, 0x60), + new SensorReg(0x3A1F, 0x28), + new SensorReg(0x4001, 0x02), + new SensorReg(0x4004, 0x04), + new SensorReg(0x4000, 0x09), + new SensorReg(0x4837, 0x16), + new SensorReg(0x4800, 0x24), + new SensorReg(0x3503, 0x03), + new SensorReg(0x3820, 0x41), + new SensorReg(0x3821, 0x03), + new SensorReg(0x380E, 0x05), + new SensorReg(0x380F, 0x9B), + new SensorReg(0x350A, 0x00), + new SensorReg(0x350B, 0x10), + new SensorReg(0x3500, 0x00), + new SensorReg(0x3501, 0x1A), + new SensorReg(0x3502, 0xF0), + new SensorReg(0x3212, 0xA0), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Ov5647Mode5Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x0103, 0x01), + new SensorReg(0x3034, 0x1A), + new SensorReg(0x3035, 0x21), + new SensorReg(0x3036, 0x62), + new SensorReg(0x303C, 0x11), + new SensorReg(0x3106, 0xF5), + new SensorReg(0x3827, 0xEC), + new SensorReg(0x370C, 0x03), + new SensorReg(0x3612, 0x59), + new SensorReg(0x3618, 0x00), + new SensorReg(0x5000, 0x06), + new SensorReg(0x5002, 0x40), + new SensorReg(0x5003, 0x08), + new SensorReg(0x5A00, 0x08), + new SensorReg(0x3000, 0x00), + new SensorReg(0x3001, 0x00), + new SensorReg(0x3002, 0x00), + new SensorReg(0x3016, 0x08), + new SensorReg(0x3017, 0xE0), + new SensorReg(0x3018, 0x44), + new SensorReg(0x301C, 0xF8), + new SensorReg(0x301D, 0xF0), + new SensorReg(0x3A18, 0x00), + new SensorReg(0x3A19, 0xF8), + new SensorReg(0x3C01, 0x80), + new SensorReg(0x3B07, 0x0C), + new SensorReg(0x3800, 0x00), + new SensorReg(0x3801, 0x00), + + // NB This value IS INCORRECT, but has been incorrect for long enough + // that changing it will cause complaints due to changing FOV. + // (It should be (0x3802, 00), (0x3803, F0) to give a symmetric crop). + // Correct the value so debug_mode isn't set, but the result is the same. + new SensorReg(0x3802, 0x00), + new SensorReg(0x3803, 0x00), + new SensorReg(0x3804, 0x0A), + new SensorReg(0x3805, 0x3F), + + // For a symmetric crop, use (0x3806, 0x06), (0x3807,0xB3) + new SensorReg(0x3806, 0x05), + new SensorReg(0x3807, 0xbf), + new SensorReg(0x3808, 0x05), + new SensorReg(0x3809, 0x10), + new SensorReg(0x380A, 0x02), + new SensorReg(0x380B, 0xDA), + new SensorReg(0x380C, 0x07), + new SensorReg(0x380D, 0x68), + new SensorReg(0x3811, 0x10), + new SensorReg(0x3813, 0x06), + new SensorReg(0x3814, 0x31), + new SensorReg(0x3815, 0x31), + new SensorReg(0x3630, 0x2E), + new SensorReg(0x3632, 0xE2), + new SensorReg(0x3633, 0x23), + new SensorReg(0x3634, 0x44), + new SensorReg(0x3636, 0x06), + new SensorReg(0x3620, 0x64), + new SensorReg(0x3621, 0xE0), + new SensorReg(0x3600, 0x37), + new SensorReg(0x3704, 0xA0), + new SensorReg(0x3703, 0x5A), + new SensorReg(0x3715, 0x78), + new SensorReg(0x3717, 0x01), + new SensorReg(0x3731, 0x02), + new SensorReg(0x370B, 0x60), + new SensorReg(0x3705, 0x1A), + new SensorReg(0x3F05, 0x02), + new SensorReg(0x3F06, 0x10), + new SensorReg(0x3F01, 0x0A), + new SensorReg(0x3A08, 0x01), + new SensorReg(0x3A09, 0x28), + new SensorReg(0x3A0A, 0x00), + new SensorReg(0x3A0B, 0xF6), + new SensorReg(0x3A0D, 0x08), + new SensorReg(0x3A0E, 0x06), + new SensorReg(0x3A0F, 0x58), + new SensorReg(0x3A10, 0x50), + new SensorReg(0x3A1B, 0x58), + new SensorReg(0x3A1E, 0x50), + new SensorReg(0x3A11, 0x60), + new SensorReg(0x3A1F, 0x28), + new SensorReg(0x4001, 0x02), + new SensorReg(0x4004, 0x04), + new SensorReg(0x4000, 0x09), + new SensorReg(0x4837, 0x16), + new SensorReg(0x4800, 0x24), + new SensorReg(0x3503, 0x03), + new SensorReg(0x3820, 0x41), + new SensorReg(0x3821, 0x03), + new SensorReg(0x380E, 0x05), + new SensorReg(0x380F, 0x9B), + new SensorReg(0x350A, 0x00), + new SensorReg(0x350B, 0x10), + new SensorReg(0x3500, 0x00), + new SensorReg(0x3501, 0x1A), + new SensorReg(0x3502, 0xF0), + new SensorReg(0x3212, 0xA0), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Ov5647Mode6Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x0103, 0x01), + new SensorReg(0x3036, 0x46), + new SensorReg(0x303C, 0x11), + new SensorReg(0x370C, 0x03), + new SensorReg(0x3612, 0x59), + new SensorReg(0x3618, 0x00), + new SensorReg(0x5000, 0x06), + new SensorReg(0x5003, 0x08), + new SensorReg(0x5A00, 0x08), + new SensorReg(0x301D, 0xF0), + new SensorReg(0x3A18, 0x00), + new SensorReg(0x3A19, 0xF8), + new SensorReg(0x3C01, 0x80), + new SensorReg(0x3B07, 0x0C), + new SensorReg(0x380C, 0x07), + new SensorReg(0x380D, 0x3C), + new SensorReg(0x3814, 0x71), + new SensorReg(0x3815, 0x71), + new SensorReg(0x3708, 0x64), + new SensorReg(0x3709, 0x52), + new SensorReg(0x3808, 0x02), + new SensorReg(0x3809, 0x80), + new SensorReg(0x380A, 0x01), + new SensorReg(0x380B, 0xE0), + new SensorReg(0x3800, 0x00), + new SensorReg(0x3801, 0x10), + new SensorReg(0x3802, 0x00), + new SensorReg(0x3803, 0x00), + new SensorReg(0x3804, 0x0A), + new SensorReg(0x3805, 0x2F), + new SensorReg(0x3806, 0x07), + new SensorReg(0x3807, 0x9F), + new SensorReg(0x3630, 0x2E), + new SensorReg(0x3632, 0xE2), + new SensorReg(0x3633, 0x23), + new SensorReg(0x3634, 0x44), + new SensorReg(0x3620, 0x64), + new SensorReg(0x3621, 0xE0), + new SensorReg(0x3600, 0x37), + new SensorReg(0x3704, 0xA0), + new SensorReg(0x3703, 0x5A), + new SensorReg(0x3715, 0x78), + new SensorReg(0x3717, 0x01), + new SensorReg(0x3731, 0x02), + new SensorReg(0x370B, 0x60), + new SensorReg(0x3705, 0x1A), + new SensorReg(0x3F05, 0x02), + new SensorReg(0x3F06, 0x10), + new SensorReg(0x3F01, 0x0A), + new SensorReg(0x3A08, 0x01), + new SensorReg(0x3A09, 0x2E), + new SensorReg(0x3A0A, 0x00), + new SensorReg(0x3A0B, 0xFB), + new SensorReg(0x3A0D, 0x02), + new SensorReg(0x3A0E, 0x01), + new SensorReg(0x3A0F, 0x58), + new SensorReg(0x3A10, 0x50), + new SensorReg(0x3A1B, 0x58), + new SensorReg(0x3A1E, 0x50), + new SensorReg(0x3A11, 0x60), + new SensorReg(0x3A1F, 0x28), + new SensorReg(0x4001, 0x02), + new SensorReg(0x4004, 0x02), + new SensorReg(0x4000, 0x09), + new SensorReg(0x3000, 0x00), + new SensorReg(0x3001, 0x00), + new SensorReg(0x3002, 0x00), + new SensorReg(0x3017, 0xE0), + new SensorReg(0x3636, 0x06), + new SensorReg(0x3016, 0x08), + new SensorReg(0x3827, 0xEC), + new SensorReg(0x3018, 0x44), + new SensorReg(0x3035, 0x21), + new SensorReg(0x3106, 0xF5), + new SensorReg(0x3034, 0x1A), + new SensorReg(0x301C, 0xF8), + new SensorReg(0x4800, 0x34), + new SensorReg(0x3503, 0x03), + new SensorReg(0x3820, 0x41), + new SensorReg(0x3821, 0x03), + new SensorReg(0x380E, 0x02), + new SensorReg(0x380F, 0xEC), + new SensorReg(0x350A, 0x00), + new SensorReg(0x350B, 0x10), + new SensorReg(0x3500, 0x00), + new SensorReg(0x3501, 0x13), + new SensorReg(0x3502, 0xB0), + new SensorReg(0x3212, 0xA0), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Ov5647Mode7Regs = new List + { + new SensorReg(0x0100, 0x00), + new SensorReg(0x0103, 0x01), + new SensorReg(0x3034, 0x1A), + new SensorReg(0x3035, 0x21), + new SensorReg(0x3036, 0x69), + new SensorReg(0x303C, 0x11), + new SensorReg(0x3106, 0xF5), + new SensorReg(0x3827, 0xEC), + new SensorReg(0x370C, 0x0F), + new SensorReg(0x3612, 0x59), + new SensorReg(0x3618, 0x00), + new SensorReg(0x5000, 0x06), + new SensorReg(0x5002, 0x40), + new SensorReg(0x5003, 0x08), + new SensorReg(0x5A00, 0x08), + new SensorReg(0x3000, 0x00), + new SensorReg(0x3001, 0x00), + new SensorReg(0x3002, 0x00), + new SensorReg(0x3016, 0x08), + new SensorReg(0x3017, 0xE0), + new SensorReg(0x3018, 0x44), + new SensorReg(0x301C, 0xF8), + new SensorReg(0x301D, 0xF0), + new SensorReg(0x3A18, 0x00), + new SensorReg(0x3A19, 0xF8), + new SensorReg(0x3C01, 0x80), + new SensorReg(0x3B07, 0x0C), + new SensorReg(0x380C, 0x07), + new SensorReg(0x380D, 0x3C), + new SensorReg(0x3814, 0x71), + new SensorReg(0x3815, 0x35), + new SensorReg(0x3708, 0x64), + new SensorReg(0x3709, 0x52), + new SensorReg(0x3808, 0x02), + new SensorReg(0x3809, 0x80), + new SensorReg(0x380A, 0x01), + new SensorReg(0x380B, 0xE0), + new SensorReg(0x3800, 0x00), + new SensorReg(0x3801, 0x10), + new SensorReg(0x3802, 0x00), + new SensorReg(0x3803, 0x00), + new SensorReg(0x3804, 0x0A), + new SensorReg(0x3805, 0x2F), + new SensorReg(0x3806, 0x07), + new SensorReg(0x3807, 0x9F), + new SensorReg(0x3630, 0x2E), + new SensorReg(0x3632, 0xE2), + new SensorReg(0x3633, 0x23), + new SensorReg(0x3634, 0x44), + new SensorReg(0x3636, 0x06), + new SensorReg(0x3620, 0x64), + new SensorReg(0x3621, 0xE0), + new SensorReg(0x3600, 0x37), + new SensorReg(0x3704, 0xA0), + new SensorReg(0x3703, 0x5A), + new SensorReg(0x3715, 0x78), + new SensorReg(0x3717, 0x01), + new SensorReg(0x3731, 0x02), + new SensorReg(0x370B, 0x60), + new SensorReg(0x3705, 0x1A), + new SensorReg(0x3F05, 0x02), + new SensorReg(0x3F06, 0x10), + new SensorReg(0x3F01, 0x0A), + new SensorReg(0x3A08, 0x01), + new SensorReg(0x3A09, 0x2E), + new SensorReg(0x3A0A, 0x00), + new SensorReg(0x3A0B, 0xFB), + new SensorReg(0x3A0D, 0x02), + new SensorReg(0x3A0E, 0x01), + new SensorReg(0x3A0F, 0x58), + new SensorReg(0x3A10, 0x50), + new SensorReg(0x3A1B, 0x58), + new SensorReg(0x3A1E, 0x50), + new SensorReg(0x3A11, 0x60), + new SensorReg(0x3A1F, 0x28), + new SensorReg(0x4001, 0x02), + new SensorReg(0x4004, 0x02), + new SensorReg(0x4000, 0x09), + new SensorReg(0x4837, 0x17), + new SensorReg(0x4800, 0x34), + new SensorReg(0x3503, 0x03), + new SensorReg(0x3820, 0x41), + new SensorReg(0x3821, 0x03), + new SensorReg(0x380E, 0x03), + new SensorReg(0x380F, 0x12), + new SensorReg(0x350A, 0x00), + new SensorReg(0x350B, 0x10), + new SensorReg(0x3500, 0x00), + new SensorReg(0x3501, 0x1D), + new SensorReg(0x3502, 0x80), + new SensorReg(0x3212, 0xA0), + new SensorReg(0x0100, 0x01) + }; + + public static readonly List Ov5647StopRegs = new List + { + new SensorReg(0x0100, 0x00) + }; + } +} diff --git a/src/MMALSharp/Config/SensorRegs/SensorReg.cs b/src/MMALSharp/Config/SensorRegs/SensorReg.cs new file mode 100644 index 00000000..705ef70d --- /dev/null +++ b/src/MMALSharp/Config/SensorRegs/SensorReg.cs @@ -0,0 +1,17 @@ +namespace MMALSharp.Config.SensorRegs +{ + public struct SensorReg + { + private int _reg; + private int _data; + + public int Reg => _reg; + public int Data => _data; + + public SensorReg(int reg, int data) + { + _reg = reg; + _data = data; + } + } +} diff --git a/src/MMALSharp/MMALRawcam.cs b/src/MMALSharp/MMALRawcam.cs new file mode 100644 index 00000000..24f294f8 --- /dev/null +++ b/src/MMALSharp/MMALRawcam.cs @@ -0,0 +1,429 @@ +using Microsoft.Extensions.Logging; +using MMALSharp.Common.Utility; +using MMALSharp.Components; +using MMALSharp.Config; +using MMALSharp.Config.SensorDefs; +using MMALSharp.Config.SensorRegs; +using MMALSharp.Native; +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +using static MMALSharp.Native.MMALI2C; + +namespace MMALSharp +{ + public sealed class MMALRawcam + { + private const int OPEN_READ_WRITE = 2; + + private const int I2C_M_RD = 0x0001; + private const int I2C_SLAVE_FORCE = 0x0706; + private const int I2C_RDWR = 0x0707; + + /// + /// Gets the singleton instance of the MMAL Raw Camera. Call to initialise the camera for first use. + /// + public static MMALRawcam Instance => Lazy.Value; + + /// + /// Reference to the camera component. + /// + public MMALRawcamComponent Camera { get; } + + private static readonly Lazy Lazy = new Lazy(() => new MMALRawcam()); + + private static List SensorDefs + { + get + { + return new List + { + Ov5647SensorDefs.Ov5647SensorDef, + Imx219SensorDefs.Imx219SensorDef + }; + } + } + + private MMALRawcamComponent RawcamComponent { get; set; } + + private MMALIspComponent IspComponent { get; set; } + + private SensorDef SensorDef { get; set; } + + private ModeDef ModeDef { get; set; } + + private string I2CDeviceName { get; set; } + + private MMALRawcam() + { + BcmHost.bcm_host_init(); + + this.Camera = new MMALRawcamComponent(); + } + + /// + /// Configures the raw camera pipeline. + /// + /// The component reference. + /// The component reference. + /// The sensor definition config object. + /// The mode definition config object. + /// The I2C device name. + public void ConfigureRawcamPipeline(MMALRawcamComponent rawcamComponent, MMALIspComponent ispComponent, SensorDef sensorDef, ModeDef modeDef, string i2cDeviceName) + { + this.RawcamComponent = rawcamComponent; + this.IspComponent = ispComponent; + this.SensorDef = sensorDef; + this.ModeDef = modeDef; + this.I2CDeviceName = i2cDeviceName; + } + + /// + /// Helper method to begin processing image data. Starts the Raw Camera component and awaits until processing is complete. + /// Cleans up resources upon finish. + /// + /// A CancellationToken to observe while waiting for a task to complete. + /// The awaitable Task. + public async Task ProcessAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var tasks = new List(); + + MMALLog.Logger.LogInformation("Attemping to enable rawcam components..."); + + var sensor = this.ProbeSensor(this.I2CDeviceName); + + if (sensor == null) + { + throw new MMALIOException($"Could not probe sensor {this.I2CDeviceName}"); + } + + this.IspComponent.EnableComponent(); + this.RawcamComponent.EnableComponent(); + + this.IspComponent.Inputs[0].Start(); + this.IspComponent.Outputs[0].Start(); + this.RawcamComponent.Outputs[0].Start(); + + tasks.Add(this.IspComponent.Outputs[0].Trigger.Task); + tasks.Add(this.RawcamComponent.Outputs[0].Trigger.Task); + + MMALLog.Logger.LogDebug("Attemping to start rawcam streaming..."); + + await this.StartCapture(this.SensorDef, this.ModeDef, this.I2CDeviceName); + + if (cancellationToken == CancellationToken.None) + { + await Task.WhenAll(tasks).ConfigureAwait(false); + + await this.StopCapture(this.SensorDef, this.I2CDeviceName); + } + else + { + await Task.WhenAny(Task.WhenAll(tasks), cancellationToken.AsTask()).ConfigureAwait(false); + + this.IspComponent.ForceStopProcessing = true; + this.RawcamComponent.ForceStopProcessing = true; + + await this.StopCapture(this.SensorDef, this.I2CDeviceName); + + await Task.WhenAll(tasks).ConfigureAwait(false); + } + + foreach (var port in this.IspComponent.ProcessingPorts.Values) + { + if (port.ConnectedReference == null) + { + port.DisablePort(); + } + } + + this.IspComponent.CleanPortPools(); + this.IspComponent.DisableConnections(); + + foreach (var port in this.RawcamComponent.ProcessingPorts.Values) + { + if (port.ConnectedReference == null) + { + port.DisablePort(); + } + } + + this.RawcamComponent.CleanPortPools(); + this.RawcamComponent.DisableConnections(); + } + + /// + /// Cleans up any unmanaged resources. It is intended for this method to be run when no more activity is to be done with MMAL. + /// + public void Cleanup() + { + MMALLog.Logger.LogDebug("Destroying final components"); + + var tempList = new List(MMALBootstrapper.DownstreamComponents); + + tempList.ForEach(c => c.Dispose()); + + BcmHost.bcm_host_deinit(); + } + + private async Task StartCapture(SensorDef sensorDef, ModeDef modeDef, string i2cDeviceName) + { + try + { + var fd = MMALI2C.Open(i2cDeviceName, OPEN_READ_WRITE); + + if (fd == 0) + { + throw new MMALIOException("Couldn't open I2C device."); + } + + if (MMALI2C.Ioctl(fd, I2C_SLAVE_FORCE, (IntPtr)sensorDef.I2CAddr) < 0) + { + throw new MMALIOException("Failed to set I2C address."); + } + + await this.SendRegs(fd, sensorDef, modeDef.Regs); + MMALI2C.Close(fd); + MMALLog.Logger.LogInformation("Now streaming..."); + } + catch (Exception e) + { + MMALLog.Logger.LogError($"An error occurred when starting capture: {e.Message}"); + } + } + + private async Task StopCapture(SensorDef sensorDef, string i2cDeviceName) + { + try + { + var fd = MMALI2C.Open(i2cDeviceName, OPEN_READ_WRITE); + + if (fd == 0) + { + throw new MMALIOException("Couldn't open I2C device."); + } + + if (MMALI2C.Ioctl(fd, I2C_SLAVE_FORCE, (IntPtr)sensorDef.I2CAddr) < 0) + { + throw new MMALIOException("Failed to set I2C address."); + } + + await this.SendRegs(fd, sensorDef, sensorDef.StopReg); + MMALI2C.Close(fd); + MMALLog.Logger.LogInformation("Stop streaming..."); + } + catch (Exception e) + { + MMALLog.Logger.LogError($"An error occurred when stopping capture: {e.Message}"); + } + } + + private SensorDef ProbeSensor(string i2cDeviceName) + { + var fd = MMALI2C.Open(i2cDeviceName, OPEN_READ_WRITE); + + if (fd == 0) + { + throw new MMALIOException("Couldn't open I2C device."); + } + + foreach (var sensorDef in SensorDefs) + { + MMALLog.Logger.LogDebug($"Probing sensor {sensorDef.Name} on addr {sensorDef.I2CAddr}"); + + if (sensorDef.I2CIdentLength <= 2) + { + var rd = this.I2CRead(fd, sensorDef.I2CAddr, sensorDef.I2CIdentReg, sensorDef.I2CIdentLength, sensorDef.I2CAddressing); + + if (rd != null && rd[0] == sensorDef.I2CIdentValue) + { + MMALLog.Logger.LogInformation($"Found sensor {sensorDef.Name} at address {sensorDef.I2CAddr}."); + + return sensorDef; + } + else + { + MMALLog.Logger.LogInformation($"Unable to probe sensor {sensorDef.Name} at address {sensorDef.I2CAddr}."); + } + } + } + + return null; + } + + private unsafe byte[] I2CRead(int fd, int i2cAddr, int reg, int n, int addressing) + { + int len = 0; + + Console.WriteLine($"I2C Addr: {i2cAddr}"); + Console.WriteLine($"Reg: {reg}"); + Console.WriteLine($"N: {n}"); + Console.WriteLine($"Addressing: {addressing}"); + + var buf = new byte[2] { (byte)(reg >> 8), (byte)(reg & 0xff) }; + + Console.WriteLine($"Buffer value 1 {reg >> 8}. Buffer value 2 {reg & 0xff}"); + + var ptr1 = Marshal.AllocHGlobal(2); + var ptr2 = Marshal.AllocHGlobal(n); + + Marshal.Copy(buf, 0, ptr1, 2); + + if (addressing == 1) + { + len = 1; + } + else + { + len = n; + } + + var msg1 = new I2CMsg(i2cAddr, 0, 2, ptr1); + var msg2 = new I2CMsg(i2cAddr, I2C_M_RD, len, ptr2); + + var msgArr = new I2CMsg[2] { msg1, msg2 }; + var err = 0; + var win32Err = 0; + + fixed (I2CMsg* pArray = msgArr) + { + IntPtr msgs = new IntPtr((void*)pArray); + + var msgSet = new I2CRdwrIoctlData(msgs, 2); + + var msgSetPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(I2CRdwrIoctlData))); + Marshal.StructureToPtr(msgSet, msgSetPtr, true); + + Console.WriteLine($"Fd: {fd}"); + + err = MMALI2C.Ioctl(fd, I2C_RDWR, msgSetPtr); + + win32Err = Marshal.GetLastWin32Error(); + + Marshal.FreeHGlobal(msgSetPtr); + } + + var arr = new byte[n]; + + Marshal.Copy(ptr2, arr, 0, n); + + Marshal.FreeHGlobal(ptr1); + Marshal.FreeHGlobal(ptr2); + + Console.WriteLine($"Return value: {err}"); + + if (err != 2) + { + MMALLog.Logger.LogWarning($"Unable to read from I2C. Error {win32Err}."); + return null; + } + + return arr; + } + + private async Task SendRegs(int fd, SensorDef sensorDef, List sensorRegs) + { + for (var i = 0; i < sensorRegs.Count; i++) + { + if (sensorRegs[i].Reg == 0xFFFF) + { + var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(sensorRegs[i].Data)); + + if (MMALI2C.Ioctl(fd, I2C_SLAVE_FORCE, ptr) < 0) + { + Marshal.FreeHGlobal(ptr); + throw new MMALIOException($"Failed to set I2C address to {sensorRegs[i].Data}"); + } + + Marshal.FreeHGlobal(ptr); + } + else if (sensorRegs[i].Reg == 0xFFFE) + { + // Sleep...? + MMALLog.Logger.LogDebug($"Delaying for {sensorRegs[i].Data}ms."); + await Task.Delay(sensorRegs[i].Data); + } + else + { + if (sensorDef.I2CAddressing == 1) + { + byte[] msg; + + if (sensorDef.I2CDataSize == 2) + { + msg = new byte[3] + { + (byte)sensorRegs[i].Reg, + (byte)((sensorRegs[i].Data >> 8) & 0xFF), + (byte)(sensorRegs[i].Data & 0xFF) + }; + } + else + { + msg = new byte[2]; + + msg[0] = (byte)sensorRegs[i].Reg; + msg[1] = (byte)(sensorRegs[i].Data & 0xFF); + } + + var unmanagedArray = Marshal.AllocHGlobal(msg.Length); + + Marshal.Copy(msg, 0, unmanagedArray, msg.Length); + + var write = MMALI2C.Write(fd, unmanagedArray, msg.Length); + + Marshal.FreeHGlobal(unmanagedArray); + + if (write != msg.Length) + { + var errno = Marshal.GetLastWin32Error(); + + throw new MMALIOException($"Failed to write register index {i} ({sensorRegs[i].Reg} val {sensorRegs[i].Data}). Msg length: {msg.Length}. Written: {write}. Errno: {errno}"); + } + } + else + { + byte[] msg; + + if (sensorDef.I2CDataSize == 2) + { + msg = new byte[4] + { + (byte)(sensorRegs[i].Reg >> 8), + (byte)sensorRegs[i].Reg, + (byte)(sensorRegs[i].Data >> 8), + (byte)sensorRegs[i].Data + }; + } + else + { + msg = new byte[3] + { + (byte)(sensorRegs[i].Reg >> 8), + (byte)sensorRegs[i].Reg, + (byte)sensorRegs[i].Data + }; + } + + var unmanagedArray = Marshal.AllocHGlobal(msg.Length); + + Marshal.Copy(msg, 0, unmanagedArray, msg.Length); + + var write = MMALI2C.Write(fd, unmanagedArray, msg.Length); + + Marshal.FreeHGlobal(unmanagedArray); + + if (write != msg.Length) + { + var errno = Marshal.GetLastWin32Error(); + + throw new MMALIOException($"Failed to write register index {i}. Msg length: {msg.Length}. Written: {write}. Errno: {errno}"); + } + } + } + } + } + } +} diff --git a/src/MMALSharp/Native/MMALI2C.cs b/src/MMALSharp/Native/MMALI2C.cs new file mode 100644 index 00000000..99d2a6a2 --- /dev/null +++ b/src/MMALSharp/Native/MMALI2C.cs @@ -0,0 +1,61 @@ +using System; +using System.Runtime.InteropServices; + +namespace MMALSharp.Native +{ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +#pragma warning disable SA1132 // Each field should be declared on its own line + public class MMALI2C + { + [DllImport("libc.so.6", EntryPoint = "open", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] + public static extern int Open(string fileName, int mode); + + [DllImport("libc.so.6", EntryPoint = "ioctl", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] + public static extern int Ioctl(int fd, int request, IntPtr data); + + [DllImport("libc.so.6", EntryPoint = "read", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] + public static extern int Read(int handle, IntPtr data, int length); + + [DllImport("libc.so.6", EntryPoint = "write", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] + public static extern int Write(int handle, IntPtr data, int length); + + [DllImport("libc.so.6", EntryPoint = "close", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] + public static extern int Close(int handle); + + [StructLayout(LayoutKind.Sequential)] + public struct I2CMsg + { + private int _addr, _flags, _len; + private IntPtr _buf; + + public int Addr => _addr; + public int Flags => _flags; + public int Len => _len; + public IntPtr Buf => _buf; + + public I2CMsg(int addr, int flags, int len, IntPtr buf) + { + _addr = addr; + _flags = flags; + _len = len; + _buf = buf; + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct I2CRdwrIoctlData + { + private IntPtr _msgs; + private int _nMsgs; + + public IntPtr Msgs => _msgs; + public int NMsgs => _nMsgs; + + public I2CRdwrIoctlData(IntPtr msgs, int nMsgs) + { + _msgs = msgs; + _nMsgs = nMsgs; + } + } + } +} diff --git a/src/MMALSharp/Native/MMALUtil.cs b/src/MMALSharp/Native/MMALUtil.cs index fbed1b88..491cbfcc 100644 --- a/src/MMALSharp/Native/MMALUtil.cs +++ b/src/MMALSharp/Native/MMALUtil.cs @@ -3,6 +3,7 @@ // Licensed under the MIT License. Please see LICENSE.txt for License info. // +using System; using System.Runtime.InteropServices; namespace MMALSharp.Native @@ -145,6 +146,7 @@ public enum MMAL_STATUS_T [DllImport("libmmal.so", EntryPoint = "mmal_4cc_to_string", CallingConvention = CallingConvention.Cdecl)] public static extern unsafe string mmal_4cc_to_string([MarshalAs(UnmanagedType.LPTStr)] string buffer, ushort len, uint fourcc); + #pragma warning restore IDE1006 // Naming Styles }