/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-03-28 ZYH the first version
*/
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-24 ZYH the first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "cJSON.h"
#include "string.h"
#include "stdio.h"
#include "swap.h"
#include "drv_common.h"
ALIGN(RT_ALIGN_SIZE)
static char dtu_stack[1024];
static struct rt_thread dtu_thread;
/* mailbox control block */
struct rt_mailbox dtu_mb;
#define LED_PIN GET_PIN(H, 8)
/* memory pool for mails storage */
static char mb_pool[128];
#define DTU_UART_NAME "uart1" /* cat.1 dtu serial */
static struct rt_semaphore rx_sem;
static rt_device_t serial;
uint8_t LED_STA = 0;
uint8_t rx[100];
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
rt_sem_release(&rx_sem);
return RT_EOK;
}
static rt_err_t uart_putchar(char *ch, uint16_t length)
{
rt_device_write(serial, 0, ch, length);
return RT_EOK;
}
int dtu_init(void)
{
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
config.baud_rate = 115200;
serial = rt_device_find(DTU_UART_NAME);
if (!serial)
{
rt_kprintf("find %s failed! ", DTU_UART_NAME);
return RT_ERROR;
}
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
rt_device_control(serial,RT_DEVICE_CTRL_CONFIG,&config);
rt_device_set_rx_indicate(serial, uart_input);
return RT_EOK;
}
uint8_t get_uart_ch(uint8_t* ch)
{
if(rt_sem_take(&rx_sem, RT_WAITING_NO) != RT_EOK)
return 0;
/* 读取 1 字节数据 */
if(rt_device_read(serial, 0, ch, 1) == 1)
{
/* 读取到数据 */
return 1;
}
return 0;
}
void PacketParser(char* json_string)
{
cJSON* cjson=cJSON_Parse(json_string);
cJSON* cjson_value=NULL;
char* value = NULL;
if(cjson != NULL)
{
value = cJSON_GetObjectItem(cjson,"value")->valuestring;
cjson_value = cJSON_Parse(value);
if(cjson_value != NULL)
{
LED_STA = cJSON_GetObjectItem(cjson,"value")->valueint;
}
}
rt_pin_write(LED_PIN, LED_STA);
cJSON_Delete(cjson);
cJSON_Delete(cjson_value);
}
void create_rt_json(float temperature, float humidity)
{
cJSON *root;
char* str=NULL;
root =cJSON_CreateObject();
cJSON_AddStringToObject(root,"request","ReportTH");
sprintf(str,"%.1f",temperature);
cJSON_AddStringToObject(root,"temperature",str);
sprintf(str,"%.1f",humidity);
cJSON_AddStringToObject(root,"humidity", str);
char *s=cJSON_Print(root);
rt_kprintf("%s length: %d ",s,strlen(s));
uart_putchar(s,strlen(s));
cJSON_Delete(root);
}
uint8_t dtu_ExtractPacket(void)
{
uint8_t ch;
static uint16_t timeout = 0, len = 0;
while(1)
{
if(get_uart_ch(&ch))
{
timeout = 0;
if(len<sizeof(rx))
{
rx[len++] = ch;
}
continue;
}
else if(++timeout>5)
{
if(len!=0)
{
rx[len+1] = '';
PacketParser((char*)rx);
}
memset(rx,0,sizeof(rx));
len = 0;
timeout = 0;
}
return 0;
}
return 0;
}
/* timer handle */
static rt_timer_t report_timer;
/* timer #1 timeout callback function */
static void report_timeout(void *parameter)
{
cJSON *root;
root =cJSON_CreateObject();
cJSON_AddStringToObject(root,"request","ReportLed");
cJSON_AddStringToObject(root,"led",LED_STA?"ON":"OFF");
char *s=cJSON_Print(root);
uart_putchar(s,strlen(s));
}
/* thread #2 entry function */
static void dtu_entry(void *param)
{
dtu_init();
rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
struct dtu_mbt_data *mbt_data;
while(1)
{
/* pend and receive mail(s) from mailbox */
if (rt_mb_recv(&dtu_mb, (rt_ubase_t *)&mbt_data, RT_WAITING_NO) == RT_EOK)
{
switch(mbt_data->type)
{
case 0x01:
create_rt_json(mbt_data->data[0]/10.0, mbt_data->data[1]/10.0);
break;
default:
break;
}
/* delay for 100ms */
}
rt_thread_mdelay(5);
dtu_ExtractPacket();
}
}
int dtu_thread_init(void)
{
rt_err_t result;
/* initiate a mailbox */
result = rt_mb_init(&dtu_mb,
"dtu_mbt",
&mb_pool[0],
sizeof(mb_pool) / sizeof(rt_ubase_t), /* size of mails */
RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
rt_kprintf("init mailbox failed. ");
return -1;
}
/* create timer #1, periodic mode */
report_timer = rt_timer_create("timer1", report_timeout,
RT_NULL, 1000,
RT_TIMER_FLAG_PERIODIC);
/* start timer #1 */
if (report_timer != RT_NULL)
rt_timer_start(report_timer);
/* create thread #2 statically */
rt_thread_init(&dtu_thread,
"dtu",
dtu_entry,
RT_NULL,
&dtu_stack[0],
sizeof(dtu_stack),
5, 10);
rt_thread_startup(&dtu_thread);
return RT_EOK;
}
INIT_APP_EXPORT(dtu_thread_init);
Please download the attachment to view the complete code! ! !
All reference designs on this site are sourced from major semiconductor manufacturers or collected online for learning and research. The copyright belongs to the semiconductor manufacturer or the original author. If you believe that the reference design of this site infringes upon your relevant rights and interests, please send us a rights notice. As a neutral platform service provider, we will take measures to delete the relevant content in accordance with relevant laws after receiving the relevant notice from the rights holder. Please send relevant notifications to email: bbs_service@eeworld.com.cn.
It is your responsibility to test the circuit yourself and determine its suitability for you. EEWorld will not be liable for direct, indirect, special, incidental, consequential or punitive damages arising from any cause or anything connected to any reference design used.
Supported by EEWorld Datasheet