@@ -50,11 +50,11 @@ static struct camera_auto_last_values
5050 double green_gain ;
5151 double blue_gain ;
5252} last = {
53- .shutter = 500 .0f ,
53+ .shutter = 1600 .0f ,
5454 .analog_gain = 1.0f ,
55- .red_gain = 1.9f ,
56- .green_gain = 1 .0f ,
57- .blue_gain = 2.2f ,
55+ .red_gain = 121.6f ,
56+ .green_gain = 64 .0f ,
57+ .blue_gain = 140.8f ,
5858};
5959
6060static struct camera_capture_settings
@@ -564,8 +564,9 @@ static int lua_camera_auto(lua_State *L)
564564 camera_metering_mode_t metering = AVERAGE ;
565565 double target_exposure = 0.18 ;
566566 double exposure_speed = 0.50 ;
567- double shutter_limit = 1600.0 ;
568- double analog_gain_limit = 60.0 ;
567+ double shutter_limit = 3072.0 ;
568+ double analog_gain_limit = 16.0 ;
569+ double rgb_gain_limit = 141.0 ;
569570
570571 // Default white balance settings
571572 double white_balance_speed = 0.5 ;
@@ -655,6 +656,17 @@ static int lua_camera_auto(lua_State *L)
655656
656657 lua_pop (L , 1 );
657658 }
659+
660+ if (lua_getfield (L , 1 , "rgb_gain_limit" ) != LUA_TNIL )
661+ {
662+ rgb_gain_limit = luaL_checknumber (L , -1 );
663+ if (rgb_gain_limit < 0.0 || rgb_gain_limit > 1023.0 )
664+ {
665+ luaL_error (L , "rgb_gain_limit must be between 0 and 1023" );
666+ }
667+
668+ lua_pop (L , 1 );
669+ }
658670 }
659671
660672 // Get current brightness from FPGA
@@ -668,6 +680,25 @@ static int lua_camera_auto(lua_State *L)
668680 double matrix_g = metering_data [4 ] / 255.0f ;
669681 double matrix_b = metering_data [5 ] / 255.0f ;
670682
683+ if (spot_r == 0.0 ) {
684+ spot_r = 0.0001 ;
685+ }
686+ if (spot_g == 0.0 ) {
687+ spot_g = 0.0001 ;
688+ }
689+ if (spot_b == 0.0 ) {
690+ spot_b = 0.0001 ;
691+ }
692+ if (matrix_r == 0.0 ) {
693+ matrix_r = 0.0001 ;
694+ }
695+ if (matrix_g == 0.0 ) {
696+ matrix_g = 0.0001 ;
697+ }
698+ if (matrix_b == 0.0 ) {
699+ matrix_b = 0.0001 ;
700+ }
701+
671702 double spot_average = (spot_r + spot_g + spot_b ) / 3.0 ;
672703 double matrix_average = (matrix_r + matrix_g + matrix_b ) / 3.0 ;
673704 double center_weighted_average = (spot_average +
@@ -769,6 +800,10 @@ static int lua_camera_auto(lua_State *L)
769800 ? matrix_g / last .green_gain
770801 : matrix_b / last .blue_gain );
771802
803+ // scale normalized RGB values to the gain scale
804+ max_rgb *= 256.0 ;
805+
806+ // target per-channel gains that we blend towards
772807 double red_gain = max_rgb / matrix_r * last .red_gain ;
773808 double green_gain = max_rgb / matrix_g * last .green_gain ;
774809 double blue_gain = max_rgb / matrix_b * last .blue_gain ;
@@ -777,19 +812,6 @@ static int lua_camera_auto(lua_State *L)
777812 double blending_factor = (scene_brightness - white_balance_min_activation ) /
778813 (white_balance_max_activation -
779814 white_balance_min_activation );
780-
781- if (red_gain > 1023.0 )
782- {
783- red_gain = 1023.0 ;
784- }
785- if (green_gain > 1023.0 )
786- {
787- green_gain = 1023.0 ;
788- }
789- if (blue_gain > 1023.0 )
790- {
791- blue_gain = 1023.0 ;
792- }
793815 if (blending_factor > 1.0 )
794816 {
795817 blending_factor = 1.0 ;
@@ -811,9 +833,51 @@ static int lua_camera_auto(lua_State *L)
811833 (blue_gain - last .blue_gain ) +
812834 last .blue_gain ;
813835
814- uint16_t red_gain_uint16 = (uint16_t )(last .red_gain * 256.0 );
815- uint16_t green_gain_uint16 = (uint16_t )(last .green_gain * 256.0 );
816- uint16_t blue_gain_uint16 = (uint16_t )(last .blue_gain * 256.0 );
836+ double max_rgb_gain = last .red_gain > last .green_gain
837+ ? (last .red_gain > last .blue_gain
838+ ? last .red_gain
839+ : last .blue_gain )
840+ : (last .green_gain > last .blue_gain
841+ ? last .green_gain
842+ : last .blue_gain );
843+
844+ // Scale per-channel gains so the largest channel is at most rgb_gain_limit
845+ if (max_rgb_gain > rgb_gain_limit )
846+ {
847+ double scale_factor = rgb_gain_limit / max_rgb_gain ;
848+ last .red_gain *= scale_factor ;
849+ last .green_gain *= scale_factor ;
850+ last .blue_gain *= scale_factor ;
851+ }
852+
853+ if (last .red_gain > 1023.0 )
854+ {
855+ last .red_gain = 1023.0 ;
856+ }
857+ if (last .red_gain <= 0.0 )
858+ {
859+ last .red_gain = 0.0001 ;
860+ }
861+ if (last .green_gain > 1023.0 )
862+ {
863+ last .green_gain = 1023.0 ;
864+ }
865+ if (last .green_gain <= 0.0 )
866+ {
867+ last .green_gain = 0.0001 ;
868+ }
869+ if (last .blue_gain > 1023.0 )
870+ {
871+ last .blue_gain = 1023.0 ;
872+ }
873+ if (last .blue_gain <= 0.0 )
874+ {
875+ last .blue_gain = 0.0001 ;
876+ }
877+
878+ uint16_t red_gain_uint16 = (uint16_t )(last .red_gain );
879+ uint16_t green_gain_uint16 = (uint16_t )(last .green_gain );
880+ uint16_t blue_gain_uint16 = (uint16_t )(last .blue_gain );
817881
818882 check_error (i2c_write (CAMERA , 0x5180 , 0x03 , red_gain_uint16 >> 8 ).fail );
819883 check_error (i2c_write (CAMERA , 0x5181 , 0xFF , red_gain_uint16 ).fail );
0 commit comments