@@ -46,8 +46,8 @@ static struct camera_auto_last_values
4646 double shutter ;
4747 double gain ;
4848} last = {
49- .shutter = 3000 ,
50- .gain = 0 ,
49+ .shutter = 500.0f ,
50+ .gain = 1.0f ,
5151};
5252
5353static lua_Integer camera_quality_factor = 50 ;
@@ -327,10 +327,9 @@ static int lua_camera_auto(lua_State *L)
327327 }
328328
329329 camera_metering_mode_t metering = AVERAGE ;
330- double exposure = 0.0 ;
331- double shutter_kp = 0.1 ;
332- double shutter_limit = 6000.0 ;
333- double gain_kp = 1.0 ;
330+ double target_exposure = 0.18 ;
331+ double exposure_speed = 0.50 ;
332+ double shutter_limit = 800.0 ; // TODO fix this value
334333 double gain_limit = 248.0 ;
335334
336335 if (lua_istable (L , 1 ))
@@ -362,21 +361,21 @@ static int lua_camera_auto(lua_State *L)
362361
363362 if (lua_getfield (L , 1 , "exposure" ) != LUA_TNIL )
364363 {
365- exposure = luaL_checknumber (L , -1 );
366- if (exposure < -2 .0 || exposure > 2 .0 )
364+ target_exposure = luaL_checknumber (L , -1 );
365+ if (target_exposure < 0 .0 || target_exposure > 1 .0 )
367366 {
368- luaL_error (L , "exposure must be between -2 and 2 " );
367+ luaL_error (L , "exposure must be between 0 and 1 " );
369368 }
370369
371370 lua_pop (L , 1 );
372371 }
373372
374- if (lua_getfield (L , 1 , "shutter_kp " ) != LUA_TNIL )
373+ if (lua_getfield (L , 1 , "exposure_speed " ) != LUA_TNIL )
375374 {
376- shutter_kp = luaL_checknumber (L , -1 );
377- if (shutter_kp < 0.0 )
375+ exposure_speed = luaL_checknumber (L , -1 );
376+ if (exposure_speed < 0.0 || exposure_speed > 1 .0 )
378377 {
379- luaL_error (L , "shutter_kp must be greater than 0 " );
378+ luaL_error (L , "exposure_speed must be between 0 and 1 " );
380379 }
381380
382381 lua_pop (L , 1 );
@@ -393,17 +392,6 @@ static int lua_camera_auto(lua_State *L)
393392 lua_pop (L , 1 );
394393 }
395394
396- if (lua_getfield (L , 1 , "gain_kp" ) != LUA_TNIL )
397- {
398- gain_kp = luaL_checknumber (L , -1 );
399- if (gain_kp < 0.0 )
400- {
401- luaL_error (L , "gain_kp must be greater than 0" );
402- }
403-
404- lua_pop (L , 1 );
405- }
406-
407395 if (lua_getfield (L , 1 , "gain_limit" ) != LUA_TNIL )
408396 {
409397 gain_limit = luaL_checknumber (L , -1 );
@@ -420,12 +408,12 @@ static int lua_camera_auto(lua_State *L)
420408 volatile uint8_t metering_data [6 ];
421409 spi_read (FPGA , 0x25 , (uint8_t * )metering_data , sizeof (metering_data ));
422410
423- double spot_r = metering_data [0 ] / 64.0 - 2 ;
424- double spot_g = metering_data [1 ] / 64.0 - 2 ;
425- double spot_b = metering_data [2 ] / 64.0 - 2 ;
426- double matrix_r = metering_data [3 ] / 64.0 - 2 ;
427- double matrix_g = metering_data [4 ] / 64.0 - 2 ;
428- double matrix_b = metering_data [5 ] / 64.0 - 2 ;
411+ double spot_r = metering_data [0 ] / 255.0f ;
412+ double spot_g = metering_data [1 ] / 255.0f ;
413+ double spot_b = metering_data [2 ] / 255.0f ;
414+ double matrix_r = metering_data [3 ] / 255.0f ;
415+ double matrix_g = metering_data [4 ] / 255.0f ;
416+ double matrix_b = metering_data [5 ] / 255.0f ;
429417
430418 double spot_average = (spot_r + spot_g + spot_b ) / 3.0 ;
431419 double matrix_average = (matrix_r + matrix_g + matrix_b ) / 3.0 ;
@@ -436,40 +424,66 @@ static int lua_camera_auto(lua_State *L)
436424
437425 // Choose error
438426 double error ;
427+
439428 switch (metering )
440429 {
441430 case SPOT :
442- error = exposure - spot_average ;
431+ error = exposure_speed * (( target_exposure / spot_average ) - 1 ) + 1 ;
443432 break ;
444433
445434 case CENTER_WEIGHTED :
446- error = exposure - center_weighted_average ;
435+ error = exposure_speed * (( target_exposure / center_weighted_average ) - 1 ) + 1 ;
447436 break ;
448437
449- default : // AVERAGE
450- error = exposure - matrix_average ;
438+ case AVERAGE :
439+ error = exposure_speed * (( target_exposure / matrix_average ) - 1 ) + 1 ;
451440 break ;
452441 }
453442
454- // Run the loop iteration
455- if (error > 0 )
443+ if (error > 1 )
456444 {
457- last . shutter += ( shutter_kp * last .shutter ) * error ;
445+ double shutter = last .shutter ;
458446
459- // Prioritize shutter over gain when image is too dark
460- if (last .shutter >= shutter_limit )
447+ last .shutter *= error ;
448+
449+ if (last .shutter > shutter_limit )
461450 {
462- last .gain += gain_kp * error ;
451+ last .shutter = shutter_limit ;
452+ }
453+
454+ error *= shutter / last .shutter ;
455+
456+ if (error > 1 )
457+ {
458+ last .gain *= error ;
459+
460+ if (last .gain > gain_limit )
461+ {
462+ last .gain = gain_limit ;
463+ }
463464 }
464465 }
465466 else
466467 {
467- // When image is too bright, reduce gain first
468- last .gain += gain_kp * error ;
468+ double gain = last .gain ;
469+
470+ last .gain *= error ;
469471
470- if (last .gain <= 0 )
472+ if (last .gain < 1. 0 )
471473 {
472- last .shutter += (shutter_kp * last .shutter ) * error ;
474+ last .gain = 1.0 ;
475+ }
476+
477+ error *= gain / last .gain ;
478+
479+ if (error < 1 )
480+ {
481+ last .shutter *= error ;
482+
483+ if (last .shutter > shutter_limit )
484+ {
485+ last .shutter = shutter_limit ;
486+ }
473487 }
474488 }
475489
@@ -497,18 +511,6 @@ static int lua_camera_auto(lua_State *L)
497511 uint16_t shutter = (uint16_t )last .shutter ;
498512 uint8_t gain = (uint8_t )last .gain ;
499513
500- // If shutter is longer than frame length (VTS register)
501- if (shutter > 0x32A )
502- {
503- check_error (i2c_write (CAMERA , 0x380E , 0xFF , shutter >> 8 ).fail );
504- check_error (i2c_write (CAMERA , 0x380F , 0xFF , shutter ).fail );
505- }
506- else
507- {
508- check_error (i2c_write (CAMERA , 0x380E , 0xFF , 0x03 ).fail );
509- check_error (i2c_write (CAMERA , 0x380F , 0xFF , 0x22 ).fail );
510- }
511-
512514 check_error (i2c_write (CAMERA , 0x3500 , 0x03 , shutter >> 12 ).fail );
513515 check_error (i2c_write (CAMERA , 0x3501 , 0xFF , shutter >> 4 ).fail );
514516 check_error (i2c_write (CAMERA , 0x3502 , 0xF0 , shutter << 4 ).fail );
@@ -599,18 +601,6 @@ static int lua_camera_set_shutter(lua_State *L)
599601 return luaL_error (L , "shutter must be between 4 and 16383" );
600602 }
601603
602- // If shutter is longer than frame length (VTS register)
603- if (shutter > 0x32A )
604- {
605- check_error (i2c_write (CAMERA , 0x380E , 0xFF , shutter >> 8 ).fail );
606- check_error (i2c_write (CAMERA , 0x380F , 0xFF , shutter ).fail );
607- }
608- else
609- {
610- check_error (i2c_write (CAMERA , 0x380E , 0xFF , 0x03 ).fail );
611- check_error (i2c_write (CAMERA , 0x380F , 0xFF , 0x22 ).fail );
612- }
613-
614604 check_error (i2c_write (CAMERA , 0x3500 , 0x03 , shutter >> 12 ).fail );
615605 check_error (i2c_write (CAMERA , 0x3501 , 0xFF , shutter >> 4 ).fail );
616606 check_error (i2c_write (CAMERA , 0x3502 , 0xF0 , shutter << 4 ).fail );
@@ -697,6 +687,32 @@ static int lua_camera_set_register(lua_State *L)
697687 return 0 ;
698688}
699689
690+ static int lua_camera_get_register (lua_State * L )
691+ {
692+ if (nrf_gpio_pin_out_read (CAMERA_SLEEP_PIN ) == false)
693+ {
694+ luaL_error (L , "camera is asleep" );
695+ }
696+
697+ lua_Integer address = luaL_checkinteger (L , 1 );
698+
699+ if (address < 0 || address > 0xFFFF )
700+ {
701+ luaL_error (L , "address must be a 16 bit unsigned number" );
702+ }
703+
704+ i2c_response_t response = i2c_read (CAMERA , (uint16_t )address , 0xFF );
705+
706+ if (response .fail )
707+ {
708+ error ();
709+ }
710+
711+ lua_pushinteger (L , response .value );
712+
713+ return 1 ;
714+ }
715+
700716void lua_open_camera_library (lua_State * L )
701717{
702718 // Wake up camera in case it was asleep
@@ -740,6 +756,9 @@ void lua_open_camera_library(lua_State *L)
740756 lua_pushcfunction (L , lua_camera_set_register );
741757 lua_setfield (L , -2 , "set_register" );
742758
759+ lua_pushcfunction (L , lua_camera_get_register );
760+ lua_setfield (L , -2 , "get_register" );
761+
743762 lua_setfield (L , -2 , "camera" );
744763
745764 lua_pop (L , 1 );
0 commit comments