//*****************************************************************************
//
//! @file am_vos_board_setup.h
//!
//! @brief The header file of am_vos_board_setup.c (H/W defines)
//
//*****************************************************************************

//*****************************************************************************
//
// Copyright (c) 2024, Ambiq Micro, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision ambiqvos_r4.5-fdfa8cf6a4 of the AmbiqSuite Development Package.
//
//*****************************************************************************

#ifndef AM_VOS_BOARD_SETUP
#define AM_VOS_BOARD_SETUP

#include "am_bsp.h"
#include "am_vos_sys_config.h"

#define PDM_HOST_TRIGGER_GAIN           AM_HAL_PDM_GAIN_P150DB

//********************************************************************************
// PCM parameters
//********************************************************************************
#if USE_DMIC_MB0 || USE_DMIC_MB1 || USE_DMIC_MB2 || USE_DMIC_MB0_T5838
#define USE_DMIC_PDM                    1
#endif

#if USE_AMIC_J15
#define USE_AMIC_AUDADC                 1
#endif

#if USE_DMIC_MB0 || USE_DMIC_MB0_T5838
#define USE_PDM_MODULE                  0
#elif USE_DMIC_MB1
#define USE_PDM_MODULE                  2
#elif USE_DMIC_MB2
#define USE_PDM_MODULE                  1
#endif

#if USE_DMIC_PDM
#define USE_PDM_CLK_SRC_HFRC_24MHZ      1
#define USE_PDM_CLK_SRC_HFRC2ADJ_24MHZ  0                       // get accurate 48KHz/16KHz PDM sample rate
#define USE_PDM_CLK_SRC_HFXTAL_32MHZ    0
/* Select PDM Clock Speed */
#define USE_PDM_CLK_750KHZ              1
#define USE_PDM_CLK_1_5MHZ              0

#define USE_PCM_SAMPLE_RATE             16000

#define AM_PGA_ADJ_STEP_DB              1.5
#define AM_PGA_LOWEST_GAIN_DB           -12
#define AM_PGA_DEFAULT_GAIN_DB          0

#elif USE_AMIC_AUDADC
#define AUDADC_CLKSRC_HFRC              1
#define AUDADC_CLKSRC_HFRC2_ADJ         0
#define AUDADC_CLKSRC_XTHS              0

#define AUDADC_LPMODE                   1
#define AUDADC_TRIGGER_TIMER6           0
#define AUDADC_DCMP_EN                  1
#define AUDADC_DC_OFFSET_CAL            1

#define USE_PCM_SAMPLE_RATE             16000

#define PREAMP_FULL_GAIN    24    // Enable op amps for full gain range
#define CH_A0_GAIN_DB       18      // LGA = 36
#define CH_A1_GAIN_DB       18
#define CH_B0_GAIN_DB       12
#define CH_B1_GAIN_DB       12

#define AM_PGA_ADJ_STEP_DB              0.5
#define AM_PGA_LOWEST_GAIN_DB           -6
#define AM_PGA_DEFAULT_GAIN_DB          CH_A0_GAIN_DB
#else
#define USE_PCM_SAMPLE_RATE             16000
#endif // USE_AMIC_AUDADC USE_DMIC_PDM

// PCM_FRAME_SIZE_SAMPLES = Sample rate / 1000 ms * frame window (ms)
#define PCM_FRAME_SIZE_SAMPLES          (USE_PCM_SAMPLE_RATE / 1000 * PCM_FRAME_SIZE_MS)

//********************************************************************************
// UART & System Log parameters
//********************************************************************************
#define UART0_BUFFER_SIZE               (512 * 2)       // gloabal UART queue size (used by transmit buffered service)
#define UART1_BUFFER_SIZE               (512 * 2)
#define UART_TRANSMIT_BUFFER            256             // size limit to frame added into global UART queue

//********************************************************************************
// Hardware Related Macro
//********************************************************************************
#define LED_SYSTEM                      0

#define RTT_DUMP_BUTTON                 AM_BSP_GPIO_BUTTON0
#define GRP_IRQ_RTT_DUMP_BUTTON         GPIO0_001F_IRQn
#define PAIRING_MODE_BUTTON             AM_BSP_GPIO_BUTTON0
#define GRP_IRQ_PAIRING_MODE_BUTTON     GPIO0_001F_IRQn
#define PUSH_TO_TALK_BUTTON             AM_BSP_GPIO_BUTTON1
#define GRP_IRQ_PUSH_TO_TALK_BUTTON     GPIO0_001F_IRQn
#define MUTE_MIC_BUTTON                 AM_BSP_GPIO_BUTTON1
#define GRP_IRQ_MUTE_MIC_BUTTON         GPIO0_001F_IRQn

#define UART0_MODULE                    0
#define UART1_MODULE                    1

#if USE_DMIC_MB0_T5838
    #define AM_T5838_WAKE_PIN           22
    #define GRP_IRQ_AAD_WAKE_PINGRP     GPIO0_001F_IRQn
    #define AAD_WAKE_PIN_MODE_SEL       AM_HAL_PIN_22_GPIO

    #define AM_T5838_THSEL_PIN          23

    #define T5838_AAD_A                 1
    #define T5838_AAD_D1                0
    #define T5838_AAD_D2                0
#endif // USE_DMIC_MB0_T5838

#define AM_VOS_BENCH_TIMER_6MHZ         (6 * 1000 * 1000)
#define AM_VOS_BENCH_TIMER_32KHZ        (32768)
#define AM_VOS_BENCH_TIMER_DWT          (96 * 1000 * 1000)

//#define AM_VOS_BENCHMARK_TIMER_CLK      AM_VOS_BENCH_TIMER_6MHZ
#define AM_VOS_BENCHMARK_TIMER_CLK      AM_VOS_BENCH_TIMER_32KHZ
//#define AM_VOS_BENCHMARK_TIMER_CLK      AM_VOS_BENCH_TIMER_DWT

#define AM_VOS_BENCHMARK_TIMER_FREQ    AM_VOS_BENCHMARK_TIMER_CLK

#define AM_VOS_BENCHMARK_TIME_SEC       10

#if (AM_VOS_BENCHMARK_TIMER_CLK == AM_VOS_BENCH_TIMER_DWT)
void am_vos_bench_dwt_reset(void);
void am_vos_bench_dwt_start(void);
void am_vos_bench_dwt_stop(void);
unsigned int am_vos_bench_dwt_getcycle(void);

extern volatile unsigned int *DWT_CYCCNT  ;
extern volatile unsigned int *DWT_CONTROL ;
extern volatile unsigned int *SCB_DEMCR   ;
#endif // (AM_VOS_BENCHMARK_TIMER_CLK == AM_VOS_BENCH_TIMER_DWT)

//*****************************************************************************
//
// Voice on SPOT global board status structure
//
//*****************************************************************************
typedef struct _VosBoardInfo {
    void                                *pvUartHandle;

    uint32_t                            pui32PcmBuf[PCM_FRAME_SIZE_SAMPLES * USE_MIC_NUM];

#if USE_DMIC_PDM
    void                                *pvPDMHandle;
    am_hal_pdm_transfer_t               sPdmTransfer;
#endif // USE_DMIC_PDM

#if USE_AMIC_AUDADC
    void                                *pvAUDADCHandle;                // AUDADC Device Handle.
    am_hal_audadc_dma_config_t          sAUDADCDMAConfig;
    bool                                bAUDADCDMAError;                // AUDADC DMA error flag.
    am_hal_audadc_gain_config_t         sAudadcGainConfig;

#if defined(AM_PART_APOLLO4P) && AUDADC_DC_OFFSET_CAL
    am_hal_offset_cal_coeffs_array_t    sOffsetCalib; 
#endif // AM_PART_APOLLO4P && AUDADC_DC_OFFSET_CAL
#endif // USE_AMIC_AUDADC

    bool                                bBurstModeAvailable;
    bool                                bBurstMode;

#if configUSE_MUTE_MIC
    bool                                bMicStatus;     // true = mic on, false = mic off
#endif // configUSE_MUTE_MIC

#if configUSE_SPP_P2A
    float                               fPGAdB;
#endif // configUSE_SPP_P2A
} VosBoardInfo;

extern VosBoardInfo g_sVosBrd;

/* Function declaration */
void am_vos_board_init(void);
void am_vos_burst_mode_enable(void);
void am_vos_burst_mode_disable(void);
void am_vos_mic_fifo_flush(void);
void am_vos_mic_enable(void);
void am_vos_mic_disable(void);
void am_vos_aad_mic_enable(void);
void am_vos_aad_mic_disable(void);
void am_vos_gpio_enable_irq(uint32_t ui32GroupIrq, uint32_t gpio);
void am_vos_gpio_disable_irq(uint32_t gpio);

void am_vos_timer_benchmark_init(void);
uint32_t am_vos_timer_benchmark_read(void);
void am_vos_timer_benchmark_clear_and_start(void);

#if configUSE_PRINTF_SWO
void am_vos_itm_printf_enable(void);
void am_vos_itm_printf_disable(void);
#endif // configUSE_PRINTF_SWO

void am_vos_pdm_init(void);
void am_vos_pdm_deinit(void);

void am_vos_audadc_init(void);
void am_vos_audadc_deinit(void);

void am_vos_uart_process(void);
bool am_vos_button_gpio_check(uint32_t gpio);

#if configUSE_MUTE_MIC
void am_vos_mute_mic_toggle(void);
#endif // configUSE_MUTE_MIC

#if USE_DMIC_PDM
extern void am_vos_pdm_trigger_dma(void);
#endif // USE_DMIC_PDM

#if USE_AMIC_AUDADC
void am_vos_audadc_config_dma(void);
#endif

#endif // AM_VOS_BOARD_SETUP

