.. _examples:

Examples
========

The `examples/` directory included in the CosmicSDK package provides working sample projects that demonstrate how to use the SDK in both **blocking** and **asynchronous** modes, across various communication protocols.

These examples are categorized by:

- **API Mode**: Blocking or Async
- **Language**: C, C++, Python, C#, Java
- **Protocol**: I2C, SPI, UART, I3C, GPIO, etc.

You can use these examples as a starting point for your own applications or to validate your SDK installation and device setup.

Async API Examples (C++)
------------------------

.. list-table::
   :widths: 30 70
   :header-rows: 1

   * - Protocol
     - Directory
   * - I2C
     - ``examples/async_api/i2c/``  

Blocking API Examples (C and C++)
---------------------------------

.. list-table::
   :widths: 30 30 40
   :header-rows: 1

   * - Protocol
     - Language
     - Directory
   * - I2C
     - C
     - ``examples/blocking_api/i2c/c/``
   * - I2C
     - C++
     - ``examples/blocking_api/i2c/cpp/``
   * - SPI
     - C
     - ``examples/blocking_api/spi/c/``
   * - SPI
     - C++
     - ``examples/blocking_api/spi/cpp/``
   * - UART
     - C
     - ``examples/blocking_api/uart/c/``
   * - UART
     - C++
     - ``examples/blocking_api/uart/cpp/``
   * - GPIO
     - C
     - ``examples/blocking_api/gpio/c/``
   * - GPIO
     - C++
     - ``examples/blocking_api/gpio/cpp/``
   * - I3C (Basic API)
     - C
     - ``examples/blocking_api/i3c/basic/c/``
   * - I3C (Basic API)
     - C++
     - ``examples/blocking_api/i3c/basic/cpp/``
   * - I3C (CCC)
     - C
     - ``examples/blocking_api/i3c/ccc/c/``
   * - I3C (CCC)
     - C++
     - ``examples/blocking_api/i3c/ccc/cpp/``
   * - I3C (DAA)
     - C
     - ``examples/blocking_api/i3c/daa/c/``
   * - I3C (DAA)
     - C++
     - ``examples/blocking_api/i3c/daa/cpp/``
   * - I3C (HDR-DDR)
     - C
     - ``examples/blocking_api/i3c/hdr-ddr/c/``
   * - I3C (HDR-DDR)
     - C++
     - ``examples/blocking_api/i3c/hdr-ddr/cpp/``
   * - I3C (Hot-Join + IBI)
     - C
     - ``examples/blocking_api/i3c/hj-ibi/c/``
   * - I3C (Hot-Join + IBI)
     - C++
     - ``examples/blocking_api/i3c/hj-ibi/cpp/``
   * - System
     - C
     - ``examples/blocking_api/system/c/``
   * - System
     - C++
     - ``examples/blocking_api/system/cpp/``

Language Bindings Examples
--------------------------

CosmicSDK includes sample code demonstrating how to use the SDK from other programming languages via bindings. For further details on integrating the CosmicSDK into other language platforms, refer to section :ref:`language_bindings`.

.. list-table::
   :widths: 20 80
   :header-rows: 1

   * - Language
     - Directory
   * - Python
     - ``examples/language_bindings/python/``
   * - C#
     - ``examples/language_bindings/csharp/``
   * - Java
     - ``examples/language_bindings/java/``

Protocol-Specific Example Guides
--------------------------------

Use the following protocol pages for hardware setup details and walkthroughs:

.. toctree::
   :maxdepth: 1

   examples/protocol_i2c
   examples/protocol_spi
   examples/protocol_uart
   examples/protocol_gpio
   examples/protocol_i3c
   examples/protocol_system

How to Build and Run the C and C++ Examples
-------------------------------------------

This section provides instructions on building and running the C/C++ examples on different operating systems. As for the language bindings examples, refer to section :ref:`language_bindings`.

To build any of the C or C++ examples, follow the instructions below based on your operating system:

**(Optional) Define environment variables**

These variables shorten commands in the steps below:

bash:

.. code-block:: bash

   export SDK_PATH=<path-to-package-root>
   export SDK_LIB_PATH="$SDK_PATH/lib"
   export SDK_INCLUDE_PATH="$SDK_PATH/include"
   export EXAMPLE_PATH="$SDK_PATH/examples/blocking_api/i2c/cpp"

cmd:

.. code-block:: bat

   set SDK_PATH=<path-to-package-root>
   set SDK_LIB_PATH=%SDK_PATH%\lib
   set SDK_INCLUDE_PATH=%SDK_PATH%\include
   set EXAMPLE_PATH=%SDK_PATH%\examples\blocking_api\i2c\cpp

.. note::
   - Replace ``<path-to-package-root>`` with the root folder of your package contents (for example: ``/home/username/CosmicSDK`` or ``C:\CosmicSDK``).
   - Adjust ``EXAMPLE_PATH`` to match the example you want to build and run.
   - Use one console consistently for all commands in a section:
      - **Windows sections** use **Command Prompt** syntax.
      - **Linux/macOS sections** use **Bash** syntax.
   - If you use **PowerShell** on Windows, translate as follows:
      - ``set VAR=value`` -> ``$env:VAR = "value"``
      - ``%VAR%`` -> ``$env:VAR``
      - Command continuation ``^`` -> PowerShell continuation `` ` `` (or run in one line).

Windows (MSVC)
~~~~~~~~~~~~~~

Building the C++ Example
^^^^^^^^^^^^^^^^^^^^^^^^

1. **Open a Developer Command Prompt for Visual Studio.**

2. **Navigate to the C++ example directory:**

Use the `EXAMPLE_PATH` variable defined above.

.. code-block:: bat
   
   cd /d "%EXAMPLE_PATH%"

3. **Configure and Build with CMake:**

If using **MSBuild**:

.. code-block:: bat
   
   cmake -B build ^
         -DLIBRARY_PATH=%SDK_LIB_PATH% ^
         -DINCLUDE_PATH=%SDK_INCLUDE_PATH% ^
         -G "Visual Studio 17 2022" -A [Win32|x64]
   
   cmake --build build --config [Debug|Release]

.. note::
   - Replace `[Win32|x64]` with `Win32` for a 32-bit build or `x64` for a 64-bit build.
   - For CMake versions 4.x.x it may be required to add the `-DCMAKE_POLICY_VERSION_MINIMUM=3.5` flag.

If using **Ninja**:

.. code-block:: bat
   
   call "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" [x86|x64]
   
   cmake -B build ^
         -DLIBRARY_PATH=%SDK_LIB_PATH% ^
         -DINCLUDE_PATH=%SDK_INCLUDE_PATH% ^
         -G "Ninja"

   cmake --build build

.. note::
   - Replace `[x86|x64]` with the architecture you need.
   - For CMake versions 4.x.x it may be required to add the `-DCMAKE_POLICY_VERSION_MINIMUM=3.5` flag.

Running the C++ Example
^^^^^^^^^^^^^^^^^^^^^^^^

1. **Set the `PATH` to include the CosmicSDK library:**
   Ensure `SDK_LIB_PATH` points to your package library folder (`lib` or `lib\debug`).

.. code-block:: bat
   
   set PATH=%PATH%;%SDK_LIB_PATH%
   
2. **Run the examples:**

- **Dynamic Example:**

.. code-block:: bat
   
   cd /d %EXAMPLE_PATH%\build\Release
   example_cpp_dynamic.exe

- **Static Example:**

.. code-block:: bat

   cd /d %EXAMPLE_PATH%\build\Release
   example_cpp_static.exe

.. note::
   
   - Ensure `%SDK_LIB_PATH%` points to the directory containing the CosmicSDK library.
   - Ensure you use a **Developer Command Prompt for Visual Studio** to build the project.
   - If using Ninja, ensure that it's installed and available in your `PATH`.


Windows (MinGW)
~~~~~~~~~~~~~~~

Prerequisites
^^^^^^^^^^^^^

Install MinGW-w64
"""""""""""""""""

**Option 1: Manual installation.**

1. Download the installer from |mingw|.
2. Install it to `C:\\mingw64` (recommended to avoid spaces and permission issues).
3. Add the `bin` directory to your system `PATH`:

.. code-block:: bat
   
   set PATH=%PATH%;C:\mingw64\bin
   

**Option 2: Install with Chocolatey (Recommended for Simplicity)**

If you have |chocolatey| installed, you can use it to install MinGW-w64 easily:

1. Open a Command Prompt as Administrator.
2. Run the following command:

.. code-block:: bat

   choco install mingw --version=11.2.0 -y


3. Once installed, ensure the MinGW `bin` directory is in your `PATH`:

.. code-block:: bat

   set PATH=%PATH%;C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin


Chocolatey typically installs MinGW-w64 under `C:\ProgramData\chocolatey`.


Install Ninja
"""""""""""""

Download **Ninja** manually from the |ninja|, or use Chocolatey:

.. code-block:: bat
   
   choco install ninja -y


After installation, verify that `ninja` is available in your `PATH` by running:

.. code-block:: bat

   ninja --version


Building the C++ Example
^^^^^^^^^^^^^^^^^^^^^^^^

1. Open a Command Prompt and ensure the environment is correctly configured. In particular, ensure the path to `mingw-w64\bin` was set correctly as explained above. 

2. **Navigate to the C++ example directory:**

   Use the `EXAMPLE_PATH` variable defined above.

.. code-block:: bat
   
   cd /d %EXAMPLE_PATH%

3. **Run CMake with Ninja as the generator and build the project:**

.. code-block:: bat

   cmake -B build ^
         -DCMAKE_C_COMPILER="gcc.exe" ^
         -DCMAKE_CXX_COMPILER="g++.exe" ^
         -DLIBRARY_PATH=%SDK_LIB_PATH% ^
         -DINCLUDE_PATH=%SDK_INCLUDE_PATH% ^
         -G "Ninja"

   cmake --build build
  

.. note::
   - For CMake versions 4.x.x it may be required to add the `-DCMAKE_POLICY_VERSION_MINIMUM=3.5` flag.

Running the C++ Example
^^^^^^^^^^^^^^^^^^^^^^^^

1. **Set the `PATH` to include the CosmicSDK library:**
   Ensure `SDK_LIB_PATH` points to your package library folder (`lib` or `lib\debug`).

.. code-block:: bat
   
   set PATH=%PATH%;%SDK_LIB_PATH%

2. **Run the examples:**

- **Dynamic Example:**

.. code-block:: bat
   
   cd /d %EXAMPLE_PATH%\build
   example_cpp_dynamic.exe

- **Static Example:**

.. code-block:: bat

   cd /d %EXAMPLE_PATH%\build
   example_cpp_static.exe

.. note::

   - Ensure `%SDK_LIB_PATH%` points to the directory containing the CosmicSDK library.
   - Use `C:\\mingw64` for MinGW installation to simplify configuration and prevent permission issues.
   - Ensure `windres` is accessible via `C:\\mingw64\\bin` in your `PATH`.


macOS
~~~~~

Building and Running the C++ Example
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

1. **Navigate to the C++ example directory:**

Use the `EXAMPLE_PATH` variable defined above.

.. code-block:: bash
   
   cd $EXAMPLE_PATH

2. **Run CMake with the specified library and include paths:**

.. code-block:: bash
   
   cmake -B build -DLIBRARY_PATH="$SDK_LIB_PATH" -DINCLUDE_PATH="$SDK_INCLUDE_PATH"

3. **Build the example:**

.. code-block:: bash
   
   cmake --build build

4. **Run the dynamic and static examples:**

For the dynamic example:

.. code-block:: bash
   
   DYLD_LIBRARY_PATH="$SDK_LIB_PATH":$DYLD_LIBRARY_PATH ./build/example_cpp_dynamic

For the static example:

.. code-block:: bash
   
   ./build/example_cpp_static


Linux
~~~~~

Building and Running the C++ Example
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

1. **(Recommended) Install udev rules for non-root access:**

.. code-block:: bash

   chmod +x "$SDK_PATH/scripts/install_udev_rules.sh"
   sudo "$SDK_PATH/scripts/install_udev_rules.sh"

Unplug and replug the device after installing the rules.

2. **Navigate to the C++ example directory:**

.. code-block:: bash

   cd $EXAMPLE_PATH

3. **Run CMake with the specified library and include paths:**

.. code-block:: bash

   cmake -B build -DLIBRARY_PATH="$SDK_LIB_PATH" -DINCLUDE_PATH="$SDK_INCLUDE_PATH"

4. **Build the example:**

.. code-block:: bash

   cmake --build build

5. **Run the dynamic and static examples:**

.. code-block:: bash

   LD_LIBRARY_PATH="$SDK_LIB_PATH":$LD_LIBRARY_PATH ./build/example_cpp_dynamic
   LD_LIBRARY_PATH="$SDK_LIB_PATH":$LD_LIBRARY_PATH ./build/example_cpp_static

.. note::

   - Binary names vary according to the language.
   - For C++ examples, the binaries are `example_cpp_dynamic` and `example_cpp_static`.
   - For C examples, binaries are `example_c_dynamic` and `example_c_static`.

.. ---------------------------------------------------------------------------
.. External links (HTML raw substitutions)
.. ---------------------------------------------------------------------------

.. |mingw| raw:: html

   <a href="https://www.mingw-w64.org/downloads/#mingw-w64-builds"
      target="_blank" rel="noopener noreferrer">
      MinGW-w64 Downloads
   </a>

.. |chocolatey| raw:: html

   <a href="https://chocolatey.org/"
      target="_blank" rel="noopener noreferrer">
      Chocolatey
   </a>

.. |ninja| raw:: html
   
   <a href="https://ninja-build.org/"
      target="_blank" rel="noopener noreferrer">
      Ninja Build System
   </a>
