/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-10-22     theo         the first version
 */

#include <gpio.h>
#include <sys.h>

#ifdef DEV_USING_BLE01_bluebooth
#define DBG_TAG "app_bluetooth"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

/* 串口设置 */
#define UART_SET                "uart3"

static rt_device_t serial; /* 串口设备句柄 */
struct serial_configure uart3_config = RT_SERIAL_CONFIG_DEFAULT; /* 初始化配置参数 */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size); /* 接收数据回调函数 */

/* 信号量 */
struct rt_semaphore sem;

/* 线程 */
#define THREAD_STACK_SIZE       1024
#define THREAD_PRIORITY         10
#define THREAD_TIMESLICE        5

static rt_thread_t uart3_thread = RT_NULL; /* 线程控制块 => 类似于身份证号 */
static void uart3_thread_entry(void *parameter); /* 线程回调函数（串口接收中断） */

int app_bluetooth_init(void)
{
    rt_err_t ret = 0;
    const char * str1[] = { "+++a", "AT+NAME=19010204\r\n", "AT+RESET\r\n" }; /* 一维数组的元素只能是单个的字符，而里面的数据却是字符串，所以，定义一个字符串数组（字符指针数组），其元素为字符串（ 字符指针 ） */
    const char * str2[] = { "+++a", "AT+MODE=S\r\n", "AT+NAME?\r\n"};

    /* 查找串口设备 */
    serial = rt_device_find(UART_SET);
    if (serial == NULL)
    {
        LOG_E("find %s failed!\n", UART_SET);
        return RT_ERROR;
    }

    /* 以中断接收及轮询发送模式打开串口设备 */
    ret = rt_device_open(serial, RT_DEVICE_FLAG_INT_RX | RT_DEVICE_OFLAG_RDWR);
    if (ret < 0)
    {
        LOG_E("open %s failed!\n", UART_SET);
        return ret;
    }

    /* 控制串口设备 */
    rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, (void *) &uart3_config);

    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(serial, uart_input);

    /* 初始化信号量 */
    rt_sem_init(&sem, "sem_A", 0, RT_IPC_FLAG_FIFO); /* RT_IPC_FLAG_FIFO 先进先出模式 */

    /* 创建线程A */
    uart3_thread = rt_thread_create("thread_A",          //线程的名字
                                    uart3_thread_entry,  //线程入口函数
                                    RT_NULL,             //线程入口函数的参量
                                    THREAD_STACK_SIZE,   //堆栈大小
                                    THREAD_PRIORITY,     //线程的优先级
                                    THREAD_TIMESLICE);   //时间片
    /* 如果获得线程控制块，启动这个线程 */
    if (uart3_thread != RT_NULL)
        rt_thread_startup(uart3_thread);

    /* 发送字符串 */
    int i, len;
    len = sizeof(str1) / sizeof(str1[0]);
    for (i = 0; i < len; i++)
    {
        rt_thread_delay(1000);
        rt_device_write(serial, 0, str1[i], rt_strlen(str1[i]));
    }
    rt_thread_delay(1000);
    len = sizeof(str2) / sizeof(str2[0]);
    for (i = 0; i < len; i++)
    {
        rt_thread_delay(1000);
        rt_device_write(serial, 0, str2[i], rt_strlen(str2[i]));
    }
//    rt_device_write(serial, 0, str[0], rt_strlen(str[0]));

    return RT_EOK;
}

/* 接收数据回调函数 */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
    /* 沒有讀取到數據就使綫程挂起，讀取到數據打印出來 */
    rt_sem_release(&sem); /* 释放一个信号量，如果信号量上有线程挂起，它将恢复。*/

    return RT_EOK;
}

/* 线程回调函数（串口接收中断） */
static void uart3_thread_entry(void *parameter)
{
    const char * buffer;
    const char * flag[] = { "LED1:ON", "LED1:OFF" };

    for (;;)
    {
        while (rt_device_read(serial, 0, &buffer, 1) != 1) /* 每次读一个size => 接收一個字符就會觸發一次中斷 */
        {
            rt_sem_take(&sem, RT_WAITING_FOREVER); /* 每接收到一個size，就獲取一次信號量 */
        }

        /* 发送数据 */
        rt_kprintf("%c", buffer);
        LED0_ON;
        rt_thread_delay(10);
        LED0_OFF;

        /* LED1 control */
//        LOG_E("%d", rt_strcmp(buffer, flag[0]));
        if (rt_strcmp(buffer, flag[0]) == 12) /* 这里为什么是 12? 去掉上一条注释，手机端输入 1 后查看串口助手的输出 */
        {
            rt_device_write(serial, 0, flag[0], rt_strlen(flag[0]));
            LED1_ON;
        }
        else
        {
            rt_device_write(serial, 0, flag[1], rt_strlen(flag[1]));
            LED1_OFF;
        }
    }
}
#endif
