/* 计算机应用程序将某个文件的数据通过USB下传到单片机的RAM中,本程序中单片机再将数据从串口输出,相当于USB转串口,供参考 */
/*
; CH375/CH372 Bulk Data Download
; U2(AT89C51) Program
; 本程序测试收大数据块
; 本程序适用于时钟频率不高于24MHz的标准MCS-51单片机
;
; Website:  http://winchiphead.com
; Email:    tech@winchiphead.com
; Author:   W.ch 2003.09
*/

/* MCS-51单片机C语言的示例程序 */

#include <reg52.h>
#include "CH375INC.H"

unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1;		/* CH375命令端口的I/O地址 */
unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0;		/* CH375数据端口的I/O地址 */

unsigned char xdata  data_buffer[0x8000]	_at_ 0x0000;
unsigned char xdata *p_xram;
unsigned char xdata *p_ser;

/* 延时2微秒,不精确 */
void	Delay2us( )
{
	unsigned char i;
#define DELAY_START_VALUE	1  /* 根据单片机的时钟选择初值,20MHz以下为0,30MHz以上为2 */
	for ( i=DELAY_START_VALUE; i!=0; i-- );
}

/* 延时50毫秒,不精确 */
void	Delay50ms( )
{
	unsigned char i, j;
	for ( i=200; i!=0; i-- ) for ( j=250; j!=0; j-- );
}

/* CH375初始化子程序 */
void	CH375_Init( )
{
	unsigned char i;
/* 设置USB工作模式, 必要操作 */
	CH375_CMD_PORT = CMD_SET_USB_MODE;
	Delay2us( );  /* 如果时钟频率低于16MHz则无需该指令延时 */
	CH375_DAT_PORT = 2;  /* 设置为使用内置固件的USB设备方式 */
	for ( i=100; i!=0; i-- ) {  /* 等待操作成功,通常需要等待10uS-20uS */
		if ( CH375_DAT_PORT==CMD_RET_SUCCESS ) break;
	}
/*	if ( i==0 ) { CH372/CH375存在硬件错误 }; */
/* 下述启用中断,假定CH375连接在INT0 */
	IT0 = 0;  /* 置外部信号为低电平触发 */
	IE0 = 0;  /* 清中断标志 */
	EX0 = 1;  /* 允许CH375中断 */
}

/* CH375中断服务程序,使用寄存器组1 */
void	mCh375Interrupt( ) interrupt 0 using 1
{
	unsigned char InterruptStatus;
	unsigned char length;
	CH375_CMD_PORT = CMD_GET_STATUS;  /* 获取中断状态并取消中断请求 */
	Delay2us( );  /* 如果时钟频率低于16MHz则无需该指令延时 */
	InterruptStatus = CH375_DAT_PORT;  /* 获取中断状态 */
	if ( InterruptStatus == USB_INT_EP2_OUT ) {  /* 批量端点下传成功 */
		CH375_CMD_PORT = CMD_RD_USB_DATA;  /* 从当前USB中断的端点缓冲区读取数据块,并释放缓冲区 */
		Delay2us( );  /* 如果时钟频率低于16MHz则无需该指令延时 */
		length = CH375_DAT_PORT;  /* 首先读取后续数据长度 */
		if ( length == 0 )   /* 如果长度为0说明计算机将要开始下传一个新的文件 */
		{	
			p_xram=data_buffer;   /* 将指针初始化以便接收 */
			p_ser=data_buffer;
		}
		else  /* 长度不为0则说明是下传文件数据,接收到缓冲区中,再由主程序处理串口发送 */
		{	
			do {
				*p_xram = CH375_DAT_PORT;
				p_xram++;
			} while ( --length);
			if ( p_xram >= 0x7f80 ) p_xram=data_buffer;  /* 防止XRAM溢出,这是简单处理,实际产品应该处理严密些 */
		}

	}
	else CH375_CMD_PORT = CMD_UNLOCK_USB;  /* 释放当前USB缓冲区 */
}

main( ) {
	Delay50ms( );	/* 延时等待CH375初始化完成,如果单片机由CH375提供复位信号则不必延时 */
	CH375_Init( );  /* 初始化CH375 */
// Init serial baudrate
	PCON = 0x80;
	SCON = 0x50;  /* 8位串行数据 */
	TL2 = RCAP2L = 0xf6;//0 - RetLen;  /* 18.432MHz, 57600bps */
	TH2 = RCAP2H = 0xFF;
	T2CON = 0x34;  /* 定时器2用于串口的波特率发生器 */
	TI = 0; RI = 0;  /* 清除中断标志 */
// ?
	EA = 1;  /* 允许中断 */
	p_xram=data_buffer;
	p_ser=data_buffer;
	while ( 1 ) {  /* 以下指令开始工作循环,等待PC机命令进行操作 */
		if(p_ser<p_xram)
		{
			SBUF=*p_ser;
			while(!TI);
			TI=0;
			p_ser++;		
		}
	}
}
