/*************************************************
 Copyright (c) 2019
 All rights reserved.
 File name:     dlt645_port.c
 Description:   DLT645 移植&使用例程文件
 History:
 1. Version:
	Date:       2019-09-19
	Author:     wangjunjie
	Modify:
*************************************************/
#include "dlt645.h"
#include "stm32f2xx.h"
#include "delay.h"
#include "usart.h"
#include "delay.h"
#include "string.h"

#define DLT_RXSIZE 200

// DLT645采集使用的串口名
#define DLT645_USART USART_485
#define DLT645_CTRL_GPIO USART_485_DE_GPIO_PORT
#define DLT645_CTRL_PIN USART_485_DE_PIN

// DL/T 645硬件拓展结构体
typedef struct
{
	uint8_t dlt645_Tx; // 用于串口接收的状态
	uint32_t timeout;  //
	uint8_t rxBuf[DLT_RXSIZE];
	uint8_t done;
	uint8_t index;
} dlt645_port_t;

static dlt645_port_t dlt645_port;

// dlt645 环境结构体
dlt645_t dlt645;

void dlt_callback()
{
	OSIntEnter();
	if(RESET!=USART_GetFlagStatus(DLT645_USART,USART_FLAG_RXNE))
	{
		if (dlt645_port.index < DLT_RXSIZE - 1)
		{
				dlt645_port.rxBuf[dlt645_port.index] = USART_ReceiveData(DLT645_USART);
				dlt645_port.index++;
			}
		else
		{
			USART_ReceiveData(DLT645_USART);
		}
	}
	if((dlt645_port.index > 0) && RESET != USART_GetFlagStatus(DLT645_USART, USART_FLAG_IDLE))
	{
		uint8_t temp;                            
		temp=DLT645_USART->SR;             //先读sr再读DR才能清除idle中断
		temp=DLT645_USART->DR;
		dlt645_port.done = 1;
	}
	OSIntExit();
}
/**
 * Name:    dlt645_hw_read
 * Brief:   dlt645 硬件层接收数据
 * Input:
 *  @ctx:   645运行环境
 *  @msg:   接收数据存放地址
 *  @len:   数据最大接收长度
 * Output:  读取数据的长度
 */
static int dlt645_hw_read(dlt645_t *ctx, uint8_t *msg, uint16_t len)
{
	int dataLength = 0;
	int startTime = gettick();
	while (1)
	{
		if (gettick() - startTime > dlt645_port.timeout )
			return 0;
		if (dlt645_port.done == 1)
		{
			dataLength = dlt645_port.index;
			memcpy(msg, &(dlt645_port.rxBuf[4]), len-4);
			dataLength = dlt645_port.index-4;
			return dataLength;
		}
	}
}

/**
 * Name:    dlt645_hw_write
 * Brief:   dlt645 硬件层发送数据
 * Input:
 *  @ctx:   645运行环境
 *  @buf:   待发送数据
 *  @len:   发送长度
 * Output:  实际发送的字节数，错误返回-1
 */
static int dlt645_hw_write(dlt645_t *ctx, uint8_t *buf, uint16_t len)
{
	memset(dlt645_port.rxBuf, 0, DLT_RXSIZE);
	delay_ms(10);
	OSIntEnter();
	GPIO_WriteBit(DLT645_CTRL_GPIO,DLT645_CTRL_PIN,1);
	for (uint16_t i = 0; i <=len; i++)
	{
		USART_SendData(USART3,buf[i]);
		while (USART_GetFlagStatus(DLT645_USART, USART_FLAG_TXE) == RESET);	
	}
	OSIntExit();
	GPIO_WriteBit(DLT645_CTRL_GPIO,DLT645_CTRL_PIN,0);
	dlt645_port.index = 0;
	dlt645_port.done = 0;
	return len;
}






void dlt645_init(uint32_t timeout)
{
	GPIO_WriteBit(DLT645_CTRL_GPIO,DLT645_CTRL_PIN,1);
	dlt645_port.timeout = timeout;
	dlt645_port.dlt645_Tx = 0;
	dlt645_port.index = 0;
}

// 645结构体注册
static dlt645_t dlt645 = {
	{0},
	0,
	dlt645_hw_write,
	dlt645_hw_read,
	(void *)&dlt645_port};
