diff --git a/source/application/bluetooth.c b/source/application/bluetooth.c index dc966465..02cef3f9 100644 --- a/source/application/bluetooth.c +++ b/source/application/bluetooth.c @@ -332,6 +332,8 @@ void SD_EVT_IRQHandler(void) bond_storage, (uint32_t *)&bond.keyset.keys_own.p_enc_key->enc_info, sizeof(bond.keyset.keys_own.p_enc_key->enc_info)); + + status = show_pairing_screen(true, false); } break; diff --git a/source/application/lua_libraries/camera.c b/source/application/lua_libraries/camera.c index 6405be06..f1f0a241 100644 --- a/source/application/lua_libraries/camera.c +++ b/source/application/lua_libraries/camera.c @@ -50,11 +50,11 @@ static struct camera_auto_last_values double green_gain; double blue_gain; } last = { - .shutter = 500.0f, + .shutter = 1600.0f, .analog_gain = 1.0f, - .red_gain = 1.9f, - .green_gain = 1.0f, - .blue_gain = 2.2f, + .red_gain = 121.6f, + .green_gain = 64.0f, + .blue_gain = 140.8f, }; static struct camera_capture_settings @@ -561,11 +561,12 @@ static int lua_camera_auto(lua_State *L) } // Default auto exposure settings - camera_metering_mode_t metering = AVERAGE; - double target_exposure = 0.18; - double exposure_speed = 0.50; - double shutter_limit = 1600.0; - double analog_gain_limit = 60.0; + camera_metering_mode_t metering = CENTER_WEIGHTED; + double target_exposure = 0.1; + double exposure_speed = 0.45; + double shutter_limit = 16383.0; + double analog_gain_limit = 16.0; + double rgb_gain_limit = 287.0; // Default white balance settings double white_balance_speed = 0.5; @@ -655,6 +656,17 @@ static int lua_camera_auto(lua_State *L) lua_pop(L, 1); } + + if (lua_getfield(L, 1, "rgb_gain_limit") != LUA_TNIL) + { + rgb_gain_limit = luaL_checknumber(L, -1); + if (rgb_gain_limit < 0.0 || rgb_gain_limit > 1023.0) + { + luaL_error(L, "rgb_gain_limit must be between 0 and 1023"); + } + + lua_pop(L, 1); + } } // Get current brightness from FPGA @@ -668,6 +680,25 @@ static int lua_camera_auto(lua_State *L) double matrix_g = metering_data[4] / 255.0f; double matrix_b = metering_data[5] / 255.0f; + if (spot_r == 0.0) { + spot_r = 0.0001; + } + if (spot_g == 0.0) { + spot_g = 0.0001; + } + if (spot_b == 0.0) { + spot_b = 0.0001; + } + if (matrix_r == 0.0) { + matrix_r = 0.0001; + } + if (matrix_g == 0.0) { + matrix_g = 0.0001; + } + if (matrix_b == 0.0) { + matrix_b = 0.0001; + } + double spot_average = (spot_r + spot_g + spot_b) / 3.0; double matrix_average = (matrix_r + matrix_g + matrix_b) / 3.0; double center_weighted_average = (spot_average + @@ -769,6 +800,10 @@ static int lua_camera_auto(lua_State *L) ? matrix_g / last.green_gain : matrix_b / last.blue_gain); + // scale normalized RGB values to the gain scale + max_rgb *= 256.0; + + // target per-channel gains that we blend towards double red_gain = max_rgb / matrix_r * last.red_gain; double green_gain = max_rgb / matrix_g * last.green_gain; double blue_gain = max_rgb / matrix_b * last.blue_gain; @@ -777,19 +812,6 @@ static int lua_camera_auto(lua_State *L) double blending_factor = (scene_brightness - white_balance_min_activation) / (white_balance_max_activation - white_balance_min_activation); - - if (red_gain > 1023.0) - { - red_gain = 1023.0; - } - if (green_gain > 1023.0) - { - green_gain = 1023.0; - } - if (blue_gain > 1023.0) - { - blue_gain = 1023.0; - } if (blending_factor > 1.0) { blending_factor = 1.0; @@ -811,9 +833,51 @@ static int lua_camera_auto(lua_State *L) (blue_gain - last.blue_gain) + last.blue_gain; - uint16_t red_gain_uint16 = (uint16_t)(last.red_gain * 256.0); - uint16_t green_gain_uint16 = (uint16_t)(last.green_gain * 256.0); - uint16_t blue_gain_uint16 = (uint16_t)(last.blue_gain * 256.0); + double max_rgb_gain = last.red_gain > last.green_gain + ? (last.red_gain > last.blue_gain + ? last.red_gain + : last.blue_gain) + : (last.green_gain > last.blue_gain + ? last.green_gain + : last.blue_gain); + + // Scale per-channel gains so the largest channel is at most rgb_gain_limit + if (max_rgb_gain > rgb_gain_limit) + { + double scale_factor = rgb_gain_limit / max_rgb_gain; + last.red_gain *= scale_factor; + last.green_gain *= scale_factor; + last.blue_gain *= scale_factor; + } + + if (last.red_gain > 1023.0) + { + last.red_gain = 1023.0; + } + if (last.red_gain <= 0.0) + { + last.red_gain = 0.0001; + } + if (last.green_gain > 1023.0) + { + last.green_gain = 1023.0; + } + if (last.green_gain <= 0.0) + { + last.green_gain = 0.0001; + } + if (last.blue_gain > 1023.0) + { + last.blue_gain = 1023.0; + } + if (last.blue_gain <= 0.0) + { + last.blue_gain = 0.0001; + } + + uint16_t red_gain_uint16 = (uint16_t)(last.red_gain); + uint16_t green_gain_uint16 = (uint16_t)(last.green_gain); + uint16_t blue_gain_uint16 = (uint16_t)(last.blue_gain); check_error(i2c_write(CAMERA, 0x5180, 0x03, red_gain_uint16 >> 8).fail); check_error(i2c_write(CAMERA, 0x5181, 0xFF, red_gain_uint16).fail); diff --git a/source/application/lua_libraries/system.c b/source/application/lua_libraries/system.c index c5439287..2ff74021 100644 --- a/source/application/lua_libraries/system.c +++ b/source/application/lua_libraries/system.c @@ -36,6 +36,12 @@ static int lua_update(lua_State *L) { + int status = show_pairing_screen(false, true); + if (status != LUA_OK) + { + const char *lua_error = lua_tostring(L, -1); + luaL_error(L, "%s", lua_error); + } check_error(sd_power_gpregret_set(0, 0xB1)); NVIC_SystemReset(); return 0; diff --git a/source/application/luaport.c b/source/application/luaport.c index 4506f744..e0d9ecfd 100644 --- a/source/application/luaport.c +++ b/source/application/luaport.c @@ -63,6 +63,39 @@ void lua_break_signal_interrupt(void) 1); } +int show_pairing_screen(bool is_paired, bool is_update) +{ + int status; + if(L_global == NULL) + { + return LUA_ERRRUN; + } + if (is_update) + { + status = luaL_dostring(L_global, "frame.display.text('Frame Update', 200, 140);" + "frame.display.show();"); + } + else if (!is_paired) + { + status = luaL_dostring(L_global, "frame.display.text('Ready to Pair', 200, 140);" + "frame.display.text('Frame '..frame.bluetooth.address():sub(-2, -1), 245, 210, { color = 'GREEN' });" + "frame.display.show();"); + } + else + { + status = luaL_dostring(L_global, "frame.display.text('Frame is Paired', 185, 140);" + "frame.display.text('Frame '..frame.bluetooth.address():sub(-2, -1), 245, 210, { color = 'ORANGE' });" + "frame.display.show();"); + } + + if (status != LUA_OK) + { + lua_pop(L_global, -1); + error(); + } + return status; +} + void run_lua(bool is_paired) { lua_State *L = luaL_newstate(); @@ -127,24 +160,8 @@ void run_lua(bool is_paired) } // Show splash screen - if (!is_paired) - { - status = luaL_dostring(L, "frame.display.text('Ready to Pair', 200, 140);" - "frame.display.text('Frame '..frame.bluetooth.address():sub(-2, -1), 245, 210, { color = 'GREEN' });" - "frame.display.show();"); - } - else - { - status = luaL_dostring(L, "frame.display.text('Frame is Paired', 185, 140);" - "frame.display.text('Frame '..frame.bluetooth.address():sub(-2, -1), 245, 210, { color = 'ORANGE' });" - "frame.display.show();"); - } + status = show_pairing_screen(is_paired, false); - if (status != LUA_OK) - { - lua_pop(L, -1); - error(); - } // Run REPL while (true) diff --git a/source/application/luaport.h b/source/application/luaport.h index 00cca7da..244f3139 100644 --- a/source/application/luaport.h +++ b/source/application/luaport.h @@ -29,7 +29,7 @@ #include #include "bluetooth.h" #include "nrfx_log.h" - +#include "lua.h" #define lua_writestring(s, l) bluetooth_send_data((uint8_t *)s, l) #define lua_writeline() #define lua_writestringerror(s, p) printf(s, p) @@ -38,4 +38,6 @@ void lua_write_to_repl(uint8_t *buffer, uint8_t length); void lua_break_signal_interrupt(void); -void run_lua(bool is_paired); \ No newline at end of file +void run_lua(bool is_paired); + +int show_pairing_screen(bool is_paired, bool is_update); \ No newline at end of file