/*
 * Copyright 2019-2020 NXP
 * This software is owned or controlled by NXP and may only be used strictly
 * in accordance with the applicable license terms.  By expressly accepting
 * such terms or by downloading, installing, activating and/or otherwise using
 * the software, you are agreeing that you have read, and that you agree to
 * comply with and are bound by, such license terms.  If you do not agree to
 * be bound by the applicable license terms, then you may not retain, install,
 * activate or otherwise use the software.
 */

#ifndef FEEDBACK_H_
#define FEEDBACK_H_

/*!
 * @addtogroup application_layer Application Layer
 * @brief
 * @{
 */

/*!
 * @addtogroup feedback Feedback
 * @brief
 * @{
 */

#include <stdint.h>

#define PHLOG_MODULE  "usb"
#include "log.h"

/* ---------------------------------------------------------------------------- */
/* Defines                                                                      */
/* ---------------------------------------------------------------------------- */

/* Desired buffer upper limit (from 0 to 100)*/
#define BUFFER_UPPER_LIMIT_PERCENTAGE  (60)
/* Desired buffer lower limit (from 0 to 100)*/
#define BUFFER_LOWER_LIMIT_PERCENTAGE  (40)
/* Allows real-time buffer monitoring */
#ifdef DEBUG
    #define FREEMASTER_DEBUG
#endif

typedef uint32_t q14;   /* The format is 10.14. Only the rightmost 24 bits are used. */

typedef uint32_t (*usb_feedback_GetFillingCb)(void);

/**
 * Feedback type created to monitor and control the number the samples the device is receiving.
 */
typedef struct _UsbFeedback_t {
    /**< Number of samples that the feedback will request;
     *  this value will be updated by @ref USB_FeedbackStart */
    q14 Feedback;

    /**< Variables used for configuration and internal book keeping  */
    uint8_t SampleRate;            /**< Sample rate of the application. */
    uint32_t BufferSize;           /**< Size of the buffer where the samples are being stored.  */
    uint32_t BufferUpperLimit;     /**< Limit where the buffer will request less samples. */
    uint32_t BufferLowerLimit;     /**< Limit where the buffer will request more samples. */
    q14 BufferMoreSamples;         /**< Number of samples that will be sent in case the feedback request more. */
    q14 BufferLessSamples;         /**< Number of samples that will be sent in case the feedback request less. */
    q14 BufferSamples;             /**< Nominal number of samples  */
    usb_feedback_GetFillingCb Cb;  /**< Callback function to ask for the current amount of buffer space in use  */
    uint32_t IntervalUs;           /**< Interval used for updating the value of 'Feedback' (in micro-seconds). */
} UsbFeedback_t;

/* -------------------------------------------------------------------------
 * Public functions
 * ------------------------------------------------------------------------- */

/*!
 * @brief Initialize the feedback application.
 *
 * @param BufferSettings Pointer to the buffer settings.
 * @param BufferSize Buffer size.
 * @param SampleRateInKhz Audio Sample rate.
 * @param RefreshRateInMs Feedback Refresh rate.
 * @param Cb Callback function to be used to get the current buffer filling (amount of buffer space in use).
 * @return void.
 */
void USB_FeedbackInit(UsbFeedback_t *BufferSettings, uint32_t BufferSize, uint8_t SampleRateInKhz, uint8_t RefreshRateInMs,
                      usb_feedback_GetFillingCb Cb);

/*!
 * @brief Start calculating the feedback regularly; this will update 'Feedback' from @ref UsbFeedback_t.
 *
 * @param BufferSettings Pointer to the buffer settings.
 * @param IntervalUs Interval used for updating the value of 'Feedback' (in micro-seconds).
 * @return void.
 */
void USB_FeedbackStart(UsbFeedback_t *BufferSettings, uint32_t IntervalUs);

/*!
 * @brief Stop calculating the feedback regularly.
 *
 * @param BufferSettings Pointer to the buffer settings.
 * @return void.
 */
void USB_FeedbackStop(UsbFeedback_t *BufferSettings);

/*!
 * @brief Resets the feedback application.
 *
 * @param BufferSettings Pointer to the buffer settings.
 * @return void.
 */
void USB_FeedbackReset(UsbFeedback_t *BufferSettings);

/*! @} End of Feedback */
/*! @} End of Application Layer */

#endif /* FEEDBACK_H_ */
