{"id":18262928,"url":"https://github.com/capablerobot/camera-trigger-gateware","last_synced_at":"2025-04-04T20:30:59.028Z","repository":{"id":63381192,"uuid":"333865096","full_name":"CapableRobot/Camera-Trigger-Gateware","owner":"CapableRobot","description":null,"archived":false,"fork":false,"pushed_at":"2022-12-03T02:14:23.000Z","size":137,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-20T18:09:53.432Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CapableRobot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-28T19:03:58.000Z","updated_at":"2024-04-21T13:53:30.000Z","dependencies_parsed_at":"2023-01-22T21:00:18.429Z","dependency_job_id":null,"html_url":"https://github.com/CapableRobot/Camera-Trigger-Gateware","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CapableRobot%2FCamera-Trigger-Gateware","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CapableRobot%2FCamera-Trigger-Gateware/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CapableRobot%2FCamera-Trigger-Gateware/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CapableRobot%2FCamera-Trigger-Gateware/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CapableRobot","download_url":"https://codeload.github.com/CapableRobot/Camera-Trigger-Gateware/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247246235,"owners_count":20907755,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-05T11:09:18.649Z","updated_at":"2025-04-04T20:30:58.364Z","avatar_url":"https://github.com/CapableRobot.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Camera Trigger Gateware\n\n### Background\n\nThis FPGA Gateware is for for the Capable Robot [Jetson TX2 / AGX Camera Interface](https://capablerobot.com/products/agx-camera-interface/).  This product:\n\n- Exposes 6x MIPI CSI-2 Camera Interfaces (2-lane) on 22-pin, 0.5mm pitch ribbon cable connectors.\n- Has an on-board Lattice ICE40UP5K FPGA provides independent or synchronized camera trigger and reset sigals. \n- Exposes an additional 4 GPIO / sync / trigger signals from the FPGA on an Auxiliary Connector (6-pin JST GH).\n\n![](https://capablerobot.imgix.net/images/agx-camera-interface/PCB-top.jpg?fit=fillmax\u0026fill=solid\u0026fill-color=FFFFFF\u0026trim=auto\u0026pad=20\u0026w=800\u0026h=440)\n\nMore information on the hardware is on the [Capable Robot website](https://capablerobot.com/products/agx-camera-interface/).\n\n### Usage\n\nOnce flashed onto the SPI Flash, the gateware can be controlled via a set of registers via I2C from the host processor.  Currently, the register mapping is:\n\n```\nName               Addr      Length  Default    RO\n-----------------  ------  --------  ---------  -----\nProduct ID         0x00           6  CRFDJ1     True\nHardware Revision  0x06           1  10         True\nGateware Revision  0x07           1  1          True\nCamera Count       0x0A           1  6          True\nGPIO Count         0x0B           1  4          True\nTrigger Count      0x0C           1  4          True\n\nClock Divider      0x14           1  10         False\nPower Control      0x15           1  3          False\nPower Sense        0x16           1  0          True\n\nCrossbar A0        0x20           1  64         False\nCrossbar A1        0x21           1  64         False\nCrossbar A2        0x22           1  64         False\nCrossbar A3        0x23           1  64         False\nCrossbar A4        0x24           1  64         False\nCrossbar A5        0x25           1  64         False\nCrossbar A6        0x26           1  64         False\nCrossbar A7        0x27           1  64         False\nCrossbar B0        0x28           1  64         False\nCrossbar B1        0x29           1  64         False\nCrossbar B2        0x2A           1  64         False\nCrossbar B3        0x2B           1  64         False\nCrossbar B4        0x2C           1  64         False\nCrossbar B5        0x2D           1  64         False\nCrossbar B6        0x2E           1  64         False\nCrossbar B7        0x2F           1  64         False\n\nTrigger Enables    0x3C           1  0          False\nTrigger0 Mode      0x40           1  0          False\nTrigger0 Interval  0x41           1  0          False\nTrigger0 Duration  0x42           1  0          False\nTrigger0 Delay     0x43           1  0          False\nTrigger1 Mode      0x48           1  0          False\nTrigger1 Interval  0x49           1  0          False\nTrigger1 Duration  0x4A           1  0          False\nTrigger1 Delay     0x4B           1  0          False\nTrigger2 Mode      0x50           1  0          False\nTrigger2 Interval  0x51           1  0          False\nTrigger2 Duration  0x52           1  0          False\nTrigger2 Delay     0x53           1  0          False\nTrigger3 Mode      0x58           1  0          False\nTrigger3 Interval  0x59           1  0          False\nTrigger3 Duration  0x5A           1  0          False\nTrigger3 Delay     0x5B           1  0          False\n```\n\n**Important Note about the I2C Register Interface :** The gateware currently has a limitation where register can only be written-to or read-from one at a time.  If you want to update two numerically adjacent registers, you must do 2x 1-byte transactions instead of a 2-byte transactions.\n\n### Notes on specific registers:\n\nThe **Clock Divider** register allows you to change how the internal 10 kHz clock is divides.  The default value is 10, which results in a 1 ms tick -- e.g. Trigger Interval, Duration, and Delay values are in 1 ms increments.  If trigger intervals longer than 255 ms are desired, the divider change be changed to a larger value.  A setting of 100 results in a 10 ms tick, meaning that Trigger Interval, Duration, and Delay values are in 10 ms increments -- allowing for intervals of 2.55 seconds.\n\nThe **Power Control** and **Power Sense** registers have the following bit field mapping:\n\n* Bit 0 : Camera FFC 3.3v rail\n* Bit 1 : Camera FFC 5.0v rail (provided via external connector)\n* All other bits are reserved\n\nThe **Crossbar** registers have the following bit field mapping:\n\n* Bit 0 to 3 : The trigger this output is assigned to\n* Bit 4 : Reserved\n* Bit 5 : Output inverts the assigned trigger\n* Bit 6 : Default value for the output when Output Enable is false (default value is 1)\n* Bit 7 : Output Enable\n\nCrossbar A0 thru A7 are normally the \"trigger\" GPIO on attached camera while B0 thru B7 are normally the \"reset / enable\" GPIO on the attached camera -- but the crossbar allow arbitrary assignment between outputs and triggers, so the opposite mapping can be done.\n\nCrossbar A0 and B0 connect to the FFC which contains CSI0 and who's I2C bus goes through output 0 of the I2C Mux.  Crossbar A1 and B1 map to CSI1 and I2C Mux ouptut 1, etc.  On the CRFDJ1 Interface there is an exception to this -- CSI6 and CSI7 connect to A4/B4 and A5/B5 and I2C Mux outputs 4 and 5.  You can consider CSI6 to be the 4th camera (0 indexing) on the interface and CSI7 to be the 5th camera (0 indexing).\n\nThe **Trigger Enable** register allows you to enable all, or a sub-set of triggers atomically.  Bit 0 enables trigger 0, bit 1 enables trigger 1, etc.\n\nThe **Trigger Mode** registers have the following capability:\n\n* 0x00 : Trigger is stopped\n* 0x01 : Trigger is idle.  Internal gateware logic will go to this state after a one-shot trigger is executed\n* 0x02 : Interval trigger with a settable duration [..-...-...]\n* 0x03 : Oneshot trigger with a settable duration [..-.......]\n* 0x04 : Constant trigger (e.g. infinite one-shot) [..-------]\n\nAll trigger modes (Interval, Oneshot, Constant) respond to the delay register.  Trigger modes, intervals, durations, \u0026 delay can all be changed on the fly and settings take effect immediately.  If you are changing a number of settings, you might want to disable the trigger (via the appropiate bit in the Trigger Enable Register) to prevent partial updates.\n\n### Example Interval Trigger\n\nIn the below screen shot the controller is configured like such:\n\n* Trigger 0 is setup with an interval of 20 ms and a duration of 10 ms.\n* Trigger 1 is setup with an interval of 20 ms and a duration of 5 ms, with a 5 ms delay.\n* Triggers are enabled\n* (100 ms pass)\n* Trigger 0 interval is changed to 10 ms and duration changed to 5 ms.\n* Trigger 1 is inverted (well actually, the invert bit on the crossbar output displayed is set) \n* (100 ms pass)\n* Triggers are disabled\n\n![VCD Trace](./images/interval_trigger.png)\n\n### Toolchain Installation\n\nInstall the [open-source FPGA toolchain](https://github.com/YosysHQ/fpga-toolchain).  \n\nThen install [nmigen](https://github.com/migen/migen) and [tabulate](https://github.com/astanin/python-tabulate) via PIP:\n\n```\npip install -r requirements.txt\n```\n\n### Building the Gateware\n\nTo target the PCB hardware:\n\n```\npython3 gateware/target.py ice\n```\n\nTo emit a VCD from the simulator:\n\n```\npython3 gateware/target.py sim\n```\n\nThe VCD file can be view using a viewer like [GTKWave](http://gtkwave.sourceforge.net) or [WaveTrace](https://www.wavetrace.io).  In this simulation, 2 ms pass before MODE is set to 0x02 (interval trigger) with a trigger duration of 2 ms and interval of 8 ms.  After 20 ms, the trigger duration and interval change to 5 ms and 10 ms.\n\n![VCD Trace](./images/vcd.png)\n\n### License\n\nThis project is distributed under the terms Apache 2.0 license.\n\nSee [LICENSE](LICENSE) for details.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcapablerobot%2Fcamera-trigger-gateware","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcapablerobot%2Fcamera-trigger-gateware","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcapablerobot%2Fcamera-trigger-gateware/lists"}