This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DM365 USB interrupt registers clarification required



Trying to figure out the interrupt status register for endpoint interrupts (not DMA) in the USB device mode. Looking at sprufh9a (USB Controller).

It seems as if the interrupt status bits are duplicated in registers INTSRCR and a TX/RX register pair INTRTX/INTRRX. Is this correct? The INTSRCR register description on p.87 mentions the endpoints status bits. The INTRTX/INTRRX description is almost the same, but it's not clear why would somebody come up with such an idea (duplicating interrupt status bits). Am I totally missing something here?

Also, the LSP driver code which I'm trying to use an an example makes references to Mentor Graphics USB (musb?), DaVinci, and other apparently different hardware platforms. Which one corresponds to the DM365?

Thanks for your help.

 

  • What's even more confusing is the fact that apparently interrupts could be enabled/disabled/masked in two different places.

    It seems that the LSP driver has some vague references to that in the comments ("workaround") but it would be nice to get some clarification.

    Anyone, please?

  • Hi,

    Sorry for the confusion. You are correct. Interrupt is handled 2 different ways.

    You can choose to handle interrupt directly from the USB Core, INTRUSB, INTRRX, INTRTX (all of these registers are byte wide). You need to insure that you configure CTRLR.UINT to 1 vice versa if you want to handle Interrupt from the Wrapper level and in this case you have clear CTRLR.UINT to Zero (PDR Interrupt handling is enabled).

    We suggest you confiure the USB Subsystem to handle interrupt at the PDR level.

    Since core level interrupts are byte wide and wrapper level interrupt register is 32-bit wide, we have aggregated all of the interrupts onto a single register.

    To use PDR interrupt, you will need to enable interrupt at both core and wrapper level.

    As you might have figured it out, we have one more interrupt bit that is resident on the wrapper level, USB_DRVVBUS, but is not present on the core level. This is because this functionality is built in outside the core. This interrupt is fired every time a state change on USB_DRVVBUS is present.

    The interrupt flags you are interested on are the general USB interrupts, like SOF, RESET, etc.

    The reason we have two sets of interrupt handling is because the Core is from Mentor and TI is embedding this core into our solution. TI has a standard way of handling interrupts. The way the core handle the interrupt is a bit hard to debug if problem occurs. TI way of handling interrupt allows you to have much control of interrupt handling. Reading the interrupt flag register will not clear an interrupt. You will have to clear it by writing another register. This is especially very important if you are about to be on the process of clearing an interrupt by reading the flag register and another interrupt happens to be registered right before you perform the read to clear the interrupt, guess what, your other interrupt is going to be lost. This happens a lot on a loaded system. That is the reason why TI way is the preferred way to handle interrupt and in this case allows you the option to  use either PDR method or non-PDR method.

    Let me know if you have specific question on this and I will get back with you with a reply.

    Best regards, Zegeye

  • Hi Zegeye,

    thanks a lot for your reply, that helps. I just want to clarify a couple of things.

    1. In my understanding, "handling interrupt at the PDR level", which you recommend, means setting CTRLR.UINT to 0 and using 32-bit registers (INTSRCR, INTCLRR, etc.) Is this corect? By the way, what is PDR?

    2.  You said "To use PDR interrupt, you will need to enable interrupt at both core and wrapper level." In my understanding enabling at the core level means I need to set bits in INTRUSBE register. However the USB manual says "Unless the UINT bit of CTRLR is set, do not read or write this register directly. Use the INTSETR/INTCLRR registers instead." (p.118). Could you please clarify?

    3. Interrupt masks: I'm used to a convention where "masked" interrupt means disabled. Is that true for INTMSKSETR/INTMSKCLRR? In other words, does setting a bit in INTMSKSETR disable a source of interrupt or enables it?

    I aapreciate your help.

    Regards,

    Alexander.

     

  • Hi Alex,

    You are welcome.

    1. Yes, that is correct. If you choose to use PDR interrupt, you should clear the CTRLR.UINT bit.

    PDR is a standard we use (Peripheral Development Requirement) that specifies as to how a peripheral needs to be developed and in this case the particular peripheral is the Interrupt controller.

    2. Yes, you are correct here too you have to enable it at the Core level (INTRUSBE, INTRRXE, and INTRTXE) and also at the PDR or Wrapper level which is INTMSKSETR.

    INTMSKSETR is interrupt Mask Enable and INTMSKCLRR is interrupt Mask Disable.

    E.g. to Enable Endpoint 0 Interrupt Enable.

    ==> Core level: INTRTXE.bit0 =1

    ==> PDR level: INTMSKSETR.bit0=1

    Endpoint 0 Interrupt Disable:

    **> Core level: INTRTXE.bit0=0

    **> PDR level: INTMSKCLRR.bit0=0

     You can inspect interrupt presence by looking into INTSRCR register, whether they are unmasked/enabled (using INTMSKSETR) or masked/disabled (using INTMSKCLRR). This is a superset of INTMASKEDR.

    Masked/Enabled only interrupt are available using INTMASKEDR register. This allows you to inspect only the interrupts you desire. This means it is a subset of INTSRCR.

    INTSETR and INTCLRR are mainly used for debug purposes. Suppose you want to set the interrupt that Endpoint 0 interrupt would set. Then you force it by setting INTSETR.bit0.

    All registers interrupt should be cleared by using INTCLRR register. Writing a 1 to the corresponding bit will clear the interrupt.

    *********************

    Having said that, once you have enabled interrupt at both Core and PDR level and CTRLR.UINT is cleared you only handle the interrupt at PDR level and you should not need to work with the core registers. You should also refrain from opening the core interrupt flag registers in a memory window so that you do not accidentally clear an interrupt.

    Within you Interrupt Handler, you should clear interrupt by writing the corresponding bit within INTCLRR register.

    You should then wrie a ZERO to EOIR register.

    The EOIR register would ensure that if successive interrupts are pending for the same event, it ensures that only one is serviced at a time and when you write ZERO to it, it will generate a new interrupt if there exist additional one.

    For this reason, you should always write ZERO to EOIR prior to exiting your ISR.

    Hope this clarifies it better.

    Best regards, Zegeye

     

     

  • Hi Alex,

    Sorry, I just realized that I have not replied to your 3rd question.

    3. Yes you are correct. Usually that is what it means when you have a single register to use to both enable (unmask) and disable (mask) interrupt. In our case, we have separated each Interrupt control capability to be controlled by separate registers.

    To Enable (unmask Interrupt) we use INTMSKSETR register

    To Disable (mask interrupt) we use INTMSKCLRR register

    E.g., if you hapeen to enable or unmask an interrupt at bit 0 location, you will have to set INTMSKSETR.bit0 (=1) and if you later want to disable the same interrupt at bit position 0, then you set INTMSKCLRR.bit0 bit (=1).

    Best regards, Zegeye

  • Hi there,

    After reviewing the above posts, I look for clarification of the following questions:

    1. When UINT=1, are all INTRTX/INTRRX/INTRUSB cleared on read ?

    2. Is the follow initalization flow supported and correct ?
     UINT=0
     INTMSKCLRR=0xFFFFFFFF to disable all interrputs
     UINT=1
     INTRTXE=INTRRXE=INTRUSBE=0xFF to route all core interrupts to wrapper
     dummy read of INTRTX,INTRRX,INTRUSB to clear all core interrupts
     UINT=0
     INTCLRR=0xFFFFFFFF to clear all interrupts
     Assert INTMSKSETR to enable interrupts of interest

    3. As a USB peripheral, which interrupt is asserted when connected to a host ?

    Thanks and regards,
    Yulin.
     

  • Hi,

    1. Yes, that is correct. You can handle interrupt from the core level using core registers l(ike INTRUSB, INTRTX, and INTRRX) or you can handle interrupt at the PDR level. When handling interrupt at the PDR level you should not read from core interrupt registers. All you to do is enable them when they are disabled.

    2. Yes to be exact but not clean. You do not need to set and clear UINT back and forth. The setting of UINT (0 or 1) does not inhibit or allow access to the core registers. The setting of UINT is present for the user to choose which set of interrupt registers to use. That is all.

    What I suggest is for you to clear UINT (set it to zero) and when enabling and disabling interrupt you will need to enable interrupt from both core side (INTRUSBE, INTRRXE, INTRTXE) and PDR side what ever those registers you listed above.

    3. When assuming the role of a Device/Peripheral, Reset interrupt is the first interrupt to wait for.

    Best regards, Zegeye

  • Hi Zegeye,

    2. I am confused.
       If PDR can do all when UINT=0, why do we have to assert the core INTR* registers besides assert PDR registers ?
       Since PDR is recomemded, my procedure enables all core interrupts to PDR and let PDR control the last mile to ARM INTC after this init procedure.
       Isn't it much simple (no need to write 2 registers for 1 interrupt) and robust (no interrupt lost) ?

    3. No interrupt is asserted for DM365 to respond the host before invoking the following procedures manually :
      reg_USB_POWER &= ~USB_POWER_SOFTCONN;
      reg_USB_POWER |= (USB_POWER_HSEN | USB_POWER_SOFTCONN);
       I checked, the setting of USB_PHYCTL should be fine.
       Please indicate more to check.

    Thanks & Regards,
    Yulin.

     

  • Hi,

    2. Not sure where the confusion comes from. PDR is a wrapper around the Core. It Iis NOT part of the USB core. What the PDR does is what you normally do when you work directly with the core. It will perform a Read and Write to the core registers in your behalf and it will place the data within its own registers. Once you enable interrupt at the core level using your initialization routine, you DO NOT need to touch the core registers.

    3. You have to set the SOFTCONN bit when operating as a peripheral. If you do not do that, it is like you have not plugged the cable. This is a means of performing connect/disconnect via s/w.

    Best regards, Zegeye

  • Hi Zegeye,

    2. uh... so does the below simplified procedures follow the HW design ?
       Does 2.5 is enough and 2.4 can be skipped ?
       2.1 UINT=0
       2.2 INTMSKCLRR=0xFFFFFFFF to disable all interrputs in PDR level
       2.3 INTRTXE=INTRRXE=INTRUSBE=0xFF to enable all interrupts in core level
       2.4 dummy read of INTRTX,INTRRX,INTRUSB to clear all interrupts in core level
       //hereafter, only PDR is enough for all interrupted-associated control/monitor
       2.5 INTCLRR=0xFFFFFFFF to clear all interrupts
       2.6 Assert INTMSKSETR to enable interrupts of interest

    3. Do you mean SOFTCONN must be asserted, despite of host is ON/OFF or cable is connected/disconnected,
       and wait for RESET interrupt as a signal to start handshake with the host ?

    Thanks & Regards,
    Yulin.

  • Hi,

    2. Step 2.5 does what step 2.4 would do. So, it is not necessary. Btw, when the Host invokes a RESET condition, the core interrupt registers would be enabled automatically. The enable part of the core interrupts can even be skipped but good to have if you might plan to use most of your initialization code for a Host configuration.

    3. Yes SOFTCONN must be asserted. Like I mentioned in my previous email, if this bit is not set it is as good as not connecting a cable to your connector and is independent of Host state/status. The Host would only perform a RESET if it sees a Device on the bus. If SOFTCONN is cleared the Data Lines are disconnected and the Host will not be able to see the Device.

    Best regards, Zegeye

  • Hi,

    I did not say this explicitly on my previous email. Remove step 2.4.

    Best regards, Zegeye