Пример #1
0
//-----------------------------------------------------------------------------
// Main Routine
//-----------------------------------------------------------------------------
void main(void) 
{
   USB_Clock_Start();                     // Init USB clock *before* calling USB_Init
   USB_Init(USB_VID,USB_PID,USB_MfrStr,USB_ProductStr,USB_SerialStr,USB_MaxPower,USB_PwAttributes,USB_bcdDevice);

	CLKSEL |= 0x02;

	
	RSTSRC	|=	0x02;

	Port_Init();						//	Initialize crossbar and GPIO

	USB_Int_Enable();					//	Enable USB_API Interrupts
		while (1);
}
Пример #2
0
//-----------------------------------------------------------------------------
// Main Routine
// after initialization, the program simply polls the !req input and when 
// !req goes low, !ack on is lowered to acknowledge, 
// the address is captured in P1 (AE0-7) and P2 (AE8-15) and is copied to XRAM.
// Then !ack is raised, we wait for !req to go high and start over.
// We initiate BlockWrite in main after disabling interrupts. This is not advised because
// device is not supposed to intiate transfers, but it works fine, at least in USBXPress v2.1
// Commands are handled in the USB ISR.
//-----------------------------------------------------------------------------
void main(void) 
{
	PCA0MD &= ~0x40;					//	Disable Watchdog timer

	/** SPI info
	18.1.4. Slave Select (NSS)
	The function of the slave-select (NSS) signal is dependent on the 
	setting of the NSSMD1 and NSSMD0 bits in the SPI0CN register. There are three 
	possible modes that can be selected with these bits:
	1.NSSMD[1:0] = 00: 3-Wire Master or 3-Wire Slave Mode: SPI0 operates in 3-wire mode, 
	and NSS is disabled. When operating as a slave device, SPI0 is always selected in 3-wire mode. 
	Since no select signal is present, SPI0 must be the only slave on the bus in 3-wire mode. 
	This is intended for point-to-point communication between a master and one slave.

	http://www.cygnal.org/ubb/Forum1/HTML/000157.html
	"The SPI0 is set in 3-wire single master mode."
	
	To configure the SPI to 3-wire mode, set it to 3-wire mode before attaching it to the crossbar. If this order is reversed, NSS signal is assigned overlapping on other peripheral pins.
	
	SPI0CN = 0x00; // 3-wire master mode
	XBR0 = 0x02; // attach SPI to crossbar
	*/

	config();

	/*
	3.1. USB_Init
	Description: Enables the USB interface and the use of Device Interface Functions. On return, the USB interface
	is configured, including the USB clock and memory. Neither the system or USB clock configurations
	should be modified by user software after calling the USB_Init function. See Appendix A for a
	complete list of SFRs that should not be modified after USB_Init is called. In addition, C8051F32x
	interrupts are globally enabled on the return of this function. User software should not globally disable
	interrupts (set EA = 0) but should enable/disable user configured interrupts individually using
	the interrupt's source interrupt enable flag.
	This function allows the user to specify the Vendor and Product IDs as well as a Manufacturer,
	Product Description and Serial Number string returned as part of the device's USB descriptor during
	the USB enumeration (connection).
	
	note that ProductID is important that windows hardware installation wizard can find the USBXPress driver
	this driver must be preinstalled before plugging in device
	see the Preinstaller but note that path in .ini file may need to be changed for preinstaller to locate driver files 
	so that they can be copied to standard windows driver search folder for drivers.
	this initVariables is for 60mA device, bus powered, serial number 1.00
	*/
	
	//void USB_Init (int VendorID, int ProductID, uchar *ManufacturerStr,uchar *ProductStr, uchar *SerialNumberStr, byte MaxPower, byte PwAttributes, uint bcdDevice)
	USB_Init (0, 0xEA61, ManufacturerStr, ProductStr, SerialNumberStr,30,0x80,0x0100);
	// very important, USB_Init should be called AFTER config() so that USB clock is setup correctly. 
	//Config doesn't deal with USB at all.

	CLKSEL |= 0x02;		// system clock 24MHz (48MHz USB/2)
	RSTSRC	|=	0x02;	// power on reset
	IP=0x01; // ext int 0 high priority ??

	LedOrangeOn();
	//SPIEN=1; // enable SPI interface -- leave it enabled so that output port SCK and MOSI don't float

	initVariables();


	isActive=0;
	USB_Int_Enable();					//	Enable USB_API Interrupts

	// send the bias values from flash memory out the SPI port
	sendFlashedBiases();

	while (1){
	if(isActive){
			while(NOTREQ==1) { // wait for !req low
				if( TH1==0xFF){	// while polling req, check if we have wrapped timer1 since last transfer
					if(AECounter>0){
						sendEvents(); 	// if so just send available events
					} 
				}
			}
			LedOrangeOn();	// got req
		
			NOTACK=0;	// lower acknowledge

			//USB_Int_Disable(); // using these functions increases cycle time to >8us
			EA=0; 	// disable interrupts during snapshot of AE to avoid USB interrupt during snapshot
			
			//note according to C51 compiler specs, shorts are stored big-endian, MSB comes first
			*AEPtr++=P2;	// AE8-15
			*AEPtr++=P1;	// AE07

			*AEPtr++=PCA0CPH0;	// captured PCA counter/timer MSB. This was captured by req low.
			*AEPtr++=PCA0CPL0;	// timer LSB.
							
			AECounter++;	// increment counter for events
			EA=1;			// reenable interrupts
			// USB_Int_Enable(); // using these functions increases cycle time to >8us

			// very important!!!!
			// check HERE if buffer is full so that last request is acknowledged and retina can take away its
			// request before the pause to transmit events over USB. during this transfer, the usb chip 
			// has acknowledged and the retina takes away its request, but it cannot generate a new request
			// until the USB chip takes away its ack, below.
			// if this is not done in this order, you get vertical streaks of events, because (hyppothesis)
			// the retina is not rapidly acknowledged and therefore it is still pulling down on the column req
			// line and pulling it to ground. this makes it easier for other pixels in the same column to generate
			// new events, compared with normally-timed handshake cyles. with the present timing scheme, the retina
			// is acknowledged with normal timing, and therefore the pixel takes away its request with normal timing.
			// this is the working hypothesis.
			if(AECounter==AE_BUFFER_SIZE){
				// when we have collected buffer, initiate transfer
				// during this 860us no handshaking is occurring
				sendEvents();
			}
		
			// if the retina is powered off, then its req will be low (no power). so this code will come here and
			// will have lowered ack and stored a bogus address. now it will wait for req to go high. 
			// but req will be low from the retina and won't go high
			// because ack is low. therefore we can get stuck here if the retina is powered on after reset. 
			while(NOTREQ==0){ // wait for req to go high 
				if( TH1==0xFF) {	// while polling req, check if we have wrapped timer1 since last transfer
					TH1=0;
					AECounter--;	// throw away that event
					break;			// break from possibly infinite loop. this will raise ack
				}
			}
			NOTACK=1;	// raise acknowledge, completing handshake
			LedOrangeOff();	// got req

//		}else if(state==ST_WAITING){
		}else{	// isActive is false, USB not open, just handshake
			// plain handshake cycle is about 1+/-0.2us
			while(NOTREQ==1) { // wait for !req low
				if( TH1==0xFF) {	// while polling req, check if we have wrapped timer1 since last transfer
					TH1=0;
					NOTACK=0;
					NOTACK=1;	// toggle ack an extra time in case we are stuck
				}
			}
		
			LedOrangeOn(); 	// !req received
			NOTACK=0;	// lower acknowledge
			while(NOTREQ==0){ // wait for req to go high 
				if( TH1==0xFF) {	// while polling req, check if we have wrapped timer1 since last transfer
					TH1=0;
					break;			// break from possibly infinite loop
				}
			}
			NOTACK=1;	// raise acknowledge, completing handshake
			LedOrangeOff();
		}
	}
}
Пример #3
0
//-----------------------------------------------------------------------------
// Main Routine
// after initialization, the program simply polls the !req input and when 
// !req goes low, !ack on P0.1 is lowered to acknowledge, 
// the address is captured in P1 (AE0-7) and P2 (AE8-15) and is copied to XRAM.
// Then !ack is raised, we wait for !req to go high and start over.
// When we get an interrupt from USB, we transmit the existing buffer of data.
//-----------------------------------------------------------------------------
void main(void) 
{
	PCA0MD &= ~0x40;					//	Disable Watchdog timer
	//void USB_Init (int VendorID, int ProductID, uchar *ManufacturerStr,uchar *ProductStr, uchar *SerialNumberStr, byte MaxPower, byte PwAttributes, uint bcdDevice)
	// note that ProductID is important that windows hardware installation wizard can find the USBXPress driver
	// this driver must be preinstalled before plugging in device
	// see the Preinstaller but note that path in .ini file may need to be changed for preinstaller to locate driver files 
	// so that they can be copied to standard windows driver search folder for drivers.
	// this initVariables is for 60mA device, bus powered, serial number 1.00
	USB_Init (0, 0xEA61, ManufacturerStr, ProductStr, SerialNumberStr,250,0x80,0x0100);
	CLKSEL |= 0x02;		// system clock 24MHz (48MHz USB/2)
	RSTSRC	|=	0x02;	// power on reset
	Timer_Init();			// Init Timer and Capture for event timing. Init PCA peripheral before port init.
	Port_Init();			//	Initialize crossbar and GPIO
	initVariables();
	LedGreenOff();
	LedBlueOff();

/*	
	LedRedOn();
	delay();
	LedRedOff();
	LedGreenOn();
	delay();
	LedGreenOff();
	LedBlueOn();
	delay();
	LedBlueOff();
*/

	//flushEvents();			// flush some events in case the sender has been powered up
	//state=ST_WAITING;
	isActive=0;
	USB_Int_Enable();					//	Enable USB_API Interrupts
	while (1){
//		if(state==ST_ACTIVE){
	if(isActive){
			while(NOTREQ==1) { // wait for !req low
				if( TH1==0xFF){	// while polling req, check if we have wrapped timer1 since last transfer
					if(AECounter>0){
						sendEvents(); 	// if so just send available events
					} 
				}
			}
			LedGreenOn();	// got req
		
			NOTACK=0;	// lower acknowledge

			//USB_Int_Disable(); // using these functions increases cycle time to >8us
			EA=0; 	// disable interrupts during snapshot of AE to avoid USB interrupt during snapshot
			
			//note according to C51 compiler specs, shorts are stored big-endian, MSB comes first
			*AEPtr++=P2;	// AE8-15
			*AEPtr++=P1;	// AE07

			*AEPtr++=PCA0CPH0;	// captured PCA counter/timer MSB. This was captured by req low.
			*AEPtr++=PCA0CPL0;	// timer LSB.
							
			AECounter++;	// increment counter for events
			EA=1;			// reenable interrupts
			// USB_Int_Enable(); // using these functions increases cycle time to >8us

		
			// if the retina is powered off, then its req will be low (no power). so this code will come here and
			// will have lowered ack and stored a bogus address. now it will wait for req to go high. 
			// but req will be low from the retina and won't go high
			// because ack is low. therefore we can get stuck here if the retina is powered on after reset. 
			while(NOTREQ==0){ // wait for req to go high 
				if( TH1==0xFF) {	// while polling req, check if we have wrapped timer1 since last transfer
					TH1=0;
					AECounter--;	// throw away that event
					break;			// break from possibly infinite loop. this will raise ack
				}
			}
			NOTACK=1;	// raise acknowledge, completing handshake
			LedGreenOff();	// got req

			if(AECounter==AE_BUFFER_SIZE){
				// when we have collected buffer, initiate transfer
				// during this 860us no handshaking is occurring
				sendEvents();
			}
//		}else if(state==ST_WAITING){
		}else{	// isActive is false, USB not open, just handshake
			// plain handshake cycle is about 1+/-0.2us
			while(NOTREQ==1) { // wait for !req low
				if( TH1==0xFF) {	// while polling req, check if we have wrapped timer1 since last transfer
					TH1=0;
					NOTACK=0;
					NOTACK=1;	// toggle ack an extra time in case we are stuck
				}
			}
		
			LedGreenOn(); 	// !req received
			NOTACK=0;	// lower acknowledge
			while(NOTREQ==0){ // wait for req to go high 
				if( TH1==0xFF) {	// while polling req, check if we have wrapped timer1 since last transfer
					TH1=0;
					break;			// break from possibly infinite loop
				}
			}
			NOTACK=1;	// raise acknowledge, completing handshake
			LedGreenOff();
		}
	}
}