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?

     

    Answer:

    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.

    C:
    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
      mov X, USBFS_5V_OPERATION
      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:
    USBFS_3V_OPERATION: 0x02
    USBFS_5V_OPERATION: 0x03

    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.


    USB_RESET_ISR:
           push   A
           push    X
           M8C_SetBank1
           mov  A, reg[USB_USB_CR1]          ; Get the RegEnable
           M8C_SetBank0
           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
    RETI

    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.


    Fix:

    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

    IF  STD_USB_RESET
    ELSE
        push    A
        push    X
        ISR_PRESERVE_PAGE_POINTERS
        M8C_SetBank1
        mov        A, reg[USBFS_1_USB_CR1]                ; Get the RegEnable
        M8C_SetBank0
        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
        RAM_RESTORE_NATIVE_PAGING
        lcall   _USBFS_1_Start     ; Restart USB
        ISR_RESTORE_PAGE_POINTERS
        pop X
        pop A

    ENDIF

       ;---------------------------------------------------
       ; 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.