#include "include.h"
#include "driver_gpio.h"
#include "driver_sddac.h"
#include "bsp_sddac.h"
#include "utils_ring_buffer.h"

#if AUDIO_OUT_LOCAL_DEBUG


#define SDDAC_PACKET_SIZE               ADPCM_BYTE_2_SAMPLE(AUDIO_MIC_PACKET_SIZE)
#define SDDAC_MIC_PACKET_NUM            10
#define SDDAC_MIC_BUFFER_SIZE           (SDDAC_PACKET_SIZE * SDDAC_MIC_PACKET_NUM)


uint16_t sddac_buf[SDDAC_PACKET_SIZE * 2] AT(.ram_text.audio.hw);
uint8_t is_playing AT(.ram_text.audio.hw);
uint8_t *sddac_buf_ptr AT(.ram_text.audio.hw);

uint16_t mic_buffer[SDDAC_MIC_BUFFER_SIZE] AT(.ram_text.audio.hw);
ring_buffer_t mic_buffer_cb AT(.ram_text.audio.hw);

AT(.com_text.isr.sddac)
void sddac_isr(void)
{
    if (sddac_get_flag(SDDAC_IT_ALL_DONE)) {
        sddac_buf_ptr = (u8 *)(sddac_buf + SDDAC_PACKET_SIZE);
        if (0 == utils_ring_buffer_read(&mic_buffer_cb, sddac_buf_ptr, SAMPLE_2_PCM16_BYTE(SDDAC_PACKET_SIZE))) {
            is_playing = 0;
            sddac_cmd(DISABLE);
        }
        sddac_clear_flag(SDDAC_IT_ALL_DONE);
    }

    if (sddac_get_flag(SDDAC_IT_HALF_DONE)) {
        sddac_buf_ptr = (u8 *)sddac_buf;
        utils_ring_buffer_read(&mic_buffer_cb, sddac_buf_ptr, SAMPLE_2_PCM16_BYTE(SDDAC_PACKET_SIZE));
        sddac_clear_flag(SDDAC_IT_HALF_DONE);
    }
}

void bsp_sddac_init(void)
{
    gpio_init_typedef gpio_init_structure;
    sddac_init_typedef sddac_config;

    clk_sdadda_clk_set(CLK_SDADDA_CLK_XOSC24M_CLK_2PLL, 0);
    clk_gate0_cmd(CLK_GATE0_DAC, CLK_EN);

    gpio_init_structure.gpio_pin = GPIO_PIN_2;
    gpio_init_structure.gpio_dir = GPIO_DIR_OUTPUT;
    gpio_init_structure.gpio_fen = GPIO_FEN_PER;
    gpio_init_structure.gpio_mode = GPIO_MODE_DIGITAL;
    gpio_init_structure.gpio_drv = GPIO_DRV_6MA;
    gpio_init(GPIOA_REG, &gpio_init_structure);

    FUNO_PA2SEL(FO_AUDIO);

    sddac_config.dma_buf = (u8 *)sddac_buf;
    sddac_config.dma_size = sizeof(sddac_buf) / 2;
    sddac_config.sample_rate = SDDAC_NORMAL_SPR_16k;
    sddac_init(&sddac_config);

    sddac_pic_config(sddac_isr, 0, SDDAC_IT_ALL_DONE | SDDAC_IT_HALF_DONE, ENABLE);

    is_playing = 0;
    memset((u8 *)mic_buffer, 0x00, SAMPLE_2_PCM16_BYTE(SDDAC_MIC_BUFFER_SIZE));
    utils_ring_buffer_init(&mic_buffer_cb, (u8 *)mic_buffer, SAMPLE_2_PCM16_BYTE(SDDAC_MIC_BUFFER_SIZE));
}

uint32_t bsp_sddac_pcm_push(uint8_t *buf, uint32_t size)
{
    u32 res = utils_ring_buffer_write(&mic_buffer_cb, buf, size);

    if (!is_playing) {
        bsp_sddac_kick();
    }

    return res;
}

void bsp_sddac_kick(void)
{
    if (!is_playing) {
        sddac_buf_ptr = (u8 *)sddac_buf;
        is_playing = 1;
        if (utils_ring_buffer_read(&mic_buffer_cb, sddac_buf_ptr, SAMPLE_2_PCM16_BYTE(SDDAC_PACKET_SIZE))) {
            printf("[SDDAC] start\n");
            sddac_cmd(ENABLE);
        }
    }
}

#endif // AUDIO_OUT_LOCAL_DEBUG
