Bridge Supernova API 1.0

This document details the API for the Bridge service designed to interface with a variety of USB host adapters, particularly the Supernova produced by Binho, and their connected downstream devices.

Introduction

The Bridge Supernova API serves as an intermediary service, acting as a conduit for various client-side entities to seamlessly interact with specific USB host adapters, notably the Supernova host adapter developed by Binho. The API's main objective is to provide a flexible, unified, and extensible interface that masks the underlying intricacies of interfacing with USB devices. This abstraction allows for easier scalability and integration of more host adapters in the future, without significant disruptions to client applications.

Architecture Overview

1. Bridge Service Layer

At its core, the Bridge is a service written in Python, characterized by its ability to operate through a JSON-based REPL mechanism. By receiving command requests via stdin and returning command responses via stdout, the Bridge can be invoked effortlessly either from the command line or through SDKs that establish a process and redirect the necessary pipes. This design choice ensures a lightweight and agile communication paradigm that's adaptable to various deployment scenarios.

2. Command Adaptors

A distinctive feature of the Bridge's architecture is its use of command adaptors. Command adaptors are akin to drivers or plugins; they're designed to translate generic command requests into specialized SDK calls tailored to specific host adapters. This modular approach ensures that the core Bridge service remains uncluttered and can easily be expanded with more adaptors in the future.
For instance, the Supernova and Nova host adapters, produced by Binho, currently have their respective command adaptors. Each of these adaptors understands the idiosyncrasies of its corresponding host adapter and facilitates communication by converting the generic JSON command requests into precise SDK calls that these host adapters can comprehend.

3. Command and Response Structure

The Bridge adopts a standardized communication protocol wherein all command requests and responses are structured as JSON objects. A typical command request is composed of a transaction_id, a command denoting the action to be undertaken, and a params dictionary housing any associated parameters.
Upon receiving a command, the Bridge sends an acknowledgment in the form of a promise response. This immediate feedback mechanism is crucial for clients to know that their request is in the processing queue. Once the request is fully processed, the Bridge then dispatches a comprehensive final response detailing the outcome of the command.

Getting Started

To launch the Bridge for the Supernova host adapter:
python bridge.py BinhoSupernova

Command Structure

Commands are structured as JSON objects. Each command request requires a transaction_id, command, and params:
{
"transaction_id": "<string>",
"command": "<string>",
"params": "<dictionary>"
}
The Bridge typically sends an immediate promise response to acknowledge that the request is queued for processing. Once processed, a final response is returned. Command responses have the following structure:
{
"transaction_id": "<string>",
"status": "<string>",
"type": "<command_response|notification>",
"is_promise": "<boolean>",
"data": "<dictionary>"
}

Bridge Commands for Supernova

1. Open a Connection

  • Command Request:
    {
    "transaction_id": "2450",
    "command": "open",
    "params": {
    "address": "SupernovaSimulatedPort"
    }
    }
  • Responses:
    {
    "transaction_id": "2450",
    "status": "success",
    "type": "command_response",
    "is_promise": false,
    "data": {
    "command": "open",
    "id": "<Unique ID>",
    "port": "<Port Address>",
    "productName": "<Name of the Product>",
    "vendorId": "<Vendor ID>",
    "productId": "<Product ID>",
    "firmwareVersion": "<Firmware Version>",
    "hardwareVersion": "<Hardware Version>",
    "mode": "<Mode>"
    }
    }

2. I3C Bus Initialization

  • Command Request:
    {
    "transaction_id": "1",
    "command": "i3c_init_bus",
    "params": {
    "busVoltageInV": "3.3"
    }
    }
  • Responses:
    • Immediate Promise Response:
      {
      "transaction_id": "1",
      "status": "success",
      "type": "command_response",
      "is_promise": true,
      "data": {
      "command": "i3c_init_bus"
      }
      }
    • Final Response to Setting Bus Voltage:
      {
      "transaction_id": "1",
      "status": "success",
      "type": "command_response",
      "is_promise": false,
      "data": {
      "is_response_to": "i3c_set_bus_voltage",
      "status": "success",
      "result": {}
      }
      }
    • Final Response to Bus Initialization:
      {
      "transaction_id": "2",
      "status": "success",
      "type": "command_response",
      "is_promise": false,
      "data": {
      "is_response_to": "i3c_init_bus",
      "status": "success",
      "result": {}
      }
      }
    • Response to Get Target Device Table:
      {
      "transaction_id": "3",
      "status": "success",
      "type": "command_response",
      "is_promise": false,
      "data": {
      "is_response_to": "i3c_get_target_device_table",
      "status": "success",
      "result": {
      "payload": [
      {"static_address": "50", "dynamic_address": "08", "bcr": "10", "dcr": "C3", "pid": ["65", "64", "00", "00", "00", "00"]},
      {"static_address": "51", "dynamic_address": "09", "bcr": "10", "dcr": "C3", "pid": ["65", "64", "00", "00", "00", "00"]},
      {"static_address": "52", "dynamic_address": "0A", "bcr": "10", "dcr": "C3", "pid": ["65", "64", "00", "00", "00", "00"]},
      {"static_address": "53", "dynamic_address": "0B", "bcr": "03", "dcr": "63", "pid": ["5A", "00", "1D", "0F", "17", "02"]}
      ]
      }
      }
      }

3. Reset I3C Bus

  • Command Request:
    {
    "transaction_id": "2",
    "command": "i3c_reset_bus",
    "params": {}
    }
  • Responses:
    1. 1.
      Initial promise indicating the command is queued:
      {
      "transaction_id": "2",
      "status": "success",
      "type": "command_response",
      "is_promise": true,
      "data": {
      "command": "i3c_reset_bus"
      }
      }
    2. 2.
      Final response indicating the outcome of the reset command:
      {
      "transaction_id": "2",
      "status": "success",
      "type": "command_response",
      "is_promise": false,
      "data": {
      "is_response_to": "i3c_reset_bus",
      "status": "success",
      "result": {}
      }
      }
    3. 3.
      Response indicating the state of the target device table after reset:
      {
      "transaction_id": "2",
      "status": "success",
      "type": "command_response",
      "is_promise": false,
      "data": {
      "is_response_to": "i3c_get_target_device_table",
      "status": "success",
      "result": {
      "payload": []
      }
      }
      }

4. Set Bus Voltage

Set the bus voltage for the connected device.
  • Command Request:
    {
    "transaction_id": 4,
    "command": "i3c_set_bus_voltage",
    "params": {
    "busVoltageInV": "3.3"
    }
    }
  • Responses:
    Immediate promise response:
    {
    "transaction_id": "4",
    "status": "success",
    "type": "command_response",
    "is_promise": true,
    "data": {
    "command": "i3c_set_bus_voltage"
    }
    }
    Final response:
    {
    "transaction_id": "4",
    "status": "success",
    "type": "command_response",
    "is_promise": false,
    "data": {
    "is_response_to": "i3c_set_bus_voltage",
    "status": "success",
    "result": {}
    }
    }

5. I3C Write

5.1 Write Using Subaddress

  • Command Request:
    {
    "transaction_id": "5",
    "command": "i3c_write_using_subaddress",
    "params": {
    "address": "08",
    "subaddress": "0000",
    "mode": "SDR",
    "pushPullClockFrequencyInMHz": "5",
    "openDrainClockFrequencyInKHz": "2500",
    "writeBuffer": "DEADBEEF"
    }
    }
  • Responses:
    • Immediate Promise:
      {
      "transaction_id": "5",
      "status": "success",
      "type": "command_response",
      "is_promise": true,
      "data": {
      "command": "i3c_write_using_subaddress"
      }
      }
    • Final Response:
      {
      "transaction_id": "5",
      "status": "success",
      "type": "command_response",
      "is_promise": false,
      "data": {
      "is_response_to": "i3c_write_using_subaddress",
      "status": "success",
      "result": {
      "payload": [],
      "payload_size": 0
      }
      }
      }

5.2 Direct Write

  • Command Request:
    {
    "transaction_id": "6",
    "command": "i3c_write",
    "params": {
    "address": "08",
    "mode": "SDR",
    "pushPullClockFrequencyInMHz": "5",
    "openDrainClockFrequencyInKHz": "2500",
    "writeBuffer": "0000"
    }
    }
  • Responses:
    • Immediate Promise:
      {
      "transaction_id": "6",
      "status": "success",
      "type": "command_response",
      "is_promise": true,
      "data": {
      "command": "i3c_write"
      }
      }
    • Final Response:
      {
      "transaction_id": "6",
      "status": "success",
      "type": "command_response",
      "is_promise": false,
      "data": {
      "is_response_to": "i3c_write",
      "status": "success",
      "result": {
      "payload": [],
      "payload_size": 0
      }
      }
      }

6. I3C Read

6.1 Basic Read

  • Command Request:
    {
    "transaction_id": 7,
    "command": "i3c_read",
    "params": {
    "address": "08",
    "mode": "SDR",
    "pushPullClockFrequencyInMHz": "5",
    "openDrainClockFrequencyInKHz": "2500",
    "bytesToRead": "5"
    }
    }
  • Responses:
    {
    "transaction_id": "7",
    "status": "success",
    "type": "command_response",
    "is_promise": true,
    "data": {
    "command": "i3c_read"
    }
    }
    {
    "transaction_id": "7",
    "status": "success",
    "type": "command_response",
    "is_promise": false,
    "data": {
    "is_response_to": "i3c_read",
    "status": "success",
    "result": {
    "payload": ["DE", "AD", "BE", "EF", "00"],
    "payload_size": 5
    }
    }
    }

6.2 Read using Subaddress

  • Command Request:
    {
    "transaction_id": 8,
    "command": "i3c_read_using_subaddress",
    "params": {
    "address": "08",
    "mode": "SDR",
    "pushPullClockFrequencyInMHz": "5",
    "openDrainClockFrequencyInKHz": "2500",
    "subaddress": "0000",
    "bytesToRead": "5"
    }
    }
  • Responses:
    {
    "transaction_id": "8",
    "status": "success",
    "type": "command_response",
    "is_promise": true,
    "data": {
    "command": "i3c_read_using_subaddress"
    }
    }
    {
    "transaction_id": "8",
    "status": "success",
    "type": "command_response",
    "is_promise": false,
    "data": {
    "is_response_to": "i3c_read_using_subaddress",
    "status": "success",
    "result": {
    "payload": ["DE", "AD", "BE", "EF", "00"],
    "payload_size": 5
    }
    }
    }

7. CCC (Common Command Codes)

The CCC (Common Command Codes) provides a set of universal commands supported across multiple devices. The Bridge for Supernova has a few CCCs which can be used to interact with the downstream devices. This section details these CCCs.

7.1 GETPID

  • Command Request:
    {
    "transaction_id": 11,
    "command": "i3c_ccc_send",
    "params": {
    "cccParams": {
    "ccc": "GETPID",
    "address": "08",
    "pushPullClockFrequencyInMHz": "5",
    "openDrainClockFrequencyInKHz": "2500"
    }
    }
    }
  • Responses:
    1. 1.
      Immediate promise:
    {
    "transaction_id": "11",
    "status": "success",
    "type": "command_response",
    "is_promise": true,
    "data": {
    "command": "i3c_ccc_send"
    }
    }
    1. 2.
      Command result:
    {
    "transaction_id": "11",
    "status": "success",
    "type": "command_response",
    "is_promise": false,
    "data": {
    "is_response_to": "i3c_ccc_getpid",
    "status": "success",
    "result": {
    "payload": ["0", "0", "0", "0", "64", "65"],
    "payload_size": 6
    }
    }
    }

7.2 DIRECTSETMRL

  • Command Request:
    {
    "transaction_id": 13,
    "command": "i3c_ccc_send",
    "params": {
    "cccParams": {
    "ccc": "DIRECTSETMRL",
    "address": "08",
    "pushPullClockFrequencyInMHz": "5",
    "openDrainClockFrequencyInKHz": "2500",
    "writeBuffer": "10"
    }
    }
    }
  • Responses:
    1. 1.
      Immediate promise:
    {
    "transaction_id": "13",
    "status": "success",
    "type": "command_response",
    "is_promise": true,
    "data": {
    "command": "i3c_ccc_send"
    }
    }
    1. 2.
      Command result:
    {
    "transaction_id": "13",
    "status": "success",
    "type": "command_response",
    "is_promise": false,
    "data": {
    "is_response_to": "i3c_ccc_direct_setmrl",
    "status": "success",
    "result": {
    "payload": ["00", "00"],
    "payload_size": 2
    }
    }
    }

Currently Supported CCCs:

  • GETBCR
  • GETDCR
  • GETPID
  • GETMRL
  • GETMWL
  • DIRECTSETMRL
  • DIRECTSETMWL
  • BROADCASTSETMRL
  • BROADCASTSETMWL

Error Handling

The Bridge service returns error messages in a specific format when a command request fails to be executed as expected.

Error Message Structure

Every error message returned by the Bridge service has the following structure:
{
"transaction_id": "<string>",
"status": "failure",
"type": null,
"is_promise": false,
"data": {
"error": "<Description of the Error>"
}
}
Where:
  • transaction_id: Represents the ID of the command request that resulted in the error.
  • status: Always set to "failure" for error messages.
  • type: Typically set to null for error messages.
  • is_promise: Set to false for error messages as they represent the final state of the command request.
  • data: Contains a description of the error.

Handling Errors

When encountering an error:
  1. 1.
    Logging: Always log the error messages for future reference and troubleshooting.
  2. 2.
    Validation: Ensure that the command requests being sent are valid and adhere to the Bridge's API specification.
  3. 3.
    Software Updates: Make sure the Bridge software and the SDK for the Supernova host adapter are up to date.
  4. 4.
    Seek Support: If unable to resolve an error, consider reaching out to the support team or consulting the documentation.