#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "utility.h"
#include "at32f403a_407_int.h"
#include <stdio.h>
#include <string.h>


volatile unsigned long ulHighFrequencyTimerTicks;


#if 1
// OS stack overflow hook
#if (configCHECK_FOR_STACK_OVERFLOW > 0)
void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )
{
    NVIC_SystemReset();
}
#endif
#endif

// OS malloc failed hook
#if (configUSE_MALLOC_FAILED_HOOK > 0)
void vApplicationMallocFailedHook(void)
{
    NVIC_SystemReset();
    while(1);
}
#endif


//
void print_binary_byte(uint8_t val)
{
    for (int i = 7; i >= 0; i--) {
        if (val & (1 << i))
            printf("1");
        else
            printf("0");
        if (i == 4)
            printf(" ");
    }
    printf("\r\n");
}

//
void print_binary_half_word(uint16_t val)
{
    for (int i = 15; i >= 0; i--) {
        if (val & (1 << i))
            printf("1");
        else
            printf("0");
        if ((i == 12) || (i == 8) || (i == 4))
            printf(" ");
    }
    printf("\r\n");
}

//
void utl_stat_timer_init(void)
{
    crm_clocks_freq_type crm_clocks_freq_struct = {0};
    
    crm_periph_clock_enable(CRM_TMR4_PERIPH_CLOCK, TRUE);

    crm_clocks_freq_get(&crm_clocks_freq_struct);
    tmr_base_init(TMR4, 999, 240 - 1);
    tmr_cnt_dir_set(TMR4, TMR_COUNT_UP);

    tmr_flag_clear(TMR4, TMR_OVF_FLAG);
    
    NVIC_ClearPendingIRQ(TMR4_GLOBAL_IRQn);
    nvic_irq_enable(TMR4_GLOBAL_IRQn, 5, 0);
       
    tmr_counter_enable(TMR4, TRUE);
    tmr_interrupt_enable(TMR4, TMR_OVF_INT, TRUE);

}

//
void print_os_stat(void)
{
    char *ptr;
    
    ptr = (char*)pvPortMalloc(800);
    
    vTaskList(ptr);
    
    printf(ptr);
    printf((char*)"\r\n");
    printf((char*)"xPortGetFreeHeapSize = %d\n\r\r\n", xPortGetFreeHeapSize());
        
    memset(ptr, 0, 800);
    vTaskGetRunTimeStats(ptr);
    printf(ptr);
    printf((char*)"\r\n");
    
    vPortFree(ptr);
}

//
void TMR4_GLOBAL_IRQHandler(void)
{
    //static uint32_t cnt = 0;
    //static uint32_t sec_cnt = 0;
  
    if (tmr_flag_get(TMR4, TMR_OVF_FLAG) != RESET)
    {
        tmr_flag_clear(TMR4, TMR_OVF_FLAG);
        ulHighFrequencyTimerTicks++;
        
#if 0        
        cnt++;
        
        if (cnt == 1000) {
            cnt = 0;
            sec_cnt++;
            printf("TIM4 cnt: %u\r\n", sec_cnt);
        }
        
        tmr_flag_clear(TMR4, TMR_OVF_FLAG);
        ulHighFrequencyTimerTicks++;
#endif        
    }
}