Problem with DT_HID (maybe!)


Closed Thread
Results 1 to 9 of 9

Hybrid View

  1. #1
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: Problem with DT_HID (maybe!)

    Why do you need to check for incomming USB reports every ~340uS ?
    DT

  2. #2
    Join Date
    Jul 2009
    Posts
    15


    Did you find this post helpful? Yes | No

    Default Re: Problem with DT_HID (maybe!)

    There is no specific timing requirement, the period is just the maximum Timer2 would allow.

    I realise that I can of course just resort to checking for incoming traffic in the main loop and in this instance that works OK. However there is obviously a restriction here that it would nice to be able to solve, i.e. how do you perform a USB read triggered by an interrupt?

    I suppose that in the ideal case the receipt of USB data would trigger an interrupt of its own where the data can be processed, therefore negating the need for polling (that I do not consider to be very elegant!).

    Do you think this is something worth exploring? Or is it a bit of a lost cause?

  3. #3
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Interrupt ON USBRX

    PIC's don't generate interrupts on received USB reports.
    The only indication a report was received is the buffer ownership bits which are controlled by the SIE.
    So at some level, those bits must be polled.

    They can be polled in the ISR, and in fact they are already being polled by DT_HID. That's how it maintains the RX_READY and TX_READY flags.
    But there isn't enough time there to actually handle incomming data during the ISR because it stops USB from being serviced.
    Even if you set a flag and handle it in the main loop, then that flag must be polled instead and nothing is gained except for the release of the ISR.

    So the only possibility for immediate response to incoming USB data is to use a Low Priority interrupt for received reports. The USB can continue being serviced by the High Priority interrupts and receive the next report while the last data is parsed and acted upon.
    But again, there are no interrupts generated for received reports. So, how to start a Low Priority Interrupt when a report arrives is the real question.

    Many of the Interrupt Flags are writable (some are not). You can write a 1 to the xxxIF bit and trigger an interrupt, even though the hardware associated with the flag is disabled.

    If you chose a peripheral that is not being used and will not change the flag, you can borrow its flag for your own use. (INTx, IOC, A/D etc. are not good candidates)

    On the 18F4550, I would guess the HLVD interrupt will probably not be used by most programs. So in this program, I've used it to generate a Low Priority interrupt when the buffer owner bits have been polled in the High Priority ISR. Then as soon as the H.P. Int finishes the L.P. Int starts. And the L.P. can be interrupted again by the H.P.

    I've aliased the HLVD_INT to USBRX_INT for readability by using the DEFINE just before the INT_LISTs. USBRX_INT is then used for the Low Priority interrupt handler.

    Another Handler for USB_INT was added to the HighPriority INT_LIST.
    That runs the USBRX_CHECK routine at the end of the source code.
    The Reset Flag option is set to NO, so the second USB_INT will still execute too.

    The end goal is to call the HandleRX subroutine immediately upon arrival of a USB report from the PC.
    That, it does.

    I used a LAB-XUSB developement board with an 18F4550 for testing.

    Code:
    '***************************************************************************
    '*  Name    : USBRX_INT.PBP                                                *
    '*  Author  : Darrel Taylor                                                *
    '*  Date    : 8/17/2011                                                    *
    '*  Version : 1.0                                                          *
    '*  Target  : 18F4550                                                      *
    '* Compiler : PBP3                                                         *
    '***************************************************************************
    CLEAR
    DEFINE OSC 48         ; Internal processor frequency
    #CONFIG
        CONFIG FOSC = HSPLL_HS
        CONFIG PLLDIV = 5
        CONFIG USBDIV = 2
        CONFIG CPUDIV = OSC1_PLL2
        CONFIG FCMEN = OFF, IESO = OFF, PWRT = ON, BOR = OFF
        CONFIG VREGEN = ON, WDT = OFF, CCP2MX = OFF, PBADEN = OFF
        CONFIG MCLRE = ON, STVREN = ON, LVP = OFF, XINST = OFF
    #ENDCONFIG
    DEFINE ADC_BITS 10 'Number of bits in ADCIN result
    ;---[Setup Interrupts]------------------------------------------------------
    DEFINE  USE_LOWPRIORITY  1     ; Use Low Priority Interrupts
    INCLUDE "DT_INTS-18.bas"       ; Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"    ; Allows re-entry to PBP from ASM interrupts
    INCLUDE "ReEnterPBP-18LP.bas"  ; Include if using Low Pr. PBP INTS
    ASM
      #define USBRX_INT HLVD_INT  ; use HLVD as false Low Priority INT
     
    ;----[High Priority Interrupts]---------------------------------------------
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   USB_INT,   USBRX_CHECK,   ASM,  no
            INT_Handler   USB_Handler
            INT_Handler   TMR1_INT,    _TMR1_ISR,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
        INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts  
    ;----[Low Priority Interrupts]----------------------------------------------
    INT_LIST_L  macro  ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler     USBRX_INT,  USB_Receive,   PBP,  yes
        endm
        INT_CREATE_L             ; Creates the Low Priority interrupt processor
        INT_ENABLE  USBRX_INT
    ENDASM
    ;---[Setup USB]-------------------------------------------------------------
    INCLUDE "DT_HID260.pbp"
    DEFINE USB_VENDORID    6017
    DEFINE USB_PRODUCTID   2000
    DEFINE USB_VERSION     2
    DEFINE USB_VENDORNAME  "Darrel Taylor"
    DEFINE USB_PRODUCTNAME "USBRX_INT"
    DEFINE USB_SERIAL      "001"
    DEFINE USB_INSIZE      64   ; IN report is PIC to PC (8,16,32,64)
    DEFINE USB_OUTSIZE     16   ; OUT report is PC to PIC
    DEFINE USB_POLLIN      10   ; Polling times in mS, MIN=1 MAX=10
    DEFINE USB_POLLOUT     10
    ; --- Each USB LED is optional, comment them if not used ----
    DEFINE USB_LEDPOLARITY 1       ; LED ON State [0 or 1]  (default = 1)
    DEFINE USB_PLUGGEDLED  PORTD,0 ; LED indicates if USB is connected
    DEFINE USB_TXLED       PORTD,1 ;  "      "     data being sent to PC
    DEFINE USB_RXLED       PORTD,2 ;  "      "     data being received from PC
    ADval    VAR WORD
    ;----[Initialize]-----------------------------------------------------------
    ADCON1 = %1101             ; AN0 and AN1 Analog
    ADCON2.7 = 1               ; Right justify A/D results
    T1CON = $31                ; Prescaler = 8, TMR1ON
    ;----[Main Program Loop]----------------------------------------------------
    Main:
        PAUSE 200
        ;--Read AN0--
        ADCIN 0, ADval
        ARRAYWRITE USBTXBuffer,[6,0,"0   ",DEC ADval,0]
        GOSUB DoUSBOut
        ;--Read AN1--
        ADCIN 1, ADval
        ARRAYWRITE USBTXBuffer,[6,0,"1   ",DEC ADval,0]
        GOSUB DoUSBOut
    GOTO Main
    ;----[USB - Handle received reports]----------------------------------------
    ; This is called from a low priority interrupt whenever a report is rcvd
    HandleRX:
        SELECT CASE USBRXBuffer(0)
            CASE "1" : SOUND PORTC.2, [100, 50]
            CASE "2" : SOUND PORTC.2, [120, 50]
            CASE "3" : TOGGLE PORTD.3
            CASE "4" : ; send string back to PC
              ARRAYWRITE USBTXBuffer,[5,"     ",STR USBRXBuffer(1)\USBBufferSizeRX-1]
              GOSUB DoUSBOut
        END SELECT
        PAUSE 100
    RETURN
    ;----[Timer1 interrupt blinks an LED]--------------------------------------
    TMR_DIV  VAR BYTE
    TMR1_ISR:
        TMR_DIV = TMR_DIV + 1
        if TMR_DIV = 12 THEN
            TOGGLE PORTD.3
            TMR_DIV = 0
        ENDIF
    @ INT_RETURN
    ;===[Generates false L.P. interrupt on USB received reports]=*===*===*===*=
    ASM
    USBRX_CHECK
        btfss    INTCON, GIEL           ; if low priority ints are available
        goto     Check_Done
        btfss    _Plugged               ;   and USB is connected
        goto     Check_Done
        btfss    _RX_READY              ;   and report has been received
        goto     Check_Done
        btfsc    _RX_Rcvd               ;   and the RX buffer is released
        goto     Check_Done
        bsf      USBRX_INT              ;   set the false interrupt flag
    Check_Done
      INT_RETURN
    ;
    USB_Receive
        ON_USBRX_GOSUB  _HandleRX
      INT_RETURN
    ENDASM
    Last edited by Darrel Taylor; - 19th August 2011 at 03:24.
    DT

  4. #4
    Join Date
    Jul 2009
    Posts
    15


    Did you find this post helpful? Yes | No

    Default Re: Problem with DT_HID (maybe!)

    Hi Darrel,

    I realised that there was no dedicated USB RX interupt, hence my problem, but that is a very nice little workaround.

    It works perfectly in my current setup and will no doubt be useful in the future. Thanks for all the help!

    Cheers

    Andy

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts