/*
 * usart.c
 *
 *  Created on: Sep 29, 2011
 *      Author: qwer1
 */

#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_usart.h"

#include "ul_ptx.h"
#include "ul_rbuf.h"

#include "usart.h"
#include "ul_uart.h"

RBUF_IMPL( usart_tx_buf );
RBUF_IMPL( usart_rx_buf );

U8 usart_tmp_buf[32];
U8 usart_modbus_mode;

void setup_usart(void) {
	USART_InitTypeDef USART_InitStructure;
	GPIO_InitTypeDef  GPIO_InitStructure;

	//enable USART1 clocking
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

	//configure USART pins RX-in, TX-alternate function out
	GPIO_StructInit(&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_OD;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	//set USART parameters
	USART_StructInit(&USART_InitStructure);
	USART_InitStructure.USART_BaudRate            = USART_BAUD;
	USART_InitStructure.USART_WordLength          = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits            = USART_StopBits_2;
	USART_InitStructure.USART_Parity              = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;

	USART_Init(USART1, &USART_InitStructure);
	USART_Cmd(USART1, ENABLE);
//	USART_HalfDuplexCmd(USART1, ENABLE);

	//initialize RX/TX buffers
	RBUF_INIT(&usart_rx_buf);
	RBUF_INIT(&usart_tx_buf);

	//start USART communication thread
	ptx_add(pt_usart, NULL, PTX_FLAG_RUN);
}

PT_THREAD( pt_usart( struct pt *pt, struct ptx *ptx ) ) {
	PT_BEGIN(pt);
	while (1) {

		//new byte in UART buffer - receive and write to usart_rx_buf
		if (!usart_rx_empty(USART_NUM)) {
			U8 data = usart_rx_U8(USART_NUM); //read received byte
			RBUF_WR(&usart_rx_buf, data); //place it to RX buffer
//RBUF_WR(&usart_tx_buf, data); //echo received data
//debug_led1 ^= 1;
		}

		//usart_tx_buf nonempty - read and TX next byte
		if (usart_tx_empty(USART_NUM) && RBUF_NONEMPTY(&usart_tx_buf)) {
			usart_tx_U8(USART_NUM, RBUF_GET(&usart_tx_buf)); //read byte from buffer and TX it
			RBUF_INC_RD(&usart_tx_buf); //increment read pointer
//debug_led2 ^= 1;
		}

		PT_YIELD(pt);
	}
	PT_END(pt);
}
