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

📄 isr.c

📁 Comlete files for fullfile the slave USB function!
💻 C
字号:
/*
//*************************************************************************
//
//                  BASBA   P R O P R I E T A R Y
//
//           COPYRIGHT (c)   2003 BY BASBA USA.
//                     --  ALL RIGHTS RESERVED  --
//
// File Name:	isr.c
// Purpose:		Handles the interrupt generated by PDIUSBD12. It retrieve
//				data from PDIUSBD12's internal FIFO  to CPU memory, and
//				setup proper event flags to inform mainloop for processing
// Author:		Shuming Yu
// Created:		10 May 2003
// Modified:
// Revision:		1.0
//
//*************************************************************************
*/

#include <reg51.h>                /* special function register declarations   */

#include "d12hal.h"
#include "cmds.h"
#include "mainloop.h"
#include "usbStruc.h"

#define INTERRUPT_INT0_Overflow 0
#define INTERRUPT_Timer_0_Overflow 1

void bus_reset(void);

void ProcessCtrlInEP(void);
void ProcessCtrlOutEP(void);

//*************************************************************************
//  Public static data
//*************************************************************************

extern EPPFLAGS bEPPflags; /* USB event flags */
extern CONTROL_XFER ControlData; /* Control endpoint TX/RX buffers */

/* ISR static vars */
//unsigned char idata GenEpBuf[EP1_PACKET_SIZE];
unsigned char idata GenEpBuf[EP0_PACKET_SIZE];
//IO_REQUEST idata ioRequest;

unsigned long ClockTicks = 0;

timer_isr() interrupt INTERRUPT_Timer_0_Overflow
{
	DISABLE;
	ClockTicks++;
	bEPPflags.bits.timer = 1;
	ENABLE;
}

usb_isr() interrupt INTERRUPT_INT0_Overflow
{
	DISABLE;
	fn_usb_isr();
	ENABLE;
}

/* Interrupt service subroutine */
void fn_usb_isr()
{
	unsigned int i_st;

	bEPPflags.bits.in_isr = 1;

	i_st = D12_ReadInterruptRegister();

	if(i_st != 0) {
		if(i_st & D12_INT_BUSRESET) {
			bus_reset();
			bEPPflags.bits.bus_reset = 1;
		}
		if(i_st & D12_INT_EOT)
			;
		if(i_st & D12_INT_SUSPENDCHANGE)
			bEPPflags.bits.suspend = 1;

		if(i_st & D12_INT_ENDP0IN)
			/* Control Endpoint IN Interrupt */
			ProcessCtrlInEP();
		if(i_st & D12_INT_ENDP0OUT) 
			/* Control Endpoint OUT Interrupt */
			ProcessCtrlOutEP();
		if(i_st & D12_INT_ENDP1IN) {
			/* Endpoint 1 IN Interrupt (generic input) */
			D12_ReadLastTransactionStatus(3); /* Clear interrupt flag */
			/* send data back to host */
			bEPPflags.bits.ep1_sxdone = 1;	//host request to send data
		}
		if(i_st & D12_INT_ENDP1OUT)
		{   /* Endpoint 1 OUT Interrupt (generic output) */
			unsigned char len;

			D12_ReadLastTransactionStatus(2); /* Clear interrupt flag */
			len = D12_ReadEndpoint(2, GenEpBuf, sizeof(GenEpBuf));
			if(len != 0)
			    bEPPflags.bits.ep1_rxdone = 1;
		}
		//if(i_st & D12_INT_ENDP2IN)
		//	main_txdone();
		//if(i_st & D12_INT_ENDP2OUT)
		//	main_rxdone();
	}

	bEPPflags.bits.in_isr = 0;
}

void bus_reset(void)
{
}

// Control OUT handler
void ProcessCtrlOutEP(void)
{
	unsigned char ep_last, i;

	/* Clear corresponding endpoint interrupt flag */
	ep_last = D12_ReadLastTransactionStatus(0); 

	/* check to see if the current received status is a SETUP package,
	   if so, SETUP endpoints have to be 'ACK'ed. */
	if (ep_last & D12_SETUPPACKET) {	/* SETUP package ? */
		ControlData.wLength = 0;
		ControlData.wCount = 0;

		/* Select control OUT endpoint, readbuffer, if validate device request,
		   save to deviceRequest clear buffer */
		if( D12_ReadEndpoint(0, (unsigned char *)(&(ControlData.DeviceRequest)),
			sizeof(ControlData.DeviceRequest)) != sizeof(DEVICE_REQUEST) ) {
			
			stall_ep0;	/* stall control endpoints */
			bEPPflags.bits.control_state = USB_IDLE;
			
			return;
		}
		
		/* swap data low byte and high byte, for USB data structure is different
		   from C51 data structure */
		ControlData.DeviceRequest.wValue  = SWAP(ControlData.DeviceRequest.wValue);
		ControlData.DeviceRequest.wIndex  = SWAP(ControlData.DeviceRequest.wIndex);
		ControlData.DeviceRequest.wLength = SWAP(ControlData.DeviceRequest.wLength);

		/* Acknowledge SETUP command to both IN and OUT endpoints, to reanable validate
	       and ClearBuffer commands. */
		D12_AcknowledgeEndpoint(0);
		D12_AcknowledgeEndpoint(1);

		/* If ControlRead, wLength means the number of bytes to be sent to host;
		   if ControlWrite,wLength means the number of bytes to be got from host. */
		ControlData.wLength = ControlData.DeviceRequest.wLength;
		ControlData.wCount = 0;

		/* Verify whether the contro transfer is Control READ/WRITE ? */
		if (ControlData.DeviceRequest.bmRequestType & (unsigned char)USB_ENDPOINT_DIRECTION_MASK) {
			/* Control Read (get command, device will need to send data packet back to host) */
			bEPPflags.bits.setup_packet = 1;	// set event SETUP packet 
			bEPPflags.bits.control_state = USB_TRANSMIT;		
		}
		else {	/* Control Write (set command) */
			if (ControlData.DeviceRequest.wLength == 0) {
			    /* Control Write without data */
				bEPPflags.bits.setup_packet = 1;	// set event SETUP packet 
				bEPPflags.bits.control_state = USB_IDLE;	
			}
			else {	/*Control Write with data */
				if(ControlData.DeviceRequest.wLength > MAX_CONTROLDATA_SIZE) {
					/* data length not acceptable */
					bEPPflags.bits.control_state = USB_IDLE;
				stall_ep0;	/* stall control endpoints */
				}
				else {
					/* Device need to be received number of wLength bytes of data from host */
					bEPPflags.bits.control_state = USB_RECEIVE;	/* set command with OUT token */
				}
			} // set command with data
		} // else set command
	} // if setup packet

	else if (bEPPflags.bits.control_state == USB_RECEIVE) {
		i =	D12_ReadEndpoint(0, ControlData.dataBuffer + ControlData.wCount,
			EP0_PACKET_SIZE);

		ControlData.wCount += i;
		if( i != EP0_PACKET_SIZE || ControlData.wCount >= ControlData.wLength) {
			bEPPflags.bits.setup_packet = 1;
			bEPPflags.bits.control_state = USB_IDLE;
		}
	}

	else {
		bEPPflags.bits.control_state = USB_IDLE;
	}
}

// Control IN handler
void ProcessCtrlInEP(void)
{
	short i = ControlData.wLength - ControlData.wCount;

	D12_ReadLastTransactionStatus(1); /* Clear interrupt flag */

	/* if not in transmit status, return */
	if (bEPPflags.bits.control_state != USB_TRANSMIT) 
		return;

	/* number of rest bytes to be sent is more then EP0_PACKET_SIZE bytes, send EP0_PACKET_SIZE bytes */
	if( i >= EP0_PACKET_SIZE) { 
		D12_WriteEndpoint(1, ControlData.pData + ControlData.wCount, EP0_PACKET_SIZE);
		ControlData.wCount += EP0_PACKET_SIZE;

		bEPPflags.bits.control_state = USB_TRANSMIT;
	}
	/* send rest of bytes (number of bytes is less than EP0_PACKET_SIZE bytes) */
	else if( i != 0) {
		D12_WriteEndpoint(1, ControlData.pData + ControlData.wCount, i);
		ControlData.wCount += i;

		bEPPflags.bits.control_state = USB_IDLE;
	}
	/* Send zero packet at the end, if no data phase, 
	   IO device acknowledging receipt of setup phase (status phanse) */
	else if (i == 0){
		D12_WriteEndpoint(1, 0, 0); 

		bEPPflags.bits.control_state = USB_IDLE;
	}
}



⌨️ 快捷键说明

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