void ProcessIO(void) { //Blink the LEDs according to the USB device status BlinkUSBStatus(); // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; // only check for new USB buffer if the old RS232 buffer is // empty. This will cause additional USB packets to be NAK'd // RS232_送信バッファに HostPC から届いたデータをFillする. if (LastRS232Out == 0) { LastRS232Out = getsUSBUSART(RS232_Out_Data,64); //until the buffer is free. if(LastRS232Out > 0) { // RS232_Out_Data_Rdy = 1; // signal buffer full RS232cp = 0; // Reset the current position } } if(LastRS232Out && (NextUSBOut==0)) { //エコーバック専用: memcpy(USB_Out_Buffer,RS232_Out_Data,LastRS232Out); NextUSBOut = LastRS232Out; LastRS232Out = 0; } //可能なら、RS232_受信バッファの内容をHostPCに送る. if((USBUSARTIsTxTrfReady()) && (NextUSBOut > 0)){ putUSBUSART(&USB_Out_Buffer[0], NextUSBOut); NextUSBOut = 0; } CDCTxService(); }
void ProcessIO(void) { BYTE numBytesRead; //Blink the LEDs according to the USB device status BlinkUSBStatus(); // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; if(buttonPressed) { if(stringPrinted == FALSE) { if(mUSBUSARTIsTxTrfReady()) { putrsUSBUSART("Button Pressed data-- \r\n"); stringPrinted = TRUE; } } } else { stringPrinted = FALSE; } if(USBUSARTIsTxTrfReady()) { numBytesRead = getsUSBUSART(USB_Out_Buffer,64); if(numBytesRead != 0) { BYTE i; for(i=0;i<numBytesRead;i++) { switch(USB_Out_Buffer[i]) { case 0x0A: case 0x0D: putUSBUSART(&USB_Out_Buffer[i],numBytesRead); break; case 0x53://letter S to start sampling ReadADC(); putUSBUSART(ADC_sample,SAMPLE_SIZE); break; case 0x51: //letter Q to stop break; default: putUSBUSART(&USB_Out_Buffer[i],numBytesRead); break; } } //putUSBUSART(USB_In_Buffer,numBytesRead); } } CDCTxService(); } //end ProcessIO
/******************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user * routines. It is a mixture of both USB and * non-USB tasks. * * Note: None *******************************************************************/ void ProcessIO(void) { //Blink the LEDs according to the USB device status BlinkUSBStatus(); // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; if(Switch3IsPressed()) //Note: Switch3IsPressed() implements only the { //crudest of switch debounce code. As a result //some pusbbuttons will behave temperamentally. //Proper debounce code should be used which //implements delays millseconds long, and //checks/reckecks pushbutton state many times to //verify that the state is stable. In order //to avoid using blocking functions, or //microcontroller timer resources this feature //is not implemented in this example. emulate_mode = !emulate_mode; } //Call the function that emulates the mouse Emulate_Mouse(); }//end ProcessIO
void BootMain(void) #endif { //NOTE: The c018.o file is not included in the linker script for this project. //The C initialization code in the c018.c (comes with C18 compiler in the src directory) //file is instead modified and included here manually. This is done so as to provide //a more convenient entry method into the bootloader firmware. Ordinarily the _entry_scn //program code section starts at 0x00 and is created by the code of c018.o. However, //the linker will not work if there is more than one section of code trying to occupy 0x00. //Therefore, must not use the c018.o code, must instead manually include the useful code //here instead. //Make sure interrupts are disabled for this code (could still be on, //if the application firmware jumped into the bootloader via software methods) INTCON = 0x00; //Initialize the C stack pointer, and other compiler managed items as //normally done in the c018.c file (applicable when using C18 compiler) #ifndef __XC8__ _asm lfsr 1, _stack lfsr 2, _stack clrf TBLPTRU, 0 _endasm #endif //Clear the stack pointer, in case the user application jumped into //bootloader mode with excessive junk on the call stack STKPTR = 0x00; // End of the important parts of the C initializer. This bootloader firmware does not use // any C initialized user variables (idata memory sections). Therefore, the above is all // the initialization that is required. //Call other initialization code and (re)enable the USB module InitializeSystem(); //Some USB, I/O pins, and other initialization //Execute main loop while(1) { ClrWdt(); //Need to call USBDeviceTasks() periodically. This function takes care of //processing non-USB application related USB packets (ex: "Chapter 9" //packets associated with USB enumeration) USBDeviceTasks(); BlinkUSBStatus(); //When enabled, blinks LEDs on the board, based on USB bus state LowVoltageCheck(); //Regularly monitor voltage to make sure it is sufficient //for safe operation at full frequency and for erase/write //operations. ProcessIO(); //This is where all the actual bootloader related data transfer/self programming takes //place see ProcessIO() function in the BootPIC[xxxx].c file. }//end while }
/* * Main program entry point. */ int main (void) { AD1PCFG = 0xFFFF; //Initialize all of the LED pins LATE |= 0x000F; TRISE &= 0xFFF0; USBDeviceInit(); //usb_device.c. Initializes USB module SFRs and firmware //variables to known states. PMCON = 0; for (;;) { // Check bus status and service USB interrupts. USBDeviceTasks(); // Interrupt or polling method. If using polling, must call // this function periodically. This function will take care // of processing and responding to SETUP transactions // (such as during the enumeration process when you first // plug in). USB hosts require that USB devices should accept // and process SETUP packets in a timely fashion. Therefore, // when using polling, this function should be called // frequently (such as once about every 100 microseconds) at any // time that a SETUP packet might reasonably be expected to // be sent by the host to your device. In most cases, the // USBDeviceTasks() function does not take very long to // execute (~50 instruction cycles) before it returns. // Application-specific tasks. // Blink the LEDs according to the USB device status BlinkUSBStatus(); // User Application USB tasks if (USBDeviceState >= CONFIGURED_STATE && ! (U1PWRC & PIC32_U1PWRC_USUSPEND)) { unsigned nbytes_read; static unsigned char inbuf[64], outbuf[64]; static unsigned led3_count = 0; // Pull in some new data if there is new data to pull in nbytes_read = getsUSBUSART ((char*) inbuf, 64); if (nbytes_read != 0) { snprintf (outbuf, sizeof(outbuf), "Received %d bytes: %02x...\r\n", nbytes_read, inbuf[0]); putUSBUSART ((char*) outbuf, strlen (outbuf)); mLED_2_Toggle(); mLED_3_On(); led3_count = 10000; } if (led3_count) { // Turn off LED3 when timeout expired. led3_count--; if (led3_count == 0) mLED_3_Off(); } CDCTxService(); } } }
/******************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user * routines. It is a mixture of both USB and * non-USB tasks. * * Note: None *******************************************************************/ void ReadADC(void){ unsigned int i; for(i=0;i<SAMPLE_SIZE;i++){ ADCON0bits.GO=1; while(ADCON0bits.DONE){BlinkUSBStatus();} ADC_sample[i]=ADRESH; } }
/******************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user * routines. It is a mixture of both USB and * non-USB tasks. * * Note: None *******************************************************************/ void ProcessIO(void) { //Blink the LEDs according to the USB device status BlinkUSBStatus(); // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; Keyboard(); //Call the function that behaves like a keyboard }//end ProcessIO
void ProcessIO(void) { uchar i; BlinkUSBStatus(); //Blink the LEDs according to the USB device status // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; // only check for new USB buffer if the old RS232 buffer is // empty. This will cause additional USB packets to be NAK'd // RS232_送信バッファに HostPC から届いたデータをFillする. if( mDataRdyUSART() < 32 ) if (LastRS232Out == 0) { LastRS232Out = getsUSBUSART(RS232_Out_Data,64); //until the buffer is free. if(LastRS232Out > 0) { // RS232_Out_Data_Rdy = 1; // signal buffer full RS232cp = 0; // Reset the current position } } #if USART_USE_TX_INTERRUPT // 送信割り込みを使用する. //USARTが送信可であれば RS232_送信バッファの内容を USARTに 1文字送る. if(LastRS232Out && mTxRdyUSART()) { // PIR1bits.TXIF = 0; // 送信割り込みフラグ. PIE1bits.TXIE = 1; // 送信割り込み許可. } #else //USARTが送信可であれば RS232_送信バッファの内容を USARTに 1文字送る. if(LastRS232Out && mTxRdyUSART()) { putcUSART(RS232_Out_Data[RS232cp]); //1文字送る. ++RS232cp; if (RS232cp == LastRS232Out) { // RS232_Out_Data_Rdy = 0; LastRS232Out=0; RS232cp=0; } } #endif //可能なら、RS232_受信バッファの内容をHostPCに送る. if((USBUSARTIsTxTrfReady()) && (mDataRdyUSART())){ i=0; while( mDataRdyUSART() ) { if(i>=CDC_DATA_OUT_EP_SIZE) break; USB_Out_Buffer[i++]=getcUSART(); } putUSBUSART(&USB_Out_Buffer[0], i); NextUSBOut = 0; } CDCTxService(); }
/******************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user * routines. It is a mixture of both USB and * non-USB tasks. * * Note: None *******************************************************************/ void ProcessIO(void) { //Blink the LEDs according to the USB device status BlinkUSBStatus(); // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; if(mUSBUSARTIsTxTrfReady()) { putrsUSBUSART("test123"); } CDCTxService(); } //end ProcessIO
/** * Main function * Main program entry point. * */ void main(void) { InitializeSystem(); tickInit(); while(1) { USBTasks(); BlinkUSBStatus(); if (!((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1))) ProcessIO(); // See user\user.c & .h } }
void ProcessIO(void) { uchar cnt; //Blink the LEDs according to the USB device status BlinkUSBStatus(); // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; // only check for new USB buffer if the old RS232 buffer is // empty. This will cause additional USB packets to be NAK'd // RS232_送信バッファに HostPC から届いたデータをFillする. if (LastRS232Out == 0) { LastRS232Out = getsUSBUSART(RS232_Out_Data,64); //until the buffer is free. if(LastRS232Out > 0) { RS232cp = 0; // Reset the current position } } for(cnt=0;cnt<32;cnt++) { //USARTが送信可であれば RS232_送信バッファの内容を USARTに 1文字送る. if(LastRS232Out && mTxRdyUSART()) { putcUSART(RS232_Out_Data[RS232cp]); //1文字送る. ++RS232cp; if (RS232cp == LastRS232Out) { LastRS232Out=0; RS232cp=0; } } //USARTがデータを受信済みであれば RS232_受信バッファに溜める. if(mDataRdyUSART()) { USB_Out_Buffer[NextUSBOut] = getcUSART(); ++NextUSBOut; //USB_Out_Buffer[NextUSBOut] = 0; } } //可能なら、RS232_受信バッファの内容をHostPCに送る. if((USBUSARTIsTxTrfReady()) && (NextUSBOut > 0)){ putUSBUSART(&USB_Out_Buffer[0], NextUSBOut); NextUSBOut = 0; } CDCTxService(); }
/****************************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user routines. * It is a mixture of both USB and non-USB tasks. * * Note: None *****************************************************************************/ void ProcessIO(void) { //Blink the LEDs according to the USB device status if(blinkStatusValid) { BlinkUSBStatus(); } // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; //respond to any USB commands that might have come over the bus PollTempOnHPCExplorer(); ServiceRequests(); //if we are logging temp data if(temp_mode == TEMP_LOGGING) { #if defined(__18CXX) //if the 1 second timer has expired (PIC18 only) if(INTCONbits.TMR0IF == 1) #endif { #if defined(__18CXX) INTCONbits.TMR0IF = 0; // Clear flag TMR0H = TIMER0H_VAL; TMR0L = TIMER0L_VAL; // Reinit timer value; #endif //get a new temp reading if(AcquireTemperature()) { //store the new value in the buffer temp_data[pTemp] = temperature.Val; // First update valid_temp if(valid_temp < 30) // 30 data points max valid_temp++; // Next update pTemp if(pTemp == 29) pTemp = 0; else pTemp++; }//end if }//end if }//end if }//end ProcessIO
/******************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user * routines. It is a mixture of both USB and * non-USB tasks. * * Note: None *******************************************************************/ void ProcessIO(void) { //Blink the LEDs according to the USB device status BlinkUSBStatus(); // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; // only check for new USB buffer if the old RS232 buffer is // empty. // Additional USB packets will be NAK'd // until the buffer is free. if (RS232_Out_Data_Rdy == 0) { LastRS232Out = getsUSBUSART(RS232_Out_Data,64); if(LastRS232Out > 0) { RS232_Out_Data_Rdy = 1; // signal //buffer full RS232cp = 0;// Reset the current position } } if(RS232_Out_Data_Rdy && mTxRdyUSART()) { putcUSART(RS232_Out_Data[RS232cp]); ++RS232cp; if (RS232cp == LastRS232Out) RS232_Out_Data_Rdy = 0; } if(mDataRdyUSART()) { USB_Out_Buffer[NextUSBOut] = getcUSART(); ++NextUSBOut; USB_Out_Buffer[NextUSBOut] = 0; } if((mUSBUSARTIsTxTrfReady()) && (NextUSBOut > 0)) { putUSBUSART(&USB_Out_Buffer[0], NextUSBOut); NextUSBOut = 0; } CDCTxService(); } //end ProcessIO
// *--------------------------------------------------------------------------------* void ProcessIO(void){ BYTE numBytesRead; //Blink the LEDs according to the USB device status BlinkUSBStatus(); // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; if(buttonPressed){ if(stringPrinted == FALSE){ if(mUSBUSARTIsTxTrfReady()){ putrsUSBUSART("Button Pressed -- \r\n"); stringPrinted = TRUE; } } }else{ stringPrinted = FALSE; } if(USBUSARTIsTxTrfReady()){ numBytesRead = getsUSBUSART(USB_Out_Buffer,64); if(numBytesRead != 0){ BYTE i; for(i=0;i<numBytesRead;i++){ switch(USB_Out_Buffer[i]){ case 0x0A: case 0x0D: USB_In_Buffer[i] = USB_Out_Buffer[i]; break; default: USB_In_Buffer[i] = USB_Out_Buffer[i] + 1; break; } } putUSBUSART(USB_In_Buffer,numBytesRead); } } CDCTxService(); }
/****************************************************************************** * Function: void Main(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: Main program entry point. * * Note: None *****************************************************************************/ void Main(void) { //NOTE: The c018.o file is not included in the linker script for this project. //The C initialization code in the c018.c (comes with C18 compiler in the src directory) //file is instead modified and included here manually. This is done so as to provide //a more convenient entry method into the bootloader firmware. Ordinarily the _entry_scn //program code section starts at 0x00 and is created by the code of c018.o. However, //the linker will not work if there is more than one section of code trying to occupy 0x00. //Therefore, must not use the c018.o code, must instead manually include the useful code //here instead. // Initialize the C stack pointer, and other compiler managed items as normally done in the c018.c file. _asm lfsr 1, _stack lfsr 2, _stack clrf TBLPTRU, 0 _endasm // End of the important parts of the C initializer. This bootloader firmware does not use // any C initialized user variables (idata memory sections). Therefore, the above is all // the initialization that is required. InitializeSystem(); //Some USB, I/O pins, and other initialization while(1) { ClrWdt(); USBTasks(); // Need to call USBTasks() periodically // it handles SETUP packets needed for enumeration BlinkUSBStatus(); //Blink the LEDs based on current USB state if((usb_device_state == CONFIGURED_STATE) && (UCONbits.SUSPND != 1)) { ProcessIO(); // This is where all the actual bootloader related data transfer/self programming takes place } // see ProcessIO() function in the Boot87J50Family.c file. }//end while }//end main
/** * blink LED, send data on queue */ void ProcessIO(void) { BlinkUSBStatus(); if ((USBDeviceState < CONFIGURED_STATE) || (USBSuspendControl == 1)) { return; } if (USBUSARTIsTxTrfReady()) { int len = 0; char temp[QUEUE_SIZE]; while (QueueHas()) { temp[len++] = QueueGet(); } if (len > 0) { putUSBUSART(temp, len); } } CDCTxService(); }
void ProcessIO(void) { // Blink the LEDs according to the USB device status // However, the LEDs are also used temporarily for showing the Num Lock // keyboard LED status. If the host sends an LED state update interrupt // out report, or sends it by a SET_REPORT control transfer, then // the demo board LEDs are temporarily taken over to show the Num Lock // LED state info. After a countdown timout, the firmware will switch // back to showing the USB state on the LEDs, instead of the num lock status. if (g_blink_status_valid == TRUE) { BlinkUSBStatus(); } else { g_usb_led_timer--; if (g_usb_led_timer == 0) { g_blink_status_valid = TRUE; } } // User Application USB tasks if ((USBDeviceState < CONFIGURED_STATE) || (USBSuspendControl == 1)) return; // Call the function that behaves like a keyboard Keyboard(); }
/****************************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user * routines. It is a mixture of both USB and * non-USB tasks. * * Note: None *****************************************************************************/ void ProcessIO(void) { //Blink the LEDs according to the USB device status, but only do so if the PC application isn't connected and controlling the LEDs. if(blinkStatusValid) { BlinkUSBStatus(); } // Check if the device is enumerated and is ready to accept commands. if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; if(!USBHandleBusy(USBGenericOutHandle)) //Check if the endpoint has received any data from the host. { switch(OUTPacket[0]) //Data arrived, check what kind of command might be in the packet of data. { case 'A': if(!USBHandleBusy(USBGenericInHandle)) { if(OUTPacket[1] == '0') { ADCON0bits.ADON = 0; // Switch off ADC. ADCON0 &= 0xF0; // Select channel 0 ADCON0bits.ADON = 1; ADCON0bits.GO = 1; // Wait if conversion is happening while(ADCON0bits.DONE); INPacket[0] = ADRESL; INPacket[1] = ADRESH; } else if(OUTPacket[1] == '1') { ADCON0bits.ADON = 0; // Switch off ADC. ADCON0 &= 0xF0; // Select channel ADCON0bits.CHS0 = 1; ADCON0bits.ADON = 1; ADCON0bits.GO = 1; // Wait if conversion is happening while(ADCON0bits.DONE); INPacket[0] = ADRESL; INPacket[1] = ADRESH; } USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket,USBGEN_EP_SIZE); } break; case 0x80: //Toggle LED(s) command from PC application. blinkStatusValid = FALSE; //Disable the regular LED blink pattern indicating USB state, PC application is controlling the LEDs. if(mGetLED_1() == mGetLED_2()) { mLED_1_Toggle(); mLED_2_Toggle(); } else { mLED_1_On(); mLED_2_On(); } break; case 0x81: //Get push button state command from PC application. if(!USBHandleBusy(USBGenericInHandle)) { //The endpoint was not "busy", therefore it is safe to write to the buffer and arm the endpoint. INPacket[0] = 0x81; //Echo back to the host PC the command we are fulfilling in the first byte. In this case, the Get Pushbutton State command. if(sw2 == 1) //pushbutton not pressed, pull up resistor on circuit board is pulling the PORT pin high { INPacket[1] = 0x01; } else //sw2 must be == 0, pushbutton is pressed and overpowering the pull up resistor { INPacket[1] = 0x00; } // Arm back the handle. USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket,USBGEN_EP_SIZE); } break; } USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE); } }//end ProcessIO
/****************************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user routines. * It is a mixture of both USB and non-USB tasks. * * Note: None *****************************************************************************/ void ProcessIO(void) { //**********Blink the LEDs according to the USB device status**************** if(blinkStatusValid) { BlinkUSBStatus(); } //****************Main background code goes here************************** // This code runs if there is neither a HISR nor a LISR // This cannot be timed data but should still run at a reasonable speed //*********switch ON the backlight if a voltage is applied (in all circumstances)**************** //**********also deal with the backlight counter - count up and ramp down the light when done**** if(backlight_flag==TRUE) // only do this if the backlight is enabled { if(voltage_applied==TRUE) // only do this if the backlight is there { LCD_ramp_up=TRUE; LCD_backlight_counter=0; } else { LCD_backlight_counter++; } if(LCD_backlight_counter>=LCD_backlight_max) { // While here also count up for the backlight delay rountine // If an buttons are pressed then reset the counter to wait // Counter will have quite big numbers in it as this will run quickly // Want to set this delay in approx seconds - might need more counters? LCD_ramp_up=FALSE; LCD_backlight_counter=0; } } //************* CHECK BUTTONS - HAVE ANY BEEN PRESSED?******************************* // This routine checks the switches. If one has been pressed there is a delay loop to ensure that it is // a positive press and to debounce. switch(switch_mode) { case 1: { //Is either button pressed? //N return to 1 //Y goto state 2 if(sw1 || sw2 == TRUE) { switch_mode=2; } } break; case 2: { // Wait 0.1ish seconds (debouce) // Goto state 3 counter1++; if(counter1>= 5000) // Just a short counter to do a debouce { counter1=0; switch_mode=3; } } break; case 3: { // Is a button pressed? // Look up SW0 and SW1 chart: // SW0 SW1 // 0 0 Return to 1 // 1 0 If adjustment_flag is TRUE goto state 7 // Else Goto state 4 - scroll through values // 0 1 If adjustment_flag is TRUE goto state 7 // Else Goto state 10 - start/stop the hold values // 1 1 If adjustment_flag is TRUE goto state 8 // Else Goto state 6 if(sw1==FALSE && sw2==FALSE) { switch_mode=1; // No button pressed hence return to waiting for button press break; } // Is the LCD backlight on already? Does it need to be on? if(backlight_flag==TRUE) // only do this if the backlight is there { if(LCD_ramp_up==FALSE) { switch_mode=11; break; } } if ((sw1==TRUE&&sw2==FALSE)) // 1 0 pressed { buzzer_flag=TRUE; // Beep the buzzer if(adjustment_flag==TRUE) { switch_mode=7; // adjust value up/down } else { switch_mode=4; // scroll up/down } } else if ((sw1==FALSE&&sw2==TRUE)) // 0 1 pressed { buzzer_flag=TRUE; // Beep the buzzer if(adjustment_flag==TRUE) { switch_mode=7; // adjust value up/down } else { switch_mode=10; // enter start/stop mode } } else if (sw1==TRUE&&sw2==TRUE) // Both sw1 and sw2 pressed - enter or leave adjustment mode { buzzer_flag=TRUE; // Beep the buzzer if(adjustment_flag==TRUE) { switch_mode=8; // leave adjustment mode } else { switch_mode=6; // Enter adjustment mode } } LCD_backlight_counter=0; // This resets the LCD backlight counter when a button has been pressed } break; case 4: { //If SW0 = 1 then scroll up (increment display counter) //If SW1 = 1 then scroll down (decrement display counter) //Goto state 5 if(sw1==TRUE) { display_mode++; if(display_mode>max_display_mode) { display_mode=1; } switch_pressed=1; // Tells case 5 which switch was previously pressed } if(sw2==TRUE) { display_mode--; if(display_mode<=0) { display_mode=max_display_mode; } switch_pressed=2; // Tells case 5 which switch was previously pressed } update_display=TRUE; switch_mode=5; // Go to the delay to stop scrolling through too quickly } break; case 5: { //Count for 0.5s – this is to stop scrolling through too quickly. //During this: //If the switch changes from 1 to zero then goto state 1 //At the end //Goto state 1 counter1++; if(counter1>= 30000) // Counter to stop things scrolling through too quickly { counter1=0; switch_mode=1; } if(switch_pressed==1&&sw1==FALSE) // This is the case if sw1 is released, do not need the counter { counter1=0; // reset the counter switch_pressed=0; // reset the switch_pressed switch_mode=1; // return from this case as switch released } if(switch_pressed==2&&sw2==FALSE) // This is the case if sw2 is released, do not need the counter { counter1=0; // reset the counter switch_pressed=0; // reset the switch_pressed switch_mode=1; // return from this case as switch released } } break; case 6: { //Entered this state to do adjustments //Want to check what display mode we are in and do things accordingly //Have all the display_modes here: //0 //Set adjustment_flag = TRUE //1 //Set adjustment_flag = FALSE //2 //3… etc //Goto state 5 switch (display_mode) // There must be as many cases here as there are display modes which allow adjustment { case 8: { // Adjustment allowed adjustment_flag=TRUE; // In case of a problem then set everything to normal and return to mode 1 switch_mode=9; // wait for person to let go of buttons } break; default: { // Display: Adjustment not allowed adjustment_flag=FALSE; // In case of a problem then set everything to normal and return to mode 1 switch_mode=9; // wait for person to let go of buttons } break; } } break; case 7: { //Enter this mode to increment any conversion factors //Have all the display_modes which can be adjusted here: switch (display_mode) // There must be as many cases here as there are display modes which allow adjustment { case 8: // Adjust the Cost_conv { if(sw2==TRUE) { //********ramp up the value**************** M_conv=M_conv+0.5; if(M_conv>=99.9) { M_conv=99.9; // Stops the value going too high } switch_pressed=1; // Tells case 5 which switch was previously pressed } if(sw1==TRUE) { //********ramp down the value**************** M_conv=M_conv-0.5; if(M_conv<=0) { M_conv=0; // Stops the value going too low } switch_pressed=2; // Tells case 5 which switch was previously pressed } /* This is where the value is written to EEPROM - stop interrupts for this time to ensure it works */ INTCONbits.GIE = 0; // Disable global interrupt bit writeEE_float(0x10,M_conv); //Store the new value to EEPROM so it can be used next time // This must be done in the HISR or else there might be an issue // This could be done by having a flag and doing the update in the HISR INTCONbits.GIE = 1; //Enable global interrupt bit M_conversion = M_conv/10; // Must recaluclate the new conversion value (done in initialisation routine) update_display=TRUE; // Show the new value on the screen switch_mode=5; // Go to the delay to stop scrolling through too quickly } break; default: { // Display: Adjustment not allowed some error so leave this state adjustment_flag=FALSE; // In case of a problem then set everything to normal and return to mode 1 switch_mode=9; // wait for person to let go of buttons } break; update_display=TRUE; // Want to do this here. } } break; case 8: { //Set adjustment_flag = FALSE //Goto state 5 // Entered here as user has wanted to leave adjustment mode // Display displaying mode on top line // update_display=TRUE; adjustment_flag=FALSE; // Set the adjustment flag FALSE as leaving that mode //Wait here until both buttons are released. if(sw1==FALSE&&sw2==FALSE) { switch_mode=5; } } break; case 9: { // Entered here as user has wanted to enter adjustment mode // ***********TO DO******************** // Display adjustment mode on top line, if adjustment flag is set //Wait here until both buttons are released. if(sw1==FALSE&&sw2==FALSE) { // update_display=TRUE; switch_mode=5; } } break; case 10: { // Entered here as user has wanted start/stop the timer for pedalling buzzer_flag=TRUE; // Beep the buzzer reset_temp_flag++; // This increments the reset flag to ensure the main loop does the correct thing if(reset_temp_flag==4) // 0=nothing, 1=reset, 2=nothing, 3=hold values { reset_temp_flag=0; } switch_mode=5; } break; case 11: { // entered here as it was the first time a switch was pressed and the backlight was set true buzzer_flag=TRUE; // Beep the buzzer LCD_ramp_up=TRUE; //first_sw_press=FALSE; LCD_backlight_counter=0; switch_mode=5; // first button pressed hence return to waiting for next button press } break; default: { Nop(); } break; } // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; //respond to any USB commands that might have come over the bus ServiceRequests(); }//end ProcessIO
void ProcessIO(void) { char oldPGDtris; char PIN; static byte counter=0; int nBytes; unsigned long address; // When the device is plugged in, the leds give the numbers 1, 2, 3, 4, 5. //After configured state, the leds are controlled by the next lines in this function if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) { BlinkUSBStatus(); return; } nBytes=USBGenRead((byte*)input_buffer,64); if(nBytes>0) { switch(input_buffer[0]) { case CMD_ERASE: setLeds(LEDS_ON | LEDS_WR); output_buffer[0]=bulk_erase(picfamily,pictype,input_buffer[1]); counter=1; setLeds(LEDS_ON); break; case CMD_READ_ID: setLeds(LEDS_ON | LEDS_RD); switch(picfamily) { case PIC24: case dsPIC30: read_code(picfamily,pictype,0xFF0000,(unsigned char*)output_buffer,2,3); break; case PIC18: case PIC18J: case PIC18K: read_code(picfamily,pictype,0x3FFFFE,(unsigned char*)output_buffer,2,3); //devid is at location 0x3ffffe for PIC18 devices break; case PIC16: set_vdd_vpp(picfamily, pictype, 0); read_code(picfamily,pictype,0x2006,(unsigned char*)output_buffer,2,3); //devid is at location 0x2006 for PIC16 devices break; } counter=2; setLeds(LEDS_ON); break; case CMD_WRITE_CODE: setLeds(LEDS_ON | LEDS_WR); address=((unsigned long)input_buffer[2])<<16| ((unsigned long)input_buffer[3])<<8| ((unsigned long)input_buffer[4]); output_buffer[0]=write_code(picfamily,pictype,address, (unsigned char*)(input_buffer+6),input_buffer[1],input_buffer[5]); counter=1; setLeds(LEDS_ON); break; case CMD_READ_CODE: setLeds(LEDS_ON | LEDS_RD); address=((unsigned long)input_buffer[2])<<16| ((unsigned long)input_buffer[3])<<8| ((unsigned long)input_buffer[4]); PIN=read_code(picfamily,pictype,address,(unsigned char*)output_buffer,input_buffer[1],input_buffer[5]); if(PIN==3)output_buffer[0]=0x3; counter=input_buffer[1]; setLeds(LEDS_ON); break; case CMD_WRITE_DATA: setLeds(LEDS_ON | LEDS_WR); address=((unsigned long)input_buffer[2])<<16| ((unsigned long)input_buffer[3])<<8| ((unsigned long)input_buffer[4]); output_buffer[0]=write_data(picfamily,pictype,address, (unsigned char*)(input_buffer+6),input_buffer[1],input_buffer[5]); counter=1; setLeds(LEDS_ON); break; case CMD_READ_DATA: setLeds(LEDS_ON | LEDS_RD); address=((unsigned long)input_buffer[2])<<16| ((unsigned long)input_buffer[3])<<8| ((unsigned long)input_buffer[4]); read_data(picfamily,pictype,address,(unsigned char*)output_buffer,input_buffer[1],input_buffer[5]); counter=input_buffer[1]; setLeds(LEDS_ON); break; case CMD_WRITE_CONFIG: setLeds(LEDS_ON | LEDS_WR); address=((unsigned long)input_buffer[2])<<16| ((unsigned long)input_buffer[3])<<8| ((unsigned long)input_buffer[4]); output_buffer[0]=write_config_bits(picfamily, pictype, address, (unsigned char*)(input_buffer+6),input_buffer[1],input_buffer[5]); counter=1; setLeds(LEDS_ON); break; case CMD_SET_PICTYPE: output_buffer[0]=set_pictype(input_buffer+1); //output_buffer[0]=1; //Ok counter=1; setLeds(LEDS_ON); break; case CMD_FIRMWARE_VERSION: strcpypgm2ram((char*)output_buffer,(const far rom char*)upp_version); counter=18; setLeds(LEDS_ON); break; case CMD_DEBUG: setLeds(LEDS_ON | LEDS_WR | LEDS_RD); switch(input_buffer[1]) { case 0: set_vdd_vpp(dsP30F, dsPIC30, 1); output_buffer[0]=1; counter=1; break; case 1: set_vdd_vpp(dsP30F, dsPIC30, 0); output_buffer[0]=1; counter=1; break; case 2: dspic_send_24_bits(((unsigned long)input_buffer[2])| ((unsigned long)input_buffer[3])<<8| ((unsigned long)input_buffer[4])<<16); output_buffer[0]=1; counter=1; break; case 3: nBytes = dspic_read_16_bits(1); output_buffer[0]=(unsigned char)nBytes; output_buffer[1]=(unsigned char)(nBytes>>8); counter=2; break; } break; case CMD_GET_PIN_STATUS: switch(input_buffer[1]) { case SUBCMD_PIN_PGC: if((!TRISPGC_LOW)&&(!PGC_LOW)) //3.3V levels { if(PGC) output_buffer[0] = PIN_STATE_3_3V; else output_buffer[0] = PIN_STATE_0V; } else //5V levels { if(PGC) output_buffer[0] = PIN_STATE_5V; else output_buffer[0] = PIN_STATE_0V; } counter=1; break; case SUBCMD_PIN_PGD: if(TRISPGD)//PGD is input { if(PGD_READ) output_buffer[0] = PIN_STATE_5V; else output_buffer[0] = PIN_STATE_0V; } else { if((!TRISPGD_LOW)&&(!PGD_LOW)) //3.3V levels { if(PGD) output_buffer[0] = PIN_STATE_3_3V; else output_buffer[0] = PIN_STATE_0V; } else //5V levels { if(PGD) output_buffer[0] = PIN_STATE_5V; else output_buffer[0] = PIN_STATE_0V; } } counter=1; break; case SUBCMD_PIN_VDD: if(VDD) output_buffer[0] = PIN_STATE_FLOAT; else output_buffer[0] = PIN_STATE_5V; counter = 1; break; case SUBCMD_PIN_VPP: counter=1; if(!VPP){output_buffer[0] = PIN_STATE_12V;break;} if(VPP_RST){output_buffer[0] = PIN_STATE_0V;break;} if(VPP_RUN){output_buffer[0] = PIN_STATE_5V;break;} output_buffer[0] = PIN_STATE_FLOAT; break; case SUBCMD_PIN_VPP_VOLTAGE: ReadAdc(output_buffer); counter=2; break; default: output_buffer[0]=3; counter=1; break; } break; case CMD_SET_PIN_STATUS: switch(input_buffer[1]) { case SUBCMD_PIN_PGC: switch(input_buffer[2]) { case PIN_STATE_0V: TRISPGC = 0; PGC = 0; TRISPGC_LOW = 1; PGC_LOW = 0; output_buffer[0]=1;//ok break; case PIN_STATE_3_3V: TRISPGC = 0; PGC = 1; TRISPGC_LOW = 0; PGC_LOW = 0; output_buffer[0]=1;//ok break; case PIN_STATE_5V: TRISPGC = 0; PGC = 1; TRISPGC_LOW = 1; PGC_LOW = 0; output_buffer[0]=1;//ok break; default: output_buffer[0]=3; break; } break; case SUBCMD_PIN_PGD: switch(input_buffer[2]) { case PIN_STATE_0V: TRISPGD = 0; PGD = 0; TRISPGD_LOW = 1; PGD_LOW = 0; output_buffer[0]=1;//ok break; case PIN_STATE_3_3V: TRISPGD = 0; PGD = 1; TRISPGD_LOW = 0; PGD_LOW = 0; output_buffer[0]=1;//ok break; case PIN_STATE_5V: TRISPGD = 0; PGD = 1; TRISPGD_LOW = 1; PGD_LOW = 0; output_buffer[0]=1;//ok break; case PIN_STATE_INPUT: TRISPGD_LOW = 1; TRISPGD = 1; output_buffer[0]=1;//ok break; default: output_buffer[0]=3; break; } break; case SUBCMD_PIN_VDD: switch(input_buffer[2]) { case PIN_STATE_5V: VDD = 0; output_buffer[0]=1; break; case PIN_STATE_FLOAT: VDD = 1; output_buffer[0]=1; break; default: output_buffer[0]=3; break; } break; case SUBCMD_PIN_VPP: switch(input_buffer[2]) { case PIN_STATE_0V: VPP = 1; VPP_RST = 1; VPP_RUN = 0; output_buffer[0]=1;//ok break; case PIN_STATE_5V: VPP = 1; VPP_RST = 0; VPP_RUN = 1; output_buffer[0]=1;//ok break; case PIN_STATE_12V: VPP = 0; VPP_RST = 0; VPP_RUN = 0; output_buffer[0]=1;//ok break; case PIN_STATE_FLOAT: VPP = 1; VPP_RST = 0; VPP_RUN = 0; output_buffer[0]=1;//ok break; default: output_buffer[0]=3; break; } break; default: output_buffer[0]=3; } counter=1; break; } } if(counter != 0) { if(!mUSBGenTxIsBusy()) USBGenWrite((byte*)&output_buffer,counter); counter=0; } }//end ProcessIO
void CDCTasks(void) { BYTE numBytesRead; // Blink the LEDs according to the USB device status if (blinkStatusValid) { BlinkUSBStatus(); } // User Application USB tasks if ((USBDeviceState < CONFIGURED_STATE) || (USBSuspendControl == 1)) { return; } #if (HILSIM_USB == 1) numBytesRead = getsUSBUSART(USB_In_Buffer, sizeof(USB_In_Buffer)); if (numBytesRead != 0) { int i = 0; while (i < numBytesRead) { udb_gps_callback_received_byte(USB_In_Buffer[i++]); } } if (mUSBUSARTIsTxTrfReady()) { int i = 0; int txchar; while ((i < sizeof(USB_Out_Buffer)) && ((txchar = udb_gps_callback_get_byte_to_send()) != -1)) { USB_Out_Buffer[i++] = txchar; } if (i > 0) { putUSBUSART(USB_Out_Buffer, i); } } #else if (mUSBUSARTIsTxTrfReady()) { numBytesRead = getsUSBUSART(USB_Out_Buffer, sizeof(USB_Out_Buffer)); if (numBytesRead != 0) { BYTE i; for (i = 0; i < numBytesRead; i++) { switch (USB_Out_Buffer[i]) { case 0x0A: case 0x0D: USB_In_Buffer[i] = USB_Out_Buffer[i]; break; default: USB_In_Buffer[i] = USB_Out_Buffer[i] + 1; break; } } putUSBUSART(USB_In_Buffer, numBytesRead); } } #endif CDCTxService(); }
/****************************************************************************** * Function: void UninitializedMain(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This is the main function for this bootloader mode firmware. * if execution gets to this function, it is assumed that we * want to stay in bootloader mode for now. * * Note: If adding code to this function, make sure to add it only * after the C initializer like code at the top of this function. *****************************************************************************/ void BootMain(void) { //NOTE: The c018.o file is not included in the linker script for this project. //The C initialization code in the c018.c (comes with C18 compiler in the src directory) //file is instead modified and included here manually. This is done so as to provide //a more convenient entry method into the bootloader firmware. Ordinarily the _entry_scn //program code section starts at 0x00 and is created by the code of c018.o. However, //the linker will not work if there is more than one section of code trying to occupy 0x00. //Therefore, must not use the c018.o code, must instead manually include the useful code //here instead. //Make sure interrupts are disabled for this code (could still be on, //if the application firmware jumped into the bootloader via software methods) INTCON = 0x00; // Initialize the C stack pointer, and other compiler managed items as normally done in the c018.c file. _asm lfsr 1, _stack lfsr 2, _stack clrf TBLPTRU, 0 _endasm //Clear the stack pointer, in case the user application jumped into //bootloader mode with excessive junk on the call stack STKPTR = 0x00; // End of the important parts of the C initializer. This bootloader firmware does not use // any C initialized user variables (idata memory sections). Therefore, the above is all // the initialization that is required. //Check if the USB module is already enabled. If so, disable it and wait //~100ms+ (>1 second recommended if CDC application firmware on XP), to //ensure that the host has a chance to see and process the USB device detach //event. if(UCONbits.USBEN == 1) { //USB module was already on. This is likely because the user applicaiton //firmware jumped into this bootloader firmware using the absolute //software entry method, without first turning off the USB module DisableUSBandExecuteLongDelay(); } //Call other initialization code and (re)enable the USB module InitializeSystem(); //Some USB, I/O pins, and other initialization //Execute main loop while(1) { ClrWdt(); //Need to call USBTasks() periodically. This function takes care of //processing non-USB application related USB packets (ex: "Chapter 9" //packets associated with USB enumeration) USBTasks(); BlinkUSBStatus(); //When enabled, blinks LEDs on the board, based on USB bus state LowVoltageCheck(); //Regularly monitor voltage to make sure it is sufficient //for safe operation at full frequency and for erase/write //operations. //Checks for and processes application related USB packets (assuming the //USB bus is in the CONFIGURED_STATE, which is the only state where //the host is allowed to send application related USB packets to the device. if((usb_device_state == CONFIGURED_STATE) && (UCONbits.SUSPND != 1)) { ProcessIO(); // This is where all the actual bootloader related data transfer/self programming takes place } // see ProcessIO() function in the BootPIC[xxxx].c file. }//end while }
/****************************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user routines. * It is a mixture of both USB and non-USB tasks. * * Note: None *****************************************************************************/ void ProcessIO(void) { //Blink the LEDs according to the USB device status, but only do so if the PC application isn't connected and controlling the LEDs. if(blinkStatusValid) { BlinkUSBStatus(); } //User Application USB tasks below. //Note: The user application should not begin attempting to read/write over the USB //until after the device has been fully enumerated. After the device is fully //enumerated, the USBDeviceState will be set to "CONFIGURED_STATE". if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; //As the device completes the enumeration process, the USBCBInitEP() function will //get called. In this function, we initialize the user application endpoints (in this //example code, the user application makes use of endpoint 1 IN and endpoint 1 OUT). //The USBGenRead() function call in the USBCBInitEP() function initializes endpoint 1 OUT //and "arms" it so that it can receive a packet of data from the host. Once the endpoint //has been armed, the host can then send data to it (assuming some kind of application software //is running on the host, and the application software tries to send data to the USB device). //If the host sends a packet of data to the endpoint 1 OUT buffer, the hardware of the SIE will //automatically receive it and store the data at the memory location pointed to when we called //USBGenRead(). Additionally, the endpoint handle (in this case USBGenericOutHandle) will indicate //that the endpoint is no longer busy. At this point, it is safe for this firmware to begin reading //from the endpoint buffer, and processing the data. In this example, we have implemented a few very //simple commands. For example, if the host sends a packet of data to the endpoint 1 OUT buffer, with the //first byte = 0x80, this is being used as a command to indicate that the firmware should "Toggle LED(s)". if(!USBHandleBusy(USBGenericOutHandle)) //Check if the endpoint has received any data from the host. { switch(OUTPacket[0]) //Data arrived, check what kind of command might be in the packet of data. { case 0x80: //Toggle LED(s) command from PC application. blinkStatusValid = FALSE; //Disable the regular LED blink pattern indicating USB state, PC application is controlling the LEDs. if(mGetLED_1() == mGetLED_2()) { mLED_1_Toggle(); mLED_2_Toggle(); } else { mLED_1_On(); mLED_2_On(); } break; case 0x81: //Get push button state command from PC application. INPacket[0] = 0x81; //Echo back to the host PC the command we are fulfilling in the first byte. In this case, the Get Pushbutton State command. // if(sw2 == 1) //pushbutton not pressed, pull up resistor on circuit board is pulling the PORT pin high if (UserSW == 1) { INPacket[1] = 0x01; } else //sw2 must be == 0, pushbutton is pressed and overpowering the pull up resistor { INPacket[1] = 0x00; } //Now check to make sure no previous attempts to send data to the host are still pending. If any attemps are still //pending, we do not want to write to the endpoint 1 IN buffer again, until the previous transaction is complete. //Otherwise the unsent data waiting in the buffer will get overwritten and will result in unexpected behavior. if(!USBHandleBusy(USBGenericInHandle)) { //The endpoint was not "busy", therefore it is safe to write to the buffer and arm the endpoint. //The USBGenWrite() function call "arms" the endpoint (and makes the handle indicate the endpoint is busy). //Once armed, the data will be automatically sent to the host (in hardware by the SIE) the next time the //host polls the endpoint. Once the data is successfully sent, the handle (in this case USBGenericInHandle) //will indicate the the endpoint is no longer busy. USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket,USBGEN_EP_SIZE); } break; } //Re-arm the OUT endpoint for the next packet: //The USBGenRead() function call "arms" the endpoint (and makes it "busy"). If the endpoint is armed, the SIE will //automatically accept data from the host, if the host tries to send a packet of data to the endpoint. Once a data //packet addressed to this endpoint is received from the host, the endpoint will no longer be busy, and the application //can read the data which will be sitting in the buffer. USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE); } }//end ProcessIO
/******************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user * routines. It is a mixture of both USB and * non-USB tasks. * * Note: None *******************************************************************/ void ProcessIO(void) { //Blink the LEDs according to the USB device status BlinkUSBStatus(); // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; if (RS232_Out_Data_Rdy == 0) // only check for new USB buffer if the old RS232 buffer is { // empty. This will cause additional USB packets to be NAK'd LastRS232Out = getsUSBUSART(RS232_Out_Data,64); //until the buffer is free. if(LastRS232Out > 0) { RS232_Out_Data_Rdy = 1; // signal buffer full RS232cp = 0; // Reset the current position } } //Check if one or more bytes are waiting in the physical UART transmit //queue. If so, send it out the UART TX pin. if(RS232_Out_Data_Rdy && mTxRdyUSART()) { #if defined(USB_CDC_SUPPORT_HARDWARE_FLOW_CONTROL) //Make sure the receiving UART device is ready to receive data before //actually sending it. if(UART_CTS == USB_CDC_CTS_ACTIVE_LEVEL) { putcUSART(RS232_Out_Data[RS232cp]); ++RS232cp; if (RS232cp == LastRS232Out) RS232_Out_Data_Rdy = 0; } #else //Hardware flow control not being used. Just send the data. putcUSART(RS232_Out_Data[RS232cp]); ++RS232cp; if (RS232cp == LastRS232Out) RS232_Out_Data_Rdy = 0; #endif } //Check if we received a character over the physical UART, and we need //to buffer it up for eventual transmission to the USB host. if(mDataRdyUSART() && (NextUSBOut < (CDC_DATA_OUT_EP_SIZE - 1))) { USB_Out_Buffer[NextUSBOut] = getcUSART(); ++NextUSBOut; USB_Out_Buffer[NextUSBOut] = 0; } #if defined(USB_CDC_SUPPORT_HARDWARE_FLOW_CONTROL) //Drive RTS pin, to let UART device attached know if it is allowed to //send more data or not. If the receive buffer is almost full, we //deassert RTS. if(NextUSBOut <= (CDC_DATA_OUT_EP_SIZE - 5u)) { UART_RTS = USB_CDC_RTS_ACTIVE_LEVEL; } else { UART_RTS = (USB_CDC_RTS_ACTIVE_LEVEL ^ 1); } #endif //Check if any bytes are waiting in the queue to send to the USB host. //If any bytes are waiting, and the endpoint is available, prepare to //send the USB packet to the host. if((USBUSARTIsTxTrfReady()) && (NextUSBOut > 0)) { putUSBUSART(&USB_Out_Buffer[0], NextUSBOut); NextUSBOut = 0; } CDCTxService(); }//end ProcessIO
void BootService(void) { BlinkUSBStatus(); if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) return; if(trf_state == SENDING_RESP) { if(!mBootTxIsBusy()) { BOOT_BD_OUT.Cnt = sizeof(dataPacket); mUSBBufferReady(BOOT_BD_OUT); trf_state = WAIT_FOR_CMD; }//end if return; }//end if if(!mBootRxIsBusy()) { counter = 0; switch(dataPacket.CMD) { case READ_VERSION: ReadVersion(); counter=0x04; break; case READ_FLASH: case READ_CONFIG: ReadProgMem(); counter+=0x05; break; case WRITE_FLASH: WriteProgMem(); counter=0x01; break; case ERASE_FLASH: EraseProgMem(); counter=0x01; break; case READ_EEDATA: ReadEE(); counter+=0x05; break; case WRITE_EEDATA: WriteEE(); counter=0x01; break; case WRITE_CONFIG: WriteConfig(); counter=0x01; break; case RESET: //When resetting, make sure to drop the device off the bus //for a period of time. Helps when the device is suspended. UCONbits.USBEN = 0; big_counter = 0; while(--big_counter); Reset(); break; case UPDATE_LED: if(dataPacket.led_num == 3) { mLED_3 = dataPacket.led_status; counter = 0x01; }//end if if(dataPacket.led_num == 4) { mLED_4 = dataPacket.led_status; counter = 0x01; }//end if break; default: break; }//end switch() trf_state = SENDING_RESP; if(counter != 0) { BOOT_BD_IN.Cnt = counter; mUSBBufferReady(BOOT_BD_IN); }//end if }//end if }//end BootService
/******************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user * routines. It is a mixture of both USB and * non-USB tasks. * * Note: None *******************************************************************/ void ProcessIO(void) { BYTE numBytesRead; //Blink the LEDs according to the USB device status BlinkUSBStatus(); // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; // if(buttonPressed) // { // if(stringPrinted == FALSE) // { // if(mUSBUSARTIsTxTrfReady()) // { // putrsUSBUSART("Button Pressed -- \r\n"); // stringPrinted = TRUE; // } // } // } // else // { // stringPrinted = FALSE; // } // // if(mUSBUSARTIsTxTrfReady()) // { // numBytesRead = getsUSBUSART(USB_Out_Buffer,64); // if(numBytesRead != 0) // { // BYTE i; // // for(i=0;i<numBytesRead;i++) // { // switch(USB_Out_Buffer[i]) // { // case 0x0A: // case 0x0D: // USB_In_Buffer[i] = USB_Out_Buffer[i]; // break; // default: // USB_In_Buffer[i] = USB_Out_Buffer[i] + 1; // break; // } // // } // // putUSBUSART(USB_In_Buffer,numBytesRead); // } // } //Check if we received a character over the physical UART, and we need //to buffer it up for eventual transmission to the USB host. if(mDataRdyUSART() && (NextUSBOut < (CDC_DATA_OUT_EP_SIZE - 1))) { USB_Out_Buffer[NextUSBOut] = getcUSART(); ++NextUSBOut; USB_Out_Buffer[NextUSBOut] = 0; } //Check if any bytes are waiting in the queue to send to the USB host. //If any bytes are waiting, and the endpoint is available, prepare to //send the USB packet to the host. if((USBUSARTIsTxTrfReady()) && (NextUSBOut > 0)) { putUSBUSART(&USB_Out_Buffer[0], NextUSBOut); NextUSBOut = 0; } CDCTxService(); } //end ProcessIO