enCoRe III design fails USB compliance, specifically signal rate in the electrical test

Version 1
    Question: enCoRe III design fails USB compliance, specifically signal rate in the electrical test. Is there a fix implemented for this?



    Yes, the firmware fix requires changes to be made to the USB_RESET ISR. This issue is only seen when using PSoC Designer versions 4.3 and above and below PSoC Designer 5.1 FCS.  From PSoC Designer 5.1 FCS, this issue has been fixed in the user module itself.

    Cause: The USB_Start function uses 2 parameters, USB Current Device and Supply voltage setting.

    void USBFS_Start(bDevice, bMode)
       bDevice: Current device(if only 1 device : 0)
       bMode: Supply voltage level: 3V or 5V

    Assembly: Accumulator holds current device and X holds voltage setting
      mov A, 0
      call USBFS_Start

    The defines for supply voltage setting (5V and 3V) also contains bit setting for a 'Enable Lock' feature. This 'Enable Lock' feature is what aids the internal oscillator (IMO) to lock onto incoming USB traffic and improve its accuracy to +/-0.25% of 12MHz. USB specification also requires full-speed devices to clock with this accuracy.

    #define values for:

    Bit [1] in this setting is what holds the ?enable lock? bit. Bit [0] is to enable the PHY regulator (5V to 3.3V) when operating with 5V supply voltage. This byte is written to reg[USB_CR1] at location 1,C1h in the USB_Start function. So, initially when this function is called the ?Enable Lock? bit is set.

    However, all USB hosts issue a 'USB Reset' after they detect connection and after getting the device descriptor. This is a part of the enumeration process. The standard/default USB Reset ISR has a call to USB_Start, but we fail to pass the 'lock bit' setting before we call USB_Start. The ISR code checks to see if we are operating at 3V or 5V, but clears the 'Enable Lock' setting before it loads this value to register 'X' to be used by USB_Start.

           push   A
           push    X
           mov  A, reg[USB_USB_CR1]          ; Get the RegEnable
           and  A, 0x01                         ; mask off the RegEnable bit
           mov  X, A                            ; save value in X
           mov     A, [USB_bCurrentDevice]     ; Select the current device
           lcall   _USB_Start     ; Restart USB
           pop X
           pop A

    The highlighted line shows that the value read out of reg[USB_CR1] is masked for only bit[0] before passing the value to register X.


    The fix involves modification to the Standard USB Reset ISR - Ensure that the 'lock bit' is set in the USB Reset ISR before calling USB_Start.

    To ensure the changes are not wiped out when a 'Generate Application' is done, paste the below code fragment in the protected section(Between the lines - Insert your custom code below this banner & Insert your custom code above this banner) of the USB_RESET_ISR in the usbfsint.asm file (under library source).

    Make sure the default STD_USB_RESET:    EQU     1 is equated to '0' in the ISR (This is already done in the below code snippet).

     ;@PSoC_UserCode_BODY_USB_RESET@ (Do not change this line.)
       ; Insert your custom code below this banner
       ;   NOTE: interrupt service routines must preserve
       ;   the values of the A and X CPU registers.

    STD_USB_RESET:    EQU     0 ; Set this equate to 0 to remove the standard
                                ; USB reset handling code below

        push    A
        push    X
        mov        A, reg[USBFS_1_USB_CR1]                ; Get the RegEnable
        and    A, 0x03                                    ; mask off the RegEnable and EnableLock bits
        mov    X, A                                       ; save value in X
        mov     A, [USBFS_1_bCurrentDevice]               ; Select the current device
        lcall   _USBFS_1_Start     ; Restart USB
        pop X
        pop A


       ; Insert your custom code above this banner
       ;@PSoC_UserCode_END@ (Do not change this line


    NOTE : This fix is applicable only for enCore-III Devices and not required for enCore-V devices.