#include "sr_gpio.h"

#include "sr_stddef.h"
#include "sr_config.h"
#include "sr_osal.h"
#include "sr_shell.h"

#include "sr_utest.h"


static int GpioOutputTcInit(void)
{
    SR_GPIO_CFG_T config = {0};

    config.gpioMode = SR_GPIO_OUTPUT; // 输出
    config.pull = SR_GPIO_NP;    // 无上下拉
    config.initLvl = SR_GPIO_LOW; // 初始低电平
    SR_HalGpioInit(SR_GPIO19, &config);    // 初始化

    SR_HalGpioInit(SR_GPIO20, &config); // 初始化

    return SR_OK;
}

static int GpioTcCleanup(void)
{
    return SR_OK;
}




static void GpioOutput_TC(void)
{
    int ret;
    uint8_t wlevel = 0, rLevel = 0;
    uint8_t oldLevel = 0, newLevel = 0;

    SR_PRINTF("[UTEST] GpioOutput_TC entry\r\n");

    /*1、电平拉高测试*/
    // 将GPIO引脚电平设置高
    ret = -1;
    ret = SR_HalGpioWrite(SR_GPIO19, SR_GPIO_HIGH);
	tp_assert_integer_equal(ret, 0);
    // 然后读取电平
    rLevel = SR_HalGpioRead(SR_GPIO19);

    // 判断读取电平为高
    tp_assert_integer_equal(rLevel, SR_GPIO_HIGH);

    osDelay(100);

    /*2、电平拉低测试*/
    // 将GPIO引脚电平设置低
    ret = -1;
    ret = SR_HalGpioWrite(SR_GPIO19, SR_GPIO_LOW);
    tp_assert_integer_equal(ret, 0);
    // 然后读取电平
    rLevel = SR_HalGpioRead(SR_GPIO19);

    // 判断读取电平为低
    tp_assert_integer_equal(rLevel, SR_GPIO_LOW);

    osDelay(100);

    /*3、电平翻转测试*/
    // 读取当前电平
    oldLevel = SR_HalGpioRead(SR_GPIO19);

    // GPIO引脚电平设置翻转
    ret = -1;
    ret = SR_HalGpioWrite(SR_GPIO19, SR_GPIO_TOGGLE);
    tp_assert_integer_equal(ret, 0);

    // 然后读取新电平
    newLevel = SR_HalGpioRead(SR_GPIO19);

    // 判断新旧电平相反
    tp_assert_integer_equal(oldLevel, !newLevel);

	//耗时测试	
    uint32_t startTick,endTick;
	float TotalTime;

	SR_GET_EXCT_TIME(SR_HalGpioWrite(SR_GPIO19, SR_GPIO_HIGH),startTick,endTick,TotalTime);
	SR_LOG(INFO,"[IOW]startTick:%u endTick:%u totalTime:%f us",startTick,endTick,TotalTime);

	SR_GET_EXCT_TIME(SR_HalGpioRead(SR_GPIO19),startTick,endTick,TotalTime);
	SR_LOG(INFO,"[IOR]startTick:%u endTick:%u totalTime:%f us",startTick,endTick,TotalTime);

	
}
UTEST_TC_EXPORT(gpio_op_tc, GpioOutput_TC, GpioOutputTcInit, GpioTcCleanup, TC_PRIORITY_HIGH);

static int GpioInputTcInit(void)
{
    SR_GPIO_CFG_T config = {0};

    config.gpioMode = SR_GPIO_INPUT; // 输入
    config.pull = SR_GPIO_PU;        // 上拉
    SR_HalGpioInit(SR_GPIO19, &config);   // 初始化

    SR_HalGpioInit(SR_GPIO20, &config); // 初始化

    return SR_OK;
}

static void GpioInput_TC(void)
{
    uint8_t rLevel1 = 0, rLevel2 = 0, rLevel3 = 0;

    SR_PRINTF("[UTEST] GpioInput_TC entry\r\n");

    SR_PRINTF("请手动改变GPIO电平，观察Log输出的读取值是否一致...\r\n");
    SR_PRINTF("结束测试请按 CTRL+C\r\n");

    gShellThreadRun = 1; // CTRL+C会将这个变量置0

    while (gShellThreadRun)
    {
        rLevel1 = SR_HalGpioRead(SR_GPIO19);

        SR_PRINTF("gpio: id(%d) level(%d) ,id(%d) level(%d) ,id(%d) level(%d)\r\n", SR_GPIO19, rLevel1, SR_GPIO20, rLevel2, SR_GPIO0, rLevel3);
        osDelay(1000);
    }
}

UTEST_TC_EXPORT(gpio_in_tc, GpioInput_TC, GpioInputTcInit, GpioTcCleanup, TC_PRIORITY_LOW);




#if   0


#define TEST_GPIO   SR_GPIO16

static uint8_t gpio16Flag=0;


static void Gpio16Cb(void *args)
{
	// 中断里不要调用朝阳写的打印函数SR_LOG

	gpio16Flag = 1;
;
}
static SR_GPIO_IRQ_CB_T GPIO16Callback;




static int GpioIrqEdgeRisingTcInit(void)
{
    uint32_t intArg = 100;
    SR_GPIO_CFG_T config = {0};
    config.pull = SR_GPIO_PD;                  // 下拉
    config.gpioMode = SR_GPIO_IRQ;             // 中断模式
    config.irqMode = SR_GPIO_IRQ_RISING;      // 上升沿触发
    GPIO16Callback.func = Gpio16Cb;            // 中断回调
    GPIO16Callback.args = &intArg;           // 中断回调参数
    config.irqCb = &GPIO16Callback;
    SR_HalGpioInit(TEST_GPIO, &config);   // 初始化

    return SR_OK;
}

static void GpioIrqEdgeRising_TC(void)
{
   uint32_t cnt=0;
   gShellThreadRun=1; 

   SR_LOG(INFO, "中断测试，请改变外部电平");
   while(gShellThreadRun && cnt<=6000)
   {
        if (gpio16Flag) // 中断，打印提示
        {
            SR_LOG(INFO, "[GPIO] gpio_cb16 enter!,args=%d", gpio16Flag);
            gpio16Flag = 0;
        }
       cnt++;
       SR_OsDelay(10);
   }

   int ret=SR_HalGpioIrqDisable(TEST_GPIO);    
   SR_LOG(INFO, "ret=%d\r\n",ret);
   SR_LOG(INFO, "禁止中断测试，请改变外部电平\r\n");
   gShellThreadRun=1;                       
   cnt=0;   
   while(gShellThreadRun && cnt<=6000)
   {
        if (gpio16Flag) // 中断，打印提示
        {
            SR_LOG(INFO, "[GPIO] gpio_cb16 enter!,args=%d", gpio16Flag);
            gpio16Flag = 0;
        }
       cnt++;
       SR_OsDelay(10);
   }

   SR_HalGpioIrqEnable(TEST_GPIO);
   SR_LOG(INFO, "再次使能中断，请改变外部电平\r\n");
   gShellThreadRun=1;                       
   cnt=0;   
   while(gShellThreadRun && cnt<=6000)
    {
        if (gpio16Flag) // 中断，打印提示
        {
            SR_LOG(INFO, "[GPIO] gpio_cb16 enter!,args=%d", gpio16Flag);
            gpio16Flag = 0;
        }
        cnt++;
        SR_OsDelay(10);
    }

   SR_HalGpioUnsetCb(TEST_GPIO);
   SR_LOG(INFO, "解绑中断，请改变外部电平\r\n");
   gShellThreadRun=1;                       
   cnt=0;   
   while(gShellThreadRun && cnt<=6000)
    {
        if (gpio16Flag) // 中断，打印提示
        {
            SR_LOG(INFO, "[GPIO] gpio_cb16 enter!,args=%d", gpio16Flag);
            gpio16Flag = 0;
        }
        cnt++;
        SR_OsDelay(10);
    }


    SR_HalGpioSetCb(TEST_GPIO, SR_GPIO_IRQ_FALLING, &GPIO16Callback);
    SR_LOG(INFO, "再次绑定中断，请改变外部电平\r\n");
    gShellThreadRun=1;                       
    cnt=0;   
    while(gShellThreadRun && cnt<=6000)
     {
        if (gpio16Flag) // 中断，打印提示
        {
            SR_LOG(INFO, "[GPIO] gpio_cb16 enter!,args=%d", gpio16Flag);
            gpio16Flag = 0;
        }
        cnt++;
        SR_OsDelay(10);
     }

}

static int GpioIrqEdgeTcCleanup(void)
{

    return SR_OK;
}
UTEST_TC_EXPORT(gpio_irq_edge_rising_tc, GpioIrqEdgeRising_TC, GpioIrqEdgeRisingTcInit, GpioIrqEdgeTcCleanup, TC_PRIORITY_LOW);

#endif





