Hello. I am having communication problems on I2C bus while serializer configuration and camera ISP configuration. My setup is:
- vision sdk 3.0.7
- late attach mode
- pipeline on M4 core
- custom TDA2PX based board
- UB960 connected to TDA2PX via CSI2
- 4 cameras connected to UB960 via FPD-Link III (camera itself is UB953 + ISP + Sensor)
When I am trying to detect UB953 by reading it's ID over i2c -- I get errors like this:
[HOST] [IPU2 ] 2.491307 s: src/bsp_deviceI2c.c @ Line 346: [HOST] [IPU2 ] 2.491398 s: I2C4: DEV 0x41: RD 0x50 ... ERROR !!! [HOST] [IPU2 ] 2.491490 s: src/bsp_deviceI2c.c @ Line 412: [HOST] [IPU2 ] 2.491581 s: I2C4: Error timeout 0 ms!!! [HOST] [IPU2 ] 2.491642 s: i2c_read Failed
I hook up logic analyzer between TDA2PX and UB960 and I see NACK from UB953. Next, after 2-3 attempts UB953 starts to respond on I2C requests.
Same thing when I am trying to configure ISP: sometimes I have error like above and observe NACK from ISP.
This errors is not stable - on next power cycle there may be no errors at all, or may be such errors again.
UB960 config:
device->write(device, 0x01, 0x02);
Task_sleep(100);
device->write(device, 0x1f, 0x00); /*1.6gbps, 200mhz, external clock*/
device->write(device, 0xB0, 0x1E); /*select csi-2 reserved registers, auto increment on */
device->write(device, 0xB1, 0x16);
device->write(device, 0xB2, 0x00); /* write 0x0 at 0x16 */
device->write(device, 0xB2, 0x00); /* write 0x0 at 0x17 */
device->write(device, 0xB2, 0x00); /* write 0x0 at 0x18 */
device->write(device, 0xB2, 0x00); /* write 0x0 at 0x19 */
device->write(device, 0xB0, 0x1C); /*select csi-2 reserved registers, auto increment off */
device->write(device, 0xB1, 0x15);
device->write(device, 0xB2, 0x0A); /* this transactions has no effect */
Task_sleep(10);
device->write(device, 0xB2, 0x00);
Task_sleep(10);
device->write(device, 0x0D, 0xB9); /* force I/O to 3V3 (0x90 in softeq, but why?) */
device->write(device, 0x32, 0x01); /* Enable TX port 0*/
device->write(device, 0x20, 0x00); /* Forwarding and using CSIport 0 */
device->write(device, 0x21, 0x03); /* Turn on round robin for both ports*/
device->write(device, 0x19, 0x01); /* frame sync high time 1 */
device->write(device, 0x1A, 0x15); /* frame sync high time 0*/
device->write(device, 0x1B, 0x09); /* frame sync low time 1*/
device->write(device, 0x1C, 0xC3); /* frame sync low time 0 */
device->write(device, 0x18, 0x01); /* Start FSIN. Delay to allow it to stabilize */
device->write(device, 0x33, 0x02);
device->write(device, 0x10, 0x81); /* BC_GPIO0 RX0 */
device->write(device, 0x11, 0x85); /* BC_GPIO1 RX1 */
device->write(device, 0x12, 0x89); /* BC_GPIO0 RX2 */
device->write(device, 0x13, 0x8D); /* BC_GPIO1 RX3 */
device->write(device, 0x14, 0x0B); /* SYNC_CAMERA0 */
device->write(device, 0x15, 0x00); /* BC_GPIO5 */
device->write(device, 0x16, 0x00); /* BC_GPIO6 */
device->write(device, 0x17, 0x00); /* BC_GPIO7 */
channel setup:
Int32 status = BSP_SOK;
UInt8 chan_sel4C;
UInt8 chan_selB0;
UInt8 reg_val = 0x0;
chan_sel4C = ((1 * chan->channel_idx) << 4 | 1 << chan->channel_idx) & 0xFF;
chan_selB0 = (4 * ( chan->channel_idx + 1)) & 0xFF;
Vps_printf("%s: [%d:%d] chan_sel4C 0x%X, chan_selB0 0x%X...\n",
__func__, des->csi_port_idx, chan->channel_idx, chan_sel4C, chan_selB0);
status |= des->write(des, 0x4C, chan_sel4C);
if (UB913 == chan->cam.serializer.id)
status |= des->write(des, 0x58, 0x58); /*Enable Back channel, set to : 2.5 Mbps*/
else {
status |= des->write(des, 0x58, 0x5E); /*Enable Back channel, set to 50Mbs*/
}
/* select channel to configure */
status |= des->write(des, 0x4C, chan_sel4C);
status |= des->write(des, 0xB0, chan_selB0);
/* set I2C alias */
status |= des->write(des, 0x5C, (chan->cam.serializer.alias << 1)); /* serializer alias */
Task_sleep(10);
/* Replica R Settings */
status |= des->write(des, 0xB1, 0x03);
status |= des->write(des, 0xB2, 0x25);
status |= des->write(des, 0xB1, 0x13);
status |= des->write(des, 0xB2, 0x25);
/* TRF control settings */
status |= des->write(des, 0xB1, 0x04);
status |= des->write(des, 0xB2, 0x30);
status |= des->write(des, 0xB1, 0x14);
status |= des->write(des, 0xB2, 0x30);
/* VCO Initial Voltage Settings & RS */
status |= des->write(des, 0xB1, 0x06);
status |= des->write(des, 0xB2, 0x40);
/* AEQ Settings */
status |= des->write(des, 0x42, 0x71); /*Unknown*/
status |= des->write(des, 0x41, 0xF0); /*Unknown*/
status |= des->write(des, 0xD5, 0xF3);
Task_sleep(10);
if (UB953 == chan->cam.serializer.id) {
status |= des->write(des, 0x6D, 0x7C); /*CSI Mode*/
status |= des->write(des, 0x72, (0x55*(UInt8)(chan->channel_idx))); /*VC Map - All to RX0->VC=0 RX1->VC=1 ...*/
status |= des->write(des, 0x7C, 0x24); /*Line Valid active high, Frame Valid active high*/
Task_sleep(10);
} else if (UB913 == chan->cam.serializer.id){
if (SYSTEM_CSI2_RAW8 == chan->csiFormat
|| SYSTEM_CSI2_YUV420_8B == chan->csiFormat
|| SYSTEM_CSI2_YUV420_8B_CHROMA_SHIFT == chan->csiFormat
|| SYSTEM_CSI2_YUV422_8B == chan->csiFormat) {
status |= des->write(des, 0x7C, 0x81); /* 8-bit processing using upper 10 bits, FrameValid is low */
status |= des->write(des, 0x6D, 0x7F); /* RAW10 mode */
} else if (SYSTEM_CSI2_RAW10 == chan->csiFormat
|| SYSTEM_CSI2_YUV420_10B == chan->csiFormat
|| SYSTEM_CSI2_YUV420_10B_CHROMA_SHIFT == chan->csiFormat
|| SYSTEM_CSI2_YUV422_10B == chan->csiFormat) {
status |= des->write(des, 0x7C, 0x01); /* 8-bit processing using upper 8 bits, FrameValid is low */
status |= des->write(des, 0x6D, 0x7F); /* RAW10 mode */
}else { //RAW12
status |= des->write(des, 0x7C, 0x01); /* 8-bit processing using upper 8 bits, FrameValid is low */
status |= des->write(des, 0x6D, 0x7E); /* RAW12 High Frequency mode */
}
status |= des->write(des, 0x70, (UInt8)(chan->channel_idx << 6) | (UInt8)chan->csiFormat); /* RAW10 setting*/
status |= des->write(des, 0x71, (UInt8)(chan->channel_idx << 6) | (UInt8)chan->csiFormat); /* RAW12 setting*/
} else {
Vps_printf("%s Unknown Serializer ID=0x%02X\n",__func__,chan->cam.serializer.id);
UTILS_assert(FALSE); /* Unknown Serializer ID */
}
UInt32 counter = 1000;
while (counter) {
status |= des->write(des, 0x4C, chan->channel_idx << 4);
status |= des->read(des, 0x5B, ®_val);
if (reg_val)
break;
Task_sleep(10);
counter -= 10;
}
if (!reg_val) {
Vps_printf("%s: [%d:%d] autoload of serializer i2c addres failed\n", __func__, chan->csi_port_idx, chan->channel_idx);
return BSP_EFAIL;
}
Vps_printf("%s: [%d:%d] end (%02X, cntr: %d, status: %d)\n", __func__, chan->csi_port_idx, chan->channel_idx, reg_val, counter, status);