VOID PWRVBUSonHandler(VOID)
{
    IntDelay();
    USB_enable();
    USB_reset();

    USBPWRCTL &= ~(VBONIFG|VBOFFIFG);       // clean pending VBUS ON and OFF interrupts, if any
    USBCNF |= PUR_EN;                       // generate rising edge on DP -> the host enumerates our device as full speed device
}
Beispiel #2
0
uint8_t USB_handleVbusOnEvent()
{
    if (USB_enable() == USB_SUCCEED) {
        USB_reset();
        USB_connect();
        Log_print0(Diags_USER1, "USB: VBus detected");
    }
    return (true);
}
Beispiel #3
0
uint8_t USB_resume(void)
{
    USB_enable();                       // enable PLL

    USBIFG &= ~(RESRIFG | SUSRIFG);     // clear interrupt flags
    USBIE = SETUPIE | RSTRIE | SUSRIE;  // enable USB specific interrupts (setup, reset, suspend)

    bFunctionSuspended  = FALSE;
    return kUSB_succeed;
}
/*
 * If this function gets executed, it indicates that a valid voltage has just been applied to the VBUS pin.
 * returns TRUE to keep CPU awake
 */
uint8_t USB_handleVbusOnEvent()
{
        //TO DO: You can place your code here

        //We switch on USB and connect to the BUS
        if (USB_enable() == USB_SUCCEED) {
                USB_reset();
                USB_connect();                  //generate rising edge on DP -> the host enumerates our device as full speed device
        }
        return TRUE;                            //return TRUE to wake the main loop (in the case the CPU slept before interrupt)
}
/*
 * If this function gets executed, it indicates that a valid voltage has just 
 * been applied to the VBUS pin. 
 * Returns TRUE to keep CPU awake.
 */
uint8_t USB_handleVbusOnEvent(void)
{
    // TODO: Migrate this to the application layer
    // Application can place specific code here. 
    if (USB_enable() == USB_SUCCEED) {
            USB_reset();
            //generate rising edge on DP -> 
            //the host enumerates our device as full speed device
            USB_connect();
    }
    return TRUE;
}
/*
 * If this function gets executed, it indicates that a valid voltage has just been applied to the VBUS pin.
 * returns TRUE to keep CPU awake
 */
BYTE USB_handleVbusOnEvent ()
{
    //TO DO: You can place your code here

    //We switch on USB and connect to the BUS
    if (USB_enable() == kUSB_succeed){
        USB_reset();
        USB_connect();  //generate rising edge on DP -> the host enumerates our device as full speed device
    }

    P1IE |= BIT6;       //Disable port interrupts

    return (TRUE);      //return TRUE to wake the main loop (in the case the CPU slept before interrupt)
}
/*
If this function gets executed, it indicates that a valid voltage has just been applied to the VBUS pin.
returns TRUE to keep CPU awake
*/
BYTE USB_handleVbusOnEvent()
{
    // The standard user experience when a USB device gets physically attached to a host is for the host to
    // enumerate the device.  Typically this happens as follows: 
    // 1) the device senses 5V VBUS from the host, which tells it a host is present; (usually; but could also be a powered hub w/o a host!  See state ST_NOENUM_SUSPENDED.) 
    // 2) the device asserts the PUR signal, which tells the host the devicde is present;   
    // 3) the host issues a number of USB device requests, including asking for the device's USB descriptors;  
    // 4) the host decides if it has the appropriate driver for what it sees in the descriptors; and if so, loads it.  Enumeration is now complete.  
    // So -- USB_handleVbusOnEvent occurs if a VBUS-on event has been detected.  We respond by doing the following.  
    // However, keep in mind that USB_enable() might take a few milliseconds while the crystal starts up, and that most events handle in
    // the context of the USB interrupt handler.  If this interrupt latency is unacceptable, it might be better to set a flag for main() to handle it.  
    if (USB_enable() == kUSB_succeed)      // Start the module; 
    {
        USB_reset();                       // Reset the internal API
        USB_connect();                     // Assert PUR, to tell the host we're here
    }                                      // Enumeration will now take place in the background
    return TRUE;                           // Meanwhile, return TRUE to wake the main loop (if LPM was entered), so 
}                                          // that it can take into account the change in state
Beispiel #8
0
/* initialize USB */
void USB_init()
{
	USB_set_pads_regulator(true);
	USB_pll_config(CRYSTAL_16MHZ);
	/* wait for PLL to lock to the clock */
        while (!PLL_is_locked())
		;
        USB_enable();
	/* make sure DETACH is off, and low speed mode is not set */
#if defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__)
	UDCON &= ~(_BV(DETACH));
#else
	UDCON &= ~(_BV(DETACH) | _BV(LSM));
#endif
	usb_current_conf = 0;
        UDIEN = _BV(EORSTE) | _BV(EORSME) | _BV(SOFE);
	sei();
	while (USB_get_configuration() == 0)
		;
	/* enable USB suspend interrupt */
	UDIEN |= _BV(SUSPE);
}
//----------------------------------------------------------------------------
VOID ConfigUSB(VOID)
{
    USB_init();                     // Init USB

    // Enable various USB event handling routines

    USB_setEnabledEvents(kUSB_VbusOnEvent+kUSB_VbusOffEvent+kUSB_receiveCompletedEvent
                          +kUSB_dataReceivedEvent+kUSB_UsbSuspendEvent+kUSB_UsbResumeEvent+kUSB_UsbResetEvent);
    
    
    // See if we're already attached physically to USB, and if so, connect to it
    // Normally applications don't invoke the event handlers, but this is an exception.  
  
    if (USB_connectionInfo() & kUSB_vbusPresent)
    {
        if (USB_enable() == kUSB_succeed)
        {
            USB_reset();
            USB_connect();
        }
    }
	
}
VOID USB_resume(VOID)
{
    USB_enable();   					// enable PLL
    USBIFG &= ~(RESRIFG | SUSRIFG);     // clear interrupt flags
    bFunctionSuspended  = FALSE;
}
Beispiel #11
0
void main(void)
{
    WDTCTL = WDTPW + WDTHOLD;                // Stop the watchdog
    __enable_interrupt();                    // Enable general interrupts
    Board_init();                            // Configure's the F5529 EXP board's I/Os
    
    // Initialize power/clocks for use with USB
    SetVCore(3);                             // The USB module requires that VCore be set to highest setting, independent of MCLK freq
    ClockUSB();
    
    disk_initialize(0);                      // SD-cards must go through a setup sequence after powerup.  This FatFs call does this.  
    USB_init();                              // Initializes the USB API, and prepares the USB module to detect USB insertion/removal events
    USB_setEnabledEvents(kUSB_allUsbEvents); // Enable all USB events
      
    // The data interchange buffer (used when handling SCSI READ/WRITE) is declared by the application, and 
    // registered with the API using this function.  This allows it to be assigned dynamically, giving 
    // the application more control over memory management.  
    USBMSC_registerBufInfo(&RW_dataBuf[0], NULL, sizeof(RW_dataBuf));
 
    
    // The API maintains an instance of the USBMSC_RWbuf_Info structure.  If double-buffering were used, it would
    // maintain one for both the X and Y side.  (This version of the API only supports single-buffering,
    // so only one structure is maintained.)  This is a shared resource between the API and application; the 
    // application must request the pointers.    
    RWbuf_info = USBMSC_fetchInfoStruct();
  
    
    // USBMSC_updateMediaInfo() must be called prior to USB connection.  We check if the card is present, and if so, pull its size
    // and bytes per block.  
    // LUN0
    mediaInfo.mediaPresent = 0x01;        // The medium is present, because internal flash is non-removable.  
    mediaInfo.mediaChanged = 0x00;        // It can't change, because it's in internal memory, which is always present.  
    mediaInfo.writeProtected = 0x00;      // It's not write-protected
    mediaInfo.lastBlockLba = 774;         // 774 blocks in the volume. (This number is also found twice in the volume itself; see mscFseData.c. They should match.)
    mediaInfo.bytesPerBlock = BYTES_PER_BLOCK; // 512 bytes per block. (This number is also found in the volume itself; see mscFseData.c. They should match.)
    USBMSC_updateMediaInfo(0, &mediaInfo); 
    
    // LUN1
    if(detectCard())
      mediaInfo.mediaPresent = kUSBMSC_MEDIA_PRESENT;
    else mediaInfo.mediaPresent = kUSBMSC_MEDIA_NOT_PRESENT;
    mediaInfo.mediaChanged = 0x00;
    mediaInfo.writeProtected = 0x00;
    disk_ioctl(0,GET_SECTOR_COUNT,&mediaInfo.lastBlockLba);   // Returns the number of blocks (sectors) in the media. 
    mediaInfo.bytesPerBlock = BYTES_PER_BLOCK;                // Block size will always be 512
    USBMSC_updateMediaInfo(1, &mediaInfo); 
    
    
    // At compile-time for this demo, there will be one file on the volume.  The root directory and data cluster
    // for this file need to be initialized.  
    //flashWrite_LBA(Root_Dir, (BYTE*)Root_Dir_init); 
    //flashWrite_LBA(Data559, (BYTE*)Data559_init); 
    
    
    // Configure Timer_A0 to prompt detection of the SD card every second
    TA0CCTL0 = CCIE;                          // Enable interrupt
    TA0CCR0 = 32768;                          // Clock will be 32kHz, so we set the int to occur when it counts to 32768
    TA0CTL = TASSEL_1 + MC_1 + TACLR;         // ACLK = 32kHz, up mode, clear TAR... go!

  
    // If USB is already connected when the program starts up, then there won't be a USB_handleVbusOnEvent(). 
    // So we need to check for it, and manually connect if the host is already present.   
    if (USB_connectionInfo() & kUSB_vbusPresent)
    {
      if (USB_enable() == kUSB_succeed)
      {
        USB_reset();
        USB_connect();      
      }
    }
  
    while(1)
    {
      BYTE ReceiveError=0, SendError=0;
      WORD count;
      switch(USB_connectionState())
      {
        case ST_USB_DISCONNECTED:
                 __bis_SR_register(LPM3_bits + GIE); 	       // Enter LPM3 until VBUS-on event
                
                 // Check if the reason we woke was a button press; and if so, log a new piece of data.  
                 if(fS1ButtonEvent)
                 {
                   // Build string
                   char str[14] = "Data entry #0\n";
                   str[12] = logCnt++;                             // Number the entries 0 through....?
                   
                   memcpy(RW_dataBuf, Data559, BYTES_PER_BLOCK);  // Copy data block 559 from flash to RAM buffer
                   memcpy(&RW_dataBuf[DataCnt], str, sizeof(str)); // Write the new entry to the RAM buffer
                   flashWrite_LBA((PBYTE)Data559, RW_dataBuf);    // Copy it back to flash
                   
                   DataCnt += sizeof(str);                         // Increment the index past the new entry
                   if((DataCnt + sizeof(str)>= BYTES_PER_BLOCK))   // Roll index back to 0, if no more room in the block
                     DataCnt = 0;
        
                   fS1ButtonEvent = 0;
                 }
                break;
          
        case ST_USB_CONNECTED_NO_ENUM:
                break;
          
        case ST_ENUM_ACTIVE:             

                // Call USBMSC_poll() to initiate handling of any received SCSI commands.  Disable interrupts 
                // during this function, to avoid conflicts arising from SCSI commands being received from the host
                // AFTER decision to enter LPM is made, but BEFORE it's actually entered (in other words, avoid
                // sleeping accidentally).  
                __disable_interrupt();
                if((USBMSC_poll() == kUSBMSC_okToSleep) && (!bDetectCard))
                {
                    __bis_SR_register(LPM0_bits + GIE);  // Enable interrupts atomically with LPM0 entry
                }
                __enable_interrupt();
                
                                               
                // If the API needs the application to process a buffer, it will keep the CPU awake by returning kUSBMSC_processBuffer
                // from USBMSC_poll().  The application should then check the 'operation' field of all defined USBMSC_RWbuf_Info
                // structure instances.  If any of them is non-null, then an operation needs to be processed.  A value of 
                // kUSBMSC_READ indicates the API is waiting for the application to fetch data from the storage volume, in response 
                // to a SCSI READ command from the USB host.  After the application does this, it must indicate whether the 
                // operation succeeded, and then close the buffer operation by calling USBMSC_bufferProcessed().  
                
                while(RWbuf_info->operation == kUSBMSC_READ)
                {
                  switch(RWbuf_info->lun)
                  {
                    case 0:
                      RWbuf_info->returnCode = Read_LBA(RWbuf_info->lba, RWbuf_info->bufferAddr, RWbuf_info->lbCount); // Fetch a block from the medium, using file system emulation
                      USBMSC_bufferProcessed();                           // Close the buffer operation
                      break;
                      
                    case 1:
                      read_LUN1();
                      break;
                  }
                }
                
                // Everything in this section is analogous to READs.  Reference the comments above.   
                while(RWbuf_info->operation == kUSBMSC_WRITE)
                {                  
                  switch(RWbuf_info->lun)
                  {
                    case 0:
                      RWbuf_info->returnCode = Write_LBA(RWbuf_info->lba, RWbuf_info->bufferAddr, RWbuf_info->lbCount); // Write the block to the medium, using file system emulation
                      USBMSC_bufferProcessed();                            // Close the buffer operation
                      break;
                    case 1:
                      write_LUN1();
                      break;
                  }
                }
                
                // Every second, the Timer_A ISR sets this flag.  The checking can't be done from within the timer ISR, because the
                // checking enables interrupts, and this is not a recommended practice due to the risk of nested interrupts.  
                if(bDetectCard)
                {
                  checkInsertionRemoval();
                  bDetectCard = 0x00;                          // Clear the flag, until the next timer ISR
                }
                
                if(bHID_DataReceived_event) //Message is received from HID application
                {
                	bHID_DataReceived_event = FALSE;          // Clear flag early -- just in case execution breaks below because of an error
                	count = hidReceiveDataInBuffer((BYTE*)dataBuffer,BUFFER_SIZE,HID0_INTFNUM);
                	strncat(wholeString," \r\nRx->",7);
                    strncat(wholeString,(char*)dataBuffer,count);
                  	strncat(wholeString," \r\n ",4);
                	if(cdcSendDataInBackground((BYTE*)wholeString,strlen(wholeString),CDC0_INTFNUM,1)) // Send message to other CDC App
                	{
                		SendError = 0x01;
                		break;
                	}
                	memset(wholeString,0,MAX_STR_LENGTH);           // Clear wholeString
                }
                if(bCDC_DataReceived_event)  //Message is received from CDC application 
                {
                  bCDC_DataReceived_event = FALSE;                  // Clear flag early -- just in case execution breaks below because of an error
                  cdcReceiveDataInBuffer((BYTE*)wholeString,MAX_STR_LENGTH,CDC0_INTFNUM);
                  ASCII(wholeString);
                  if(hidSendDataInBackground((BYTE*)wholeString,strlen(wholeString),HID0_INTFNUM,1))  // Send message to HID App
                  {
                    SendError = 0x01;                          // Something went wrong -- exit
                    break;
                  }
                  memset(wholeString,0,MAX_STR_LENGTH);  // Clear wholeString
                }
                                               
                break;
                
            case ST_ENUM_SUSPENDED:
                __bis_SR_register(LPM3_bits + GIE);            // Enter LPM3, until a resume or VBUS-off event
                break;
              
          case ST_ENUM_IN_PROGRESS:
                break;
              
          case ST_ERROR:
                break;           
          default:;
      }
      if(ReceiveError || SendError)
      { 
          //TO DO: User can place code here to handle error
      }    
    }
}
Beispiel #12
0
/*  
 * ======== main ========
 */
int main (void)
{
    WDT_A_hold(WDT_A_BASE); // Stop watchdog timer

    // Minumum Vcore setting required for the USB API is PMM_CORE_LEVEL_2 .
    PMM_setVCore(PMM_CORE_LEVEL_2);
    USBHAL_initPorts();                // Config GPIOS for low-power (output low)
    USBHAL_initClocks(MCLK_FREQUENCY); // Config clocks. MCLK=SMCLK=FLL=MCLK_FREQUENCY; ACLK=REFO=32kHz
    hal_sd_pwr_on();
    initTimer();
    USB_setup(FALSE, TRUE);      // Init USB & events; if a host is present, connect

    __enable_interrupt();       // Enable interrupts globally

   // GPS_init();

    // state machine
    while (1)
    {
    	switch( state )
    	{
    	case sIDLE:

    		hal_led_a(0);
    		hal_led_b(0);
    		hal_gps_pwr_off();
    		hal_sd_pwr_off();
    		UCS_turnOffXT2();



    			/* USB connected */
    			if(USB_getConnectionInformation() & USB_VBUS_PRESENT)
    			{
    				hal_led_a(CYAN);



    				//PMM_setVCore(PMM_CORE_LEVEL_2);
    				hal_sd_pwr_on();
    				shortDelay();
    				USBMSC_initMSC();                  // Initialize MSC API, and report media to the host
    				if (USB_enable() == USB_SUCCEED){
    					state = sUSB;
    					hal_led_a(GREEN);
    					//hal_sd_pwr_on();
    					//detectCard();

    					USB_reset();
    				    USB_connect();  //generate rising edge on DP -> the host enumerates our device as full speed device
    				}
    				break; // don't enter sleep
    			}

    			/* start GPS */
    			if(hal_button_event())
    			{

    				/* delay for starting */
    				hal_led_a(RED);
    				uint8_t timeout = 16;
    				while( hal_button_status() == 1 && --timeout )
    				{
    					shortDelay();
    				}
    				hal_led_a(0);
    				if( hal_button_status() == 0 )
    					break;

    				state = sGPS;
    				hal_led_a(CYAN);

    				hal_sd_pwr_on();

    				timeout = 8;
    				while( --timeout )
					{
						shortDelay();
					}

    				detectCard();
    			    Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE);

    			    gps_start();
    				hal_button_event();
    				break; // don't enter sleep
    			}


    			USB_disable(); //Disable
    			hal_gps_rtc_on(); // saves around 7uA
    			Timer_A_stop(TIMER_A0_BASE);
    			//UCS_turnOffSMCLK();
    			//PMM_setVCore(PMM_CORE_LEVEL_0);
    			__bis_SR_register(LPM4_bits + GIE);
    			_NOP();
    			//UCS_turnOnSMCLK();
    			//PMM_setVCore(PMM_CORE_LEVEL_2);

    		break;

    	case sGPS:


				/* stop GPS */
				if((USB_getConnectionInformation() & USB_VBUS_PRESENT))
				{
					state = sIDLE;
					gps_stop();
					break;
				}

				if(hal_button_event())
				{
					/* delay for stopping */
					uint8_t timeout = 16;

					while( hal_button_status() == 1 && --timeout )
					{
						hal_led_a(RED);
						shortDelay();
						hal_led_a(RED);
					}
					hal_led_a(0);
					if( hal_button_status() == 0 )
						break;

					state = sIDLE;
					gps_stop();
					break;


				}



    			if (bDetectCard){
					USBMSC_checkMSCInsertionRemoval();

					// Clear the flag, until the next timer ISR
					bDetectCard = 0x00;
				}
    			while( gps_check() )
    			{
    				gps_do();
    			}
    			__bis_SR_register(LPM0_bits + GIE);
    			_NOP();


    		break;

    	case sUSB:

    			if(!(USB_getConnectionInformation() & USB_VBUS_PRESENT))
				{
    				state = sIDLE;
    				break;
				}
    					/* check state of chareger? */
    			if( hal_charge_status())
    				hal_led_b(RED);
    			else
    				hal_led_b(GREEN);

    			hal_button_event(); // clear button event
    					switch (USB_getConnectionState())
    					{
    						case ST_ENUM_ACTIVE:



    							USBMSC_processMSCBuffer(); // Handle READ/WRITE cmds from the host

    							// Every second, the Timer_A ISR sets this flag.  The
    							// checking can't be done from within the timer ISR, because it
    							// enables interrupts, and this is not a recommended
    							// practice due to the risk of nested interrupts.
    							if (bDetectCard){
    								USBMSC_checkMSCInsertionRemoval();

    								// Clear the flag, until the next timer ISR
    								bDetectCard = 0x00;
    							}

    							break;

    						// These cases are executed while your device is disconnected from
    						// the host (meaning, not enumerated); enumerated but suspended
    						// by the host, or connected to a powered hub without a USB host
    						// present.
    						case ST_PHYS_DISCONNECTED:
    						case ST_ENUM_SUSPENDED:
    						case ST_PHYS_CONNECTED_NOENUM_SUSP:
    							hal_led_a(BLUE);
    							//state = sIDLE;
    							break;

    						// The default is executed for the momentary state
    						// ST_ENUM_IN_PROGRESS.  Usually, this state only last a few
    						// seconds.  Be sure not to enter LPM3 in this state; USB
    						// communication is taking place here, and therefore the mode must
    						// be LPM0 or active-CPU.
    						case ST_ENUM_IN_PROGRESS:
    						default:;
    					}
    		break;
    	}
    }

}
Beispiel #13
0
/*----------------------------------------------------------------------------+
| Main Routine                                                                |
+----------------------------------------------------------------------------*/
VOID main(VOID)
{
    WDTCTL = WDTPW + WDTHOLD;	    // Stop watchdog timer
    Init_StartUp();                 // Initialize clocks, power, I/Os
    __enable_interrupt(); 
    USB_init();                     // Initialize the USB module


    // Enable all USB events
    USB_setEnabledEvents(kUSB_allUsbEvents);

    
    // The data interchange buffer (used when handling SCSI READ/WRITE) is declared by the application, and 
    // registered with the API using this function.  This allows it to be assigned dynamically, giving 
    // the application more control over memory management.  
    USBMSC_registerBufInfo(&RW_dataBuf[0], NULL, sizeof(RW_dataBuf));
   
    
    // The API maintains an instance of the USBMSC_RWbuf_Info structure.  If double-buffering were used, it would
    // maintain one for both the X and Y side.  (This version of the API only supports single-buffering,
    // so only one structure is maintained.)  This is a shared resource between the API and application; the 
    // application must request the pointers.  This function returns the pointer for a given LUN and buffer side.  
    RWbuf = USBMSC_fetchInfoStruct();  // 0 for X-buffer
    
    
    // The application must tell the API about the media.  Since the media isn't removable, this is only called 
    // once, at the beginning of execution.  If the media were removeable, the application must call this any time
    // the status of the media changes.  
    struct USBMSC_mediaInfoStr mediainfo; // This struct type contains information about the state of the medium.   
                                          // Since it's only used locally, it's declared within main so that it's 
                                          // taken from the heap rather than as a static global.
    mediainfo.mediaPresent = 0x01;        // The medium is present, because internal flash is non-removable.  
    mediainfo.mediaChanged = 0x00;        // It can't change, because it's in internal memory, which is always present.  
    mediainfo.writeProtected = 0x00;      // It's not write-protected
    mediainfo.lastBlockLba = 774;         // 774 blocks in the volume. (This number is also found twice in the volume itself; see mscFseData.c. They should match.)
    mediainfo.bytesPerBlock = BYTES_PER_BLOCK; // 512 bytes per block. (This number is also found in the volume itself; see mscFseData.c. They should match.)
    USBMSC_updateMediaInfo(0, &mediainfo); 
    
    // If USB is already connected when the program starts up, then there won't be a USB_handleVbusOnEvent(). 
    // So we need to check for it, and manually connect if the host is already present.   
    if (USB_connectionInfo() & kUSB_vbusPresent)
    {
        if (USB_enable() == kUSB_succeed)
        {
            USB_reset();
            USB_connect();
        }
    }

    
    while(1)
    {
        switch(USB_connectionState())
        {
        case ST_USB_DISCONNECTED:
             __bis_SR_register(LPM3_bits + GIE); 	       // Enter LPM3 until VBUS-on event
            
             // Check if the reason we woke was a button press; and if so, log a new piece of data.  
             if(fS1ButtonEvent)
             {
               // Build string
               char str[14] = "Data entry #0\n";
               str[12] = logCnt++;                             // Number the entries 0 through....?
               
               memcpy(RW_dataBuf, Data559, BYTES_PER_BLOCK);  // Copy data block 559 from flash to RAM buffer
               memcpy(&RW_dataBuf[DataCnt], str, sizeof(str)); // Write the new entry to the RAM buffer
               flashWrite_LBA((PBYTE)Data559, RW_dataBuf);    // Copy it back to flash
               
               DataCnt += sizeof(str);                         // Increment the index past the new entry
               if((DataCnt + sizeof(str)>= BYTES_PER_BLOCK))   // Roll index back to 0, if no more room in the block
                 DataCnt = 0;

               fS1ButtonEvent = 0;
             }
             
             break;
            
        case ST_USB_CONNECTED_NO_ENUM:
             break;
            
        case ST_ENUM_ACTIVE:             

                // Call USBMSC_poll() to initiate handling of any received SCSI commands.  Disable interrupts 
                // during this function, to avoid conflicts arising from SCSI commands being received from the host
                // AFTER decision to enter LPM is made, but BEFORE it's actually entered (avoid sleeping accidentally).  
                __disable_interrupt();
                if(USBMSC_poll() == kUSBMSC_okToSleep)
                {
                    __bis_SR_register(LPM0_bits + GIE);  // Enable interrupts atomically with LPM0 entry
                }
                __enable_interrupt();
                        
                            
                // If the API needs the application to process a buffer, it will keep the CPU awake by returning kUSBMSC_processBuffer
                // from USBMSC_poll().  The application should respond by checking the 'operation' field of all defined USBMSC_RWbuf_Info
                // structure instances.  If any of them is non-null, then an operation needs to be processed.  A value of 
                // kUSBMSC_READ indicates the API is waiting for the application to fetch data from the storage volume, in response 
                // to a SCSI READ command from the USB host.  After doing so, we must indicate whether the operation succeeded, and 
                // close the buffer operation by calling USBMSC_bufferProcessed().  
                while(RWbuf->operation == kUSBMSC_READ)
                {
                  RWbuf->returnCode = Read_LBA(RWbuf->lba, RWbuf->bufferAddr, RWbuf->lbCount); // Fetch a block from the medium, using file system emulation
                  USBMSC_bufferProcessed();                           // Close the buffer operation
                }
                
                // Same as above, except for WRITE.  If operation == kUSBMSC_WRITE, then the API is waiting for us to 
                // process the buffer by writing the contents to the storage volume.  
                while(RWbuf->operation == kUSBMSC_WRITE)
                {
                  RWbuf->returnCode = Write_LBA(RWbuf->lba, RWbuf->bufferAddr, RWbuf->lbCount); // Write the block to the medium, using file system emulation
                  USBMSC_bufferProcessed();                            // Close the buffer operation
                }
                break;
                
            case ST_ENUM_SUSPENDED:
                 __bis_SR_register(LPM3_bits + GIE);            // Enter LPM3, until a resume or VBUS-off event
                 break;
                
            case ST_ENUM_IN_PROGRESS:
                 break;
                
            case ST_ERROR:
                 break;
                
            default:;
        }    
    }  // while(1)
} //main()
Beispiel #14
0
void MassStorage(void)
{
    buttonsPressed = 0;

    SFRIE1 &= ~OFIE;
    disk_initialize(0);                   // Initialize Disk Drive #0

    SFRIE1 |= OFIE;

    DEBUG("Init clock\r\n");
    ClockUSB();

    DEBUG("Init USB\r\n");
    USB_init();                           // Initialize the USB module
    P1OUT |= BIT1;

    // Enable all USB events
    USB_setEnabledEvents(kUSB_allUsbEvents);

    // Clal Initialization Function
    DEBUG("Init MSC\r\n");
    msc_Init();
    P1OUT |= BIT2;

    // If USB is already connected when the program starts up, then there won't be a
    // USB_handleVbusOnEvent().
    // So we need to check for it, and manually connect if the host is already present.
    if (USB_connectionInfo() & kUSB_vbusPresent)
    {
        if (USB_enable() == kUSB_succeed)
        {
            USB_reset();
            USB_connect();
            P1OUT |= BIT3;
        }
    }

    while (1)
    {
        switch (USB_connectionState())
        {
            DEBUG("Connection state: %u\r\n", USB_connectionState());
            case ST_USB_DISCONNECTED:
                //__bis_SR_register(LPM3_bits + GIE);    // Enter LPM3 until VBUS-on event
                _NOP();
                break;

            case ST_USB_CONNECTED_NO_ENUM:
                break;

            case ST_ENUM_ACTIVE:

                msc_Loop();
                break;

            case ST_ENUM_SUSPENDED:
                //__bis_SR_register(LPM3_bits + GIE);    // Enter LPM3, until a resume or VBUS-off
                                                       // event
                break;

            case ST_ENUM_IN_PROGRESS:
                break;

            case ST_ERROR:
                break;
            default:;
        }
    }

    DEBUG("Done with MassStorage\r\n");
    buttonsPressed = 0;
    Board_ledOff(LED_ALL);
    USB_disable();
    SFRIE1 &= ~OFIE;
    Init_FLL_Settle(25000, 762);          // Return to normal clock settings
    SFRIE1 |= OFIE;
}