/*
 * Copyright (c) 2025, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*!****************************************************************************
 *  @file       DAP.h
 *  @brief      <b>PRELIMINARY</b> DAP for EdgeAI
 *
 *  <b>WARNING</b> These APIs are <b>PRELIMINARY</b>, and subject to change in
 *  the next few months.
 *
 *  To use the DAP, include this header file in the application as follows:
 *  @code
 *  #include <ti/ai/edge_ai/DAP.h>
 *  @endcode
 *
 *  @anchor ti_edgeai_DAP_Overview
 *  # Overview #
 *  The Device Agent Protocol (DAP) is a serial communication protocol using
 *  packets that facilitates interaction between Edge AI Studio (the host) and
 *  TI Microcontrollers (the target devices). This protocol is specifically
 *  designed to support edge AI applications.
 *
 *  Communication follows a controller-responder model where the host initiates
 *  all transfers or commands, and the target device must acknowledge each
 *  command with a response. Depending on the command type, the target may send
 *  additional responses.
 *
 *  Application execution is controlled by the host through a variety of
 *  commands. The application can be configured to operate in one of four
 *  distinct pipeline modes, as specified in the #DAP_PipelineMode enumeration.
 *
 *  Configuration details specific to each pipeline mode are maintained in the
 *  #DAP_PipelineConfiguration structure. To retrieve this configuration
 *  information, the #DAP_getPipelineConfiguration() function can be utilized.
 *
 *  Depending on the active operation mode, the host may request various types
 *  of data from the target device. The readiness for data streaming can be
 *  determined using the DAP_isReadyToStartStreaming function. When streaming is
 *  available, data transmission is performed via the #DAP_sendData() function.
 *  The #DAP_SendDataType enumeration defines the supported data types for
 *  transmission.
 *
 *  # Design Architecture
 *  This protocol operates in duplex mode, enabling simultaneous transmission
 *  and reception of data packets. The implementation achieves this capability
 *  by separating functionality into dedicated RX (receiving) and TX
 *  (transmitting) tasks.
 *
 *  The RX task is in charge of receiving the packets, decoding them and
 *  constructing the response packet. The response packet is then posted in a
 *  message queue shared with the TX task.
 *
 *  The TX task is in charge of reading packets from the message queue and
 *  sending them over to the host through the transport layer.
 *
 *  The transport layer utilizes a serial communication protocol, with its
 *  backend implementation located in the ti/ai/edge_ai/dap/core/DAP_core.h
 *  file.
 *
 *  <hr>
 *  # Usage
 *  To use the DAP the application calls the following APIs:
 *    - DAP_init(): One time initialization of the DAP.
 *    - DAP_open(): Initializes the serial protocol, the message queue, and the
 *      RX and TX tasks.
 *
 ******************************************************************************
 */

#ifndef ti_edgeai_DAP__include
#define ti_edgeai_DAP__include

#include <stdint.h>
#include <stdbool.h>

#include <ti/drivers/UART2.h>
#include <ti/drivers/dpl/MessageQueueP.h>

#ifdef __cplusplus
extern "C" {
#endif

/*!
 *  @brief      DAP pipeline modes
 *
 *  This enum defines the modes of operation for the application inferencing
 *  pipeline.
 */
typedef enum
{
    /*! Mode not yet initialized */
    DAP_PIPELINE_MODE_UNINITIALIZED      = 0x00,
    /*! Real time data acquisition streaming from a sensor. */
    DAP_PIPELINE_MODE_DATA_ACQUISITION   = 0x01,
    /*! Real time inferencing streaming from a sensor. */
    DAP_PIPELINE_MODE_SENSOR_INFERENCING = 0x02,
    /*! Non-real time inferencing streaming from the host. */
    DAP_PIPELINE_MODE_HOST_INFERENCING   = 0x03,
    /*! Non-real time streaming data from the host back to the host. */
    DAP_PIPELINE_MODE_LOOPBACK           = 0x04,
} DAP_PipelineMode;

/*!
 *  @brief    DAP  pipeline configuration
 *
 *  This structure holds the configuration for the application pipeline. The
 *  host is in charge of sending a DAP command with the pipline configuration.
 */
typedef struct
{
    /* Mode of operation. */
    DAP_PipelineMode mode;
    /* Index of the model to use for Sensor and Host Inferencing modes. */
    uint8_t inferenceModelIndex;
    /* Indices of the sensors to be used for Data Acquisition and Sensor
     * Inferencing modes.
     */
    uint8_t inferenceSensorsIndex[10];
} DAP_PipelineConfiguration;

/*!
 *  @brief  DAP configuration
 *
 *  The DAP_Handle structure contains a set of pointers used to characterize
 *  the DAP implementation.
 *
 */
typedef struct
{
    /*! UART handle */
    UART2_Handle uartHandle;

    /*! Message Queue handle */
    MessageQueueP_Handle messageQueueHandle;

    bool isCrc;

    bool startStreamingFlag;

    DAP_PipelineConfiguration pipelineConfig;
} DAP_Handle;

typedef enum
{
    /*! Raw sensor output sent from target device to the host. */
    DAP_SEND_DATA_TYPE_SENSOR_SIGNAL      = 0x01,
    /*! Output signal from inferencing, same format as sensor signal data. */
    DAP_SEND_DATA_TYPE_INFERENCING_SIGNAL = 0x03,
    /*! The result from inferencing, like object detection regions or
     * classification class.
     */
    DAP_SEND_DATA_TYPE_INFERENCING_RESULT = 0x04,
    /*! Inferencing values like average cpu usage, or inferencing time. */
    DAP_SEND_DATA_TYPE_INFERENCING_VALUE  = 0x05,
    /*! Textual log for displaying to the user during live demo. */
    DAP_SEND_DATA_TYPE_INFERENCING_LOG    = 0x06,

} DAP_SendDataType;

/*!
 *  @brief  Swap Endianess value to support the endianess format expected by
 *          EdgeAI Studio
 *
 *  @param[in]  value   Scalar float value to be modified.
 */

float DAP_swapEndianness(float value);

/*!
 *  @brief  Initialize the DAP.
 */
void DAP_init(void);

/*!
 *  @brief  Open the DAP.
 *
 *  Initialize the serial protocol, the message queue, and the RX and TX tasks.
 */
void DAP_open(void);

/*!
 *  @brief  Get Pipeline Configuration
 *
 *  @return Returns a structure with the pipeline configuration
 */
DAP_PipelineConfiguration DAP_getPipelineConfiguration(void);

/*!
 *  @brief  Get samples to send
 *
 *  @return Returns the number of samples to send to the host
 */
uint32_t DAP_getSamplesToSend(void);

/*!
 *  @brief  Get samplign frequency
 *
 *  @return Returns the sampling frequency in hertz
 */
uint32_t DAP_getSamplingFrequency(void);

/*!
 *  @brief  Check if the DAP is ready for data streaming
 *
 *  @return  Returns if the DAP is ready for data streaming
 */
bool DAP_isReadyToStartStreaming(void);

/*!
 *  @brief  Send Data to host
 *
 *  @param[in]  sendDataType Type of the data sent
 *
 *  @param[in]  data pointer to a buffer with the data
 *
 *  @param[in]  dataSize size of the data buffer in bytes
 */
void DAP_sendData(DAP_SendDataType sendDataType, void *data, size_t dataSize);

#ifdef __cplusplus
}
#endif
#endif /* ti_edgeai_DAP__include */