#include "omw_config.h"
#include "omw_dbg.h"
#include "omw_uart.h"
#include "periph_gpio.h"
#include "periph_gpadc.h"

#define DISP_VOLT_AVG       4
#define DISP_VOLT_NUM       32
#define DISP_TEST_NUM       1000
#define DISP_METHOD         0

void gpio_init(void);
void adc_init(void);
void Display_Voltage_Distribution(void);

int main()
{
    int cnt, div_bak, div_cur;
    unsigned int samp, volt, volt2, res;
    cnt = 0;
    div_cur = 0;
    div_bak = 0;
    omw_dbg_init();
    adc_init();
    gpio_init();
    printf("GPADC test ...\n");
    DELAY_MS(1000);
    
    // loop
    while(1){
        // 2 pulse
        GPIO_SetBits(GPIO_PIN_3);
        GPIO_ResetBits(GPIO_PIN_3);
        GPIO_SetBits(GPIO_PIN_3);
        GPIO_ResetBits(GPIO_PIN_3);

		// vbat voltage sample
        GPADC_BATUpdate();

		// sample first
        GPIO_SetBits(GPIO_PIN_3);
        //samp = GPADC_GetSample();
        samp = GPADC_GetSampleAvgexp(3);
        GPIO_ResetBits(GPIO_PIN_3);

        // calculate voltage
        GPIO_SetBits(GPIO_PIN_3);
        volt = GPADC_SampleToVoltage(samp);
        GPIO_ResetBits(GPIO_PIN_3);

        // sample and calculate voltage
        GPIO_SetBits(GPIO_PIN_3);
        volt2 = GPADC_SampleVoltagePoll();
        GPIO_ResetBits(GPIO_PIN_3);
        // res
        res = GPIO_GetIORes(GPIO_DRIVE_STRENGTH_0, g_gpadc_vbat, 1);
		
		// display
        div_cur = ((GPADC_ANA->GPADC_CTRL) >> 13) & 0x03;
        if(div_cur != div_bak){
            printf("    **  cnt: %4d, div: %2d, gpio: %4d mV, vbat: %4d mV, res: %d Ohm, samp: 0x%04x, volt: %d mV, volt2: %d mV\n", cnt, div_cur, volt, g_gpadc_vbat, res, samp, volt, volt2);
            div_bak = div_cur;
        } else {
            printf("        cnt: %4d, div: %2d, gpio: %4d mV, vbat: %4d mV, res: %d Ohm, samp: 0x%04x, volt: %d mV, volt2: %d mV\n", cnt, div_cur, volt, g_gpadc_vbat, res, samp, volt, volt2);
        }
        cnt ++;
		DELAY_MS(300);
    }
    
    while(1);
    return 0;
}

void gpio_init(void){
   GPIO_InitTypeDef GPIO_InitStruct;
    // GPIO3 output
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin = GPIO_PIN_3;
    GPIO_InitStruct.GPIO_Mode = GPIO_MODE_OUT_PP;
    GPIO_InitStruct.GPIO_DriveStrength = GPIO_DRIVE_STRENGTH_3; // highest drive strength
    GPIO_Init(&GPIO_InitStruct);
    GPIO_ResetBits(GPIO_PIN_3);
    // GPIO22 output
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin = GPIO_PIN_22;
    GPIO_InitStruct.GPIO_Mode = GPIO_MODE_OUT_PP;
    GPIO_InitStruct.GPIO_DriveStrength = GPIO_DRIVE_STRENGTH_3; // highest drive strength
    GPIO_Init(&GPIO_InitStruct);
    GPIO_SetBits(GPIO_PIN_22);
}

void adc_init(void){
    GPADC_InitTypeDef GPADC_InitStruct;
    GPADC_StructInit(&GPADC_InitStruct);

    GPADC_InitStruct.GPADC_InputDivide = GPADC_INPUT_DIV3;
    GPADC_InitStruct.GPADC_DiffEN = DISABLE;
    GPADC_InitStruct.GPADC_PositiveInputChannel = GPADC_CHANNEL_GPIO6;
    GPADC_InitStruct.GPADC_AverageWindow = GPADC_AVG_NUM_32;
    GPADC_InitStruct.GPADC_ContinueMode = DISABLE;

    GPADC_Init(&GPADC_InitStruct);
	GPADC_StartCalibration();

    GPADC_Cmd(ENABLE); // enable
}


