SoC to Microcontroller Communications

NVIDIA Camera Control Protocol

Since the Microcontroller Unit (MCU) has access to the Camera Interface Module (CIM), the MCU controls camera power and multiplex camera control between different devices. NVIDIA Camera Control Protocol (NVCCP) is used to send camera control commands from SoC to the MCU and receive acknowledgement back. The communication is conducted over ethernet.
Warning:
Consult the Operating System Release Notes before making any changes to the default configuration of the platform.
For the DRIVE AGX platform, Camera Control Protocol (NVCCP) is implemented using the generic shared user-space library (libtacp.so)and the NVCCP user-space daemon (nvccp_daemon).
All camera applications intending to use NVCCP shall link to the NVCCP user space library. The library layer exports a set of APIs which the camera applications shall use.
A screenshot of a cell phone Description automatically generatedThe NVCCP user-space daemon runs on the Xavier in the same partition as the camera application. The daemon waits for NVCCP messages from the camera application that is linking to the NVCCP user library. Any message received at the daemon is forwarded to the MCU and the response is received from the MCU. This response is then sent back to the camera application. The NVCCP daemon also auto releases ownership of a camera group if the camera application using that camera group crashes or exits. The daemon is launched at startup. The following diagram explains the communication flow.
 

Camera Control Protocol

The NVIDIA Camera Control Protocol is used to control the states of the Cameras and Camera Aggregators/De-Serializers from Xavier A, Xavier B, and Xavier CVM by communicating with the MCU. It is an application level protocol which carries the camera and aggregator states. It has been designed to handle multiple captures from multiple SoCs. It satisfies these requirements:
1. Frame Sync Control
All use cases enforce Xavier A to be booted and generating Frame Sync.
Xavier A is ALWAYS chosen as Frame Sync source at MCUboot.
All four FRSYNC buffers are to be enabled by default at MCUboot.
2. Camera Group Ownership
Any camera application MUST request a camera group ownership using request_ownership() API before power control and release the ownership using release_ownership()API at application exit.
Each Xavier can capture independently as primary if they capture on camera groups exclusive to each other.
A camera group can ONLY have one primary and one secondary for dual Xavier capture.
For all dual Xavier cases, Xavier A is ALWAYS the Primary and Xavier B is ALWAYS the secondary.
3. Power Control
Each Xavier MUST register itself as primary or secondary using request_ownership()API before using the power control APIs.
Only Primary can hardware power ON the deserializer/cameras. Secondary cannot issue power ON before Primary.
Either Primary or Secondary can hardware power OFF based on the exit sequence.
These requirements are implemented in the form of state machines in the MCU Firmware. There is a state machine associated with each camera unit and a state machine for each camera aggregator. Therefore, each camera group has five state machines associated with it.
The state for any camera is as follows.
Execution of each command on MCU returns a Status message to the invoking Tegra providing information about the execution.
The Transitions denote the commands generated from Primary or Secondary and the returned Status.
For either Tegra to execute commands in the state machine, the Tegra must register itself by requesting ownership of the camera group as Primary or secondary.
The logic flow for this process is as follows.

Library Usage and Configuration

The default configuration files are provided in the root file system at:
/etc/tacp/tacp_non_vlan.cfg
/etc/tacp/tacp_vlan.cfg
This configuration file is used by libtacp.so to obtain the required values such as:
Remote MCU IP
Tegra IP
Receive timeout values
Model and interface information.
The configuration file supports these parameters:
AURIX_IP_ADDRESS=<ip address>
TEGRA_A_IP_ADDRESS=<ip address>
TEGRA_B_IP_ADDRESS=<ip address>
TEGRACVM_IP_ADDRESS=<ip address>
TEGRA_IP_ADDRESS=<ip address>
AURIX_SERVER_PORT=<server port>
model=<interface>
RECEIVE_TIMEOUT_S=<value>
RECEIVE_TIMEOUT_US=<value>
CLIENT_DAEMON_TIMEOUT_S=<value>
AURIX_EASYCAN_PORT=50000
TEGRA_EASYCAN_PORT=60395
SPI_RECEIVE_TIMEOUT_US=100000
Where:
<interface> must be VLAN interface eth0.200.
Note:
All SoC-MCU communication moved from virtual Ethernet interface to fixed VLAN based interface; therefore, the <interface> value is fixed to eth0.200 and is not configurable.
In the case of the Ethernet interface, the required parameters are:
AURIX_IP_ADDRESS
<model>=<interface>
In the case of the ethernet interface, these parameters are used for automatic IP assignment by nv_tacp_init service while booting.
 
Xavier
TEGRA_A_IP_ADDRESS
TEGRA_B_IP_ADDRESS
TEGRA_CVM_IP_ADDRESS
NVCCP ethernet interface to the MCU is supported on AURIX_SERVER_PORT 5000 only.
For NVCCP ethernet interface, AURIX and SoC IP address in the configuration file must match the IP address stored in AURIX.
Example of settings in tacp.cfg:
AURIX_IP_ADDRESS=10.42.0.146
TEGRA_A_IP_ADDRESS=10.42.0.28
TEGRA_B_IP_ADDRESS=10.42.0.29
TEGRA_CVM_IP_ADDRESS=10.42.0.30
AURIX_SERVER_PORT=5000
RECEIVE_TIMEOUT_S=5
RECEIVE_TIMEOUT_US=0
CLIENT_DAEMON_TIMEOUT_S=5
 
The communication between the NVCCP user-space library and the NVCCP daemon happens using TCP protocol.
Following are the port numbers used for communication between the NVCCP user-space library and the NVCCP daemon. The are fixed and cannot be changed by configuration.
Daemon Endpoint:
IP Address
Port
Localhost
5200
Client Endpoints
The Client has multiple TCP endpoints. These endpoints are based on the camera group/ownership combination. These ports are defined as follows:
Camera Group
Ownership
IP Address
Port
0
Primary
Localhost
5100
0
Secondary
Localhost
5101
1
Primary
Localhost
5102
1
Secondary
Localhost
5103
2
Primary
Localhost
5104
2
Secondary
Localhost
5105
3
Primary
Localhost
5106
3
Secondary
Localhost
5107
The Client also has a pool of generic endpoints that are used for NVCCP API not related to camera group ownership as follows:
IP Address
Port
Localhost
5150
Localhost
5151
Localhost
5152
Localhost
5153
Localhost
5154

Supported APIs

The file ccp.h provides the APIs for various commands and camera structures. There are four camera groups in Xavier enumerated as A, B, C, and D. Each camera group has an associated aggregator which must be turned on before a camera can be powered on. Each camera group also has four individual camera units enumerated from 1 to 16.
Camera Group Id ENUM
typedef enum {
NVCCP_GROUP_A = 0x00,
NVCCP_GROUP_B = 0x01,
NVCCP_GROUP_C = 0x02,
NVCCP_GROUP_D = 0x03
} nvccp_cam_group_id;
 
Camera Unit Id ENUM
typedef enum{
/* Camera group A */
NVCCP_CAM_A0 = 0x01,
NVCCP_CAM_A1 = 0x02,
NVCCP_CAM_A2 = 0x04,
NVCCP_CAM_A3 = 0x08,
/* Camera group B */
NVCCP_CAM_B0 = 0x10,
NVCCP_CAM_B1 = 0x20,
NVCCP_CAM_B2 = 0x40,
NVCCP_CAM_B3 = 0x80,
/* Camera group C */
NVCCP_CAM_C0 = 0x0100,
NVCCP_CAM_C1 = 0x0200,
NVCCP_CAM_C2 = 0x0400,
NVCCP_CAM_C3 = 0x0800,
/* Camera group D */
NVCCP_CAM_D0 = 0x1000,
NVCCP_CAM_D1 = 0x2000,
NVCCP_CAM_D2 = 0x4000,
NVCCP_CAM_D3 = 0x8000
} nvccp_cam_id;
 
NVCCP Command Status ENUM
typedef enum {
NVCCP_STATUS_OK = 0,
NVCCP_STATUS_DENIED,
NVCCP_STATUS_NOT_REGISTERED,
NVCCP_STATUS_ALREADY_ON,
NVCCP_STATUS_ALREADY_OFF,
NVCCP_STATUS_SLAVE_RUNNING,
NVCCP_REQ_FILE_OP_FAIL = 1000,
NVCCP_REQ_TIMEOUT,
NVCCP_REQ_INVALID,
NVCCP_REQ_DENIED,
NVCCP_REQ_FAILED,
NVCCP_REQ_CONNECT_ERR,
} nvccp_return_t;
Camera Ownership Mode ENUM
typedef enum {
NVCCP_CAM_MASTER = 0x01,
NVCCP_CAM_SLAVE
} nvccp_cam_mode;
Tegra Id ENUM
typedef enum {
NVCCP_TEGRA_A = 0x41,
NVCCP_TEGRA_B = 0x42
} nvccp_tegra_id;
NVCCP command APIs
nvccp_return_t nvccp_request_ownership(nvccp_cam_group_id cam_group,nvccp_cam_mode cam_master);
nvccp_return_t nvccp_release_ownership(nvccp_cam_group_id cam_group,nvccp_cam_mode cam_master);
nvccp_return_t nvccp_set_cam_pwr_on(nvccp_cam_group_id cam_group);
nvccp_return_t nvccp_set_cam_pwr_off(nvccp_cam_group_id cam_group);
nvccp_return_t nvccp_set_cam_unit_pwr_on(nvccp_cam_id cam_id);
nvccp_return_t nvccp_set_cam_unit_pwr_off(nvccp_cam_id cam_id);
nvccp_return_t nvccp_set_aggreg_pwr_on(nvccp_cam_group_id cam_group);
nvccp_return_t nvccp_set_aggreg_pwr_off(nvccp_cam_group_id cam_group);
nvccp_return_t nvccp_set_frsync_owner(nvccp_tegra_id tegra_id);
nvccp_return_t nvccp_set_frsync_enable(nvccp_cam_group_id cam_group);
nvccp_return_t nvccp_set_frsync_disable(nvccp_cam_group_id cam_group);
nvccp_return_t nvccp_get_cam_unit_pwr_status(uint16_t *cam_id);
nvccp_return_t nvccp_get_aggreg_pwr_status(uint8_t *cam_group);
nvccp_return_t nvccp_get_frsync_enable_status(uint8_t *cam_group);

CCP Sample Application Usage

The ccp_test_app can be used to test the NVCCP functionality. It provides a command line interface to execute each of the NVCCP commands from the SoC. When the application requests for a group ownership, it will retain the ownership of the camera group until it explicitly releases the ownership or the application dies. This can be exercised by the "wait" argument to the ccp_test_app application while requesting ownership. If the application dies or the "nowait" option is used, the camera group ownership will be automatically released by the NVCCP daemon when the cpp_test_app application exits. 
Command Usage
./ccp_test_app req_ownership m/master/s/slave a/b/c/d wait/nowait
./ccp_test_app rel_ownership m/master/s/slave a/b/c/d
./ccp_test_app set_cam_agg_pwr_on a/b/c/d
./ccp_test_app set_cam_agg_pwr_off a/b/c/d
./ccp_test_app set_cam_pwr_on a/b/c/d
./ccp_test_app set_cam_pwr_off a/b/c/d
./ccp_test_app set_cam_unit_pwr_on 0-15
./ccp_test_app set_cam_unit_pwr_off 0-15
./ccp_test_app set_cam_fsync_en a/b/c/d
./ccp_test_app set_cam_fsync_dis a/b/c/d
./ccp_test_app set_cam_fsync_owner ta/tb
./ccp_test_app get_cam_unit_pwr_status
./ccp_test_app get_cam_agg_pwr_status
./ccp_test_app multithread_test <no of threads>

Use cases

Single SoC Capture Use case
Dual SoC Capture Use case
 
 
 
 
 
 

Common Interface for Soc to MCU communication

MCU manages Power-On, Power-Off, Recovery, Reset sequence of SoC on DRIVE AGX board. It supports re-flashing its firmware and its configuration, and GPIO based boot chain selection of SoC firmware.
User application on SoC such as Driver Update communicate with MCU to harvest these features of MCU. This communication is established through Common Interface which exposes set of interfaces on SoC and connects to MCU using UDP over ethernet.
Common Interface offers below features:
Set and get Hyperion configuration from MCU firmware
Enable, disable, and get current state of L3SS from MCU firmware
Read InfoROM dump
Set Bootstrap
Get current version information of MCU firmware
Validate MCU firmware to be flashed for compatibility
Flash program Update and Production MCU firmware
Set GPIO based Boot chain configuration
Read current configuration of GPIO based Boot chain configuration
SoC reboot and MCU reboot
 
Below diagram provides positioning of Common Interface modules in the system:
 
 
 

Library Usage and Configuration

User applications intending to use these functionalities shall link to Common Interface Library (libmcu_common_if.so).
 
Availability of these features are build configuration dependent. All features are available on standard build whereas Boot Chain APIs are available in safety build also.
 
Configurable parameters are maintained in tacp configuration file. Appropriate changes must be made at MCU if the parameter values are altered.
Parameter applicable for Common Interface are listed below :
IP address of MCU: AURIX_IP_ADDRESS=10.42.0.146
IP address of Tegra A: TEGRA_A_IP_ADDRESS=10.42.0.28
Server Port on MCU: AURIX_BOOTCHAIN_PORT=5001
VLAN ID : e3550_t194a=eth0.200

Common Interface Sample Application Usage

The common_if_testapp is a command line interface to verify supported features. Executing “common_if_testapp -h“ lists supported commands with briefs description.
Examples of command with short description:
Resets MCU. Reset the complete DRIVE AGX board
#common_if_testapp -mcureset
 
Reset Tegra x1
#common_if_testapp -tegrareset x1
 
Sets default boot chain of Tegra x1 to A
#common_if_testapp -set_default_bootchain x1 A
 
Makes Tegra x1 to boot from non default boot chain on next boot
#common_if_testapp -set_next_bootchain x1 Alternate
 
Gets the default boot chain for Tegra of x1
#common_if_testapp -get_default_bootchain x1
 
Gets active/current boot chain for Tegra x1
#common_if_testapp -get_active_bootchain x1
 
Flashes given production firmware
#common_if_testapp -flash_mcu_fw lib/firmware/DRIVE-V5.2.3-E3550-AFW-Aurix-With3LSS-StepA-4.03.01.hex
 
Flashes given update firmware
#common_if_testapp -flash_mcu_ufw lib/firmware/DRIVE-V5.2.x-E3550-NV-Aurix-UPDATE-StepA-1.29.16.hex
 
Reads currently running firmware version
 
#common_if_testapp -get_fw_version
 
Reads update firmware version flashed on MCU
#common_if_testapp -get_update_fw_version
 
Reads the version of the hexfile from its content
#common_if_testapp -get_mcu_hexfile_version lib/firmware/DRIVE-V5.2.x-E3550-NV-Aurix-UPDATE-StepA-1.29.16.hex
 
Reads data from infoROM dump
#common_if_testapp -get_inforom_dump
 
Sets Tegra x1 boot strap medium to QSPI
#common_if_testapp -set_bootstrap x1 qspi
 
Enable Safety Services on MCU.
#common_if_testapp -safety_services enable
 
Gets current Hyperion Configuration on MCU
#common_if_testapp -hyperion_cfg getStatus
 
Reboot MCU in Production FW mode
#common_if_testapp -reboot_mcu_afw
 
Reboot MCU in Update-FW mode
#common_if_testapp -reboot_mcu_ufw

Programming Sequence

Flowchart for production firmware flash programming
Flowchart for update firmware flash programming