Token Done Interrupt in MCF52223 USB OTG Controller

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Token Done Interrupt in MCF52223 USB OTG Controller

4,355 Views
SetAlias
Contributor I
Hi Tech's,
 Presently we are working on MCF52223 USB Device controller.After RESET we configure the Endpoint 0 for receieving the Setup packet, for that we set  Endpoint Control Register 0 = 0x0D.
After that in BD Byte format we set BC(bit 16:25) as 64 as Max. Packet Size and Enable the DTS bit for synchronization purpose , both Even and ODD bank. For Sending DATA  we set as all BD Byte format as 0. In Initialization part we set the BDT Base address in PAGE0,1,2 registers.
 
After that we  enable the TOKEN_DONE bit in INT_ENB register to get the interrupt. But we are nit getting the TOKEN_DONE interrupt, when we see the INT_STAT register.
 
Our main problem is why we are not getting the TOKEN DONE interrupt.
Labels (1)
0 Kudos
9 Replies

582 Views
RichTestardi
Senior Contributor II
> Our main problem is why we are not getting the TOKEN DONE interrupt.
 
Did you enable the interrupt at the interrupt controller, as well as the usb INT_STAT?
 
I do:
 
    // enable usb interrupt
    __VECTOR_RAM[117] = (uint32)usbisr;
    MCF_INTC0_ICR53 = MCF_INTC_ICR_IL(SPL_USB)|MCF_INTC_ICR_IP(SPL_USB);
    MCF_INTC0_IMRH &= ~MCF_INTC_IMRH_INT_MASK53;  // usb
    MCF_INTC0_IMRL &= ~MCF_INTC_IMRL_MASKALL;

And then, of course, you need to enable CPU interrupts if you have not yet:
 
I call splx(0), below:
 
  // set the current interrupt mask level and return the old one
  static
  int
  splx(int level)
  {
      short oldlevel = 0;
      level = (level & 7) << 8;
      // enable cpu interrupts
      asm {
          move.w sr,d1
          move.w d1,oldlevel  // get the old level from the sr
          and #0xf8ff,d1
          or level,d1  // insert the new level into the sr
          move.w d1,sr
      }
      return (oldlevel >> 8) & 7;
  }

 
I have a simple host mode driver working with interrupts just for device attach at:
 
 
if you want to see it...
 
I also had one issue with interrupts working in the INTERNAL_FLASH and CONSOLE_RAM configuration, but not RAM, which I traced to a difference in the Linker Entry Point settings...  I now use _asm_startmeup from the coldfire stationery (rather than start) exclusively, so I can see what is going on and change it...
 
-- Rich T
0 Kudos

582 Views
SetAlias
Contributor I
Hi Rich,
              Thanks for your reply.
               Our mistake is we haven't configured the PLL clock divider for the USB.Initilally we created the project with Console debug mode. When we enter into the debug mode ,the debug cursor was placed at main(), before that "mcf5222x_init ( )"  hardware initlization was completed.But it was not that what we think.Now i changed the linker entry point as you said.
 
Now Iam getting the TOKEN_DONE interrupt, but when i read the BDT attributes with Endpoint number from STAT register, we got " 0x00400088" which was configured for the Even bank. We configured the BDT buffer address with 8 bytes of global array for the setup packet.
 
for the first time only we have to see the  BDT attributes with "0x0080034" value.
 
I have so many doubts regarding the Code warrior IDE after creating the project.What is the use of  "mcf5222x_vectors.s" file in which USB Interrupt Service Routine(ISR) was already configured, but when the interrupts are enabled for USB, we haven't seen the printf statements in the function.Once again we have to configure from the main function.
 
We are attaching our code for our unknown mistakes, in which "MCF52223_BusNotify()" for RESET, if we uncomment the  line MCF_USB_INT_ENB = MCF_USB_INT_ENB_TOK_DNE; we are getting the attributes for Setup packet , but if  we comment we are getting the attributes what we set.Insted of uncomenting if we OR the TOKEN_DONE interrupt then for INT_ENB register , we are not getting the attributes for setup packet.
 
                               Thanks for your reading.
0 Kudos

582 Views
RichTestardi
Senior Contributor II
Hi,
 
> Now i changed the linker entry point as you said.
 
I also had to change the cw project wizard's PLL initialization code, which was running my 66 MHz part at 80 MHz! :-)  So I decided to eliminate everything that was unnecessary from my initialization sequence created by the cw project wizard, and am left with just the attached files if you want to see them -- the linker entry point is still _asm_startmeup.  This reduces code bloat (printf(3) is huge and makes RAM debugging almost impossible for all but the smallest program!) and makes it a lot easier for me to follow what is actually going on!
 
> What is the use of  "mcf5222x_vectors.s" file ...
 
From what I can tell, the only purpose of this is to set the initial startup vectors and flash configuration information.  Once these are used, everything else is copied to and used from RAM.  You can see from my code that all vectors except 0 and 1 (initial sp and pc) simply "halt", so they are simply unneeded.  I then patch the RAM values in my boot sequence, so I have a consistent model for when running from either FLASH or RAM (which has the quicker debug cycle, though you can typically only debug a subset of your code because of the 16k/32k limitation).
 
As for your code, just looking at MCF52223_EnableEndpoint(), it seems you might be confusing the two separate "toggles"...  One "toggle" is the even/odd selector for the BDT to allow concurrent outstanding commands, and the other is specified by USB for data0/data1 phase sequencing.
 
In your code, when you reset the BDT data toggles:
 
  void  MCF52223_ResetBDT (void)      
  { 
      CPU_INT08U  idx;
                                             /* RESET All BDT ODD bits to zero                        */ 
      MCF_USB_CTL |= MCF_USB_CTL_ODD_RST;
      MCF_USB_CTL &= ~MCF_USB_CTL_ODD_RST;
     
      for (idx = 0; idx < MCF52223_MAX_EPS; idx++) {
          EpInf[idx] = 0;
      }
  }
 
You reset EpInf[] to 0.  This would lead me to believe EpInf is the even/odd BDT toggle (not the data0/data1 toggle).  But then later you use EpInf as the data0/data1 toggle (*not* as the even/odd toggle):
 
  void MCF52223_EnableEndpoint (CPU_INT08U  ep_addr, CPU_INT08U  odd_bnk)
  {  
    CPU_INT08U  data_tgl_bit;
    CPU_INT32U  bdt_attr;
  
     data_tgl_bit = GET_DATA_TOGGLE(EpInf[EP(ep_addr)]);    
  
     bdt_attr = BDT_Read(BDT_BASE_ATTR_CORE(ep_addr, odd_bnk));
  
     if (EP_DIR(ep_addr)) {
       bdt_attr &= ~(0xFF);
     }
  
     bdt_attr |= (MCF_BDT_CTL_OWN | data_tgl_bit | MCF_BDT_CTL_DTS);  
  
     BDT_Write(BDT_BASE_ATTR_CORE(ep_addr, odd_bnk), bdt_attr);
  }

To my understanding, these two toggles should be managed completely independently...  Setting MCF_USB_CTL_ODD_RST should *not* change the data0/data1 toggle state, and a new setup transaction should not change the BDT even/odd toggle state.
 
The even/odd toggle is used *only* as a parameter to what you call "bnk" in BDT_BASE_ATTR_CORE() and BDT_BASE_ADDR_CORE().  For a host USB driver, there is only one of these since you only use endpoint 0.  It is reset when you set MCF_USB_CTL_ODD_RST.
 
The data0/data1 toggle, on the other hand, is used as a parameter to what you call "val" in BDT_Write() and BDT_Read().  There is one of these per logical endpoint.  It is set to data0 for a setup transaction and data1 for a status transaction.  It is reset at various times called out in the spec, most notably on a configuration event on a bulk endpoint.
 
If you want to check out when I toggle, you can see my code (http://www.testardi.com/rich/coldfire/) and search for "toggle" to see the USB-specified data0/data1 toggle, and "bdtodd" to see the coldfire USB module hardware BDT odd/even toggle.
 
-- Rich
 
0 Kudos

582 Views
SetAlias
Contributor I
Hi Rich, Thanks for your reply.
              The problem why we are not getting the correct BDT attributes when setup packet is received because of more "printf" statements.Now we reduced the unnecessary code and modified according to your notes.
 
Let me explain what we understood about BDT banks , Data toggle bits and How EpInf[ ] is using in our code.
 
For Each endpoint in one direction it has two banks one is Even and other is Odd bank. For Each bank we have two Toggle bits Data0 and Data1. Is it correct? Let me know.
 
EpInf[ ] has the following bits:
/*
  EpInf:
  7   6   5   4   3   2   1   0
----------------------------------
|   | DT|   |   |E/O|   |   |   |                 bit 3: Even and ODD bank. bit6: Data0/1 toggle bit
----------------------------------
*/
 
In MCF52223_EnableEndpoint (CPU_INT08U  ep_addr, CPU_INT08U  odd_bnk) , we are reading the data toggle bits, from a particular bank with argument "odd_bnk = EVEN or ODD Bank".

The parameter 'bnk 'in BDT_BASE_ATTR_CORE() and BDT_BASE_ADDR_CORE() is for EVEN and ODD bank only.

The parameter 'val 'in BDT_Write() is for Bdt  attributes only.

Now the EpInf[ ] is used for both banks and toggle bits.

Now we are added some code for enumeration purpose, in which host asking for 18 bytes for device desriptor and we are sending the 18 bytes and waiting for Status out, but we are getting the RESET event.

we are attaching the code.In the code "SetupFlag " is modifed in 

MCF52223_WriteEndpoint( ),MCF52223_EndPoint0IN( ),MCF52223_EndPoint0OUT( ) and in MCF52223_EpOpen( ).

Even and Odd Banks are changed in MCF52223_EndPoint0IN( ),MCF52223_EndPoint0OUT( ) .

Data toggle bits are chnaged in MCF52223_EndPoint0IN( ),MCF52223_EndPoint0OUT( ) with SetupFlag value.

Thnaks for reading.

0 Kudos

582 Views
RichTestardi
Senior Contributor II
Oh, sorry, I totally missed you were storing two different things in EpInf[]! :smileyhappy:
 
So, in MCF52223_ResetBDT(), I don't believe you should be clearing bit 6 (only bit 3), since bit 6 is USB protocol state unaffected by MCF_USB_CTL_ODD_RST, though I doubt that is the source of your problem since you probably only call that on boot...
 
-- Rich
 
0 Kudos

582 Views
SetAlias
Contributor I
Hay Rich,
                Our USB Device stack is working.The problem  with the "MCF52223_GetBnk( )" function logic, where every time we are writing the data on same bank,so we changed the logic and it's working now.
 
  Can we get any  RTOS for Code Warrior IDE 6.7 ?
 
  Now we are getting one more problem, where we removed the unneccssary code which we get when project was created ,and added our stack. When we running the program in Debug mode we are getting unexpected exception mostly BUS Errors in our code.The BUS Error was not at same code,that we can't say where it will be happen.
 
we have "M52223EVB_SRAM.lcf", in this file we added the below lines:
 
MEMORY {
 vector_ram (RWX) : ORIGIN = 0x20000000, LENGTH = 0x00000500
 usb            (RW)    : ORIGIN = 0x20000600, LENGTH = 0x00000200
 user          (RWX)   : ORIGIN = 0x20000800, LENGTH = 0x00007B00
 ipsbar       (RWX) :   ORIGIN = 0x40000000, LENGTH = 0x0
}
 
 
.usb_bdt:
    {
       . = ALIGN (0x200);
   
    } > usb
 
__USB_BDT_BASE  = ADDR(.usb_bdt);
 
After this we modified as you noticed like program entry point and in"mcf5222x_vectors.s", all the vectors are replaced by "asm exception handler", and in initialization "mcf5222x_init( )" part we didn't modified but kept as it is.
 
Why we are getting so many BUS Errors?
Many many thanks for your input....
 
0 Kudos

582 Views
RichTestardi
Senior Contributor II
Hi,
 
It's hard to say where a random bus error comes from -- my guess is you are corrupting memory somewhere, or playing with memory while hardware (or isr) is looking at it, or something...
 
Can you try disabling different pieces of your software and seeing when the problem goes away?
 
-- Rich
 
0 Kudos

582 Views
SetAlias
Contributor I
Hi Rich,
            Ok we will test the code in pieces .Can you tell me how to program the flash memory in MCF52223 EVB, (Flash Memory = 256KBytes )What are the settings we have to change in *.LCF files and settings in the IDE.
How can I know that my program is flashed to RAM or FLASH memory.
0 Kudos

582 Views
RichTestardi
Senior Contributor II
Hi,
 
> Can you tell me how to program the flash memory in MCF52223 EVB,
> (Flash Memory = 256KBytes )
 
I just use "Tools->Flash Programmer" and then click "Load Settings" and
select "CFM_MCF52221.xml" -- I assume you'd select "CFM_MCF52223.xml"
instead.  Then just click "Erase / Blank Check" and then "Erase" and it
should do the work for you...  And then "Program / Verify" and "Program".
(Of course, that is after selecting the INTERNAL_FLASH target and doing
a build...)
 
> How can I know that my program is flashed to RAM or FLASH memory.
 
I have two targets in my project, INTERNAL_FLASH and RAM -- if I select
INTERNAL_FLASH, I can use the flash programmer and then debug from
flash; otherwise, if I select RAM, I run directly from RAM.
 
Hopefully that will work for you -- I didn't need to edit any linker config files.
 
-- Rich
0 Kudos