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.
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
HTH,
Bookmarks