#include "hal_data.h"
#include "audio_record.h"
#include "dcds.h"
#include <realityai/baby_cry_10_sm_model.h>

FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER

static bool g_led_toggle = 0;
static int16_t g_audio_samples[DCDS_FRAME_LEN];
int16_t buffer[4000];

/*******************************************************************************************************************//**
 * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function
 * is called by main() when no RTOS is used.
 **********************************************************************************************************************/
void hal_entry(void)
{
    FSP_CRITICAL_SECTION_DEFINE;
    fsp_err_t err = FSP_SUCCESS;
    ring_buffer_size_t sz;
    R_BSP_PinAccessEnable();

    dcds_init();
    audio_record_init();
    audio_record_start();
    while( 1 )
    {
        R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MICROSECONDS);

        /* Wait for samples (1/4 sec @ 16kHz) */
        FSP_CRITICAL_SECTION_ENTER;
    	sz = uac_frame_buf_size();
    	FSP_CRITICAL_SECTION_EXIT;
    	if( sz < DCDS_FRAME_SIZE ){
    	    R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MICROSECONDS);
    	    continue;
    	}

        /* Toggle Blue LED */
    	R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_06_PIN_00, g_led_toggle ? BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW);
    	g_led_toggle = !g_led_toggle;

        /* Get samples from FIFO */
        FSP_CRITICAL_SECTION_ENTER;
    	sz = uac_frame_buf_get((uint16_t*)g_audio_samples, DCDS_FRAME_SIZE);
    	memcpy(buffer, g_audio_samples, sizeof(g_audio_samples));
    	FSP_CRITICAL_SECTION_EXIT;
    	assert( sz == DCDS_FRAME_SIZE );

        /* Ship Data */
    	err = dcds_write(g_audio_samples, DCDS_FRAME_SIZE);
        assert( err == FSP_SUCCESS );

        baby_cry_10_sm_predict(buffer);
    }

#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

/*******************************************************************************************************************//**
 * This function is called at various points during the startup process.  This implementation uses the event that is
 * called right before main() to set up the pins.
 *
 * @param[in]  event    Where at in the start up process the code is currently at
 **********************************************************************************************************************/
void R_BSP_WarmStart(bsp_warm_start_event_t event)
{
    if (BSP_WARM_START_RESET == event)
    {
#if BSP_FEATURE_FLASH_LP_VERSION != 0

        /* Enable reading from data flash. */
        R_FACI_LP->DFLCTL = 1U;

        /* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
         * C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
    }

    if (BSP_WARM_START_POST_C == event)
    {
        /* C runtime environment and system clocks are setup. */

        /* Configure pins. */
        R_IOPORT_Open (&IOPORT_CFG_CTRL, &IOPORT_CFG_NAME);

#if BSP_CFG_SDRAM_ENABLED

        /* Setup SDRAM and initialize it. Must configure pins first. */
        R_BSP_SdramInit(true);
#endif
    }
}

#if BSP_TZ_SECURE_BUILD

FSP_CPP_HEADER
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();

/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{

}
FSP_CPP_FOOTER

#endif
