#include "key.h"
#include "uart.h"
#include "string.h"
#include "stdlib.h"
#include "stdio.h"
#include "altera_avalon_uart_regs.h"
#include "stdint.h"

alt_u8 uart0_tx_state;
unsigned char FLAG_USART1_IT=0;         //1жϱ־ ʾյ 0ʾδжϣ1
uint16_t TimeLag = 0;              //֡жʱ
uint8_t FLAG_FlowData = 0;        //ģʽʶ
uint8_t FLAG_StartFlowData;       //ģʽʼ/ʶ
uint8_t FLAG_FrameData;       //ʾһ֡ݽ
uint8_t CocheData[64];            //ʱݻ
uint8_t count=0;                  //ռ
uint8_t uart_revdata[4];
/******************************************************************************
*   : Set_Uart_Bps
* 	: ò
* 	: uart_bpsڲ
* Return
*******************************************************************************/
void Set_Uart_Bps(void *p, alt_u32 uart_bps)
{
	CoreCourse_UART *pt = (CoreCourse_UART *)p;
	IOWR_ALTERA_AVALON_UART_DIVISOR(pt->uart_base, uart_bps);
}

/******************************************************************************
*   : UART_Init
* 	: ʼ UARTṹ岢ؽṹַָ
* 	: uart_base system.hж UARTĻַ
* 		uart_ic_id UARTжϿid
* 		uart_irq UARTжϺ
* 		uart_irq_mask UARTжβ1Ϊʹжϣ0Ϊж
* 		: uart_bpsڲ
* 		uart_isrжϺ
* 	: 
* Return:ʼuartṹָ
******************************************************************************/
UART_HANDLE UART_Init(
		const alt_u32 uart_base,
		const alt_u32 uart_ic_id,
		const alt_u32 uart_irq,
		const alt_u32 uart_irq_mask,
		alt_u32 uart_bps,
		alt_isr_func uart_isr
		){
    CoreCourse_UART *p;
    alt_u8 bSuccess;
    int rc;

    p = malloc(sizeof(CoreCourse_UART));
    if (!p)
    	return p;
    memset(p, 0, sizeof(CoreCourse_UART));//ṹ0

    p->uart_base = uart_base;
	p->uart_ic_id = uart_ic_id;
	p->uart_irq = uart_irq;
	p->irq_mask = uart_irq_mask;

    Set_Uart_Bps(p,(ALT_CPU_FREQ/uart_bps-1));	//ôڲ
    IOWR_ALTERA_AVALON_UART_STATUS(p->uart_base, 0);//״̬Ĵ
    //עж
    rc = alt_ic_isr_register(
    		p->uart_ic_id,
    		p->uart_irq,
    		uart_isr,
    		p,
    		NULL);
    IOWR_ALTERA_AVALON_UART_CONTROL(p->uart_base, p->irq_mask); //жϵĿͨ/ض

    if (rc != 0){
        //DEBUG_OUT(("[uart]register IRQ fail\n"));
        bSuccess = UART_FALSE;
    }else{
        //DEBUG_OUT(("[uart]register IRQ success\n"));
    	bSuccess = UART_TRUE;
    }
    if (!bSuccess && p){
        free(p);	//ע᲻ɹͷſռ
        p = NULL;
    }
    return p;
}
/******************************************************************************
*   : UART_UnInit
* 	: رմ
*******************************************************************************/
void UART_UnInit(UART_HANDLE pHandle){
	CoreCourse_UART *p = (CoreCourse_UART *)pHandle;
    if (!p)
        return;

    //״̬Ĵ
    IOWR_ALTERA_AVALON_UART_STATUS(p->uart_base, 0x0000);
    // رж
    IOWR_ALTERA_AVALON_UART_CONTROL(p->uart_base, 0x0000);
    // ͷſռ
    free(p);
}

/******************************************************************************
*   : UART0_isr
* 	: UART0жϷյݴ洢fifoУȻfifoݷͳȥ
* 	: context uartṹָ
* 		id,жID
* Return0
*******************************************************************************/
alt_isr_func UART0_isr(void* context, alt_u32 id)
{
    CoreCourse_UART *p = (CoreCourse_UART *)context;
    static alt_u8 i = 0;
    alt_u8 data_cnt = 0;
    //ȡ״̬Ĵ
    p->uart_state = IORD_ALTERA_AVALON_UART_STATUS(p->uart_base);
    if(p->uart_state & 0x0080)//ճɹ
    {
    	FLAG_USART1_IT = 1;                                     //λжϱ־
    	CocheData[count] = IORD_ALTERA_AVALON_UART_RXDATA(p->uart_base);
    	uart_revdata[data_cnt] = IORD_ALTERA_AVALON_UART_RXDATA(p->uart_base);
    	//յݴ洢fifo
    	p->uart_rxfifo[p->rxfifo_len] = IORD_ALTERA_AVALON_UART_RXDATA(p->uart_base);
    	p->rxfifo_len ++;//ճȼ1
    	count++;
    	data_cnt++;
    }
    if((p->uart_state & 0x0040))//ͼĴΪգɷ
    {
		if(p->txfifo_len)
		{//FIFOǿ Ҫ
			IOWR_ALTERA_AVALON_UART_TXDATA(p->uart_base,p->uart_txfifo[i]);
			p->txfifo_len --;
			i ++;
		}
		else
		{//FIFO
			i = 0;
			uart0_tx_state = UART_TX_IDLE;	//ô0״̬Ϊ̬
			p->irq_mask = p->irq_mask & ~ITRDY_IRQ_MASK;
			IOWR_ALTERA_AVALON_UART_CONTROL(p->uart_base, p->irq_mask);//رշжʹ
		}
    }
    return 0;
}
/******************************************************************************
*   : UARTx_Tx
* 	: ڷݺ
* 	: context uartṹָ
* 		datasҪ͵
* 		len,͵
* Return
*******************************************************************************/
void UARTx_Tx(void* context, alt_u8 * datas, alt_u8 len)
{
	CoreCourse_UART *p = (CoreCourse_UART *)context;
	memcpy(p->uart_txfifo, datas, len);//ݿfifo
	p->txfifo_len = len;//͵ݴݸڷͳȱ
	p->irq_mask = p->irq_mask | ITRDY_IRQ_MASK;	//򿪴ڷж
	IOWR_ALTERA_AVALON_UART_CONTROL(p->uart_base, p->irq_mask);
}
/******************************************************************************
*   : UARTx_Rx
* 	: ڽݺ
* 	: context uartṹָ
* 		datasյ
* Returnضݵĳ
*******************************************************************************/
alt_u8 UARTx_Rx(void* context, alt_u8 * datas)
{
	alt_u8 len;
	CoreCourse_UART *p = (CoreCourse_UART *)context;
	memcpy(datas, p->uart_rxfifo, p->rxfifo_len);//յݿdatas
	len = p->rxfifo_len;	//洢յݳ
	p->rxfifo_len = 0;	//㴮ڽṹеĽճ
	return len;	//ضݳ
}
/*жǷһ֡ жģʽǷ*/
void Judge_ETB() {         //ʱ
	if (FLAG_USART1_IT) {                //жϴǷж
		FLAG_USART1_IT = 0;              //жϣжϱ־
		TimeLag = 5;                    //ж֡ʱ
	}
	else if (TimeLag>0) {                //ûзжϿʼʱ
		TimeLag--;
		if (TimeLag==0){                 //ʱʱ֮ڴûзжϣ˵ݴ
			/*0ģʽ*/
			if (FLAG_FlowData) {
				FLAG_StartFlowData = 0;        //ģʽʼ/ʶߺĳҪģʽѾ
				return;                        //ģʽҪλ֡־
			}
			FLAG_FrameData = 1;                //λ֡־ߺĳҪʼ
		}
	}
}

/*	mainгʼʾ
 *
	//ʼ0
	UART_HANDLE hUART0;

	hUART0 = UART_Init(
			UART_0_BASE,
			UART_0_IRQ_INTERRUPT_CONTROLLER_ID,
			UART_0_IRQ,
			(IRRDY_IRQ_MASK),
			115200,
			(alt_isr_func)UART0_isr
		);
*/

/*	UARTx_Tx()ʹʾ
 *
	//
	UARTx_Tx(hUART0, (alt_u8 *)"Hello!\n",sizeof("Hello!\n"));
	uart0_tx_state = UART_TX_BUSY;//Ǵ0״̬Ϊæ
*/

/*	UARTx_Rx()ʹʾ
 *
	rx_len = UARTx_Rx(hUART0, (alt_u8 *)data_tmp);//ȡڽ
*/



