fix: 跑通摄像头640x480配置
This commit is contained in:
parent
f253a33c83
commit
e25f08739a
|
@ -72,7 +72,7 @@ public class Image
|
|||
var b8 = (byte)((b5 * 255) / 31); // 5位扩展到8位
|
||||
|
||||
// 存储到 RGB24 数组
|
||||
var rgb24Index = i * 3;
|
||||
var rgb24Index = (i%2 == 0)?((i+1) * 3):((i-1) * 3);
|
||||
rgb24Data[rgb24Index] = r8; // R
|
||||
rgb24Data[rgb24Index + 1] = g8; // G
|
||||
rgb24Data[rgb24Index + 2] = b8; // B
|
||||
|
|
|
@ -9,7 +9,8 @@ static class CameraAddr
|
|||
|
||||
public const UInt32 STORE_ADDR = BASE + 0x12;
|
||||
public const UInt32 STORE_NUM = BASE + 0x13;
|
||||
public const UInt32 CAPTURE_ON = BASE + 0x14;
|
||||
public const UInt32 EXPECTED_VH = BASE + 0x14;
|
||||
public const UInt32 CAPTURE_ON = BASE + 0x15;
|
||||
}
|
||||
|
||||
class Camera
|
||||
|
@ -17,7 +18,7 @@ class Camera
|
|||
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
readonly int timeout = 2000;
|
||||
|
||||
readonly int taskID;
|
||||
readonly int port;
|
||||
readonly string address;
|
||||
private IPEndPoint ep;
|
||||
|
@ -25,27 +26,25 @@ class Camera
|
|||
|
||||
const uint CAM_I2C_ADDR = 0x3C;
|
||||
const Peripherals.I2cClient.I2cProtocol CAM_PROTO = Peripherals.I2cClient.I2cProtocol.SCCB;
|
||||
|
||||
const UInt16 ISP_INPUT_SIZE_X = 2624;
|
||||
const UInt16 ISP_INPUT_SIZE_Y = 1952;
|
||||
const UInt16 X_OFFSET = 16;
|
||||
const UInt16 Y_OFFSET = 4;
|
||||
const UInt16 X_OUTPUT_SIZE = 640;
|
||||
const UInt16 Y_OUTPUT_SIZE = 480;
|
||||
const UInt16 X_TOTAL_OUTPUT_SIZE = 2844;
|
||||
const UInt16 Y_TOTAL_OUTPUT_SIZE = 1968;
|
||||
const UInt16 PISYCAL_PIXEL_START_X = 336;
|
||||
const UInt16 PISYCAL_PIXEL_START_Y = 434;
|
||||
const UInt16 PISYCAL_PIXEL_END_X = PISYCAL_PIXEL_START_X + ISP_INPUT_SIZE_X - 1;
|
||||
const UInt16 PISYCAL_PIXEL_END_Y = PISYCAL_PIXEL_START_Y + ISP_INPUT_SIZE_Y - 1;
|
||||
const byte PLL_MUX = 105;
|
||||
|
||||
const UInt16 H_START = 0; //default: 0
|
||||
const UInt16 V_START = 0; //default: 0
|
||||
const UInt16 DVPHO = 640; //default: 2592 (0xA20)
|
||||
const UInt16 DVPVO = 480; //default: 1944 (0x798)
|
||||
const UInt16 H_END = H_START + 1500 - 1; //default: 2624-1 (0xA3F)
|
||||
const UInt16 V_END = V_START + 1300 - 1; //default: 1951-1 (0x79F)
|
||||
const UInt16 HTS = 1700; //default: 2844 (0xB1C)
|
||||
const UInt16 VTS = 1500; //default: 1968 (0x7B0)
|
||||
const UInt16 H_OFFSET = 16; //default: 16 (0x10)
|
||||
const UInt16 V_OFFSET = 4; //default: 4 (0x04)
|
||||
const byte PLL_MUX = 10;
|
||||
const UInt32 FrameAddr = 0x00;
|
||||
const UInt32 FrameLength = X_OUTPUT_SIZE * Y_OUTPUT_SIZE * 16 / 32;
|
||||
const UInt32 FrameLength = DVPHO * DVPVO * 16 / 32;
|
||||
|
||||
static byte[][] InitCmdData = new byte[][] {
|
||||
// Stop streaming
|
||||
new byte[] { 0x30, 0x08, 0x42 },
|
||||
new byte[] { 0x30, 0x08, 0x82 }, //82是复位
|
||||
// delay 5ms
|
||||
new byte[] { 0x30, 0x08, 0x42 }, //42是休眠
|
||||
new byte[] { 0x31, 0x03, 0x02 },
|
||||
new byte[] { 0x30, 0x17, 0xff },
|
||||
new byte[] { 0x30, 0x18, 0xff },
|
||||
|
@ -83,30 +82,30 @@ class Camera
|
|||
new byte[] { 0x3c, 0x04, 0x28 },
|
||||
new byte[] { 0x3c, 0x05, 0x98 },
|
||||
new byte[] { 0x3c, 0x06, 0x00 },
|
||||
new byte[] { 0x3c, 0x07, 0x07 },
|
||||
new byte[] { 0x3c, 0x07, 0x08 },
|
||||
new byte[] { 0x3c, 0x08, 0x00 },
|
||||
new byte[] { 0x3c, 0x09, 0x1c },
|
||||
new byte[] { 0x3c, 0x0a, 0x9c },
|
||||
new byte[] { 0x3c, 0x0b, 0x40 },
|
||||
// X_OFFSET/Y_OFFSET
|
||||
new byte[] { 0x38, 0x10, unchecked((byte)((X_OFFSET >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x11, unchecked((byte)(X_OFFSET & 0xFF)) },
|
||||
new byte[] { 0x38, 0x12, unchecked((byte)((Y_OFFSET >> 8) & 0xFF)) },
|
||||
// H_OFFSET/V_OFFSET
|
||||
new byte[] { 0x38, 0x10, unchecked((byte)((H_OFFSET >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x11, unchecked((byte)(H_OFFSET & 0xFF)) }, //0010
|
||||
new byte[] { 0x38, 0x12, unchecked((byte)((V_OFFSET >> 8) & 0xFF)) },
|
||||
new byte[] { 0x37, 0x08, 0x64 },
|
||||
new byte[] { 0x40, 0x01, 0x02 },
|
||||
new byte[] { 0x40, 0x05, 0x1a },
|
||||
new byte[] { 0x30, 0x00, 0x00 },
|
||||
new byte[] { 0x30, 0x04, 0xff },
|
||||
new byte[] { 0x43, 0x00, 0x00 }, // RAW: BGGR
|
||||
new byte[] { 0x50, 0x1f, 0x03 }, // ISP RAW DPC
|
||||
new byte[] { 0x43, 0x00, 0x6F }, // RGB565:first byte:{g[2:0],b[4:0]],second byte:{r[4:0],g[5:3]}
|
||||
new byte[] { 0x50, 0x1f, 0x01 }, // Format: ISP RGB
|
||||
new byte[] { 0x44, 0x0e, 0x00 },
|
||||
new byte[] { 0x50, 0x00, 0x06 },
|
||||
new byte[] { 0x3a, 0x0f, 0x78 },
|
||||
new byte[] { 0x3a, 0x10, 0x68 },
|
||||
new byte[] { 0x3a, 0x1b, 0x78 },
|
||||
new byte[] { 0x3a, 0x1e, 0x68 },
|
||||
new byte[] { 0x3a, 0x11, 0xD0 },
|
||||
new byte[] { 0x3a, 0x1f, 0x40 },
|
||||
new byte[] { 0x50, 0x00, 0xA7 }, //ISP控制
|
||||
new byte[] { 0x3a, 0x0f, 0x30 }, //AEC控制;stable range in high
|
||||
new byte[] { 0x3a, 0x10, 0x28 }, //AEC控制;stable range in low
|
||||
new byte[] { 0x3a, 0x1b, 0x30 }, //AEC控制;stable range out high
|
||||
new byte[] { 0x3a, 0x1e, 0x26 }, //AEC控制;stable range out low
|
||||
new byte[] { 0x3a, 0x11, 0x60 }, //AEC控制; fast zone high
|
||||
new byte[] { 0x3a, 0x1f, 0x14 }, //AEC控制; fast zone low
|
||||
// LENC
|
||||
new byte[] { 0x58, 0x00, 0x23 }, new byte[] { 0x58, 0x01, 0x14 }, new byte[] { 0x58, 0x02, 0x0f },
|
||||
new byte[] { 0x58, 0x03, 0x0f }, new byte[] { 0x58, 0x04, 0x12 }, new byte[] { 0x58, 0x05, 0x26 },
|
||||
|
@ -164,65 +163,66 @@ class Camera
|
|||
new byte[] { 0x53, 0x0a, 0x30 }, new byte[] { 0x53, 0x0b, 0x04 }, new byte[] { 0x53, 0x0c, 0x06 },
|
||||
new byte[] { 0x50, 0x25, 0x00 },
|
||||
// 系统时钟分频
|
||||
new byte[] { 0x30, 0x35, 0x21 }, // 30fps
|
||||
new byte[] { 0x30, 0x35, 0x11 }, // 30fps
|
||||
new byte[] { 0x30, 0x36, PLL_MUX }, // PLL倍频
|
||||
new byte[] { 0x3c, 0x07, 0x08 },
|
||||
// 时序控制
|
||||
new byte[] { 0x38, 0x20, 0x41 }, // vflip
|
||||
new byte[] { 0x38, 0x21, 0x00 }, // mirror
|
||||
new byte[] { 0x38, 0x14, 0x11 }, // timing X inc
|
||||
new byte[] { 0x38, 0x15, 0x11 }, // timing Y inc
|
||||
// PISYCAL_PIXEL_START_X/Y
|
||||
new byte[] { 0x38, 0x00, unchecked((byte)((PISYCAL_PIXEL_START_X >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x01, unchecked((byte)(PISYCAL_PIXEL_START_X & 0xFF)) },
|
||||
new byte[] { 0x38, 0x02, unchecked((byte)((PISYCAL_PIXEL_START_Y >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x03, unchecked((byte)(PISYCAL_PIXEL_START_Y & 0xFF)) },
|
||||
// PISYCAL_PIXEL_END_X/Y
|
||||
new byte[] { 0x38, 0x04, unchecked((byte)((PISYCAL_PIXEL_END_X >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x05, unchecked((byte)(PISYCAL_PIXEL_END_X & 0xFF)) },
|
||||
new byte[] { 0x38, 0x06, unchecked((byte)((PISYCAL_PIXEL_END_Y >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x07, unchecked((byte)(PISYCAL_PIXEL_END_Y & 0xFF)) },
|
||||
new byte[] { 0x38, 0x20, 0x46 }, // vflip
|
||||
new byte[] { 0x38, 0x21, 0x01 }, // mirror
|
||||
new byte[] { 0x38, 0x14, 0x31 }, // timing X inc
|
||||
new byte[] { 0x38, 0x15, 0x31 }, // timing Y inc
|
||||
// H_START/Y
|
||||
new byte[] { 0x38, 0x00, unchecked((byte)((H_START >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x01, unchecked((byte)(H_START & 0xFF)) },
|
||||
new byte[] { 0x38, 0x02, unchecked((byte)((V_START >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x03, unchecked((byte)(V_START & 0xFF)) },
|
||||
// H_END/Y
|
||||
new byte[] { 0x38, 0x04, unchecked((byte)((H_END >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x05, unchecked((byte)(H_END & 0xFF)) },
|
||||
new byte[] { 0x38, 0x06, unchecked((byte)((V_END >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x07, unchecked((byte)(V_END & 0xFF)) },
|
||||
// 输出像素个数
|
||||
new byte[] { 0x38, 0x08, unchecked((byte)((X_OUTPUT_SIZE >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x09, unchecked((byte)(X_OUTPUT_SIZE & 0xFF)) },
|
||||
new byte[] { 0x38, 0x0A, unchecked((byte)((Y_OUTPUT_SIZE >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x0B, unchecked((byte)(Y_OUTPUT_SIZE & 0xFF)) },
|
||||
new byte[] { 0x38, 0x08, unchecked((byte)((DVPHO >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x09, unchecked((byte)(DVPHO & 0xFF)) },
|
||||
new byte[] { 0x38, 0x0A, unchecked((byte)((DVPVO >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x0B, unchecked((byte)(DVPVO & 0xFF)) },
|
||||
// 总像素
|
||||
new byte[] { 0x38, 0x0C, unchecked((byte)((X_TOTAL_OUTPUT_SIZE >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x0D, unchecked((byte)(X_TOTAL_OUTPUT_SIZE & 0xFF)) },
|
||||
new byte[] { 0x38, 0x0E, unchecked((byte)((Y_TOTAL_OUTPUT_SIZE >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x0F, unchecked((byte)(Y_TOTAL_OUTPUT_SIZE & 0xFF)) },
|
||||
new byte[] { 0x38, 0x13, unchecked((byte)(Y_OFFSET & 0xFF)) }, // Timing Voffset
|
||||
new byte[] { 0x38, 0x0C, unchecked((byte)((HTS >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x0D, unchecked((byte)(HTS & 0xFF)) },
|
||||
new byte[] { 0x38, 0x0E, unchecked((byte)((VTS >> 8) & 0xFF)) },
|
||||
new byte[] { 0x38, 0x0F, unchecked((byte)(VTS & 0xFF)) },
|
||||
new byte[] { 0x38, 0x13, unchecked((byte)(V_OFFSET & 0xFF)) }, // Timing Voffset
|
||||
new byte[] { 0x36, 0x18, 0x00 },
|
||||
new byte[] { 0x36, 0x12, 0x29 },
|
||||
new byte[] { 0x37, 0x09, 0x52 },
|
||||
new byte[] { 0x37, 0x0c, 0x03 },
|
||||
new byte[] { 0x3a, 0x02, 0x17 },
|
||||
new byte[] { 0x3a, 0x03, 0x10 },
|
||||
new byte[] { 0x3a, 0x14, 0x17 },
|
||||
new byte[] { 0x3a, 0x15, 0x10 },
|
||||
new byte[] { 0x40, 0x04, 0x02 },
|
||||
new byte[] { 0x47, 0x13, 0x00 },
|
||||
new byte[] { 0x44, 0x07, 0x04 },
|
||||
new byte[] { 0x3a, 0x02, 0x17 }, //60Hz max exposure
|
||||
new byte[] { 0x3a, 0x03, 0x10 }, //60Hz max exposure
|
||||
new byte[] { 0x3a, 0x14, 0x17 }, //50Hz max exposure
|
||||
new byte[] { 0x3a, 0x15, 0x10 }, //50Hz max exposure
|
||||
new byte[] { 0x40, 0x04, 0x02 }, //BLC(背光) 2 lines
|
||||
new byte[] { 0x47, 0x13, 0x03 }, //JPEG mode 3
|
||||
new byte[] { 0x44, 0x07, 0x04 }, //量化标度
|
||||
new byte[] { 0x46, 0x0c, 0x20 },
|
||||
new byte[] { 0x48, 0x37, 0x22 },
|
||||
new byte[] { 0x38, 0x24, 0x02 },
|
||||
new byte[] { 0x50, 0x01, 0x80 }, // 关闭缩放
|
||||
new byte[] { 0x3b, 0x07, 0x0a },
|
||||
new byte[] { 0x48, 0x37, 0x22 }, //DVP CLK divider
|
||||
new byte[] { 0x38, 0x24, 0x02 }, //DVP CLK divider
|
||||
new byte[] { 0x50, 0x01, 0xA3 }, //ISP 控制
|
||||
new byte[] { 0x3b, 0x07, 0x0a }, //帧曝光模式
|
||||
// 彩条测试使能
|
||||
new byte[] { 0x50, 0x3d, 0x00 },
|
||||
new byte[] { 0x47, 0x41, 0x00 },
|
||||
// 闪光灯禁用
|
||||
new byte[] { 0x30, 0x16, 0x00 },
|
||||
new byte[] { 0x30, 0x1c, 0x00 },
|
||||
new byte[] { 0x30, 0x19, 0x00 },
|
||||
new byte[] { 0x30, 0x31, 0x08 },
|
||||
new byte[] { 0x30, 0x2c, 0xC2 },
|
||||
new byte[] { 0x46, 0x00, 0xA0 },
|
||||
new byte[] { 0x30, 0x16, 0x02 },
|
||||
new byte[] { 0x30, 0x1c, 0x02 },
|
||||
new byte[] { 0x30, 0x19, 0x02 }, //开启闪光灯
|
||||
new byte[] { 0x30, 0x19, 0x00 }, //关闭闪光灯
|
||||
// new byte[] { 0x30, 0x2c, 0xC2 }, //控制驱动能力的
|
||||
// new byte[] { 0x46, 0x00, 0xA0 },
|
||||
// for subsample=OFF
|
||||
new byte[] { 0x36, 0x18, 0x04 },
|
||||
new byte[] { 0x36, 0x12, 0x2b },
|
||||
new byte[] { 0x37, 0x09, 0x12 },
|
||||
new byte[] { 0x37, 0x0c, 0x00 },
|
||||
// new byte[] { 0x36, 0x18, 0x04 },
|
||||
// new byte[] { 0x36, 0x12, 0x2b },
|
||||
// new byte[] { 0x37, 0x09, 0x12 },
|
||||
// new byte[] { 0x37, 0x0c, 0x00 },
|
||||
// Start streaming
|
||||
new byte[] { 0x30, 0x08, 0x02 }
|
||||
};
|
||||
|
@ -247,7 +247,7 @@ class Camera
|
|||
public async ValueTask<Result<bool>> Init()
|
||||
{
|
||||
{
|
||||
var ret = await UDPClientPool.WriteAddr(this.ep, 2, CameraAddr.STORE_ADDR, FrameAddr);
|
||||
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.STORE_ADDR, FrameAddr);
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Failed to write STORE_ADDR to camera at {this.address}:{this.port}, error: {ret.Error}");
|
||||
|
@ -261,7 +261,7 @@ class Camera
|
|||
}
|
||||
|
||||
{
|
||||
var ret = await UDPClientPool.WriteAddr(this.ep, 2, CameraAddr.STORE_NUM, FrameLength);
|
||||
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.STORE_NUM, FrameLength);
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Failed to write STORE_NUM to camera at {this.address}:{this.port}, error: {ret.Error}");
|
||||
|
@ -274,7 +274,21 @@ class Camera
|
|||
}
|
||||
}
|
||||
|
||||
var i2c = new Peripherals.I2cClient.I2c(this.address, this.port, this.timeout);
|
||||
{
|
||||
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.EXPECTED_VH, (DVPVO)<<16 | (DVPHO*2));
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Failed to write EXPECTED_VH to camera at {this.address}:{this.port}, error: {ret.Error}");
|
||||
return new(ret.Error);
|
||||
}
|
||||
if (!ret.Value)
|
||||
{
|
||||
logger.Error($"EXPECTED_VH write returned false for camera at {this.address}:{this.port}");
|
||||
return new(new Exception($"EXPECTED_VH write returned false for camera at {this.address}:{this.port}"));
|
||||
}
|
||||
}
|
||||
|
||||
var i2c = new Peripherals.I2cClient.I2c(this.address, this.port, this.taskID, this.timeout);
|
||||
|
||||
foreach (var cmd in InitCmdData)
|
||||
{
|
||||
|
@ -291,6 +305,12 @@ class Camera
|
|||
logger.Error($"I2C write 0x{CAM_I2C_ADDR.ToString("X")} returned false: {BitConverter.ToString(cmd)}");
|
||||
return false;
|
||||
}
|
||||
if (cmd[0] == 0x30 && cmd[1] == 0x08 && cmd[2] == 0x82)
|
||||
{
|
||||
// 复位命令,等待5MS
|
||||
await Task.Delay(5);
|
||||
}
|
||||
else await Task.Delay(5); // 其他命令延时1ms
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -298,7 +318,7 @@ class Camera
|
|||
|
||||
public async ValueTask<Result<bool>> EnableCamera(bool isEnable)
|
||||
{
|
||||
var ret = await UDPClientPool.WriteAddr(this.ep, 2, CameraAddr.CAPTURE_ON, Convert.ToUInt32(isEnable));
|
||||
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAPTURE_ON, Convert.ToUInt32(isEnable));
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Failed to write CAPTURE_ON to camera at {this.address}:{this.port}, error: {ret.Error}");
|
||||
|
@ -319,14 +339,14 @@ class Camera
|
|||
public async ValueTask<Result<byte[]>> ReadFrame()
|
||||
{
|
||||
// 清除UDP服务器接收缓冲区
|
||||
await MsgBus.UDPServer.ClearUDPData(this.address, 2);
|
||||
await MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
|
||||
|
||||
logger.Trace($"Clear up udp server {this.address} receive data");
|
||||
|
||||
// 使用UDPClientPool读取图像帧数据
|
||||
var result = await UDPClientPool.ReadAddr4Bytes(
|
||||
this.ep,
|
||||
2, // taskID
|
||||
this.taskID, // taskID
|
||||
FrameAddr,
|
||||
((int)FrameLength),
|
||||
this.timeout);
|
||||
|
|
|
@ -69,7 +69,7 @@ public class I2c
|
|||
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
readonly int timeout = 2000;
|
||||
|
||||
readonly int taskID;
|
||||
readonly int port;
|
||||
readonly string address;
|
||||
private IPEndPoint ep;
|
||||
|
@ -79,13 +79,15 @@ public class I2c
|
|||
/// </summary>
|
||||
/// <param name="address">[TODO:parameter]</param>
|
||||
/// <param name="port">[TODO:parameter]</param>
|
||||
/// <param name="taskID">[TODO:parameter]</param>
|
||||
/// <param name="timeout">[TODO:parameter]</param>
|
||||
/// <returns>[TODO:return]</returns>
|
||||
public I2c(string address, int port, int timeout = 2000)
|
||||
public I2c(string address, int port, int taskID,int timeout = 2000)
|
||||
{
|
||||
if (timeout < 0)
|
||||
throw new ArgumentException("Timeout couldn't be negative", nameof(timeout));
|
||||
this.address = address;
|
||||
this.taskID = taskID;
|
||||
this.port = port;
|
||||
this.ep = new IPEndPoint(IPAddress.Parse(address), port);
|
||||
this.timeout = timeout;
|
||||
|
@ -107,7 +109,7 @@ public class I2c
|
|||
}
|
||||
|
||||
// 清除UDP服务器接收缓冲区
|
||||
await MsgBus.UDPServer.ClearUDPData(this.address, 2);
|
||||
await MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
|
||||
|
||||
logger.Trace($"Clear up udp server {this.address} receive data");
|
||||
|
||||
|
@ -123,7 +125,7 @@ public class I2c
|
|||
i2cData[i++] = item;
|
||||
}
|
||||
|
||||
var ret = await UDPClientPool.WriteAddr(this.ep, 2, I2cAddr.Write, i2cData);
|
||||
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, I2cAddr.Write, i2cData);
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Failed to write data to I2C FIFO: {ret.Error}");
|
||||
|
@ -139,7 +141,7 @@ public class I2c
|
|||
|
||||
// 配置本次传输数据量
|
||||
{
|
||||
var ret = await UDPClientPool.WriteAddr(this.ep, 2, I2cAddr.TranConfig, ((uint)(data.Length - 1)));
|
||||
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, I2cAddr.TranConfig, ((uint)(data.Length - 1)));
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Failed to configure transfer length: {ret.Error}");
|
||||
|
@ -156,7 +158,7 @@ public class I2c
|
|||
// 配置I2C地址、协议及启动传输
|
||||
{
|
||||
var ret = await UDPClientPool.WriteAddr(
|
||||
this.ep, 2, I2cAddr.BaseConfig, (devAddr) | (((uint)proto) << 16) | (1 << 24));
|
||||
this.ep, this.taskID, I2cAddr.BaseConfig, (devAddr) | (((uint)proto) << 16) | (1 << 24));
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Failed to configure I2C address/protocol/start: {ret.Error}");
|
||||
|
@ -172,7 +174,7 @@ public class I2c
|
|||
|
||||
// 等待I2C命令完成
|
||||
{
|
||||
var ret = await UDPClientPool.ReadAddrWithWait(this.ep, 2, I2cAddr.Flag, 0x0000_0001, 0xFFFF_FFFF);
|
||||
var ret = await UDPClientPool.ReadAddrWithWait(this.ep, this.taskID, I2cAddr.Flag, 0x0000_0001, 0xFFFF_FFFF);
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Failed to wait for I2C command completion: {ret.Error}");
|
||||
|
@ -205,13 +207,13 @@ public class I2c
|
|||
}
|
||||
|
||||
// 清除UDP服务器接收缓冲区
|
||||
await MsgBus.UDPServer.ClearUDPData(this.address, 2);
|
||||
await MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
|
||||
|
||||
logger.Trace($"Clear up udp server {this.address} receive data");
|
||||
|
||||
// 配置本次传输数据量
|
||||
{
|
||||
var ret = await UDPClientPool.WriteAddr(this.ep, 2, I2cAddr.TranConfig, ((uint)(length - 1)));
|
||||
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, I2cAddr.TranConfig, ((uint)(length - 1)));
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Failed to configure transfer length: {ret.Error}");
|
||||
|
@ -228,7 +230,7 @@ public class I2c
|
|||
// 配置I2C地址、协议及启动传输(读操作)
|
||||
{
|
||||
var ret = await UDPClientPool.WriteAddr(
|
||||
this.ep, 2, I2cAddr.BaseConfig, (devAddr) | (1 << 8) | (((uint)proto) << 16) | (1 << 24));
|
||||
this.ep, this.taskID, I2cAddr.BaseConfig, (devAddr) | (1 << 8) | (((uint)proto) << 16) | (1 << 24));
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Failed to configure I2C address/protocol/start: {ret.Error}");
|
||||
|
@ -244,7 +246,7 @@ public class I2c
|
|||
|
||||
// 等待I2C命令完成
|
||||
{
|
||||
var ret = await UDPClientPool.ReadAddrWithWait(this.ep, 2, I2cAddr.Flag, 0x0000_0001, 0xFFFF_FFFF);
|
||||
var ret = await UDPClientPool.ReadAddrWithWait(this.ep, this.taskID, I2cAddr.Flag, 0x0000_0001, 0xFFFF_FFFF);
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Failed to wait for I2C command completion: {ret.Error}");
|
||||
|
@ -260,7 +262,7 @@ public class I2c
|
|||
|
||||
// 读取数据
|
||||
{
|
||||
var ret = await UDPClientPool.ReadAddr(this.ep, 2, I2cAddr.Read, length);
|
||||
var ret = await UDPClientPool.ReadAddr(this.ep, this.taskID, I2cAddr.Read, length);
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Failed to read data from I2C FIFO: {ret.Error}");
|
||||
|
|
|
@ -627,7 +627,7 @@ public class HttpVideoStreamService : BackgroundService
|
|||
}
|
||||
|
||||
// 将 RGB565 转换为 RGB24
|
||||
var rgb24Result = Common.Image.ConvertRGB565ToRGB24(rgb565Data, _frameWidth, _frameHeight);
|
||||
var rgb24Result = Common.Image.ConvertRGB565ToRGB24(rgb565Data, _frameWidth, _frameHeight, isLittleEndian: false);
|
||||
if (!rgb24Result.IsSuccessful)
|
||||
{
|
||||
logger.Error("RGB565转RGB24失败: {Error}", rgb24Result.Error);
|
||||
|
|
Loading…
Reference in New Issue