Yup, you 2 were right. It only picked up the Plugged, not the un-plugged state.
After a bit of re-thinking, ...
This seems to work pretty good.
The way it works is by watching the IDLEIF and SOFIF interrupt flags.
IDLEIF is triggered if the USB buss is idle for more than 3ms.
SOFIF is the Start-Of-Frame flag, which is a good indication of buss activity.
If it sees a SOFIF it sets the Plugged bit, and if it sees an IDLEIF flag it clears the Plugged bit.
Then in the Main loop you can use that flag to stop sending data if not Plugged.
This example uses Interrupts, but you can do the same thing without interrupts, just be sure to check for the flags before servicing USB.
The example turns on LED1 when Plugged, and toggles a second LED to show that the Main loop keeps executing when un-plugged.
HTH,Code:DEFINE OSC 48 CLEAR INCLUDE "DT_INTS-18.bas" ' Base Interrupt System ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler USB_INT, _DoUSBService, ASM, yes endm INT_CREATE ; Creates the interrupt processor endasm UIE VAR BYTE EXT UEIE VAR BYTE EXT UIR VAR BYTE EXT IDLEIF VAR UIR.4 SOFIF VAR UIR.6 Plugged VAR BIT LED1 VAR PORTB.0 : LOW LED1 LED2 VAR PORTC.1 : LOW LED2 USBBufferCount Var Byte DataToSend var byte[8] USBBufferCount = 8 pause 500 ' initialise USB... usbinit usbservice UIE = $7F UEIE = $9F @ INT_ENABLE USB_INT ;----[Main program starts here]----------------------------------------------- Main: LED1 = Plugged ; LED1 indicates OK to Send IF Plugged then ; if bus available, transmit data USBOut 1, DataToSend, USBBufferCount, Main ENDIF toggle LED2 ; blink LED2 to show Main Loop is still running pause 100 goto Main ;----[USB Interrupt Handler]-------------------------------------------------- DoUSBService: IF IDLEIF THEN Plugged = 0 IF SOFIF THEN Plugged = 1 usbservice @ INT_RETURN








Bookmarks