6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7135
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Camera flash driver released

Fri Aug 01, 2014 5:34 pm

Hi All.

As mentioned on http://www.raspberrypi.org/forums/viewt ... 43&t=83353, we now have a very basic flash driver. Dom is currently doing the release so "sudo rpi-update" should pick it up soon (please watch the Twitter feed if you're a real eager beaver).

Copying my comments from there to here:
In basic terms you define up to 2 GPIOs for it.

The first is used to trigger an LED flash or equivalent (not xenon as we don't have a global shutter/reset). Please be aware that the AGC algorithm will use a preflash before the capture to judge how much extra illumination the flash is contributing by the flash and hence how much to adjust the exposure and analogue gain by to compensate. Control the mode of operation with MMAL_PARAMETER_FLASH. The settings are fairly self explanatory.

The second GPIO is used for an indicator/privacy light. It's a legal requirement in some countries to give a visual indication during video recording or on stills capture that a capture has occurred. If set to ON with the new MMAL parameter, then the GPIO will go high for a minimum of (IIRC) 2 secs AFTER the frame has finished being exposed, so it should never interfere with the captured image. (The FORCE_ON setting is a quirky one for a particular requirement where we didn't get told whether recording was happening or not, so it just got set on every frame request of the recording type, and would time out when those requests ended. Probably best to ignore it).
It will do NOTHING by default as it needs to be told which GPIOs to use. This uses the same configuration method that has been discussed elsewhere, and the documentation is almost merged via https://github.com/raspberrypi/documentation/pull/105 Please read that first.
There are now 4 new pins added.

Code: Select all

                  [email protected]_0_ENABLE {
                     type = "absent";
                  };
                  [email protected]_0_INDICATOR {
                     type = "absent";
                  };
                  [email protected]_1_ENABLE {
                     type = "absent";
                  };
                  [email protected]_1_INDICATOR {
                     type = "absent";
                  };
All four set to absent is the current default. FLASH_0 links to camera 0, and FLASH_1 should link to camera 1 on a compute module (I've not double checked that works yet).
Rebuilding the blob (see the instructions in the docs) with say

Code: Select all

                  [email protected]_0_INDICATOR {
                     type = "internal";
                     number = <5>;
                  };
(on a B, 32 on a B+) and set CAMERA_0_LED to "absent" and the LED on the camera board will take on the role of privacy indicator.
Dom and I have had a quick chat about whether we change the default association of the camera board LED from effectively a power LED to privacy indicator - current decision is "not now, but maybe". The downside of changing is that it is currently a very useful tell-tale as to whether the module or firmware is doing anything.

I have not and will not be updating Raspistill / Raspivid to select this. I am currently concentrating on firmware issues, but if others wish to make the changes and submit a pull request on github then it will be accepted. As it won't do anything on a default build comments will be required in the app to state that.

WHAT YOU CONNECT TO THE GPIO IS YOUR BUSINESS. The GPIOs only have a limited current drive, so if you are adding real amounts of illumination then you will have to sort out a suitable drive circuit. No liability is accepted for blown GPIOs because you do something silly.
For reference, the flash driver chips we have used on mobile phones will often drive up to 500mA into the LED. If you're aiming for that, then please think about your power supply too.

I will also say again, this is NOT suitable for xenon flashes due to the sensor having a rolling shutter.

Have fun.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7135
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Camera flash driver released

Fri Aug 01, 2014 5:35 pm

Current complete blob source with the new pin descriptions is

Code: Select all

/dts-v1/;

/ {
   videocore {
            pins_rev1 {
               pin_config {
                  [email protected] {
                     polarity = "active_high";
                     termination = "pull_down";
                     startup_state = "inactive";
                     function = "input";
                  }; // pin
                  [email protected]  { function = "i2c1";   termination = "pull_up"; }; // I2C 1 SDA
                  [email protected]  { function = "i2c1";   termination = "pull_up"; }; // I2C 1 SCL
                  [email protected]  { function = "output"; termination = "pull_down"; }; // CAM_LED
                  [email protected]  { function = "output"; termination = "pull_down"; }; // LAN NRESET
                  [email protected] { function = "uart0";  termination = "no_pulling"; drive_strength_mA = < 8 >; }; // TX uart0
                  [email protected] { function = "uart0";  termination = "pull_up"; drive_strength_mA = < 8 >; }; // RX uart0
                  [email protected] { function = "output"; termination = "pull_up"; polarity="active_low"; }; // activity LED
                  [email protected] { function = "output"; termination = "no_pulling";    }; // Camera shutdown
                  [email protected] { function = "pwm";    termination = "no_pulling"; drive_strength_mA = < 16 >; }; // Left audio
                  [email protected] { function = "pwm";    termination = "no_pulling"; drive_strength_mA = < 16 >; }; // Right audio
                  [email protected] { function = "input";  termination = "no_pulling";    }; // Hotplug
                  [email protected] { function = "input";  termination = "no_pulling";    }; // SD card detect
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD CLK
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD CMD
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D0
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D1
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D2
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D3

               }; // pin_config
               pin_defines {
                  [email protected]_CONTROL_ATTACHED {
                     type = "internal";
                     number = <46>;
                  };
                  [email protected]_CAMERAS {
                     type = "internal";
                     number = <1>;
                  };
                  [email protected]_0_UNICAM_PORT {
                     type = "internal";
                     number = <1>;
                  };
                  [email protected]_0_I2C_PORT {
                     type = "internal";
                     number = <1>;
                  };
                  [email protected]_0_SDA_PIN {
                     type = "internal";
                     number = <2>;
                  };
                  [email protected]_0_SCL_PIN {
                     type = "internal";
                     number = <3>;
                  };
                  [email protected]_0_SHUTDOWN {
                     type = "internal";
                     number = <27>;
                  };
                  [email protected]_0_LED {
                     type = "internal";
                     number = <5>;
                  };
                  [email protected]_0_ENABLE {
                     type = "absent";
                  };
                  [email protected]_0_INDICATOR {
                     type = "absent";
                  };
                  [email protected]_1_ENABLE {
                     type = "absent";
                  };
                  [email protected]_1_INDICATOR {
                     type = "absent";
                  };
                  [email protected]_LOW {
                     type = "absent";
                  };
                  [email protected]_DISK_ACTIVITY {
                     type = "internal";
                     number = <16>;
                  };
                  [email protected]_RESET {
                     type = "internal";
                     number = <6>;
                  };
               }; // pin_defines
            }; // pins_rev1

            pins_rev2 {
               pin_config {
                  [email protected] {
                     polarity = "active_high";
                     termination = "pull_down";
                     startup_state = "inactive";
                     function = "input";
                  }; // pin
                  [email protected]  { function = "i2c0";   termination = "pull_up"; }; // I2C 0 SDA
                  [email protected]  { function = "i2c0";   termination = "pull_up"; }; // I2C 0 SCL
                  [email protected]  { function = "output"; termination = "pull_down"; }; // CAM_LED
                  [email protected]  { function = "output"; termination = "pull_down"; }; // LAN NRESET
                  [email protected] { function = "uart0";  termination = "no_pulling"; drive_strength_mA = < 8 >; }; // TX uart0
                  [email protected] { function = "uart0";  termination = "pull_up"; drive_strength_mA = < 8 >; }; // RX uart0
                  [email protected] { function = "output"; termination = "pull_up"; polarity = "active_low"; }; // activity LED
                  [email protected] { function = "output"; termination = "no_pulling";    }; // Camera shutdown
                  [email protected] { function = "pwm";    termination = "no_pulling"; drive_strength_mA = < 16 >; }; // Left audio
                  [email protected] { function = "pwm";    termination = "no_pulling"; drive_strength_mA = < 16 >; }; // Right audio
                  [email protected] { function = "input";  termination = "no_pulling";    }; // Hotplug
                  [email protected] { function = "input";  termination = "no_pulling";    }; // SD card detect
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD CLK
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD CMD
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D0
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D1
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D2
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D3

               }; // pin_config
               pin_defines {
                  [email protected]_CONTROL_ATTACHED {
                     type = "internal";
                     number = <46>;
                  };
                  [email protected]_CAMERAS {
                     type = "internal";
                     number = <1>;
                  };
                  [email protected]_0_I2C_PORT {
                     type = "internal";
                     number = <0>;
                  };
                  [email protected]_0_SDA_PIN {
                     type = "internal";
                     number = <0>;
                  };
                  [email protected]_0_SCL_PIN {
                     type = "internal";
                     number = <1>;
                  };
                  [email protected]_0_SHUTDOWN {
                     type = "internal";
                     number = <21>;
                  };
                  [email protected]_0_UNICAM_PORT {
                     type = "internal";
                     number = <1>;
                  };
                  [email protected]_0_LED {
                     type = "internal";
                     number = <5>;
                  };
                  [email protected]_0_ENABLE {
                     type = "absent";
                  };
                  [email protected]_0_INDICATOR {
                     type = "absent";
                  };
                  [email protected]_1_ENABLE {
                     type = "absent";
                  };
                  [email protected]_1_INDICATOR {
                     type = "absent";
                  };
                  [email protected]_LOW {
                     type = "absent";
                  };
                  [email protected]_DISK_ACTIVITY {
                     type = "internal";
                     number = <16>;
                  };
                  [email protected]_RESET {
                     type = "internal";
                     number = <6>;
                  };
                }; // pin_defines
            }; // pins

            pins_bplus {
               pin_config {
                  [email protected] {
                     polarity = "active_high";
                     termination = "pull_down";
                     startup_state = "inactive";
                     function = "input";
                  }; // pin
                  [email protected] { function = "uart0";  termination = "no_pulling"; drive_strength_mA = < 8 >; }; // TX uart0
                  [email protected] { function = "uart0";  termination = "pull_up"; drive_strength_mA = < 8 >; }; // RX uart0
                  [email protected] { function = "i2c0";   termination = "pull_up";    }; // I2C 0 SDA
                  [email protected] { function = "i2c0";   termination = "pull_up";    }; // I2C 0 SCL
                  [email protected] { function = "output"; termination = "pull_down"; }; // LAN NRESET
                  [email protected] { function = "output"; termination = "pull_down"; }; // Camera LED
                  [email protected] { function = "input";  termination = "no_pulling"; polarity = "active_low"; }; // Power low
                  [email protected] { function = "output"; termination = "no_pulling";    }; // USB current limit (0=600mA, 1=1200mA)
                  [email protected] { function = "pwm";    termination = "no_pulling"; drive_strength_mA = < 16 >; }; // Left audio
                  [email protected] { function = "output"; termination = "no_pulling";    }; // Camera enable
                  [email protected] { function = "gp_clk"; termination = "pull_down"; }; // Ethernet 25MHz output
                  [email protected] { function = "pwm";    termination = "no_pulling"; drive_strength_mA = < 16 >; }; // Right audio
                  [email protected] { function = "input";  termination = "no_pulling"; polarity = "active_low"; }; // Hotplug
                  [email protected] { function = "output"; termination = "pull_down"; }; // activity LED
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD CLK
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD CMD
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D0
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D1
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D2
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D3

               }; // pin_config
               pin_defines {
                  [email protected]_CONTROL_ATTACHED {
                     type = "internal";
                     number = <46>;
                  };
                  [email protected]_CAMERAS {
                     type = "internal";
                     number = <1>;
                  };
                  [email protected]_0_I2C_PORT {
                     type = "internal";
                     number = <0>;
                  };
                  [email protected]_0_SDA_PIN {
                     type = "internal";
                     number = <28>;
                  };
                  [email protected]_0_SCL_PIN {
                     type = "internal";
                     number = <29>;
                  };
                  [email protected]_0_SHUTDOWN {
                     type = "internal";
                     number = <41>;
                  };
                  [email protected]_0_UNICAM_PORT {
                     type = "internal";
                     number = <1>;
                  };
                  [email protected]_0_LED {
                     type = "internal";
                     number = <32>;
                  };
                  [email protected]_0_ENABLE {
                     type = "absent";
                  };
                  [email protected]_0_INDICATOR {
                     type = "absent";
                  };
                  [email protected]_1_ENABLE {
                     type = "absent";
                  };
                  [email protected]_1_INDICATOR {
                     type = "absent";
                  };
                  [email protected]_LOW {
                     type = "internal";
                     number = <35>;
                  };
                  [email protected]_DISK_ACTIVITY {
                     type = "internal";
                     number = <47>;
                  };
                  [email protected]_RESET {
                     type = "internal";
                     number = <31>;
                  };
                }; // pin_defines
            }; // pins

            pins_cm {
               pin_config {
                  [email protected] {
                     polarity = "active_high";
                     termination = "pull_down";
                     startup_state = "inactive";
                     function = "input";
                  }; // pin
                  [email protected] { function = "uart0";  termination = "no_pulling";    }; // TX uart0
                  [email protected] { function = "uart0";  termination = "pull_up"; }; // RX uart0
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD CLK
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD CMD
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D0
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D1
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D2
                  [email protected] { function = "sdcard"; termination = "pull_up";    drive_strength_mA = < 8 >; }; // SD D3

               }; // pin_config
               pin_defines {
               }; // pin_defines
            }; // pins_cm
   };
};
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

ShiftPlusOne
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 5857
Joined: Fri Jul 29, 2011 5:36 pm
Location: The unfashionable end of the western spiral arm of the Galaxy

Re: Camera flash driver released

Fri Aug 01, 2014 6:01 pm

I've updated the github PR with the blob source you've provided.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7135
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Camera flash driver released

Fri Aug 01, 2014 7:14 pm

ShiftPlusOne wrote:I've updated the github PR with the blob source you've provided.
Thank you. Has it been decided where the DTS file source is living within a git repo? I forgot to ask Dom.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

ShiftPlusOne
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 5857
Joined: Fri Jul 29, 2011 5:36 pm
Location: The unfashionable end of the western spiral arm of the Galaxy

Re: Camera flash driver released

Fri Aug 01, 2014 7:32 pm

6by9 wrote:
ShiftPlusOne wrote:I've updated the github PR with the blob source you've provided.
Thank you. Has it been decided where the DTS file source is living within a git repo? I forgot to ask Dom.
I've been meaning to ask that myself. Might be one for gsh and jdb.

jdb
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2071
Joined: Thu Jul 11, 2013 2:37 pm

Re: Camera flash driver released

Fri Aug 01, 2014 9:30 pm

ShiftPlusOne wrote:
6by9 wrote:
ShiftPlusOne wrote:I've updated the github PR with the blob source you've provided.
Thank you. Has it been decided where the DTS file source is living within a git repo? I forgot to ask Dom.
I've been meaning to ask that myself. Might be one for gsh and jdb.
It is indeed.

There's a .dtb currently incorporated into start.elf - it contains the GPIOMAN "default" settings for Pi rev1 B, rev2 B, B+, etc. We should make the .dts available and maintained in order to facilitate HAT development as well as the flash/privacy LED functionality incorporated on the videocore DT nodes.

For HATs, device tree fragments need the ability to symbolically link to nodes in the parent tree - you can only do this if you have the dtb or dts that Videocore provides to the ARM.
Rockets are loud.
https://astro-pi.org

wofwof42
Posts: 3
Joined: Wed Sep 10, 2014 9:50 pm

Re: Camera flash driver released

Wed Sep 10, 2014 10:15 pm

I've been trying to hack this into RaspiStill.c.
I got an external GPIO/LED turning on using the MMAL_PARAMETER_PRIVACY_INDICATOR,
so my wiring and dtc/dt-blob are working properly.

However, I can't enable the flash itself. All I get is error 3, MMAL_EINVAL.
I'm using PI model A. The basic code is

Code: Select all

MMAL_PARAMETER_FLASH_T camera_flash =
  {{MMAL_PARAMETER_FLASH, sizeof(MMAL_PARAMETER_FLASH_T)}, state.flash};
status = mmal_port_parameter_set(camera_still_port, &camera_flash.hdr);
where state.flash is a number from MMAL_PARAM_FLASH_T.

I place this code just before
mmal_port_parameter_set_boolean(camera_still_port, MMAL_PARAMETER_CAPTURE, 1).

Am I doing something incorrectly or is the camera flash not enabled for the older models (model A) or is the firmware not there yet?

ethanol100
Posts: 583
Joined: Wed Oct 02, 2013 12:28 pm

Re: Camera flash driver released

Wed Sep 10, 2014 11:39 pm

I think you need to set this to the camera control and not the still port. Can you try to change "camera_still_port" to
"state.camera_component->control"?

wofwof42
Posts: 3
Joined: Wed Sep 10, 2014 9:50 pm

Re: Camera flash driver released

Thu Sep 11, 2014 7:52 am

This made it work. Many thanks! Here is a patch to RaspiStill.c for anyone else interested:

Code: Select all

--- a/host_applications/linux/apps/raspicam/RaspiStill.c
+++ b/host_applications/linux/apps/raspicam/RaspiStill.c
@@ -150,6 +150,8 @@ typedef struct
 
    RASPITEX_STATE raspitex_state; /// GL renderer state and parameters
 
+   MMAL_PARAM_FLASH_T flash; /// Flash mode
+
 } RASPISTILL_STATE;
 
 /** Struct used to pass information in encoder port userdata to callback
@@ -187,6 +189,7 @@ static void store_exif_tag(RASPISTILL_STATE *state, const char *exif_tag);
 #define CommandSettings     19
 #define CommandCamSelect    20
 #define CommandBurstMode    21
+#define CommandFlashMode    22
 
 static COMMAND_LIST cmdline_commands[] =
 {
@@ -212,6 +215,7 @@ static COMMAND_LIST cmdline_commands[] =
    { CommandSettings, "-settings",  "set","Retrieve camera settings and write to stdout", 0},
    { CommandCamSelect, "-camselect","cs", "Select camera <number>. Default 0", 1 },
    { CommandBurstMode, "-burst",    "bm", "Enable 'burst capture mode'", 0},   
+   { CommandFlashMode, "-flash",    "fl", "Flash mode to use (off, auto, on, redeye, fillin, torch)", 1},
 };
 
 static int cmdline_commands_size = sizeof(cmdline_commands) / sizeof(cmdline_commands[0]);
@@ -247,6 +251,22 @@ static struct
 
 static int next_frame_description_size = sizeof(next_frame_description) / sizeof(next_frame_description[0]);
 
+static struct
+{
+  const char *name;
+  MMAL_PARAM_FLASH_T mode;
+} flash_modes[] =
+{
+  {"off", MMAL_PARAM_FLASH_OFF},
+  {"auto", MMAL_PARAM_FLASH_AUTO},
+  {"on", MMAL_PARAM_FLASH_ON},
+  {"redeye", MMAL_PARAM_FLASH_REDEYE},
+  {"fillin", MMAL_PARAM_FLASH_FILLIN},
+  {"torch", MMAL_PARAM_FLASH_TORCH},
+};
+
+static int flash_modes_size = sizeof(flash_modes) / sizeof(flash_modes[0]);
+
 /**
  * Assign a default set of parameters to the state passed in
  *
@@ -290,6 +310,7 @@ static void default_status(RASPISTILL_STATE *state)
    state->settings = 0;
    state->cameraNum = 0;
    state->burstCaptureMode=0;
+   state->flash = MMAL_PARAM_FLASH_OFF;
 
    // Setup preview window defaults
    raspipreview_set_defaults(&state->preview_parameters);
@@ -622,6 +643,28 @@ static int parse_cmdline(int argc, const char **argv, RASPISTILL_STATE *state)
          state->burstCaptureMode=1;
          break;
 
+      case CommandFlashMode :
+      {
+         int len = strlen(argv[i + 1]);
+         valid = 0;
+
+         if (len)
+         {
+            int j;
+            for (j = 0;j < flash_modes_size;j++)
+            {
+               if (strcmp(argv[i + 1], flash_modes[j].name) == 0)
+               {
+                  state->flash = flash_modes[j].mode;
+                  valid = 1;
+                  i++;
+                  break;
+               }
+            }
+         }
+         break;
+      }
+
       default:
       {
          // Try parsing for any image specific parameters
@@ -1852,6 +1895,21 @@ int main(int argc, const char **argv)
                      mmal_port_parameter_set_boolean(state.camera_component->control,  MMAL_PARAMETER_CAMERA_BURST_CAPTURE, 1);
                   }
 
+                  if (state.flash != MMAL_PARAM_FLASH_OFF)
+                  {
+                     if (state.verbose)
+                        fprintf(stderr, "Enabling flash mode %x\n", state.flash);
+
+                     MMAL_PARAMETER_FLASH_T camera_flash = {{MMAL_PARAMETER_FLASH, sizeof(MMAL_PARAMETER_FLASH_T)}, state.flash};
+
+                     status = mmal_port_parameter_set(state.camera_component->control, &camera_flash.hdr);
+                     if (status != MMAL_SUCCESS)
+                     {
+                        vcos_log_error("Could not set camera flash : error %d", status);
+                        goto error;
+                     }
+                  }
+
                   if (state.verbose)
                      fprintf(stderr, "Starting capture %d\n", frame);
 
For me only two flash modes seem to actually do anything: ON and TORCH.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7135
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Camera flash driver released

Thu Sep 11, 2014 4:05 pm

wofwof42 wrote:For me only two flash modes seem to actually do anything: ON and TORCH.
Auto should work if the tuner has determined that it is worth firing the flash (ie it is dark enough). I'm fairly certain I tried it whilst adding this and had it working.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

wofwof42
Posts: 3
Joined: Wed Sep 10, 2014 9:50 pm

Re: Camera flash driver released

Thu Sep 11, 2014 5:18 pm

6by9 wrote:
wofwof42 wrote:For me only two flash modes seem to actually do anything: ON and TORCH.
Auto should work if the tuner has determined that it is worth firing the flash (ie it is dark enough). I'm fairly certain I tried it whilst adding this and had it working.
Retested with the advantage of it being actually dark in the room now (thanks to nighttime). It works. I did try to cover it before but I guess enough light got through for the flash not to engage.

dchapma1
Posts: 16
Joined: Sun Aug 05, 2012 12:54 am
Location: Upstate New York

Re: Camera flash driver released

Fri Jan 16, 2015 7:39 pm

Well I am very new here and new to Raspberry Pi and the camera. I do have this wonderful camera working and have been experimenting with it.

I currently output a GPIO to an optocoupler that is driving some bright LEDs, capture an image and then turn the GPIO off. This is working but as I read through this thread I guess I do not understand exactly how to properly use this flash driver.

My code is being written using the excellent picamera API.

Can someone help me out here by providing some guidance on how to use this flash driver? I have a B+ and I am upgrading it as I type this to the latest stuff available. I do assume apt-get upgrade is the proper way to ensure I am running the latest firmware and OS.

Thanks much,

Don

User avatar
waveform80
Posts: 303
Joined: Mon Sep 23, 2013 1:28 pm
Location: Manchester, UK

Re: Camera flash driver released

Mon Mar 16, 2015 7:51 pm

Hi Don,
dchapma1 wrote:Well I am very new here and new to Raspberry Pi and the camera. I do have this wonderful camera working and have been experimenting with it.

I currently output a GPIO to an optocoupler that is driving some bright LEDs, capture an image and then turn the GPIO off. This is working but as I read through this thread I guess I do not understand exactly how to properly use this flash driver.

My code is being written using the excellent picamera API.

Can someone help me out here by providing some guidance on how to use this flash driver? I have a B+ and I am upgrading it as I type this to the latest stuff available. I do assume apt-get upgrade is the proper way to ensure I am running the latest firmware and OS.

Thanks much,

Don
Sorry I didn't notice this earlier. At the moment, picamera doesn't support the flash but it's being added in the next version, release 1.10 (which should be out sometime this month).

Dave.

dchapma1
Posts: 16
Joined: Sun Aug 05, 2012 12:54 am
Location: Upstate New York

Re: Camera flash driver released

Mon Mar 16, 2015 9:42 pm

Dave,

That is great news! Can't wait for the next release. With the flash enabled I can do so many more things with this wonderful solution.

Don

pindiza
Posts: 8
Joined: Sat Aug 16, 2014 11:23 am
Location: Warwickshire, UK

Re: Camera flash driver released

Mon May 11, 2015 2:11 pm

Great stuff... it works a treat for still captures in Picamera v1.10 !

Is there any possibility of making this work during video recording?

I'd like to trigger a powerful LED drive circuit to expose the video frames while using low frame rates and high shutter speeds. Using a strobe effect should drastically reduce the heat and power consumption which is important for my application. I'm not particularly concerned about the pulse timing in relation to the exposure starting time of each frame as long as its deterministic. The duration of each pulse isn't important either as I'll shift and stretch the timing in the external circuit, which is likely to be edge triggered anyway.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7135
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Camera flash driver released

Mon May 11, 2015 8:57 pm

pindiza wrote:Great stuff... it works a treat for still captures in Picamera v1.10 !

Is there any possibility of making this work during video recording?

I'd like to trigger a powerful LED drive circuit to expose the video frames while using low frame rates and high shutter speeds. Using a strobe effect should drastically reduce the heat and power consumption which is important for my application. I'm not particularly concerned about the pulse timing in relation to the exposure starting time of each frame as long as its deterministic. The duration of each pulse isn't important either as I'll shift and stretch the timing in the external circuit, which is likely to be edge triggered anyway.
Not easily. Certainly the driver isn't set up to do anything like that.

You don't say how low you intend to go on frame rate, so I don't know how much of a strobing you would get as the flash must be on for the entire time the frame is being exposed, and that is extended due to using a rolling shutter. If in the normal binned mode, then the minimum frame readout time is 23ms, so combine with a typical exposure time of 20ms, and you flash has to be on for 43ms per frame. Anything faster than 23fps would therefore not turn the LED off at all.
To get the accurate timing required for that, you would have to get the strobe line off the sensor working, except that isn't brought out on the standard camera board.

The only dirty hack I can think of is to end up toggling a GPIO on frame start and frame end interrupts, but those aren't absolutely reliable either. I also don't really want to start looking into that either as it is almost impossible to get a generic solution that works for everyone. Seeing as the flash driver is already playing with DT-blob, I could hide it in there with various options. I'll have a think.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

pindiza
Posts: 8
Joined: Sat Aug 16, 2014 11:23 am
Location: Warwickshire, UK

Re: Camera flash driver released

Tue May 12, 2015 4:44 pm

6by9 wrote:You don't say how low you intend to go on frame rate, so I don't know how much of a strobing you would get as the flash must be on for the entire time the frame is being exposed, and that is extended due to using a rolling shutter.
I'm using sensor mode 5, 12fps and shutter speeds below 1ms.
6by9 wrote:If in the normal binned mode, then the minimum frame readout time is 23ms, so combine with a typical exposure time of 20ms, and you flash has to be on for 43ms per frame.
This had me puzzled. I understood the difference between global and rolling shutters but assumed that the total duration to expose one frame would only be two or three times that of the shutter speed (1ms in my case) which was nowhere near the 23ms+ you stated. :shock:

So before disagreeing with you, I decided to make a strobe to do a bit of testing today ... turns out it pretty much confirmed your figures. I used 50% duty cycle and pulse widths ranging from 200us to 50ms on the strobe and only started seeing solid black frames at around 16ms which is less than 23ms but perhaps not unexpected because I use sensor mode 5 (16:9).

So I guess the absolute best I can expect is to have the flash on for a total of around 200ms (12x16ms) every second ... sadly I was hoping for as little as 40ms. Then again, 80% saving in power and heat might still be worth all the hassle as my project is battery powered.

Just a pity the strobe line from the sensor isn't accessible.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7135
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Camera flash driver released

Tue May 12, 2015 8:38 pm

pindiza wrote:
6by9 wrote:If in the normal binned mode, then the minimum frame readout time is 23ms, so combine with a typical exposure time of 20ms, and you flash has to be on for 43ms per frame.
This had me puzzled. I understood the difference between global and rolling shutters but assumed that the total duration to expose one frame would only be two or three times that of the shutter speed (1ms in my case) which was nowhere near the 23ms+ you stated. :shock:

So before disagreeing with you, I decided to make a strobe to do a bit of testing today ... turns out it pretty much confirmed your figures. I used 50% duty cycle and pulse widths ranging from 200us to 50ms on the strobe and only started seeing solid black frames at around 16ms which is less than 23ms but perhaps not unexpected because I use sensor mode 5 (16:9).

So I guess the absolute best I can expect is to have the flash on for a total of around 200ms (12x16ms) every second ... sadly I was hoping for as little as 40ms. Then again, 80% saving in power and heat might still be worth all the hassle as my project is battery powered.

Just a pity the strobe line from the sensor isn't accessible.
For each mode the sensor has a fixed time to read out a line due to the speed of the ADC. From the magic spreadsheet of Omnivision's, mode 5 (and mode 4) takes 23216ns to read out one line. Mode 5 has 730 lines, so the minimum time to read out a frame is 730 * 23216ns = 16.94ms. Frame rate is reduced by adding extra blanking lines to the frame. (Hmm, the min frame length is set at 870 lines which restricts us to 49.5fps, but we only have 730 active lines. In theory that allows for 59.5fps. Another one for me to check out)

A rolling shutter can be considered to be a read and a write pointer cycling through the image. Write = start exposure. Read = read out resulting values. The distance between the read and write pointer is the exposure time.
In your case, if you want a 1ms exposure, then the write pointer has to start 1ms before you start the 16.94ms required to read out the whole frame, so a total of 17.94ms. That extra exposure time for 12fps is within the additional blanking lines required for the reduced frame rate. If you were running at max fps, then the start of the frame would start exposing before the end of the previous frame had finished reading out.

From a post earlier today (viewtopic.php?f=43&t=48238&start=50#p756126), Arducam have just brought out a board that exposes the physical strobe line from the sensor (http://www.arducam.com/raspberry-pi-cam ... rformance/), but as far as I am aware, the register set we are using in the GPU driver does not tell the OV5647 to drive the strobe line at all. If I find myself with suddenly loads of time on my hands, then I might revisit that, but the likelihood is pretty remote, and the number of potential users is pretty small.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

sinc
Posts: 3
Joined: Tue Jun 02, 2015 3:44 pm

Re: Camera flash driver released

Tue Jun 02, 2015 4:33 pm

Thanks for all your hard work! This camera module makes prototyping new ideas amazingly easier than any alternative.

I am working on a project that takes advantage of your GPIO LED flash control and ran into a problem. With exposure_mode='off', it looks like the pulse is not synchronized with the shutter.

Repro (Python / picamera):
- Setup on-board LED as flash in device tree as per instructions
- Hold mirror to camera, capture photo using provided example code - works great: image captured shows LED lit
- add exposure_mode='off' to the camera setup
- Hold mirror to camera: LED visibly pulses, but captured photo does not show it lit

Any guidance appreciated!

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7135
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Camera flash driver released

Wed Jun 03, 2015 10:51 am

sinc wrote:I am working on a project that takes advantage of your GPIO LED flash control and ran into a problem. With exposure_mode='off', it looks like the pulse is not synchronized with the shutter.

Repro (Python / picamera):
- Setup on-board LED as flash in device tree as per instructions
- Hold mirror to camera, capture photo using provided example code - works great: image captured shows LED lit
- add exposure_mode='off' to the camera setup
- Hold mirror to camera: LED visibly pulses, but captured photo does not show it lit
Full manual control of shutter and gains when using a flash driver does not make sense - a flash requires recomputation of exposure parameters to compensate for the increased lighting provided by the flash, that is why the preflash is run to determine how much scene illumination the flash provides.
Admittedly it shouldn't incorrectly trigger - I'll add that to the list of things to look at.

A modified raspistill would be appreciated - picamera is not provided or maintained by the Foundation, and adds an extra layer of "stuff" in the way.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

sinc
Posts: 3
Joined: Tue Jun 02, 2015 3:44 pm

Re: Camera flash driver released

Wed Jun 03, 2015 3:56 pm

Thanks for the quick response!

Yes certainly using the flash trigger with fixed exposure settings is a niche case usually reserved for industrial, scientific, and artistic users. In this case we're photographing a known subject and are doing computation on the image, so consistency is pretty important. The trigger allows us to use high impulse power in our lighting. Like most postings here, this may just be another obscure use-case.

Agreed on the extra "stuff"--as soon as I have a moment I'll take a shot at a PR for flash support in raspistill.

Thanks again!

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7135
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Camera flash driver released

Wed Jun 03, 2015 4:28 pm

sinc wrote:Yes certainly using the flash trigger with fixed exposure settings is a niche case usually reserved for industrial, scientific, and artistic users. In this case we're photographing a known subject and are doing computation on the image, so consistency is pretty important. The trigger allows us to use high impulse power in our lighting. Like most postings here, this may just be another obscure use-case.
You're not really using the flash driver in a normal way - it will run a preflash sequence, recalculate exposure times and gains based on that preflash, a stats pass will occur, and AWB will recalculate red and blue gains based on those stats. That is the needed behaviour for a flash, and all adds to the latency on capture.

What duration can you boost the ltighting for?
You seemingly more want it just as a trigger for "capturing". That could be shifted back to userspace via a normal GPIO pin access, and should be relatively simple in raspistill.

You obviously know when you make your capture request via the mmal_port_parameter_set() call for MMAL_PARAMETER_CAPTURE. If you register for MMAL_PARAMETER_CHANGE_EVENT_RQUEST on MMAL_PARAMETER_CAPTURE_STATUS (see MMAL_PARAMETER_CAMERA_SETTINGS used for the -set option for an example), you should get 3 callbacks
  • first shortly after your request with staus MMAL_PARAM_CAPTURE_STATUS_CAPTURE_STARTED at the point the capture request has been submitted to the lower layers (flash cycles, focus cycles, and any other pre-capture processing completed).
  • second to MMAL_PARAM_CAPTURE_STATUS_CAPTURE_ENDED is a smidge later than ideal for you. It is when the ISP has finished producing the screen resolution output, which will be a few ms after the frame has finished being received. It will be delayed about 30ms if you run a stats pass, but it sounds like you don't want one of those anyway. (This was the first easy hook we had without doing lots of replumbing into the lower levels)
  • third to MMAL_PARAM_CAPTURE_STATUS_NOT_CAPTURING when the image processing is complete and the camera system has finished dealing with that capture.
Set your GPIO probably just before you make your request, clear it on CAPTURE_ENDED, and I think you'll get better results than trying to abuse the flash driver. Overall your lighting should still only be on for in the order of 3 frame times (probably 180ms), compared to probably 2 for the flash driver.

(You may be able to use CAPTURE_STARTED instead of when you make your request, but you're then at the mercy of Linux scheduling as to the delay before your userspace app can react to it. It depends on what your exposure time is compared to frame time as the sensor will be reading out a "drop" frame before the actual capture, but the exposing of the wanted frame may overlap with that - see my other explanations of rolling shutter and when lines get exposed. If your shutter speed is significantly less than 60ms (15fps mode), then you will almost certainly be OK).

I haven't checked this behaviour works on the Pi branch, but that is what should happen. If not then I should be able to cherry-pick fixes fairly easily to make it work in this way.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

Kozuch
Posts: 64
Joined: Sun Aug 10, 2014 10:35 am

Re: Camera flash driver released

Thu Feb 16, 2017 12:58 pm

I would like to use hardware flash sync signal for precise photo geotagging. If I understand this thread correctly, the flash driver is among other things able to send electric pulse to a given GPIO pin - is this correct? Since this is operated by the firmware I think the delay between frame exposure start and rising edge of the flash GPIO pulse should really be minimal (probably in the terms of microseconds?)... Can someone confirm this?

Thanks for the posted raspistill.c patch, but does someone actually have a fully working code example on how to map a given GPIO for the pulse? I preffer C++ but python or other language is ok too.

Thanks for your efforts in advance guys!

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7135
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Camera flash driver released

Thu Feb 16, 2017 1:44 pm

Kozuch wrote:I would like to use hardware flash sync signal for precise photo geotagging. If I understand this thread correctly, the flash driver is among other things able to send electric pulse to a given GPIO pin - is this correct? Since this is operated by the firmware I think the delay between frame exposure start and rising edge of the flash GPIO pulse should really be minimal (probably in the terms of microseconds?)... Can someone confirm this?

Thanks for the posted raspistill.c patch, but does someone actually have a fully working code example on how to map a given GPIO for the pulse? I preffer C++ but python or other language is ok too.
How fast are you moving such that you think you'll move much in the time between triggering the capture and the capture actually happening (typically <200ms)? And you don't get motion blur or rolling shutter effects at that speed?
Your GPS is unlikely to be updating more frequently than tens of milliseconds.

The flash driver is going to confuse both your logger (it produces multiple pulses) and the auto exposure algorithim anyway. It'll also delay the capture as AE is trying to work out correct settings for the flash/shutter speed/gain based on how much change the prefash made.
I would avoid trying to abuse it in the way you're suggesting.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

Kozuch
Posts: 64
Joined: Sun Aug 10, 2014 10:35 am

Re: Camera flash driver released

Thu Feb 16, 2017 3:23 pm

6by9, thanks for your fast reply!

I will be using a setup based on this hardware - RTK GPS is used and the flash sync signal is captured as a timestamp on GPS device and later interpolated for precise location. I basically want to replace the Sony NEX camera from that article with RPi camera. I dont mind if there is a delay from trigger to actual capture, I just need the flash sync to be as close as possible to the actual capture.

I see that the flash driver is probably more sophisticated that what I thought it is... So there is no simple way of how to only output the hw sync signal without messing any of the AE and other stuff? I wont be actually using the flash physically at all (my scene will be outdoors, well lit, or too far away...).

You say there are multiple pulses? How many and what do they mean? If I knew this I can probably filter these on my logger (which will be another RPi - I can sample GPIOs quite fast, right?) How long are the pulses? Can the preflash be disabled?

I think rolling shutter wont affect this kind of usage - even though I need precision my scene is moving slowly...

Return to “Camera board”