22
22
#include " selfdrive/common/swaglog.h"
23
23
#include " selfdrive/camerad/cameras/sensor2_i2c.h"
24
24
25
+ // For debugging:
26
+ // echo "4294967295" > /sys/module/cam_debug_util/parameters/debug_mdl
27
+
25
28
extern ExitHandler do_exit;
26
29
27
30
const size_t FRAME_WIDTH = 1928 ;
@@ -39,6 +42,14 @@ CameraInfo cameras_supported[CAMERA_ID_MAX] = {
39
42
.bayer_flip = 1 ,
40
43
.hdr = false
41
44
},
45
+ [CAMERA_ID_IMX390] = {
46
+ .frame_width = FRAME_WIDTH,
47
+ .frame_height = FRAME_HEIGHT,
48
+ .frame_stride = FRAME_STRIDE,
49
+ .bayer = true ,
50
+ .bayer_flip = 1 ,
51
+ .hdr = false
52
+ },
42
53
};
43
54
44
55
const float DC_GAIN = 2.5 ;
@@ -160,8 +171,15 @@ void clear_req_queue(int fd, int32_t session_hdl, int32_t link_hdl) {
160
171
// ************** high level camera helpers ****************
161
172
162
173
void CameraState::sensors_start () {
163
- int start_reg_len = sizeof (start_reg_array) / sizeof (struct i2c_random_wr_payload );
164
- sensors_i2c (start_reg_array, start_reg_len, CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG);
174
+ if (camera_id == CAMERA_ID_AR0231) {
175
+ int start_reg_len = sizeof (start_reg_array_ar0231) / sizeof (struct i2c_random_wr_payload );
176
+ sensors_i2c (start_reg_array_ar0231, start_reg_len, CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, true );
177
+ } else if (camera_id == CAMERA_ID_IMX390) {
178
+ int start_reg_len = sizeof (start_reg_array_imx390) / sizeof (struct i2c_random_wr_payload );
179
+ sensors_i2c (start_reg_array_imx390, start_reg_len, CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, false );
180
+ } else {
181
+ assert (false );
182
+ }
165
183
}
166
184
167
185
void CameraState::sensors_poke (int request_id) {
@@ -181,7 +199,7 @@ void CameraState::sensors_poke(int request_id) {
181
199
release_fd (multi_cam_state->video0_fd , cam_packet_handle);
182
200
}
183
201
184
- void CameraState::sensors_i2c (struct i2c_random_wr_payload * dat, int len, int op_code) {
202
+ void CameraState::sensors_i2c (struct i2c_random_wr_payload * dat, int len, int op_code, bool data_word ) {
185
203
// LOGD("sensors_i2c: %d", len);
186
204
uint32_t cam_packet_handle = 0 ;
187
205
int size = sizeof (struct cam_packet )+sizeof (struct cam_cmd_buf_desc )*1 ;
@@ -199,7 +217,7 @@ void CameraState::sensors_i2c(struct i2c_random_wr_payload* dat, int len, int op
199
217
i2c_random_wr->header .count = len;
200
218
i2c_random_wr->header .op_code = 1 ;
201
219
i2c_random_wr->header .cmd_type = CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR;
202
- i2c_random_wr->header .data_type = CAMERA_SENSOR_I2C_TYPE_WORD;
220
+ i2c_random_wr->header .data_type = data_word ? CAMERA_SENSOR_I2C_TYPE_WORD : CAMERA_SENSOR_I2C_TYPE_BYTE ;
203
221
i2c_random_wr->header .addr_type = CAMERA_SENSOR_I2C_TYPE_WORD;
204
222
memcpy (i2c_random_wr->random_wr_payload , dat, len*sizeof (struct i2c_random_wr_payload ));
205
223
@@ -220,7 +238,7 @@ static cam_cmd_power *power_set_wait(cam_cmd_power *power, int16_t delay_ms) {
220
238
return (struct cam_cmd_power *)(unconditional_wait + 1 );
221
239
};
222
240
223
- void CameraState::sensors_init () {
241
+ int CameraState::sensors_init () {
224
242
int video0_fd = multi_cam_state->video0_fd ;
225
243
uint32_t cam_packet_handle = 0 ;
226
244
int size = sizeof (struct cam_packet )+sizeof (struct cam_cmd_buf_desc )*2 ;
@@ -239,17 +257,17 @@ void CameraState::sensors_init() {
239
257
switch (camera_num) {
240
258
case 0 :
241
259
// port 0
242
- i2c_info->slave_addr = 0x20 ;
260
+ i2c_info->slave_addr = (camera_id == CAMERA_ID_AR0231) ? 0x20 : 0x34 ;
243
261
probe->camera_id = 0 ;
244
262
break ;
245
263
case 1 :
246
264
// port 1
247
- i2c_info->slave_addr = 0x30 ;
265
+ i2c_info->slave_addr = (camera_id == CAMERA_ID_AR0231) ? 0x30 : 0x36 ;
248
266
probe->camera_id = 1 ;
249
267
break ;
250
268
case 2 :
251
269
// port 2
252
- i2c_info->slave_addr = 0x20 ;
270
+ i2c_info->slave_addr = (camera_id == CAMERA_ID_AR0231) ? 0x20 : 0x34 ;
253
271
probe->camera_id = 2 ;
254
272
break ;
255
273
}
@@ -263,8 +281,15 @@ void CameraState::sensors_init() {
263
281
probe->addr_type = CAMERA_SENSOR_I2C_TYPE_WORD;
264
282
probe->op_code = 3 ; // don't care?
265
283
probe->cmd_type = CAMERA_SENSOR_CMD_TYPE_PROBE;
266
- probe->reg_addr = 0x3000 ; // 0x300a; //0x300b;
267
- probe->expected_data = 0x354 ; // 0x7750; //0x885a;
284
+ if (camera_id == CAMERA_ID_AR0231) {
285
+ probe->reg_addr = 0x3000 ;
286
+ probe->expected_data = 0x354 ;
287
+ } else if (camera_id == CAMERA_ID_IMX390) {
288
+ probe->reg_addr = 0x330 ;
289
+ probe->expected_data = 0x1538 ;
290
+ } else {
291
+ assert (false );
292
+ }
268
293
probe->data_mask = 0 ;
269
294
270
295
// buf_desc[1].size = buf_desc[1].length = 148;
@@ -293,7 +318,7 @@ void CameraState::sensors_init() {
293
318
power->count = 1 ;
294
319
power->cmd_type = CAMERA_SENSOR_CMD_TYPE_PWR_UP;
295
320
power->power_settings [0 ].power_seq_type = 0 ;
296
- power->power_settings [0 ].config_val_low = 19200000 ; // Hz
321
+ power->power_settings [0 ].config_val_low = (camera_id == CAMERA_ID_AR0231) ? 19200000 : 24000000 ; // Hz
297
322
power = power_set_wait (power, 10 );
298
323
299
324
// 8,1 is this reset?
@@ -341,14 +366,15 @@ void CameraState::sensors_init() {
341
366
342
367
LOGD (" probing the sensor" );
343
368
int ret = do_cam_control (sensor_fd, CAM_SENSOR_PROBE_CMD, (void *)(uintptr_t )cam_packet_handle, 0 );
344
- assert (ret == 0 );
345
369
346
370
munmap (i2c_info, buf_desc[0 ].size );
347
371
release_fd (video0_fd, buf_desc[0 ].mem_handle );
348
372
munmap (power_settings, buf_desc[1 ].size );
349
373
release_fd (video0_fd, buf_desc[1 ].mem_handle );
350
374
munmap (pkt, size);
351
375
release_fd (video0_fd, cam_packet_handle);
376
+
377
+ return ret;
352
378
}
353
379
354
380
void CameraState::config_isp (int io_mem_handle, int fence, int request_id, int buf0_mem_handle, int buf0_offset) {
@@ -561,9 +587,10 @@ void CameraState::enqueue_req_multi(int start, int n, bool dp) {
561
587
562
588
// ******************* camera *******************
563
589
564
- void CameraState::camera_init (MultiCameraState *multi_cam_state_, VisionIpcServer * v, int camera_id , int camera_num_, unsigned int fps, cl_device_id device_id, cl_context ctx, VisionStreamType rgb_type, VisionStreamType yuv_type) {
590
+ void CameraState::camera_init (MultiCameraState *multi_cam_state_, VisionIpcServer * v, int camera_id_ , int camera_num_, unsigned int fps, cl_device_id device_id, cl_context ctx, VisionStreamType rgb_type, VisionStreamType yuv_type) {
565
591
LOGD (" camera init %d" , camera_num);
566
592
multi_cam_state = multi_cam_state_;
593
+ camera_id = camera_id_;
567
594
assert (camera_id < std::size (cameras_supported));
568
595
ci = cameras_supported[camera_id];
569
596
assert (ci.frame_width != 0 );
@@ -586,17 +613,24 @@ void CameraState::camera_init(MultiCameraState *multi_cam_state_, VisionIpcServe
586
613
}
587
614
588
615
void CameraState::camera_open () {
616
+ int ret;
589
617
sensor_fd = open_v4l_by_name_and_index (" cam-sensor-driver" , camera_num);
590
618
assert (sensor_fd >= 0 );
591
619
LOGD (" opened sensor for %d" , camera_num);
592
620
593
621
// probe the sensor
594
622
LOGD (" -- Probing sensor %d" , camera_num);
595
- sensors_init ();
623
+ ret = sensors_init ();
624
+ if (ret != 0 ) {
625
+ LOGD (" AR0231 init failed, trying IMX390" );
626
+ camera_id = CAMERA_ID_IMX390;
627
+ ret = sensors_init ();
628
+ }
629
+ assert (ret == 0 );
596
630
597
631
// create session
598
632
struct cam_req_mgr_session_info session_info = {};
599
- int ret = do_cam_control (multi_cam_state->video0_fd , CAM_REQ_MGR_CREATE_SESSION, &session_info, sizeof (session_info));
633
+ ret = do_cam_control (multi_cam_state->video0_fd , CAM_REQ_MGR_CREATE_SESSION, &session_info, sizeof (session_info));
600
634
LOGD (" get session: %d 0x%X" , ret, session_info.session_hdl );
601
635
session_handle = session_info.session_hdl ;
602
636
@@ -675,10 +709,13 @@ void CameraState::camera_open() {
675
709
config_isp (0 , 0 , 1 , buf0_handle, 0 );
676
710
677
711
LOG (" -- Configuring sensor" );
678
- sensors_i2c (init_array_ar0231, std::size (init_array_ar0231), CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG);
679
- // sensors_i2c(start_reg_array, std::size(start_reg_array), CAM_SENSOR_PACKET_OPCODE_SENSOR_STREAMON);
680
- // sensors_i2c(stop_reg_array, std::size(stop_reg_array), CAM_SENSOR_PACKET_OPCODE_SENSOR_STREAMOFF);
681
-
712
+ if (camera_id == CAMERA_ID_AR0231) {
713
+ sensors_i2c (init_array_ar0231, std::size (init_array_ar0231), CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, true );
714
+ } else if (camera_id == CAMERA_ID_IMX390) {
715
+ sensors_i2c (init_array_imx390, std::size (init_array_imx390), CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, false );
716
+ } else {
717
+ assert (false );
718
+ }
682
719
683
720
// config csiphy
684
721
LOG (" -- Config CSI PHY" );
@@ -1008,14 +1045,28 @@ void CameraState::set_camera_exposure(float grey_frac) {
1008
1045
}
1009
1046
// LOGE("ae - camera %d, cur_t %.5f, sof %.5f, dt %.5f", camera_num, 1e-9 * nanos_since_boot(), 1e-9 * buf.cur_frame_data.timestamp_sof, 1e-9 * (nanos_since_boot() - buf.cur_frame_data.timestamp_sof));
1010
1047
1011
- uint16_t analog_gain_reg = 0xFF00 | (new_g << 4 ) | new_g;
1012
- struct i2c_random_wr_payload exp_reg_array[] = {
1013
- {0x3366 , analog_gain_reg},
1014
- {0x3362 , (uint16_t )(dc_gain_enabled ? 0x1 : 0x0 )},
1015
- {0x3012 , (uint16_t )exposure_time},
1016
- };
1017
- sensors_i2c (exp_reg_array, sizeof (exp_reg_array)/sizeof (struct i2c_random_wr_payload ),
1018
- CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG);
1048
+ if (camera_id == CAMERA_ID_AR0231) {
1049
+ uint16_t analog_gain_reg = 0xFF00 | (new_g << 4 ) | new_g;
1050
+ struct i2c_random_wr_payload exp_reg_array[] = {
1051
+ {0x3366 , analog_gain_reg},
1052
+ {0x3362 , (uint16_t )(dc_gain_enabled ? 0x1 : 0x0 )},
1053
+ {0x3012 , (uint16_t )exposure_time},
1054
+ };
1055
+ sensors_i2c (exp_reg_array, sizeof (exp_reg_array)/sizeof (struct i2c_random_wr_payload ), CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, true );
1056
+ } else if (camera_id == CAMERA_ID_IMX390) {
1057
+ // if gain is sub 1, we have to use exposure to mimic sub 1 gains
1058
+ uint32_t real_exposure_time = (gain < 1.0 ) ? (exposure_time*gain) : exposure_time;
1059
+ // invert real_exposure_time, max exposure is 2
1060
+ real_exposure_time = (exposure_time >= 0x7cf ) ? 2 : (0x7cf - exposure_time);
1061
+ uint32_t real_gain = int ((10 *log10 (fmax (1.0 , gain)))/0.3 );
1062
+ // printf("%d expose: %d gain: %f = %d\n", camera_num, exposure_time, gain, real_gain);
1063
+ struct i2c_random_wr_payload exp_reg_array[] = {
1064
+ {0x000c , real_exposure_time&0xFF }, {0x000d , real_exposure_time>>8 },
1065
+ {0x0010 , real_exposure_time&0xFF }, {0x0011 , real_exposure_time>>8 },
1066
+ {0x0018 , real_gain&0xFF }, {0x0019 , real_gain>>8 },
1067
+ };
1068
+ sensors_i2c (exp_reg_array, sizeof (exp_reg_array)/sizeof (struct i2c_random_wr_payload ), CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, false );
1069
+ }
1019
1070
}
1020
1071
1021
1072
void camera_autoexposure (CameraState *s, float grey_frac) {
0 commit comments