1.29.2007

ISP1582 Interrupt Handler - BRST

由polling mode轉移到interrupt mode :

interrupt 發生的順序依次是..
  1. VBUS
  2. RESUME (don't care)
  3. RESUME + SUSPEND (don't care)
  4. BUS RESET
  5. HS_STATE (High Speed State Change)
  6. EP0SETUP (reveiced)
其中由BUS_RESET 到HS_STATE比較多動作要作,也就是說,在interrupt handler中,處理 BUS RESET 中斷時,比較多事情要作,如果沒做好,下一個 HS_STATE就不會進來..

參考data sheet,所有register 除了一般的Reset, Access外,還有一個"Bus Reset"。
代表該bit 在 Bus reset後的狀態 (數值,或是unchanged)。

重要的幾個register :

Mode Register
  • CLKAON : core clock always ON。這個bit在bus reset後會被clear to zero。
    clock always on 跟 unlock 動作有關。ISP1582 內部有一個省電功能的timer,當有一段時間沒有access chip,他會自動timeout,這時候,在access chip register之前,要先寫入unlock register,啟動PLL。
    所以如果沒有將CLKAON社為1。進入interrupt handler之前就要先unlock。
    如果有將CLKAON設為1,就不需要unlock。
    這個bit在bus reset後會被clear,所以要重新設定。
    *為了怕麻煩,還是設定得好。
  • WKUPCS : 這個...是設定"只要chip select有動作,就自動wakeup chip"。
    Bus Reset後會被clear,sample code有設為1。
Interrupt Enable Register
  • 除了IEBRST外,其他bit在Bus Reset後都會被清除,所以在bus reset後一定要重新設定。
Interrupt Configure Register
  • 除了interrupt level , polarity 在bus reset後依然維持不變外,其他bit都會被set。一般要設成0x54,所以Bus Reset後應該要重新設定過。
Endpoint -
  • Endpoint 在Bus Reset後會reset,所以所有Endpoint設定都要重新設定一次。
還有一個很重要的就是在進入真正處理 interrupt 的code之前,要先將ISP1582的 interrupt enable disable,等到所有狀態都處理完後,要退出interrupt 之前,再打開。
=>否則不會再進入中斷..很奇怪。
也就是說 interrupt handler的code 大概是..
void __irq EInt_Usb(void)
{
ModeReg &= ~bGLINTENA;

... //handle int event here
...
...
Ack_EInt( );

ModeReg |= bGLINRENA;
}

其他奇怪的現象:
  • 有時候發生interrupt,讀取 interrupt register卻發現是0x00 (沒有中斷原因)。
  • BRST (Bus Reset) handler沒寫好(完全),使用multi-ice test run。一次可以發生HS_STATE interrupt,一次不行。
  • 使用ICE在BRST處設break point,可以正常產生 HS_STATE 中斷,將BRST的斷點移除,HS_STATE就不會發生。 ==> 這是因為interrupt handler沒有作UNLOCK,或是在BRST handler中沒有將 Mode Register的 CLKAON 重新set 。
    或是因為在ICE中 EP0SETUP 發生後,沒有繼續run 下去,完成interrupt 的後續動作,可能是因為 ISP1582 hardware reset 不完全所以re-run沒有辦法再進入中斷,要下一次才行。

沒有留言: