__interrupt VOID UNMI_ISR(VOID) { switch (__even_in_range(SYSUNIV, SYSUNIV_SYSBUSIV)) { case SYSUNIV_NONE: __no_operation(); break; case SYSUNIV_NMIIFG: __no_operation(); break; case SYSUNIV_OFIFG: UCSCTL7 &= ~(DCOFFG+0+0+0); // Clear OSC fault source flags SFRIFG1 &= ~OFIFG; // Clear OFIFG flag break; case SYSUNIV_ACCVIFG: __no_operation(); break; case SYSUNIV_SYSBUSIV: // In the rare event of an internal system bus error - must clear the flag and re-initialize USB. SYSBERRIV = 0; // Clear flag USB_disable(); // Disable USB if (USB_connectionInfo() & kUSB_vbusPresent) USB_handleVbusOnEvent(); } }
/* If this function gets executed, it indicates that the USB host has chosen to suspend this device after a period of active operation. returns TRUE to keep CPU awake */ BYTE USB_handleSuspendEvent() { // If this device draws power from the host over VBUS, then this event is the signal for software to ensure that // no more than 2.5mA is drawn over VBUS. Code can be placed here to do this, or it can be placed in the main loop // under ST_ENUM_SUSPENDED (but make sure this handler returns TRUE to wake the main loop, if LPM0 was entered). // Or, if the device was attached to a bus situation that's somehow providing VBUS but has no active host (host is in standby, // or attached to a powered hub with no upstream host), then this will show up as a suspend event without successful enumeration. // A good course of action might be to "cancel" the attempt to enumerate: if(!(USB_connectionInfo() & kUSB_Enumerated)) { USB_disconnect(); USB_disable(); } // Now, if this branch executes, the USB state will shift to ST_USB_DISCONNECTED when the function returns. return TRUE; // Return TRUE so that the main loop can adapt. }
void usb_printf_init(void) { SetVCore(3); init_clock(); //Init USB USB_init(); //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) { usb_printf_state = USB_ENABLED; USB_handleVbusOnEvent(); } }
/** * Configuration de l'USB et de ses Events */ void iUSB::config() { //Ne pas oublier d'avoir setVcore(3) avant //initialisation de l'USB this->initUSB(); //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) { USB_handleVbusOnEvent(); } //desactiver LDO USBPWRCTL &= ~(SLDOEN); // Disable the VUSB LDO and the SLDO }
//---------------------------------------------------------------------------- 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(); } } }
/* * ======== main ======== */ VOID main (VOID) { WDTCTL = WDTPW + WDTHOLD; //Stop watchdog timer Init_Ports(); //Init ports (do first ports because clocks do change ports) SetVCore(3); Init_Clock(); //Init clocks USB_init(); //Init USB Init_TimerA1(); //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){ USB_handleVbusOnEvent(); } __enable_interrupt(); //Enable interrupts globally while (1) { BYTE i; //Check the USB state and directly main loop accordingly switch (USB_connectionState()) { case ST_USB_DISCONNECTED: __bis_SR_register(LPM3_bits + GIE); //Enter LPM3 w/ interrupts enabled _NOP(); //For Debugger break; case ST_USB_CONNECTED_NO_ENUM: break; case ST_ENUM_ACTIVE: __bis_SR_register(LPM0_bits + GIE); //Enter LPM0 (can't do LPM3 when active) _NOP(); //For Debugger //Exit LPM on USB receive and perform a receive //operation if (bCDCDataReceived_event){ //Some data is in the buffer; begin receiving a //command char pieceOfString[MAX_STR_LENGTH] = ""; //Holds the new addition to the string char outString[MAX_STR_LENGTH] = ""; //Holds the outgoing string //Add bytes in USB buffer to theCommand cdcReceiveDataInBuffer((BYTE*)pieceOfString, MAX_STR_LENGTH, CDC0_INTFNUM); //Get the next piece of the string strcat(wholeString,pieceOfString); cdcSendDataInBackground((BYTE*)pieceOfString, strlen(pieceOfString),CDC0_INTFNUM,0); //Echoes back the characters received (needed //for Hyperterm) if (retInString(wholeString)){ //Has the user pressed return yet? if (!(strcmp(wholeString, "LED ON"))){ //Compare to string #1, and respond TA1CTL &= ~MC_1; //Turn off Timer P1OUT |= BIT0; //Turn on LED P1.0 strcpy(outString,"\r\nLED is ON\r\n\r\n"); //Prepare the outgoing string cdcSendDataInBackground((BYTE*)outString, strlen(outString),CDC0_INTFNUM,0); //Send the response over USB } else if (!(strcmp(wholeString, "LED OFF"))){ //Compare to string #2, and respond TA1CTL &= ~MC_1; //Turn off Timer P1OUT &= ~BIT0; //Turn off LED P1.0 strcpy(outString,"\r\nLED is OFF\r\n\r\n"); //Prepare the outgoing string cdcSendDataInBackground((BYTE*)outString, strlen(outString),CDC0_INTFNUM,0); //Send the response over USB } else if (!(strcmp(wholeString, "LED TOGGLE - SLOW"))){ //Compare to string #3, and respond TA1CTL &= ~MC_1; //Turn off Timer TA1CCR0 = SlowToggle_Period; //Set Timer Period for slow LED toggle TA1CTL |= MC_1; //Start Timer strcpy(outString, "\r\nLED is toggling slowly\r\n\r\n"); //Prepare the outgoing string cdcSendDataInBackground((BYTE*)outString, strlen(outString),CDC0_INTFNUM,0); //Send the response over USB } else if (!(strcmp(wholeString, "LED TOGGLE - FAST"))){ //Compare to string #4, and respond TA1CTL &= ~MC_1; //Turn off Timer TA1CCR0 = FastToggle_Period; //Set Timer Period for fast LED toggle TA1CTL |= MC_1; strcpy(outString,"\r\nLED is toggling fast\r\n\r\n"); //Prepare the outgoing string cdcSendDataInBackground((BYTE*)outString, strlen(outString),CDC0_INTFNUM,0); //Send the response over USB } else { //Handle other strcpy(outString,"\r\nNo such command!\r\n\r\n"); //Prepare the outgoing string cdcSendDataInBackground((BYTE*)outString, strlen(outString),CDC0_INTFNUM,0); //Send the response over USB } for (i = 0; i < MAX_STR_LENGTH; i++){ //Clear the string in preparation for the next //one wholeString[i] = 0x00; } } bCDCDataReceived_event = FALSE; } break; case ST_ENUM_SUSPENDED: P1OUT &= ~BIT0; //When suspended, turn off LED __bis_SR_register(LPM3_bits + GIE); //Enter LPM3 w/ interrupts _NOP(); break; case ST_ENUM_IN_PROGRESS: break; case ST_NOENUM_SUSPENDED: P1OUT &= ~BIT0; __bis_SR_register(LPM3_bits + GIE); _NOP(); break; case ST_ERROR: _NOP(); break; default:; } } //while(1) } //main()
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 } } }
/*----------------------------------------------------------------------------+ | Main Routine | +----------------------------------------------------------------------------*/ VOID main(VOID) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer Init_StartUp(); USB_init(); USB_setEnabledEvents(kUSB_VbusOnEvent+kUSB_VbusOffEvent+kUSB_receiveCompletedEvent +kUSB_dataReceivedEvent+kUSB_UsbSuspendEvent+kUSB_UsbResumeEvent+kUSB_UsbResetEvent); // Check if we're already physically attached to USB, and if so, connect to it // This is the same function that gets called automatically when VBUS gets attached. if (USB_connectionInfo() & kUSB_vbusPresent) USB_handleVbusOnEvent(); //PWRVBUSonHandler(); while(1) { switch(USB_connectionState()) { case ST_USB_DISCONNECTED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt break; case ST_USB_CONNECTED_NO_ENUM: break; case ST_ENUM_ACTIVE: if(!bCommandBeingProcessed) // If no command is being processed, then make sure there's a rcv operation { // open to receive the start of the "packet" if(!(USBCDC_intfStatus(0,&x,&y) & kUSBCDC_waitingForReceive)) // Only open it if we haven't already done so if(USBCDC_receiveData(buffer,1,0) == kUSBCDC_busNotAvailable) // Start a receive operation for a single byte -- the "size" byte of the "packet" { USBCDC_abortReceive(&x,0); // Abort receive break; // If bus is no longer available, escape out of the loop } } __bis_SR_register(LPM0_bits + GIE); // Wait in LPM0 until a receive operation has completed //__bis_SR_register(LPM0_bits + GIE); if(bDataReceiveCompleted_event) { bDataReceiveCompleted_event = FALSE; if(!bCommandBeingProcessed) // This means that the incoming byte is the start of the "packet" -- the "size" byte { if ((buffer[0]>=0x31) && (buffer[0]<= 0x39)) { size = buffer[0]-0x30; // It's in ASCII, so convert it to a number if(USBCDC_receiveData(buffer,size,0) == kUSBCDC_busNotAvailable) // And then open a rcv operation for that size { USBCDC_abortReceive(&x,0); // Abort receive break; // If bus is no longer available, escape out of the loop } bCommandBeingProcessed = TRUE; // Now we're waiting for the "data" part of the "packet" } else { strcpy(outString,"\r\nEnter a valid number between 1 and 9\r\n\r\n"); // Prepare the outgoing string if(cdcSendDataInBackground((BYTE*)outString,strlen(outString),0,0)) // Send the response over USB { USBCDC_abortSend(&x,0); // Operation may still be open; cancel it break; // If the send fails, escape the main loop } bCommandBeingProcessed = FALSE; // Now we're back to waiting for the "size" byte } } else // This means that the incoming data is the "data" part of the "packet" { strcpy(outString,"\r\nI received your packet with size of "); // Prepare the outgoing string buffer[bufferLen-1]= 0; c[0] = (char)(size+'0'); c[1] = 0; outString[64] = 0; // Convert the size back to ASCII strcat(outString,c); strcat(outString," bytes.\r\n\r\n"); if(cdcSendDataInBackground((BYTE*)outString,strlen(outString),0,0)) // Send the response over USB { USBCDC_abortSend(&x,0); // Operation may still be open; cancel it break; // If the send fails, escape the main loop } bCommandBeingProcessed = FALSE; // Now we're back to waiting for the "size" byte } } break; case ST_ENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt break; case ST_ENUM_IN_PROGRESS: break; case ST_NOENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); _NOP(); break; case ST_ERROR: _NOP(); break; default:; } } // while(1) } //main()
VOID main(VOID) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer Init_StartUp(); //initialize device USB_init(); USB_setEnabledEvents(USBEVIE); // 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) USB_handleVbusOnEvent(); while(1) { switch(USB_connectionState()) { case ST_USB_DISCONNECTED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt _NOP(); break; case ST_USB_CONNECTED_NO_ENUM: break; case ST_ENUM_ACTIVE: __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 until an event occurs. // This flag would have been set by the handleDataReceived event; this event is only enabled when waiting // for 'press any key' if(bCDCDataReceived_event) { bCDCDataReceived_event = FALSE; // Change the event flags, in preparation for receiving 1K data USBEVIE &= ~kUSB_dataReceivedEvent; // No more data-received. We only used this for 'press any key' USBEVIE |= kUSB_receiveCompletedEvent; // But enable receive-completed; we want to be prompted when 1K data has been received USB_setEnabledEvents(USBEVIE); USBCDC_rejectData(0); // We don't care what char the key-press was // Prompt user for 1K data strcpy(outString,"I'm ready to receive 1K of data.\r\n"); // Prepare the outgoing string if(cdcSendDataWaitTilDone((BYTE*)outString,strlen(outString),0,0)) // Send it over USB { USBCDC_abortSend(&x,0); // It failed for some reason; abort and leave the main loop break; } // Set up rcv operation for 1K data if(USBCDC_receiveData(dataBuff,1024,0) == kUSBCDC_busNotAvailable) //first USBCDC_receiveData { USBCDC_abortReceive(&x,0); // It failed because of surprise removal or suspended by host; break; // abort and leave the main loop } } // This flag would have been set by the handleReceiveCompleted event; this event is only enabled // while receiving 1K data, and signals that all 1K has been received if(bDataReceiveCompleted_event) { bDataReceiveCompleted_event = FALSE; strcpy(outString,"Thanks for the data.\r\n"); // Prepare the outgoing string if(cdcSendDataInBackground((BYTE*)outString,strlen(outString),0,0)) //Send the response over USB { USBCDC_abortSend(&x,0); // It failed for some reason; abort and leave the main loop break; } // Change the event flags, in preparation for 'press any key' USBEVIE &= ~kUSB_receiveCompletedEvent; // No more receive-completed. USBEVIE |= kUSB_dataReceivedEvent; // This will tell us that data -- any data -- has arrived (i.e., a key-press) USB_setEnabledEvents(USBEVIE); } break; case ST_ENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/ interrupts _NOP(); break; case ST_ENUM_IN_PROGRESS: break; case ST_NOENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); _NOP(); break; case ST_ERROR: _NOP(); break; default:; } } // while(1) } //main()
/*----------------------------------------------------------------------------+ | Main Routine | +----------------------------------------------------------------------------*/ VOID main(VOID) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer Init_StartUp(); USB_init(); USB_setEnabledEvents(kUSB_VbusOnEvent + kUSB_VbusOffEvent + kUSB_UsbSuspendEvent + kUSB_UsbResumeEvent + kUSB_dataReceivedEvent); // Check if we're already physically attached to USB, and if so, connect to it // This is the same function that gets called automatically when VBUS gets attached. if (USB_connectionInfo() & kUSB_vbusPresent) USB_handleVbusOnEvent(); // Pre-fill the buffers with visible ASCII characters (0x21 to 0x7E) for(x=0;x<BUF_SIZE;x++) { dataBuf[x] = y++; if(y>0x7E) y = 0x21; } while(1) { switch(USB_connectionState()) { case ST_USB_DISCONNECTED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt break; case ST_USB_CONNECTED_NO_ENUM: break; case ST_ENUM_ACTIVE: if(!bHIDDataReceived_event) // Do this until a key is pressed { strcpy(outString,"Press any key.\r"); // Prepare the outgoing string if(hidSendDataWaitTilDone((BYTE*)outString,strlen(outString),0,0)) // Send it; no timeout { USBHID_abortSend(&x,0); // Operation may still be open; cancel it break; } } else { bHIDDataReceived_event = FALSE; USBHID_rejectData(0); for(rounds=0;rounds<300;rounds++) { if(hidSendDataWaitTilDone(dataBuf,BUF_SIZE,0,0)) // Send all of RAM { USBHID_abortSend(&x,0); // Operation probably still open; cancel it break; } } strcpy(outString,"\r\n\r\n\r\nThe test is completed.\r\n"); // Prepare the outgoing string if(hidSendDataWaitTilDone((BYTE*)outString,strlen(outString),0,0)) // Send it; no timeout { USBHID_abortSend(&x,0); // Operation may still be open; cancel it break; } } break; case ST_ENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt break; case ST_ENUM_IN_PROGRESS: break; case ST_NOENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); break; case ST_ERROR: _NOP(); break; default:; } } // while(1) } //main()
/*----------------------------------------------------------------------------+ | Main Routine | +----------------------------------------------------------------------------*/ VOID main(VOID) { BYTE y; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer Init_StartUp(); USB_init(); USB_setEnabledEvents(kUSB_VbusOnEvent+kUSB_VbusOffEvent+kUSB_receiveCompletedEvent +kUSB_dataReceivedEvent+kUSB_UsbSuspendEvent+kUSB_UsbResumeEvent+kUSB_UsbResetEvent); // Check if we're already physically attached to USB, and if so, connect to it // This is the same function that gets called automatically when VBUS gets attached. if (USB_connectionInfo() & kUSB_vbusPresent) USB_handleVbusOnEvent(); // Pre-fill the buffers with visible ASCII characters (0x21 to 0x7E) y=0x21; for(w=0;w<MEGA_DATA_LENGTH;w++) { bufferX[w] = y; bufferY[w] = y++; if(y>0x7E) y = 0x21; } while(1) { switch(USB_connectionState()) { case ST_USB_DISCONNECTED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt break; case ST_USB_CONNECTED_NO_ENUM: break; case ST_ENUM_ACTIVE: if(!bCDCDataReceived_event) // Do this until a key is pressed { strcpy(pakOutString,"Press any key.\r"); // Prepare the outgoing string if(cdcSendDataInBackground((BYTE*)pakOutString,strlen(pakOutString),0,0)) // Send it { USBCDC_abortSend(&w,0); // Operation probably still open; cancel it break; // The break isn't really necessary since it'll go to the end of the loop anyway, but it's shown for completeness } } else { if(cdcSendDataInBackground((BYTE*)bufferX,MEGA_DATA_LENGTH,0,0)) { bCDCDataReceived_event = FALSE; USBCDC_abortSend(&w,0); // Operation probably still open; cancel it break; } // Between these functions, don't modify bufferX. However, bufferY can be modified. if(cdcSendDataInBackground((BYTE*)bufferY,MEGA_DATA_LENGTH,0,0)) { bCDCDataReceived_event = FALSE; USBCDC_abortSend(&w,0); // Operation probably still open; cancel it break; } // Until the next call to sendData_inBackground(), don't modify bufferY. However, bufferX can be modified. if(rounds++>=500) { strcpy(outString,"\r\n\r\nThe test is completed.\r\n\r\n"); // Prepare the outgoing string if(cdcSendDataInBackground((BYTE*)outString,strlen(outString),0,0)) // Send it { USBCDC_abortSend(&w,0); // Operation may still be open; cancel it break; } bCDCDataReceived_event= FALSE; rounds = 0; USBCDC_rejectData(0); // Reject data from previous keypress, in preparation for another one } // It's been in the USB buffer all this time... } break; case ST_ENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt break; case ST_ENUM_IN_PROGRESS: break; case ST_NOENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); _NOP(); break; case ST_ERROR: _NOP(); break; default:; } } // while(1) } //main()
/*----------------------------------------------------------------------------+ | 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()
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; }