ChamberPlus System Level Studio

  首頁 | Contact to us

 

News
Products
FAQ
Technicality
Links
OldNews

互動區:

留下您的足跡

想討論嗎?

 

Q: 在什麼情況之下會使用suspend state ?
 

A: 關於USB Suspend 這一類的問題是有點牽涉到USB 硬體觀念的東西,因為許多人作USB 的東西,一開始都會浸淫在韌體與通訊協定上,就很容易忘了這一類的問題。也搞不太清楚這部分要做什麼?!關於 Suspend 有關的名詞有:

Suspend : 不會翻譯,就是要讓USB裝置處於『待命』狀態。在『待命』狀態下,USB Host 不會對您再發任何 Protocol 的東西,包括SOF !既然稱為『待命』,就是要隨時會回   到原來狀態。

Resume : 就是『喚醒』,什麼『喚醒』?就是叫USB 裝置從『待命』再回到原來狀態。

Remote Wake-Up : 也是『喚醒』!那他跟 Resume 有什麼不一樣?!Resume 是由PC Host 主機叫醒 USB device 的;而Wake-Up 是由 USB Device 叫醒 PC Host 主機的。

    前面兩個主控權,當然是在PC Host 囉,但是,Wake-Up 卻必須在USB device 裝置插入主機時,在Device configuration 時,就必須宣告,然後主機才會支援。以簡單的規格的通訊協定來說,就是這麼一回事。

    但是在硬體上,就有額外一層意義了。USB 規格規定:所有的USB Device 裝置都必須支援Suspend 規格(什麼是支援Suspend ?就是在韌體上,USB Controller 也必須接受到Suspend 訊息,就是中斷的意思啊∼待會兒我就用韌體說明!),而且在進入 Suspend 時,整個USB Device耗電必須低於 500uA 。您一定覺得,這個規格很簡單?!哈∼哈∼ 我們就簡單推算一下吧:

因為若您的USB 裝置是高速裝置的話,您的 D+ 會Pull-high 1.5K ,然後因為經由南橋一個內阻到GND,所以,會有一個約 220uA 的基本耗電。又因為 USB 供電是5.0 VDC,您還是需要一棵整流IC將 5VDC 轉成3.3VDC。一般這種IC都屬於Linear regulator 型的,他的基本內耗也都是100 uA 級的,以前我用過類似立錡科技的Switch 型的如9262 ~結果是:他本身耗34uA+Feedback 5uA+ CE 那根控制線約 12 uA 所以是 51uA ~ 因為又要拿來偵測USB插入狀態,所以,又用掉一根 Pull-high pin ~ 約50uA 就是  100 uA + 基本220uA= 320 uA 了。當然,您若要支援 Remote wake-up 的話,您還是用一根 I/O 來當 Push-button也會有額外的耗電了。所以,您當然是不可能點LED燈號了。 所以在電路設計上就要小心了。有沒有看過電影『阿波羅十一號』?!您就會有那種感覺了就是了。

        那在韌體上要如何處理呢?!就以我  USB ROM Emulator 來說明吧:

    一般USB Controller 硬體設計上,收到 USB Bus 上Suspend 訊號時,(譬如PC 主機不是關機,而是進入『待命』時,或是裝置移除時,就會收到這個訊號∼)都會發一個中斷給您的韌體,此時,您的程式寫法就得如下所示:

_Suspend6816: ;; b7:R51, b6:Reversed, b5:6803, b4:Low Speed,
                    ;; b3:PLL Clock, b2:PLL, b1:6802, b0:M2
;;------------------------------------------------------------------------------
        USBPowerOff

        ;; 所有的I/O 都必須切到最省電方向!

        CLRP2 USBDevCtl ;; disable suspend/resume timer(detect suspend/resume event in USB bus)
;------------------------------------------------------------------------------
        REG_WR SCR, #00000001b ;; M2
        orl A, #00100011b ;; M2,6802,6803
        movx @DPTR, A
        orl A, #00110011b ;; M2,6802,6803,LS
        movx @DPTR, A
        orl A, #00111111b ;; M2,6802,6803,LS,PLL
        movx @DPTR, A
        mov C, MD6Init_ ;;
        mov A.6, C
        orl A, #10111111b ;; M2,6802,6803,LS,PLL,51
        movx @DPTR, A

        ;;<---------- 程式停在此處!   
        ;;
        ;; into Suspend mode wait USB K State or WakeUp Low -> High
        ;; Now Power <= 2.5 mA
        ;;
        ;; REG_WR SCR, #00110011b ;; PLL Enable
        anl A, #00110011b
        movx @DPTR, A
        ;;
        ;; Wait PLL stabe
        ;;
        mov R0, #2 ;; Delay 2*400uS=800uS
SysSuspend029:
        mov R1, #238 ;; Delay 400uS
        djnz R1, $
        djnz R0, SysSuspend029

        ;; REG_WR SCR, #00100011b ;; High Speed
        anl A, #00100011b
        movx @DPTR, A
        anl A, #00000001b
        movx @DPTR, A
        clr A
        movx @DPTR, A
SysWakeUp:

        REG_RD ASR
        jnb WakeupInit_, SysSuspend030
        cpl A.7
SysSuspend030:
        jnb A.7, SysSuspend050

        USB_K_State
        mov R0, #4 ;; Delay 4*50uS=200uS
SysSuspend040:
        mov R1, #238 ;; Delay 50uS
        djnz R1, $
        djnz R0, SysSuspend040

SysSuspend050:
        USBNormal

        REG_RD USBDevCtl ;; suspend/resume timer(detect suspend/resume event in USB bus)
        setb A.2
        movx @DPTR, A

        ret

 

        這段程式,沒什麼意思,只有兩個重點:第一:收到Suspend 後要利用韌體,把硬體上的耗電切成最省電方式,(I/O 盡量不要有Output 狀態!)然後,就是把USB  Controller 內部會耗電的部分也一併關掉∼諸如:記憶體啊∼PLL啦∼等等:重要的是:連8051自己都得關掉!!哈∼哈∼所以,程式就停在原點∼當硬體收到 Resume 時,自然就會往下跑∼所以,有些人程式寫不好,就會一覺不醒了。哈∼哈∼或許,每一家USB Controller 的設計都不一樣,但是,奇怪的是:我玩過兩家的最法都是一樣的∼因為大家設計 USB Controller 都沒把握可以作到很省電,所以乾脆讓 8051 直接停下來最省電∼(其實,8051 是很耗電的∼這點大家都知道!)不信的話:看另一個程式:

void USB_Intr_Suspend_Process() USING_1
{
        // printf("sleep\n");
        _G_USB_Setup_Interrupt1 = 0; // Clear flag for Enable LCD_Reset Controller
        LCD_Reset();
        _G_USB_Setup_Interrupt1 = 1; // restore the flag for USB status !
        DbgP15=0;//turn off DAC OP Power
        DbgP16=1;//A LED OFF MP3 Mode
        DbgP17=1;//B LED OFF DVR Mode
        TIMER0_Stop();
        XBYTE[0x25d0] |= 0x80; //Enable interrupt for Resume
        CPUIO_PushState();

        USB_Suspend_Process();   


        XBYTE[0x2050]|=0x04; // Enable Wake-Up !

        XBYTE[0x2003] = 0x01; //Suspend       
///程式也是停在這裡!!哈∼哈∼
        //----------------------------------------------------
        //wakeup
        XBYTE[0x2003] = 0x00; // Suspend Normal
        XBYTE[0x2010] = 0x1e; //Close 48MHz Clk
        CPUIO_PopState();
        XBYTE[0x2050]&=0xfb; // Enable GPIO.2(Wakeup)
        // XBYTE[0x2050]&=0xbf; // Disable GPIO Intr.
        XBYTE[0x2048]=0x00; // Clear GPIO intr Event
        XBYTE[0x2040]&=0xbf; // Clear GPIO intr Event
        XBYTE[0x25d0] = 0x37; //Disable interrupt for Resume/Enable Supsend Intr
        //----------------------------
        DbgP15=0;//turn on DAC OP Power
        Charge_Pin=1;

        XBYTE[0x2010] |= 0x01; //DSP Wakeup
...

        至於Resume 這個中斷∼有些USB Controller 也會提供,但是好像用到的機會不多,因為就如同上述的程式所示∼程式都自己醒來,執行Resume 程式了∼還要進入  Resume 中斷要做什麼?!

        其實,當您完成一個 USB Device 之後,您自己可以用一個電表量一下,您USB 裝置有沒有達到USB的規格。還有 讓主機進入 待命狀態,然後,在鍵盤上隨便按個鍵,把主機叫醒,看您的USB Device 醒不醒得過來?!很好玩喔∼這是需要一點調教功力的。作不好,還得改硬體電路的。

        當然,這部分還有許多值得討論的空間,改天我在用一些實際範例,拍一些照片來說明的。譬如:您的USB Device 是 Self-Power 呢?還是 Bus-Power ?!還可利用USB POWER來作充電器等!

        謝謝各位的指教!

首頁 | News | Products | FAQ | Technicality | Links | OldNews

Telephone : 886-3-5439918    FAX : 886-3-5437632

Copyright(C) 2005 . ChamberPlus System Level Studio All rights reserved.  Last Update: 2008年01月18日。