/*
 * Copyright (c) 2010 仪星电子
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

/*
 * 著作权所有(C) 2010 仪星电子
 *
 * 本程序为自由软件；您可依据自由软件基金会所发表的GNU通用公共授权条款规定，
 * 就本程序再为发布与／或修改；无论您依据的是本授权的第二版或（您自行选择的）
 * 任一日后发行的版本。

 * 本程序是基于使用目的而加以发布，然而不负任何担保责任；亦无对适售性或特定
 * 目的适用性所为的默示性担保。详情请参照GNU通用公共授权。

 * 您应已收到附随于本程序的GNU通用公共授权的副本；如果没有，请写信至自由软件
 * 基金会：59 Temple Place - Suite 330, Boston, Ma 02111-1307, USA。

 * Email yixingdianzi@126.com
 * Email/MSN yixingdianzi@hotmail.com
 * QQ 648887464
 */

/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
* File Name          : usb_endp.c
* Author             : MCD Application Team
* Version            : V3.1.0
* Date               : 10/30/2009
* Description        : Endpoint routines
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
#include "usb_desc.h"
#include "usb_mem.h"
#include "usb_istr.h"
#include "qdmx_adc.h"
#include "math.h"

#define SEND 32

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t buffer_out[VIRTUAL_COM_PORT_DATA_SIZE];
__IO uint32_t count_out = 0;

uint32_t count_in;
uint32_t cyl;			   //可以设置为采样率和存储深度的数据

uint8_t shakesuccess=0;
uint8_t status=0;
uint8_t csbb=0;
uint8_t sign=0;
uint8_t back[32]={0};
uint8_t b[37]={0};
uint8_t d[32]={0};

static const uint8_t banbe[32]=					/*仪器版本信息*/
{
    'Y','i','X','i','n','g','D','i','a','n', 'Z', 'i', 0, 0, 0, 0, 	//厂商ID   16*8B
    'S','t','u','-','0','.', '1', 0, 0 , 0 , 0  ,  0 , 0, 0, 0, 0		//型号ID   16*8B
};

uint8_t ADCConvertedValue[16384];
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/*******************************************************************************
* Function Name  : EP1_IN_Callback
* Description    :
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void EP1_IN_Callback(void)
{
   	if(count_in<256)
   	{
   		if (GetENDPOINT(ENDP1) & EP_DTOG_RX)
		{
		   	FreeUserBuffer(ENDP1, EP_DBUF_IN); 
			UserToPMABufferCopy(ADCConvertedValue+64*count_in, ENDP1_TX1ADDR, 64);
		   	SetEPDblBuf1Count(ENDP1,EP_DBUF_IN,64);
		}
		else
		{
			FreeUserBuffer(ENDP1, EP_DBUF_IN);
			UserToPMABufferCopy(ADCConvertedValue+64*count_in, ENDP1_TX0ADDR, 64);
			SetEPDblBuf0Count(ENDP1,EP_DBUF_IN,64);
		}
		count_in++;	
   	}
}

/*******************************************************************************
* Function Name  : EP3_IN_Callback
* Description    :
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void EP3_OUT_Callback(void)
{
	uint8_t i;
	uint8_t j;
	uint8_t k;
	uint8_t q[32]={0xff,0xff,0xff,0xff,0xff,0x11,0x22,0x33,0x44,0x55,0};
	uint8_t s[32]={0};
	j=0;
	k=0;
  
  	count_out = GetEPRxCount(ENDP3);//获得接收到的数据长度 
  	PMAToUserBufferCopy(d, ENDP3_RXADDR, count_out);//将数据从USB EP3 RX的缓冲区拷贝到用户指定的数组中 
 
	#ifndef STM32F10X_CL
	  /* Enable the receive of data on EP3 */
	  SetEPRxValid(ENDP3);
	#endif /* STM32F10X_CL */

/*				******				*/
/* 		检测发送的是不是重启命令 	*/
/*				******				*/
	for(i=0;i<10;i++)
	{
		if(q[i]==d[i])
		{
			k++;
		}
	}		   
/*				******				*/
/* 		  表示命令是重启命令		*/
/*				******				*/
	if(k==10)
	{
		SetEPDblBuffCount(ENDP1 , EP_DBUF_IN , SEND);
		ADC_Cmd(ADC1, DISABLE);
		shakesuccess=0;
		status=0;
		Callback(q);
		k=0;
	}
/*				******				*/
/* 		表示命令不是重启命令		*/
/*				******				*/
	else
	{
/*				******				*/
/*	 下位机与上位机命令传输过程		*/
/*				******				*/
	  	if(shakesuccess)
		{
			if(d[0]==0xff)
			{
				switch(d[1])						   //	 示波器开启	
				{
					case 0x01 :	
					{	
						SetEPDblBuffCount(ENDP1 , EP_DBUF_IN , SEND);
						back[0]=d[0];
						back[1]=0x01;
						for(i=2;i<32;i++)
							back[i]=0;
						csbb=0x55;
						ADC_Cmd(ADC1, DISABLE);
						Callback(back);	
						break; 
					} 
					case 0x10 :	
					{
						SetEPDblBuffCount(ENDP1 , EP_DBUF_IN , SEND);
						back[0]=d[0];
						back[1]=0x01;
						for(i=2;i<32;i++)
							back[i]=0;
						csbb=0;
						ADC_Cmd(ADC1, DISABLE);
						Callback(back);	
						break; 
					}
					case 0x02 :
					{
						SetEPDblBuffCount(ENDP1 , EP_DBUF_IN , SEND);
						back[0]=d[0];
						back[1]=0x01;
						back[2]=0x00;
						back[3]=0x00;
						back[4]=0x00;
						back[5]=0x02;
						for(i=6;i<32;i++)
							back[i]=0;
						Callback(back);	
						break; 
					}
					case 0x04 :
					{
						SetEPDblBuffCount(ENDP1 , EP_DBUF_IN , SEND);
						back[0]=d[0];
						back[1]=0x01;
						back[2]=0x00;
						back[3]=0x00;
						back[4]=0x00;
						back[5]=0x08;
						for(i=6;i<32;i++)
							back[i]=0;
						Callback(back);	
						break; 
					}
					case 0x08 :
					{
						SetEPDblBuffCount(ENDP1 , EP_DBUF_IN , SEND);
						back[0]=d[0];
						back[1]=0x01;
						for(i=2;i<32;i++)
							back[i]=0;
						Callback(back);	
						break; 
					}
					case 0x12 :	
					{
						SetEPDblBuffCount(ENDP1 , EP_DBUF_IN , SEND);
						cyl=428571;//857143;//1000000;
						back[0]=d[0];
						back[1]=0x01;
						back[2]=cyl/16777216%256;
						back[3]=cyl/65536%256;
						back[4]=cyl/256%256;
						back[5]=cyl%256;
						for(i=6;i<32;i++)
							back[i]=0;
						Callback(back);	
						break; 
					}
					case 0x14 :	
					{
						SetEPDblBuffCount(ENDP1 , EP_DBUF_IN , 64);
						if(csbb==0x55)
						{
			/******************************************************************************************************
					  分频方式				RCC_PCLK2_Div2		RCC_PCLK2_Div4	   RCC_PCLK2_Div6	RCC_PCLK2_Div8
					   采样率				   36000000			   18000000		   	  12000000		   9000000
				ADC_SampleTime_1Cycles5       2571428.571        1285714.286   		857142.857		  642857.143
				ADC_SampleTime_7Cycles5       1800000             900000			600000			  450000
				ADC_SampleTime_13Cycles5      1384615.385         692307.692    	461538.462		  346153.846
				ADC_SampleTime_28Cycles5       878048.780         439024.390    	292682.927		  219512.195
				ADC_SampleTime_41Cycles5       666666.667         333333.333   		222222.222		  166666.667
				ADC_SampleTime_55Cycles5       529411.765         264705.882   		176470.588		  132352.941
				ADC_SampleTime_71Cycles5       428571.429         214285.714   		142857.143		  107142.857
				ADC_SampleTime_239Cycles5 	   142857.143		   71428.571		 47619.476		   35714.286
			******************************************************************************************************/
//							ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_1Cycles5);	 	 //调节采样率
//  						ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_1Cycles5);
							ADC_Cmd(ADC1, ENABLE);
							ADC_Cmd(ADC1, ENABLE);
							ADC_SoftwareStartConvCmd(ADC1, ENABLE);
							ADC_SoftwareStartConvCmd(ADC1, ENABLE);
						}
						break;
					}
					case 0x18 :	
					{
						SetEPDblBuffCount(ENDP1 , EP_DBUF_IN , SEND);
						back[0]=d[0];
						back[1]=0x01;
	
						cyl=8;
						back[2]=cyl/16777216%256;
						back[3]=cyl/65536%256;
						back[4]=cyl/256%256;
						back[5]=cyl%256;
	
						for(i=6;i<32;i++)
							back[i]=0;
						Callback(back);	
						break; 
					}
					case 0x80 :	
					{
						SetEPDblBuffCount(ENDP1 , EP_DBUF_IN , SEND);

						ADC_Cmd(ADC1, DISABLE);

						csbb=0x55;
						count_in=554;
						back[0]=d[0];
						back[1]=0x01;
						for(i=2;i<32;i++)
							back[i]=0;
						Callback(back);	
						Delay(0xfffff);
						Delay(0xfffff);
						Delay(0xfffff);
						Delay(0xfffff);
						Delay(0xfffff);
						Delay(0xfffff);
						Delay(0xfffff);
						break; 
					}
					default   : break;
				}
			}
		}
		else										
		{
			SetEPDblBuffCount(ENDP1 , EP_DBUF_IN , SEND);
	
	   		switch(status)
			{
				case 0  : 	   //握手传输发送五个随机数
				{
					if(count_out!=0x05)	break;
	
					b[5]=(uint8_t)(rand()&0x00ff);
					b[6]=(uint8_t)(rand()&0x00ff);
					b[7]=(uint8_t)(rand()&0x00ff);
					b[8]=(uint8_t)(rand()&0x00ff);
					b[9]=(uint8_t)(rand()&0x00ff); 
					
					for(i=0;i<5;i++)
					{
						b[i]=d[i];
					}
	
					Callback(b+5); 
					status=1;
	  				break;
				}
				case 1  :	  //握手传输比较随机数，传输版本、功能信息
				{	
					if(count_out!=0x0a)	break;
	
					for(i=0;i<10;i++)
					{
						if(b[i]==d[i])
						{
							j++;
						}
					} 
					if(j==10)
					{	
						status=2;
						Callback(banbe);
					}
					else
					{
						status=0;
						s[0]=0;
						Callback(s); 		 /*回复握手错误命令*/
					}	
					break;
				}
				case 2  :		 //握手成功传输
				{
					if(count_out!=0x01)	break;
					
					if(d[0]==0xaa)
					{
						s[0]=0xaa;
						Callback(s); 		 	/*回复握手成功命令*/
						shakesuccess=1;
					}
					else
					{
						s[0]=0;
						Callback(s);  			  /*回复握手错误命令*/
					}
					status=0;
					break;
				}
				default : 				break;
			}	
		}
	}		  
}

/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

