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

📄 chap_9.c

📁 msp430单片机与pdiusbd12接口的固件程序
💻 C
📖 第 1 页 / 共 2 页
字号:

   //*************************************************************************
   // USB Protocol Layer
   //*************************************************************************
void reserved(void)
{
	stall_ep0();
}

//*************************************************************************
   // USB standard device requests
//*************************************************************************
//*************************************************************************
//获取设备状态,Get Status请求要求接收方返回一个相应的状态,设备返回16位的状态描述.
//*************************************************************************
void get_status(void)
{
	unsigned char endp, txdat[2];
	unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
	unsigned char c;

	if (bRecipient == USB_RECIPIENT_DEVICE) 
	{
	  //获取设备的状态状态,返回值信息如下:
	  //Bit0: 			0 总线供电 			1 自供电
	  //Bit1:			0 不支持远程唤醒		1 支持远程唤醒
	  //Bit2~bit15:
		if(bEPPflags.bits.remote_wakeup == 1)	//获取远程唤醒状态
			txdat[0] = 3;
		else
			txdat[0] = 1;
		txdat[1]=0;
		single_transmit(txdat, 2);
	}
	else if (bRecipient == USB_RECIPIENT_INTERFACE) 
	{
	  //获取接口状态,16位全部保留,返回全0即可
	  	txdat[0]=0;
		txdat[1]=0;
		single_transmit(txdat, 2);
	} 
	else if (bRecipient == USB_RECIPIENT_ENDPOINT) 
	{
	  //获取端点状态,一个端点有输入和输出两个端点号,用Bit7区分: 0 要求返回输出端点的状态	1 要求返回输入端点的状态
	  //Bit0:	0	端点允许			1 端点禁止
		endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
			c = D12_SelectEndpoint(endp*2 + 1);	//Control-in 端点
		else
			c = D12_SelectEndpoint(endp*2);		// Control-out 端点
		if(c & D12_STALL)
			txdat[0] = 1;						//端点禁止
		else
			txdat[0] = 0;						//端点允许
		txdat[1] = 0;
		single_transmit(txdat, 2);
	}
	else
		stall_ep0();
}
//*************************************************************************
//特性清除
//*************************************************************************
//Clear Feature用来清除或禁止设备一个特定的特性.当接收到这个请求后设备就执行相应的操作,
//并返回一个空的数据表示执行完毕.如果请求的特性不存在或不能清除就发出一个STALL的握手.
//请求的值: 1 清除设备的远程唤醒功能;
//			0 清除索引号对应的输入或输出端点的禁止功能,恢复其使用
void clear_feature(void)
{
	unsigned char endp;
	unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
	if (bRecipient == USB_RECIPIENT_DEVICE
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP) 
	{
	  //清除设备的远程唤醒功能
		DISABLE;
		bEPPflags.bits.remote_wakeup = 0;
		ENABLE;
		single_transmit(0, 0);
	}
	else if (bRecipient == USB_RECIPIENT_ENDPOINT
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL)
	{
	  //清除端点的禁止功能
		endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
			/* clear TX stall for IN on EPn. */
			D12_SetEndpointStatus(endp*2 + 1, 0); 	//使能输入端点
		else
			/* clear RX stall for OUT on EPn. */
			D12_SetEndpointStatus(endp*2, 0);		//使能输出端点
		single_transmit(0, 0);
	}
	else
		stall_ep0();
}
//*************************************************************************
//特性设置
//*************************************************************************
//Set Feature用来设置或允许一个特性,当接收到这个请求后设备就执行相应的操作,
//并返回一个空的数据表示执行完毕.如果请求的特性不存在或不能清除就发出一个STALL的握手.
//请求的值: 1 启动设备的远程唤醒功能;
//			0 禁止索引号对应的输入或输出端点
void set_feature(void)
{
	unsigned char endp;
	unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;

	if (bRecipient == USB_RECIPIENT_DEVICE
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP) 
	{
	  //设置远程唤醒功能
		DISABLE;
		bEPPflags.bits.remote_wakeup = 1;
		ENABLE;
		single_transmit(0, 0);
	}
	else if (bRecipient == USB_RECIPIENT_ENDPOINT
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL)
	{
	  //禁止端点
		endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
			/* clear TX stall for IN on EPn. */
			D12_SetEndpointStatus(endp*2 + 1, 1);	//禁止输入端点
		else
			/* clear RX stall for OUT on EPn. */
			D12_SetEndpointStatus(endp*2, 1);		//禁止输出端点
		single_transmit(0, 0);
	}
	else
		stall_ep0();
}
//*************************************************************************
////设置地址
//*************************************************************************
//在USB设备枚举时,主机会分配一个新的地址给设备,以取代默认地址(0).当设备接收
//到这个设备请求时就把设备的当前地址改为分配的地址,以让设备对新的地址做出响应,
//此请求不含数据阶段,固件需要向主机写一个零长度的数据包作为应答
void set_address(void)
{
	D12_SetAddressEnable((unsigned char)(ControlData.DeviceRequest.wValue &
		DEVICE_ADDRESS_MASK), 1);
	single_transmit(0, 0); 
}
//*************************************************************************
//获取描述符
//*************************************************************************
//用来获取USB设备相对应的描述符设备,请求的高位字节为要求的描述符类型
void get_descriptor(void)
{
	unsigned char bDescriptor = MSB(ControlData.DeviceRequest.wValue);

	if (bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE) 
	{
	  //获取设备描述符
		code_transmit((unsigned char *)&DeviceDescr, sizeof(USB_DEVICE_DESCRIPTOR));
	} 
	else if (bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE) 
	{
	  //获取配置描述符或描述符集合,
	  //配置描述符的返回可长可短,要视主机的长度要求而定
		code_transmit((unsigned char *)&DescriptorSet, CONFIG_DESCRIPTOR_LENGTH);

//***NOTE****: 上句中,将原来的ConfigDescr换为DescriptorSet
//使意义更清晰,固件根据上位机的请求来决定是返回单一个配置描述符,还是返回一个描述符集合
	} 
	else
		stall_ep0();
}
//*************************************************************************
//获取配置状态
//*************************************************************************
//如果设备已经配置,则返回信息为当前的配置值(一个字节);否则返回为0,表示设备还没有配置
void get_configuration(void)
{
	unsigned char c = bEPPflags.bits.configuration;
	single_transmit(&c, 1);
}
//*************************************************************************
//设置配置状态
//*************************************************************************
//此请求用来选择设备的工作配置值域只能是0,或与配置描述符中与
//bConfigureation Value字段(在本固件中设置为1)相同的值,固件应向主机发送零数
//据包作为应答
void set_configuration(void)
{
	if (ControlData.DeviceRequest.wValue == 0) 
	{
	//设备进入地址状态,所有端点除控制端点外,都应被禁止.
	//需要新的Set Configuration请求来配置
		single_transmit(0, 0);
		DISABLE;
		bEPPflags.bits.configuration = 0;
		ENABLE;
		init_unconfig();
	} 
	else if (ControlData.DeviceRequest.wValue == 1) 
	{
		//配置设备且置标志
		single_transmit(0, 0);
		init_unconfig();
		init_config();
		DISABLE;
		bEPPflags.bits.configuration = 1;
		ENABLE;
	} else
		stall_ep0();
}
//*************************************************************************
//获取接口状态
//*************************************************************************
void get_interface(void)
{
	unsigned char txdat = 0;        /* Only /Current interface = 0 */
	single_transmit(&txdat, 1);
}
//*************************************************************************
//设置接口状态
//*************************************************************************
//用于设备支持多接口的时候,主机用来选择一个接口.选择正确,设备发送一个空的数
//据表示执行完毕;当接口不存在时,设备返回STALL.
void set_interface(void)
{
	if (ControlData.DeviceRequest.wValue == 0 && ControlData.DeviceRequest.wIndex == 0)
		single_transmit(0, 0);
	else
		stall_ep0();
}

⌨️ 快捷键说明

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