⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 device.c

📁 CH374EVT.ZIP
💻 C
📖 第 1 页 / 共 2 页
字号:
													if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) P2 = dat;
													else dat = P2;
													break;
												case 0xA8:
													if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) IE = dat;
													else dat = IE;
													break;
												case 0xB0:
													if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) P3 = dat;
													else dat = P3;
													break;
												case 0xB8:
													if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) IP = dat;
													else dat = IP;
													break;
												case 0xC8:
													if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) T2CON = dat;
													else dat = T2CON;
													break;
												default:
													dat = 0;
													break;
											}
											break;
										case USB_CMD_MEM_S_IRAM:
											if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) *(PUINT8)pudp->down.u.mByte[0] = dat;
											else dat = *(PUINT8)pudp->down.u.mByte[0];
											break;
										case USB_CMD_MEM_S_XRAM:
											if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) *(PUINT8X)( pudp->down.u.mByte[0] | (UINT16)pudp->down.u.mByte[1] << 8 )= dat;
											else dat = *(PUINT8X)( pudp->down.u.mByte[0] | (UINT16)pudp->down.u.mByte[1] << 8 );
											break;
										case USB_CMD_MEM_S_ROM:
											if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) pudp->up.mStatus = ERR_UNSUPPORT;  /* 命令不支持 */
											else dat = *(PUINT8C)( pudp->down.u.mByte[0] | (UINT16)pudp->down.u.mByte[1] << 8 );
											break;
									}
									if ( ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) == 0 ) pudp->up.mBuffer[ l ] = dat;  /* 返回读出的数据 */
									pudp->down.u.mByte[0] ++;
									if ( pudp->down.u.mByte[0] == 0 ) pudp->down.u.mByte[1] ++;
								}
								if ( pudp->down.mCommand & USB_CMD_MEM_DIR_WR ) pudp->up.mLength = 0;  /* 写操作不返回数据 */
								pudp->up.mStatus = ERR_SUCCESS;
							}
						}
						else switch ( pudp->down.mCommand ) {  /* 命令类型:实现特定功能,分析命令码 */
							case USB_CMD_GET_FW_INFO:  /* 获取调试固件程序的版本,并取消未完成的上传数据块 */
								pudp->up.mBuffer[0] = THIS_FIRMWARE_VER;
								pudp->up.mLength = 1;
								pudp->up.mStatus = ERR_SUCCESS;
								Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) );  /* 同步触发位不变,设置USB端点2的IN正忙,返回NAK */
								break;
							case USB_CMD_GET_APP_INFO:  /* 获取当前应用系统的版本和说明字符串 */
								pudp->up.mBuffer[0] = THIS_APP_SYS_VER;
								l = 0;
								str = THIS_APP_SYS_STR;
								while ( pudp->up.mBuffer[ l ] = *str ) { l ++; str ++; }  /* 说明字符串 */
								pudp->up.mLength = 1 + sizeof( THIS_APP_SYS_STR );
								pudp->up.mStatus = ERR_SUCCESS;
								break;
/* 							case MY_CMD_CH451: */
							default:  /* 命令不支持 */
								pudp->up.mLength = 0;
								pudp->up.mStatus = ERR_UNSUPPORT;
								break;
						}
						l = pudp->up.mLength + (UINT8)( & ( (USB_UP_PKT *)0 ) -> mBuffer );
						Write374Byte( REG_USB_LENGTH, l );
						Write374Block( RAM_ENDP2_TRAN, l, (PUINT8)&pudp->up );  // 向USB端点2的发送缓冲区写入数据块
						Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_RECV_TOG );
//						Write374Index( REG_USB_ENDP2 );  // 对于并口连接可以用本行及下面一行代替上一行的程序,减少写一次index的时间,提高效率
//						Write374Data( M_SET_EP2_TRAN_ACK( Read374Data0( ) ) ^ BIT_EP2_RECV_TOG );
					}
				}
				break;
			}
			case USB_INT_EP2_IN: {  // 批量端点上传成功,未处理
				Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_TRAN_TOG );
//				Write374Index( REG_USB_ENDP2 );  // 对于并口连接可以用本行及下面一行代替上一行的程序,减少写一次index的时间,提高效率
//				Write374Data( M_SET_EP2_TRAN_NAK( Read374Data0( ) ) ^ BIT_EP2_TRAN_TOG );
				break;
			}
			case USB_INT_EP1_IN: {  // 中断端点上传成功,未处理
				Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( Read374Byte( REG_USB_ENDP1 ) ) ^ BIT_EP1_TRAN_TOG );
				break;
			}
			case USB_INT_EP0_SETUP: {  // 控制传输
				USB_SETUP_REQ	SetupReqBuf;
				l = Read374Byte( REG_USB_LENGTH );
				if ( l == sizeof( USB_SETUP_REQ ) ) {
					Read374Block( RAM_ENDP0_RECV, l, (PUINT8)&SetupReqBuf );
					SetupLen = SetupReqBuf.wLengthL;
					if ( SetupReqBuf.wLengthH || SetupLen > 0x7F ) SetupLen = 0x7F;  // 限制总长度
					l = 0;  // 默认为成功并且上传0长度
					if ( ( SetupReqBuf.bType & DEF_USB_REQ_TYPE ) != DEF_USB_REQ_STAND ) {  /* 只支持标准请求 */
						l = 0xFF;  // 操作失败
					}
					else {  // 标准请求
						SetupReq = SetupReqBuf.bReq;  // 请求码
						switch( SetupReq ) {
							case DEF_USB_GET_DESCR:
								switch( SetupReqBuf.wValueH ) {
									case 1:
										pDescr = (PUINT8)( &MyDevDescr[0] );
										l = sizeof( MyDevDescr );
										break;
									case 2:
										pDescr = (PUINT8)( &MyCfgDescr[0] );
										l = sizeof( MyCfgDescr );
										break;
									case 3:
										switch( SetupReqBuf.wValueL ) {
											case 1:
												pDescr = (PUINT8)( &MyManuInfo[0] );
												l = sizeof( MyManuInfo );
												break;
											case 2:
												pDescr = (PUINT8)( &MyProdInfo[0] );
												l = sizeof( MyProdInfo );
												break;
											case 0:
												pDescr = (PUINT8)( &MyLangDescr[0] );
												l = sizeof( MyLangDescr );
												break;
											default:
												l = 0xFF;  // 操作失败
												break;
										}
										break;
									default:
										l = 0xFF;  // 操作失败
										break;
								}
								if ( SetupLen > l ) SetupLen = l;  // 限制总长度
								l = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen;  // 本次传输长度
								Write374Block( RAM_ENDP0_TRAN, l, pDescr );  /* 加载上传数据 */
								SetupLen -= l;
								pDescr += l;
								break;
							case DEF_USB_SET_ADDRESS:
								SetupLen = SetupReqBuf.wValueL;  // 暂存USB设备地址
								break;
							case DEF_USB_GET_CONFIG:
								Write374Byte( RAM_ENDP0_TRAN, UsbConfig );
								if ( SetupLen >= 1 ) l = 1;
								break;
							case DEF_USB_SET_CONFIG:
								UsbConfig = SetupReqBuf.wValueL;
								break;
							case DEF_USB_CLR_FEATURE:
								if ( ( SetupReqBuf.bType & 0x1F ) == 0x02 ) {  // 不是端点不支持
									switch( SetupReqBuf.wIndexL ) {
										case 0x82:
											Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) );
											break;
										case 0x02:
											Write374Byte( REG_USB_ENDP2, M_SET_EP2_RECV_ACK( Read374Byte( REG_USB_ENDP2 ) ) );
											break;
										case 0x81:
											Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( Read374Byte( REG_USB_ENDP1 ) ) );
											break;
										case 0x01:
											Write374Byte( REG_USB_ENDP1, M_SET_EP1_RECV_ACK( Read374Byte( REG_USB_ENDP1 ) ) );
											break;
										default:
											l = 0xFF;  // 操作失败
											break;
									}
								}
								else l = 0xFF;  // 操作失败
								break;
							case DEF_USB_GET_INTERF:
								Write374Byte( RAM_ENDP0_TRAN, 0 );
								if ( SetupLen >= 1 ) l = 1;
								break;
							case DEF_USB_GET_STATUS:
								Write374Byte( RAM_ENDP0_TRAN, 0 );
								Write374Byte( RAM_ENDP0_TRAN + 1, 0 );
								if ( SetupLen >= 2 ) l = 2;
								else l = SetupLen;
								break;
							default:
								l = 0xFF;  // 操作失败
								break;
						}
					}
				}
				else l = 0xFF;  // 操作失败
				if ( l == 0xFF ) {  // 操作失败
					Write374Byte( REG_USB_ENDP0, M_SET_EP0_RECV_STA( M_SET_EP0_TRAN_STA( 0 ) ) );  // STALL
				}
				else if ( l <= RAM_ENDP0_SIZE ) {  // 上传数据
					Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ), l ) | BIT_EP0_TRAN_TOG );  // DATA1
				}
				else {  // 下传数据或其它
					Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ) ) | BIT_EP0_RECV_TOG );  // DATA1
				}
				break;
			}
			case USB_INT_EP0_IN: {
				switch( SetupReq ) {
					case DEF_USB_GET_DESCR:
						l = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen;  // 本次传输长度
						Write374Block( RAM_ENDP0_TRAN, l, pDescr );  /* 加载上传数据 */
						SetupLen -= l;
						pDescr += l;
						Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( Read374Byte( REG_USB_ENDP0 ), l ) ^ BIT_EP0_TRAN_TOG );
						break;
					case DEF_USB_SET_ADDRESS:
						Write374Byte( REG_USB_ADDR, SetupLen );
					default:
						Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) );  // 结束
						break;
				}
				break;
			}
			case USB_INT_EP0_OUT: {
				switch( SetupReq ) {
//					case download:
//						get_data;
//						break;
					case DEF_USB_GET_DESCR:
					default:
						Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) );  // 结束
						break;
				}
				break;
			}
			default: {
				break;
			}
		}
		Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER );  // 清中断标志
	}
	else if ( s & BIT_IF_USB_SUSPEND ) {  // USB总线挂起
		Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_USB_SUSPEND );  // 清中断标志
		Write374Byte( REG_SYS_CTRL, Read374Byte( REG_SYS_CTRL ) | BIT_CTRL_OSCIL_OFF );  // 时钟振荡器停止振荡,进入睡眠状态
	}
	else if ( s & BIT_IF_WAKE_UP ) {  // 芯片唤醒完成
		Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_WAKE_UP );  // 清中断标志
	}
	else {  // 意外的中断,不可能发生的情况,除了硬件损坏
		Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG );  // 清中断标志
	}
/*	IE0 = 0;  清中断标志,与单片机硬件有关,对应于INT0中断 */
}

/* 关闭CH374的所有USB通讯 */
void	CH374OffUSB( void ) {
	EX0 = 0;  /* 关闭USB中断,本程序中USB主机模式下使用查询方式 */
	Write374Byte( REG_USB_SETUP, 0x00 );  /* 关闭USB操作 */
//	CH374Reset( );  /* 复位也可以 */
	CH374DelaymS( 10 );  /* 为USB主从切换进行时间缓冲,这是必要的延时操作,用于让计算机认为USB设备已经撤离 */
/* 如果CH374仍然连接着计算机,而程序使CH374切换到USB主机模式,那么会导致与计算机之间双USB主机冲突 */
}

void device( ) {
	CH374DeviceInit( );  /* 初始化USB设备模式 */
	FreeUSBmS = 0;  /* 清除USB空闲计时 */
	while( 1 ) {
		if ( IsKeyPress( ) ) {  /* 有键按下 */
			if ( FreeUSBmS >= 250 ) {  /* USB空闲超过250毫秒 */
				printf( "Exit USB device mode\n" );
				CH374OffUSB( );  /* 关闭USB设备 */
				return;
			}
		}
		if ( FreeUSBmS < 250 ) FreeUSBmS ++;  /* USB空闲计时,避免在USB通讯过程中由用户按键导致USB主从切换 */
		CH374DelaymS( 1 );
/* USB设备模式全部在中断服务中处理,主程序可以做其它事情,当然也可以在主程序中使用查询方式处理USB设备的通讯 */
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -