Skip to content

Commit 7b0d2f7

Browse files
authored
Merge pull request #4116 from raspberrypi/develop
Deploy to production
2 parents 7db840e + 9e5c51a commit 7b0d2f7

File tree

10 files changed

+266
-161
lines changed

10 files changed

+266
-161
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
with:
3333
version: 1.10.2
3434
- name: Install arm-none-eabi-gcc GNU Arm Embedded Toolchain
35-
uses: carlosperate/[email protected].0
35+
uses: carlosperate/[email protected].1
3636
- name: Install Doxygen
3737
run: |
3838
wget https://www.doxygen.nl/files/doxygen-1.10.0.linux.bin.tar.gz

documentation/asciidoc/accessories/camera/external_trigger.adoc

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,6 @@ We can use a Raspberry Pi Pico to provide the trigger. Connect any Pico GPIO pin
2121

2222
image::images/pico_wiring.jpg[alt="Image showing Raspberry Pi Pico wiring",width="50%"]
2323

24-
==== Boot up the Raspberry Pi with the camera connected.
25-
26-
Enable external triggering through superuser mode:
27-
28-
[source,console]
29-
----
30-
$ sudo su
31-
$ echo 1 > /sys/module/imx296/parameters/trigger_mode
32-
$ exit
33-
----
34-
3524
==== Raspberry Pi Pico MicroPython Code
3625

3726
[source,python]
@@ -55,15 +44,37 @@ The low pulse width is equal to the shutter time, and the frequency of the PWM e
5544

5645
NOTE: In this example, Pin 28 connects to the XTR touchpoint on the GS camera board.
5746

58-
=== Operation
47+
=== Camera driver configuration
48+
49+
This step is only necessary if you have more than one camera with XTR wired in parallel.
50+
51+
Edit `/boot/firmware/config.txt`. Change `camera_auto_detect=1` to `camera_auto_detect=0`.
52+
53+
Append this line:
54+
[source]
55+
----
56+
dtoverlay=imx296,always-on
57+
----
58+
When using the CAM0 port on a Raspberry Pi 5, CM4 or CM5, append `,cam0` to that line without a space. If both cameras are on the same Raspberry Pi you will need two dtoverlay lines, only one of them ending with `,cam0`.
59+
60+
If the external trigger will not be started right away, you also need to increase the libcamera timeout xref:camera.adoc#libcamera-configuration[as above].
61+
62+
=== Starting the camera
63+
64+
Enable external triggering:
65+
66+
[source,console]
67+
----
68+
$ echo 1 | sudo tee /sys/module/imx296/parameters/trigger_mode
69+
----
5970

60-
Run the code on the Pico, and set the camera running:
71+
Run the code on the Pico, then set the camera running:
6172

6273
[source,console]
6374
----
6475
$ rpicam-hello -t 0 --qt-preview --shutter 3000
6576
----
6677

67-
Every time that the Pico pulses the pin, it should generate a frame. To control the framerate, vary the duration between pulses.
78+
Every time the Pico pulses the pin, it should capture a frame. However, if `--gain` and `--awbgains` are not set, some frames will be dropped to allow AGC and AWB algorithms to settle.
6879

69-
NOTE: When running `rpicam-apps`, always specify a fixed shutter duration to ensure the AGC does not adjust the camera's shutter speed. The duration does not matter, since it is actually controlled by the external trigger pulse.
80+
NOTE: When running `rpicam-apps`, always specify a fixed shutter duration, to ensure the AGC does not try to adjust the camera's shutter speed. The value is not important, since it is actually controlled by the external trigger pulse.
Lines changed: 59 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,108 @@
11
== Synchronous Captures
22

3-
Both the HQ Camera and the Global Shutter Camera, have support for synchronous captures.
4-
Making use of the XVS pin (Vertical Sync) allows one camera to pulse when a frame capture is initiated.
5-
The other camera can then listen for this sync pulse, and capture a frame at the same time as the other camera.
3+
The High Quality (HQ) Camera supports synchronous captures.
4+
One camera (the "source") can be configured to generate a pulse on its XVS (Vertical Sync) pin when a frame capture is initiated.
5+
Other ("sink") cameras can listen for this pulse, and capture a frame at the same time as the source camera.
66

7-
=== Using the HQ Camera
7+
This method is largely superseded by xref:../computers/camera_software.adoc#software-camera-synchronisation[software camera synchronisation] which can operate over long distances without additional wires and has sub-millisecond accuracy. But when cameras are physically close, wired synchronisation may be used.
88

9-
For correct operation, both cameras require a 1.65V pull up voltage on the XVS line, which is created by a potential divider through the 3.3V and GND pins on the Raspberry Pi.
9+
NOTE: Global Shutter (GS) Cameras can also be operated in a synchronous mode. However, the source camera will record one extra frame. Instead, for GS Cameras we recommend using an xref:camera.adoc#external-trigger-on-the-gs-camera[external trigger source]. You cannot synchronise a GS Camera and an HQ Camera.
1010

11-
image::images/synchronous_camera_wiring.jpg[alt="Image showing potential divider setup",width="50%"]
11+
=== Connecting the cameras
1212

13-
Create a potential divider from two 10kΩ resistors to 3.3V and ground (to make 1.65V with an effective source impedance of 5kΩ). This can be connected to either Raspberry Pi.
13+
Solder a wire to the XVS test point of each camera, and connect them together.
1414

15-
Solder the GND and XVS test points of each HQ Camera board to each other.
15+
Solder a wire to the GND test point of each camera, and connect them together.
1616

17-
Connect the XVS wires to the 1.65V potential divider pull-up.
17+
*For GS Cameras only,* you will also need to connect the XHS (Horizontal Sync) test point of each camera together. On any GS Camera that you wish to act as a sink, bridge the two halves of the MAS pad with solder.
1818

19-
==== Boot up both Raspberry Pis
19+
NOTE: An earlier version of this document recommended an external pull-up for XVS. This is no longer recommended. Instead, ensure you have the latest version of Raspberry Pi OS and set the `always-on` property for all connected cameras.
2020

21-
The file `/sys/module/imx477/parameters/trigger_mode` determines which board outputs pulses, or waits to receive pulses (source and sink).
22-
This parameter can only be altered in superuser mode.
21+
=== Driver configuration
2322

24-
Run the following commands to configure the sink:
23+
You will need to configure the camera drivers to keep their 1.8V power supplies on when not streaming, and optionally to select the source and sink roles.
2524

26-
[source,console]
25+
==== For the HQ Camera
26+
27+
Edit `/boot/firmware/config.txt`. Change `camera_auto_detect=1` to `camera_auto_detect=0`.
28+
29+
Append this line for a source camera:
30+
[source]
2731
----
28-
$ sudo su
29-
$ echo 2 > /sys/module/imx477/parameters/trigger_mode
30-
$ exit
32+
dtoverlay=imx477,always-on,sync-source
3133
----
3234

33-
Run the following commands to configure the source:
34-
35-
[source,console]
35+
Or for a sink:
36+
[source]
3637
----
37-
$ sudo su
38-
$ echo 1 > /sys/module/imx477/parameters/trigger_mode
39-
$ exit
38+
dtoverlay=imx477,always-on,sync-sink
4039
----
4140

42-
Run the following command to start the sink:
41+
When using the CAM0 port on a Raspberry Pi 5, CM4 or CM5, append `,cam0` to that line without a space. If two cameras are on the same Raspberry Pi you will need two dtoverlay lines, only one of them ending with `,cam0`.
42+
43+
Alternatively, if you wish to swap the cameras' roles at runtime (and they are not both connected to the same Raspberry Pi), omit `,sync-source` or `,sync-sink` above. Instead you can set a module parameter before starting each camera:
4344

45+
For the Raspbery Pi with the source camera:
4446
[source,console]
4547
----
46-
$ rpicam-vid --frames 300 --qt-preview -o sink.h264
48+
$ echo 1 | sudo tee /sys/module/imx477/parameters/trigger_mode
4749
----
4850

49-
Run the following command to start the source:
50-
51+
For the Raspberry Pi with the sink camera:
5152
[source,console]
5253
----
53-
$ rpicam-vid --frames 300 --qt-preview -o source.h264
54+
$ echo 2 | sudo tee /sys/module/imx477/parameters/trigger_mode
5455
----
56+
You will need to do this every time the system is booted.
5557

56-
Frames should be synchronous. Use `--frames` to ensure the same number of frames are captured, and that the recordings are exactly the same length.
57-
Running the sink first ensures that no frames are missed.
58-
59-
NOTE: The potential divider is needed to pull up the XVS pin to high whilst the source is in an idle state. This ensures that no frames are created or lost upon startup. The source whilst initialising goes from LOW to HIGH which can trigger a false frame.
60-
61-
=== Use the GS Camera
58+
==== For the GS Camera
6259

63-
NOTE: The Global Shutter (GS) camera can also be operated in a synchronous mode. However, the source camera will record one extra frame. A much better alternative method to ensure that both cameras capture the same amount of frames is to use the xref:camera.adoc#external-trigger-on-the-gs-camera[external trigger method].
60+
Edit `/boot/firmware/config.txt`. Change `camera_auto_detect=1` to `camera_auto_detect=0`.
6461

65-
To operate as source and sink together, the Global Shutter Cameras also require connection of the XHS (horizontal sync) pins together. However, these do not need connection to a pullup resistor.
66-
67-
The wiring setup is identical to the xref:camera.adoc#using-the-hq-camera[HQ Camera method], except that you will also need to connect the XHS pins together.
68-
69-
Create a potential divider from two 10kΩ resistors to 3.3V and ground (to make 1.65V with an effective source impedance of 5kΩ). This can be connected to either Raspberry Pi.
70-
71-
Solder 2 wires to the XVS test points on each board and connect both of these wires together to the 1.65V potential divider.
62+
For either a source or a sink, append this line:
63+
[source]
64+
----
65+
dtoverlay=imx296,always-on
66+
----
67+
When using the CAM0 port on a Raspberry Pi 5, CM4 or CM5, append `,cam0` to that line without a space. If two cameras are on the same Raspberry Pi you will need two dtoverlay lines, only one of them ending with `,cam0`.
7268

73-
Solder the GND of each Camera board to each other. Also solder 2 wires to the XHS test points on each board and connect these. No pullup is needed for XHS pin.
69+
On the GS Camera, the sink role is enabled by the MAS pin and cannot be configured by software ("trigger_mode" and "sync-sink" relate to the xref:camera.adoc#external-trigger-on-the-gs-camera[external trigger method], and should _not_ be set for this method).
7470

75-
On the boards that you wish to act as sinks, solder the two halves of the MAS pad together. This tells the sensor to act as a sink, and will wait for a signal to capture a frame.
71+
=== Libcamera configuration
7672

77-
==== Boot up source and sink
73+
If the cameras are not all started within 1 second, the `rpicam` applications can time out. To prevent this, you must edit a configuration file on any Raspberry Pi(s) with sink cameras.
7874

79-
Run the following command to start the sink:
75+
On Raspberry Pi 5 or CM5:
76+
[source,console]
77+
----
78+
$ cp /usr/share/libcamera/pipeline/rpi/pisp/example.yaml timeout.yaml
79+
----
8080

81+
On other Raspberry Pi models:
8182
[source,console]
8283
----
83-
$ rpicam-vid --frames 300 -o sync.h264
84+
$ cp /usr/share/libcamera/pipeline/rpi/vc4/rpi_apps.yaml timeout.yaml
8485
----
8586

86-
Due to the limitations of the IMX296 sensor, the sink cannot record exactly the same number of frames as the source. **The source records one extra frame before the sink starts recording**. Because of this, you need to specify that the sink records one less frame with the `--frames` option.
87+
Now edit the copy. In both cases, delete the `#` (comment) from the `"camera_timeout_value_ms":` line, and change the number to `60000` (60 seconds).
8788

88-
Wait at least two seconds before you start the source.
89+
=== Starting the cameras
8990

90-
After waiting two seconds, run the following command to start the source:
91+
Run the following commands to start the sink:
9192

9293
[source,console]
9394
----
94-
$ rpicam-vid --frames 299 -o sync.h264
95+
$ export LIBCAMERA_RPI_CONFIG_FILE=timeout.yaml
96+
$ rpicam-vid --frames 300 --qt-preview -o sink.h264
9597
----
9698

97-
Because the sink and source record a different number of frames, use `ffmpeg` to resync the videos. By dropping the first frame from the source, we then get two recordings with the same starting point and frame length:
99+
Wait a few seconds, then run the following command to start the source:
98100

99101
[source,console]
100102
----
101-
$ ffmpeg -i source.h264 -vf select="gte(n\, 1)" source.h264
103+
$ rpicam-vid --frames 300 --qt-preview -o source.h264
102104
----
105+
Frames should be synchronised. Use `--frames` to ensure the same number of frames are captured, and that the recordings are exactly the same length.
106+
Running the sink first ensures that no frames are missed.
107+
108+
NOTE: When using the GS camera in synchronous mode, the sink will not record exactly the same number of frames as the source. **The source records one extra frame before the sink starts recording**. Because of this, you need to specify that the sink records one less frame with the `--frames` option.

documentation/asciidoc/computers/camera/rpicam_options_common.adoc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,3 +571,24 @@ The number of buffers to allocate for still image capture or for video recording
571571
==== `viewfinder-buffer-count`
572572
573573
As the `buffer-count` option, but applies when running in preview mode (that is `rpicam-hello` or the preview, not capture, phase of `rpicam-still`).
574+
575+
==== `metadata`
576+
577+
Save captured image metadata to a file or `-` for stdout. The fields in the metadata output will depend on the camera model in use.
578+
579+
See also `metadata-format`.
580+
581+
==== `metadata-format`
582+
583+
Format to save the metadata in. Accepts the following values:
584+
585+
* `txt` for text format
586+
* `json` for JSON format
587+
588+
In text format, each line will have the form
589+
590+
key=value
591+
592+
In JSON format, the output is a JSON object.
593+
594+
This option does nothing unless `--metadata` is also specified.

documentation/asciidoc/computers/config_txt/boot.adoc

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,26 @@ If `erase_eeprom` is set to `1` then `recovery.bin` will erase the entire SPI EE
189189

190190
Default: `0`
191191

192+
[[set_reboot_arg1]]
193+
==== `set_reboot_arg1`
194+
Raspberry Pi 5 only.
195+
196+
Sets the value of `boot_arg1` to be passed via a reset-safe register to the bootloader after a reboot.
197+
See xref:config_txt.adoc#boot_arg1[`boot_arg1`] for more details.
198+
Default: ``
199+
200+
[[set_reboot_order]]
201+
==== `set_reboot_order`
202+
203+
Raspberry Pi 5 only.
204+
205+
Sets the value of xref:raspberry-pi.adoc#BOOT_ORDER[BOOT_ORDER] to be passed via a reset-safe register to the bootloader after a reboot. As with `tryboot`, this is a one-time setting and is automatically cleared after use.
206+
207+
This property could be used to debug different xref:raspberry-pi.adoc#BOOT_ORDER[BOOT_ORDER] settings. Alternatively, it could be used in a provisioning system which has control over power and the `nRPIBOOT` GPIO to override the boot mode without specifying xref:config_txt.adoc#conditional-filters[conditional filter] statements in the EEPROM config.
208+
209+
Default: ``
210+
211+
192212
[[eeprom_write_protect]]
193213
==== `eeprom_write_protect`
194214

@@ -255,14 +275,21 @@ Default: `0`
255275
[[revoke_devkey]]
256276
==== `revoke_devkey`
257277

258-
If this property is set to `1` then `recovery.bin` will write a value to OTP that prevents the ROM from loading old versions of the second stage bootloader which do not support `secure-boot`. This prevents `secure-boot` from being turned off by reverting to an older release of the bootloader.
278+
Raspberry Pi 4 only.
279+
280+
If this property is set to `1` then `recovery.bin` will write a value to OTP that prevents the ROM from loading old versions of the second stage bootloader which do not support `secure-boot`. This prevents `secure-boot` from being turned off by reverting to an older release of the bootloader. Therefore, this property must be set if `secure-boot` is enabled on production devices.
281+
282+
This property is automatically is set by `recovery.bin` `2025/05/16` and newer if `program_pubkey=1`.
283+
259284

260285
Default: `0`
261286

262287
[[program_rpiboot_gpio]]
263288
==== `program_rpiboot_gpio`
264289

265-
Compute Modules have a dedicated `nRPIBOOT` jumper to select `RPIBOOT` mode. Flagship and Keyboard Raspberry Pi devices with EEPROM lack a dedicated `nRPIBOOT` jumper. To select `RPIBOOT` mode on Flagship and Keyboard devices, pull one of the following GPIO pins low:
290+
Raspberry Pi 4B and Raspberry Pi 400 only.
291+
292+
Compute Module 4 and 4S have a dedicated `nRPIBOOT` jumper to select `RPIBOOT` mode. Raspberry Pi 4B and Raspberry Pi 400 lack a dedicated `nRPIBOOT` jumper so one of the following GPIOs must be selected for use as `nRPIBOOT`.
266293

267294
* `2`
268295
* `4`
@@ -271,11 +298,11 @@ Compute Modules have a dedicated `nRPIBOOT` jumper to select `RPIBOOT` mode. Fla
271298
* `7`
272299
* `8`
273300

274-
This property does not depend on `secure-boot`. However, you should verify that this GPIO configuration does not conflict with any HATs which might pull the GPIO low during boot.
301+
The GPIO may be used as a general-purpose I/O pin after the OS has started. However, you should verify that this GPIO configuration does not conflict with any HATs which might pull the GPIO low during boot.
275302

276-
For safety, this property can _only_ be programmed via `RPIBOOT`. As a result, you must first clear the bootloader EEPROM using `erase_eeprom`. This causes the ROM to failover to `RPIBOOT` mode, which then allows this option to be set.
303+
Although `secure-boot` requires this property to be set on Raspberry Pi 4B and Raspberry Pi 400, it does not depend on `secure-boot`. For example, `RPIBOOT` can be useful for automated testing.
277304

278-
On BCM2712, you can alternatively force `RPIBOOT` mode by holding down the power button while simultaneously connecting a USB-C power supply.
305+
For safety, this OTP value can _only_ be programmed via `RPIBOOT`. As a result, you must first clear the bootloader EEPROM using `erase_eeprom`. The blank EEPROM causes the ROM to failover to `RPIBOOT` mode, which then allows this option to be set.
279306

280307
Default: `{nbsp}`
281308

0 commit comments

Comments
 (0)