feat: 完善camera复位逻辑
This commit is contained in:
parent
e8a16fd446
commit
d901a440a7
|
@ -3,7 +3,7 @@
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class MsgBus
|
public static class MsgBus
|
||||||
{
|
{
|
||||||
private static readonly UDPServer udpServer = new UDPServer(1234, 11);
|
private static readonly UDPServer udpServer = new UDPServer(1234, 12);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取UDP服务器
|
/// 获取UDP服务器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using DotNext;
|
using DotNext;
|
||||||
|
using Peripherals.PowerClient;
|
||||||
|
|
||||||
namespace Peripherals.CameraClient;
|
namespace Peripherals.CameraClient;
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ class Camera
|
||||||
|
|
||||||
const uint CAM_I2C_ADDR = 0x3C;
|
const uint CAM_I2C_ADDR = 0x3C;
|
||||||
const Peripherals.I2cClient.I2cProtocol CAM_PROTO = Peripherals.I2cClient.I2cProtocol.SCCB;
|
const Peripherals.I2cClient.I2cProtocol CAM_PROTO = Peripherals.I2cClient.I2cProtocol.SCCB;
|
||||||
const byte PLL_MUX = 60;
|
const byte PLL_MUX = 105;
|
||||||
const UInt32 FrameAddr = 0x00;
|
const UInt32 FrameAddr = 0x00;
|
||||||
|
|
||||||
// 动态分辨率参数
|
// 动态分辨率参数
|
||||||
|
@ -54,6 +55,8 @@ class Camera
|
||||||
|
|
||||||
public async ValueTask<Result<bool>> Init()
|
public async ValueTask<Result<bool>> Init()
|
||||||
{
|
{
|
||||||
|
await PowerHardwareCamera(true);
|
||||||
|
await SleepHardwareCamera(false);
|
||||||
// 步骤1: 复位
|
// 步骤1: 复位
|
||||||
var resetResult = await Reset();
|
var resetResult = await Reset();
|
||||||
if (!resetResult.IsSuccessful) return resetResult;
|
if (!resetResult.IsSuccessful) return resetResult;
|
||||||
|
@ -139,14 +142,16 @@ class Camera
|
||||||
var resolutionResult = await ConfigureResolution1280x720();
|
var resolutionResult = await ConfigureResolution1280x720();
|
||||||
if (!resolutionResult.IsSuccessful) return resolutionResult;
|
if (!resolutionResult.IsSuccessful) return resolutionResult;
|
||||||
|
|
||||||
// 步骤22: 开始流
|
// // 步骤22: 开始流
|
||||||
var startResult = await StartStreaming();
|
var startResult = await StartStreaming();
|
||||||
if (!startResult.IsSuccessful) return startResult;
|
if (!startResult.IsSuccessful) return startResult;
|
||||||
|
// var resetResult2 = await Reset();
|
||||||
|
// if (!resetResult2.IsSuccessful) return resetResult2;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ValueTask<Result<bool>> EnableCamera(bool isEnable)
|
public async ValueTask<Result<bool>> EnableHardwareTrans(bool isEnable)
|
||||||
{
|
{
|
||||||
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAPTURE_ON, Convert.ToUInt32(isEnable));
|
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAPTURE_ON, Convert.ToUInt32(isEnable));
|
||||||
if (!ret.IsSuccessful)
|
if (!ret.IsSuccessful)
|
||||||
|
@ -162,7 +167,7 @@ class Camera
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ValueTask<Result<bool>> EnableCameraHardware(bool isEnable)
|
public async ValueTask<Result<bool>> PowerHardwareCamera(bool isEnable)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAMERA_POWER, (isEnable ? 0x00000001u : 0x00000000u));
|
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAMERA_POWER, (isEnable ? 0x00000001u : 0x00000000u));
|
||||||
|
@ -180,7 +185,7 @@ class Camera
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ValueTask<Result<bool>> SleepCameraHardware(bool isEnable)
|
public async ValueTask<Result<bool>> SleepHardwareCamera(bool isEnable)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAMERA_POWER, (isEnable ? 0x00000101u : 0x00000001u));
|
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAMERA_POWER, (isEnable ? 0x00000101u : 0x00000001u));
|
||||||
|
@ -323,7 +328,7 @@ class Camera
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await Task.Delay(3); // 其他命令延时3ms
|
await Task.Delay(5); // 其他命令延时3ms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -404,11 +409,6 @@ class Camera
|
||||||
// 2. 配置I2C寄存器
|
// 2. 配置I2C寄存器
|
||||||
var resolutionRegisters = new UInt16[][]
|
var resolutionRegisters = new UInt16[][]
|
||||||
{
|
{
|
||||||
// H_OFFSET/V_OFFSET
|
|
||||||
[0x3810, unchecked((byte)((hOffset >> 8) & 0xFF))],
|
|
||||||
[0x3811, unchecked((byte)(hOffset & 0xFF))],
|
|
||||||
[0x3812, unchecked((byte)((vOffset >> 8) & 0xFF))],
|
|
||||||
|
|
||||||
// H_START/V_START
|
// H_START/V_START
|
||||||
[0x3800, unchecked((byte)((hStart >> 8) & 0xFF))],
|
[0x3800, unchecked((byte)((hStart >> 8) & 0xFF))],
|
||||||
[0x3801, unchecked((byte)(hStart & 0xFF))],
|
[0x3801, unchecked((byte)(hStart & 0xFF))],
|
||||||
|
@ -433,6 +433,10 @@ class Camera
|
||||||
[0x380E, unchecked((byte)((vts >> 8) & 0xFF))],
|
[0x380E, unchecked((byte)((vts >> 8) & 0xFF))],
|
||||||
[0x380F, unchecked((byte)(vts & 0xFF))],
|
[0x380F, unchecked((byte)(vts & 0xFF))],
|
||||||
|
|
||||||
|
// H_OFFSET/V_OFFSET
|
||||||
|
[0x3810, unchecked((byte)((hOffset >> 8) & 0xFF))],
|
||||||
|
[0x3811, unchecked((byte)(hOffset & 0xFF))],
|
||||||
|
[0x3812, unchecked((byte)((vOffset >> 8) & 0xFF))],
|
||||||
// Timing Voffset
|
// Timing Voffset
|
||||||
[0x3813, unchecked((byte)(vOffset & 0xFF))]
|
[0x3813, unchecked((byte)(vOffset & 0xFF))]
|
||||||
};
|
};
|
||||||
|
@ -561,10 +565,11 @@ class Camera
|
||||||
{
|
{
|
||||||
var resetRegisters = new UInt16[][]
|
var resetRegisters = new UInt16[][]
|
||||||
{
|
{
|
||||||
[0x30, 0x08, 0x82] // 复位命令
|
[0x3103, 0x11],// system clock from pad, bit[1]
|
||||||
|
[0x3008, 0x82] // 复位命令
|
||||||
};
|
};
|
||||||
|
|
||||||
return await ConfigureRegisters(resetRegisters, customDelayMs: 5); // 复位后等待5ms
|
return await ConfigureRegisters(resetRegisters, customDelayMs: 50); // 复位后等待5ms
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -589,7 +594,7 @@ class Camera
|
||||||
{
|
{
|
||||||
var basicRegisters = new UInt16[][]
|
var basicRegisters = new UInt16[][]
|
||||||
{
|
{
|
||||||
[0x3103, 0x02],
|
[0x3103, 0x02], // system clock from pad, bit[1]
|
||||||
[0x3017, 0xff],
|
[0x3017, 0xff],
|
||||||
[0x3018, 0xff],
|
[0x3018, 0xff],
|
||||||
[0x3037, 0x13],
|
[0x3037, 0x13],
|
||||||
|
@ -646,9 +651,7 @@ class Camera
|
||||||
{
|
{
|
||||||
[0x3905, 0x02],
|
[0x3905, 0x02],
|
||||||
[0x3906, 0x10],
|
[0x3906, 0x10],
|
||||||
[0x3901, 0x0a],
|
[0x3901, 0x0a]
|
||||||
[0x3035, 0x11], // 30fps
|
|
||||||
[0x3036, PLL_MUX] // PLL倍频
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return await ConfigureRegisters(clockRegisters);
|
return await ConfigureRegisters(clockRegisters);
|
||||||
|
@ -706,7 +709,6 @@ class Camera
|
||||||
[0x3c04, 0x28],
|
[0x3c04, 0x28],
|
||||||
[0x3c05, 0x98],
|
[0x3c05, 0x98],
|
||||||
[0x3c06, 0x00],
|
[0x3c06, 0x00],
|
||||||
[0x3c07, 0x08],
|
|
||||||
[0x3c08, 0x00],
|
[0x3c08, 0x00],
|
||||||
[0x3c09, 0x1c],
|
[0x3c09, 0x1c],
|
||||||
[0x3c0a, 0x9c],
|
[0x3c0a, 0x9c],
|
||||||
|
@ -766,10 +768,6 @@ class Camera
|
||||||
[0x3a1e, 0x26], // AEC控制;stable range out low
|
[0x3a1e, 0x26], // AEC控制;stable range out low
|
||||||
[0x3a11, 0x60], // AEC控制; fast zone high
|
[0x3a11, 0x60], // AEC控制; fast zone high
|
||||||
[0x3a1f, 0x14], // AEC控制; fast zone low
|
[0x3a1f, 0x14], // AEC控制; fast zone low
|
||||||
[0x3a02, 0x17], // 60Hz max exposure
|
|
||||||
[0x3a03, 0x10], // 60Hz max exposure
|
|
||||||
[0x3a14, 0x17], // 50Hz max exposure
|
|
||||||
[0x3a15, 0x10], // 50Hz max exposure
|
|
||||||
[0x3b07, 0x0a] // 帧曝光模式
|
[0x3b07, 0x0a] // 帧曝光模式
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -913,14 +911,13 @@ class Camera
|
||||||
{
|
{
|
||||||
var timingRegisters = new UInt16[][]
|
var timingRegisters = new UInt16[][]
|
||||||
{
|
{
|
||||||
[0x3820, 0x46], // vflip
|
[0x3035, 0x11], // 60fps
|
||||||
[0x3821, 0x01], // mirror
|
[0x3036, PLL_MUX],// PLL倍频
|
||||||
[0x3814, 0x31], // timing X inc
|
[0x3c07, 0x08],
|
||||||
[0x3815, 0x31], // timing Y inc
|
[0x3820, 0x41], // vflip
|
||||||
[0x3618, 0x00],
|
[0x3821, 0x00], // mirror
|
||||||
[0x3612, 0x29],
|
[0x3814, 0x11], // timing X inc
|
||||||
[0x3709, 0x52],
|
[0x3815, 0x11] // timing Y inc
|
||||||
[0x370c, 0x03]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return await ConfigureRegisters(timingRegisters);
|
return await ConfigureRegisters(timingRegisters);
|
||||||
|
@ -934,14 +931,22 @@ class Camera
|
||||||
{
|
{
|
||||||
var testRegisters = new UInt16[][]
|
var testRegisters = new UInt16[][]
|
||||||
{
|
{
|
||||||
|
[0x3618, 0x00],
|
||||||
|
[0x3612, 0x29],
|
||||||
|
[0x3709, 0x52],
|
||||||
|
[0x370c, 0x03],
|
||||||
[0x4004, 0x02], // BLC(背光) 2 lines
|
[0x4004, 0x02], // BLC(背光) 2 lines
|
||||||
[0x4713, 0x03], // JPEG mode 3
|
[0x4713, 0x03], // JPEG mode 3
|
||||||
[0x4407, 0x04], // 量化标度
|
[0x4407, 0x04], // 量化标度
|
||||||
[0x460c, 0x20],
|
[0x460c, 0x20],
|
||||||
|
[0x3a02, 0x17], // 60Hz max exposure
|
||||||
|
[0x3a03, 0x10], // 60Hz max exposure
|
||||||
|
[0x3a14, 0x17], // 50Hz max exposure
|
||||||
|
[0x3a15, 0x10], // 50Hz max exposure
|
||||||
[0x4837, 0x22], // DVP CLK divider
|
[0x4837, 0x22], // DVP CLK divider
|
||||||
[0x3824, 0x02], // DVP CLK divider
|
[0x3824, 0x02], // DVP CLK divider
|
||||||
// 彩条测试禁用
|
// 彩条测试禁用
|
||||||
[0x503d, 0x00],
|
[0x503d, 0x80],
|
||||||
[0x4741, 0x00],
|
[0x4741, 0x00],
|
||||||
// 闪光灯配置
|
// 闪光灯配置
|
||||||
[0x3016, 0x02],
|
[0x3016, 0x02],
|
||||||
|
|
|
@ -156,8 +156,7 @@ public class HttpVideoStreamService : BackgroundService
|
||||||
throw new Exception("Please config camera first");
|
throw new Exception("Please config camera first");
|
||||||
}
|
}
|
||||||
_cameraEnable = isEnabled;
|
_cameraEnable = isEnabled;
|
||||||
await _camera.EnableCamera(_cameraEnable);
|
await _camera.EnableHardwareTrans(_cameraEnable);
|
||||||
await _camera.SleepCameraHardware(!_cameraEnable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Reference in New Issue