0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

使用MM32F0270 USB從Suspend模式喚醒

jf_pJlTbmA9 ? 來源:靈動MM32MCU ? 作者:靈動MM32MCU ? 2023-09-26 16:39 ? 次閱讀

在許多的PC的USB應(yīng)用中,越來越多的需要使用低功耗功能,PC可結(jié)合USB提供一定的供電能力,使得外設(shè)在1.5W以內(nèi),可以不用其他單獨的外部供電;更巧妙的是PC可以進入Sleep,驅(qū)使USB外設(shè)也進入Suspend狀態(tài),達到只提供2.5mA的供電需求,以達到低功耗的目的。靈動微電子推出的MM32F0270系列,支持多種靈活的低功耗模式,支持Suspend模式的USB Device模塊。USB外設(shè)支持 USB掛起 /恢復(fù)操作,可以通過停止MCU時鐘來實現(xiàn)降低功耗。

當USB設(shè)備處于掛起狀態(tài)時,它仍然為其D+或D-及上拉電阻器供電,以保持空閑狀態(tài)并保持其內(nèi)部狀態(tài),包括地址和配置。當它被USB總線上的恢復(fù)信號喚醒時,它不需要經(jīng)歷重新枚舉過程。

USB總線上的恢復(fù)信號可以由主機和設(shè)備發(fā)送。遠程喚醒功能使USB設(shè)備能夠喚醒掛起的主機;例如,將鼠標連接到筆記本電腦時,您可以通過單擊鼠標來喚醒已經(jīng)進入睡眠狀態(tài)的筆記本電腦(PC端需要配置為支持遠程喚醒)。遠程喚醒功能在枚舉階段在配置描述符中報告,并且可以使用標準 USB 請求啟用(或禁用)。

本文介紹了如何使用 MM32F0270的USB來實現(xiàn)通過接收USB的D+/D-信號在實現(xiàn)Suspend/Resume的狀態(tài)轉(zhuǎn)換。

1、MM32F0270 USB的簡要介紹

符合 USB 2.0全速設(shè)備的技術(shù)規(guī)范;

支持全速模式(12M)

包含四個獨立的通用端點和一個控制傳輸端點用于中斷傳輸和批量傳輸

控制、批量 、 中斷傳輸 最大可傳輸 64字節(jié)的包

CRC生成 /校驗, NRZI編碼 /解碼和位填充

支持 USB掛起 /恢復(fù)操作

支持 DMA傳輸

poYBAGIPK7yAVVvyAACZ9vN0WK4582.png 圖1 USB的功能框圖

2、USB的功能特性

2.1、MM32的USB具有以下特性

USB模塊可以為PC主機和微控制器提供一種符合USB規(guī)范的通信連接,用于兩者所實現(xiàn)的功能之間的連接。PC主機和微控制器之間通過數(shù)據(jù)緩沖區(qū)完成數(shù)據(jù)傳輸,USB模塊與PC主機通信,根據(jù)USB規(guī)范完成對令牌分組的檢測,對數(shù)據(jù)發(fā)送/接收和握手分組的處理。由硬件完成對包括CRC的生成和校驗等整個傳輸?shù)母袷?。每一個端點都有一個64字節(jié)緩沖區(qū)描述塊,且該緩沖區(qū)是在USB模塊內(nèi)部,不能直接被CPU訪問的。一個有效的功能/端點的令牌分組被USB模塊識別,當端點已配置完成后發(fā)生相關(guān)的數(shù)據(jù)傳輸。USB模塊與專用數(shù)據(jù)緩沖區(qū)的數(shù)據(jù)交換通過內(nèi)部寄存器完成。在所有的數(shù)據(jù)傳輸完成后,根據(jù)需要的傳輸方向,發(fā)送或接收適當?shù)奈帐址纸M。

數(shù)據(jù)傳輸完成時,USB模塊會觸發(fā)端點相關(guān)的中斷,通過讀取狀態(tài)寄存器或利用不同的中斷處理程序,可以確定:

主機請求的傳輸類型

哪個端點需要得到服務(wù)

正在進行的是哪種類型的服務(wù)

端點的應(yīng)答

傳輸是否完成

USB模塊在不工作時,可以通過配置USB_POWER寄存器使 USB模塊處于SUSPEND模式(低功耗模式)。USB模塊在低功耗模式下,USB時鐘會減慢或停止且USB模塊不產(chǎn)生靜態(tài)電流功耗。USB模塊在低功耗模式下,可以通過USB線上數(shù)據(jù)傳輸將其喚醒,也可以通過軟件直接將其喚醒?;蛘咄ㄟ^將特定的中斷輸入源連接到喚醒引腳上,使系統(tǒng)立即恢復(fù)正常的時鐘,可以直接啟動或停止時鐘系統(tǒng)。

2.2、MM32F0270 USB用于掛起和恢復(fù)的USB總線狀態(tài)

USB 規(guī)范定義了與 USB 總線上的信號電壓相對應(yīng)的總線狀態(tài)。

下圖為連接到D+的1.5 kΩ上拉電阻的全速總線。

poYBAGIPLAqAYYFmAAAwxsQ2EXY306.jpg

MM32F0270系列芯片內(nèi)置1.5K上拉電阻。

下面介紹USB 總線如何定義掛起、恢復(fù)和空閑狀態(tài)的總線狀態(tài)。

設(shè)備的掛起

在USB系統(tǒng)中,正常狀態(tài)下PC,Hub或Root Hub會一直周期性地發(fā)送SOF包(Start Of Frame,全速USB每1ms發(fā)送一個,高速USB則是125μs發(fā)送一個)。根據(jù)USB協(xié)議,如果USB線上一直處于空閑(Idle)狀態(tài)超過3ms,設(shè)備應(yīng)該把它當作一個掛起(Suspended)信號,要求設(shè)備在10ms內(nèi)進入掛起狀態(tài),并把設(shè)備所需的電流大小降到規(guī)定的值;對于low-power設(shè)備,要求是500μA,而對于high-power或支持遠程喚醒(remote wakeup)功能的設(shè)備是2.5mA。在掛起狀態(tài)中,設(shè)備必須繼續(xù)向數(shù)據(jù)項D+/D-的上拉電阻提供電壓以維持Idle狀態(tài)。

poYBAGIPLq2AVXeHAAASZhVC_-c413.jpg

設(shè)備的喚醒

設(shè)備處于掛起狀態(tài)時,任何總線上的活動(非空閑信號)都可以把設(shè)備喚醒/恢復(fù),從而退出低功耗模式。同樣,設(shè)備也可以換醒host,比如電腦待機時通過USB鍵盤來換醒主機,這種功能稱之為“遠程喚醒”(remote wakeup),不在本文的討論范圍內(nèi)。

因為設(shè)備掛起時處于全速信號,在當host需要把將設(shè)備退出suspend狀態(tài)時,需要先發(fā)送一個持續(xù)時間超過20ms的Fulll Speed K狀態(tài)。設(shè)備看到K狀態(tài)結(jié)束的1.3us內(nèi)醒過來,而host需要在3ms內(nèi)發(fā)送SOF信號以維持正常的高速信號模式,否則設(shè)備又將進入suspend。如下圖所示:

poYBAGIPLs6AM1zmAAAnTq4v-SQ493.jpg

下面是USB的數(shù)據(jù)狀態(tài)與信號的說明:

數(shù)據(jù) J 和 K 狀態(tài)Data J and K states

對于全速總線段,J 狀態(tài)與差分 1 相同,即 D+ 為邏輯高電平時和 D- 為邏輯低電平,而 K 狀態(tài)與差分 0 相同,即當 D+ 為邏輯低電平且D- 是邏輯高電平。

空閑狀態(tài)Idle state

在空閑狀態(tài)下,對于全速總線段,D+ 比 D- 的電平高。

掛起狀態(tài)Suspend signal

由于當USB總線處于空閑狀態(tài)超過3 ms時進入掛起狀態(tài),因此掛起狀態(tài)與空閑狀態(tài)相同或與全速總線段中的J狀態(tài)相同。

恢復(fù)信號Resume signal

當設(shè)備處于掛起狀態(tài)時,設(shè)備端口上的數(shù)據(jù)K狀態(tài)表示從掛起狀態(tài)恢復(fù)。這意味著恢復(fù)信號是全速段中從數(shù)據(jù)J狀態(tài)到數(shù)據(jù)K狀態(tài)的變化。

2.3、MM32F0270 USB支持從Suspend模式下喚醒

MM32F0270 可通過EXTI線 18連接到 USB總線掛起中斷實現(xiàn)USB從掛起狀態(tài)喚醒。

需要使用喚醒時,需要使能相應(yīng)的USB中斷外,還需配置EXTI 18以使能相關(guān)的功能。

相關(guān)的寄存器與控制狀態(tài)位的控制與查詢,可以參考MM32F0270的用戶手冊。

3、USB進入Suspend與Res ume的軟硬件設(shè)計

3.1、在庫函數(shù)版本的樣例中可以通過如下順序初始化USB

a.配置系統(tǒng)時鐘為48MHz或96Mhz,使能GPIOA時鐘,使能USB時鐘

void USB_ClockConfig(void)
{
    USB_HSI48M_Config();
    Set_CRS();      // The calibration of vibration
    // Select USBCLK source
//    RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div2); //if SYSCLK is 96MHz
    // Enable USB clock
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_USB, ENABLE);
}

b.配置USB D+和D-所需用到的GPIO引腳,使用GPIO_Configuration函數(shù)

void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_StructInit( GPIO_InitStruct);
    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);

    // USB_DISCONNECT used as USB pull-up
    GPIO_InitStruct.GPIO_Pin = USB_DISCONNECT_PIN;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_FLOATING;
    GPIO_Init(USB_DISCONNECT,  GPIO_InitStruct);
}

c.配置USB的中斷,調(diào)用USB_NVIC_Config函數(shù)

void USB_NVIC_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStruct;

    NVIC_InitStruct.NVIC_IRQChannel = USB_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPriority = 0;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init( NVIC_InitStruct);
}

d.設(shè)置USB的時鐘,調(diào)用USB_ClockConfig

void USB_ClockConfig(void)
{
    USB_HSI48M_Config();
    Set_CRS();      // The calibration of vibration
    // Select USBCLK source
//    RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div2);
    // Enable USB clock
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_USB, ENABLE);
}

e.設(shè)置USB 初始化

void USB_Init(void)
{
    pInformation =  Device_Info;
    pInformation->ControlState = 2;
    pProperty =  Device_Property;
    pUser_Standard_Requests =  User_Standard_Requests;
    // Initialize devices one by one
    pProperty->Init();
}

f.設(shè)定USB對應(yīng)喚醒的EXTI參數(shù)

void USB1_WKUP_Init(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;

    EXTI_InitStructure.EXTI_Line = EXTI_Line18;            
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;    
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init( EXTI_InitStructure);                        
}

g.中斷相應(yīng)處理函數(shù)

void USB_Istr(void)
{
    __IO u16 wIstr;
    wIstr = _GetUSB_INT_STA();
    //USB->INT_STATE = wIstr;

    // fSuspendEnabled = 0;
    if(wIstr   USB_INT_STATE_RSTF) {
        _ClrUSB_INT_STA(USB_INT_STATE_RSTF) ;
        Device_Property.Reset();
    }
//…
    EXTI_ClearITPendingBit(EXTI_Line22);
}

3.2、實現(xiàn)main Demo功能的主要函數(shù)代碼

s32 main(void)
{
    GPIO_Configuration();
    USB_NVIC_Config();
    USB_ClockConfig();
    USB_Init();
    while(1) {
        if(bDeviceState == CONFIGURED) {
            if(!(_GetUSB_CTRL1() EP1_CTRL_TRANEN)) {
                UserToPMABufferCopy(gTableData, ENDP1, BUFF_SIZE);
                _SetUSB_CTRL1(EP1_CTRL_TRANEN | BUFF_SIZE) ; //Loop IN transmission
            }
        }
    }
}

配置好初始化USB收發(fā)的初始化操作后,PC端會發(fā)現(xiàn)USB HID枚舉成功;此時PC端進入待機模式,

poYBAGIPLwmANDGFAAAhuVnmhYE253.png

MCU的USB收到Suspend的命令后,執(zhí)行:

void Suspend(void)
{

    if(bDeviceState == CONFIGURED) {
        //Frequency the bus clock 512
        USB->POWER  = ~USB_POWER_SUSP;

        bDeviceState = SUSPENDED;
        fSuspendEnabled = true;

        RCC->CFGR  = ~RCC_CFGR_HPRE;
        RCC->CFGR |=  RCC_CFGR_HPRE_DIV512;
        RCC->CR  = ~(0x1f << 26);

        RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div4);

        UART_DeInit(UART1);

    }

}

USB喚醒機制

USB設(shè)備進入掛起狀態(tài)之后,將由Resume信號進行喚醒。Resume信號可以由USB主機發(fā)起,也可以由USB設(shè)備本身觸發(fā),但是只有USB主機可以結(jié)束Resume信號。

主機在掛起設(shè)備后可通過翻轉(zhuǎn)數(shù)據(jù)線上的極性并保持20ms來喚醒設(shè)備,并以低速EOP信號結(jié)尾。

如果設(shè)備支持遠程喚醒,設(shè)備可向主機發(fā)起遠程喚醒請求,前提是設(shè)備已進入idle狀態(tài)至少5ms,設(shè)備會驅(qū)動總線進入K狀態(tài),如下圖,K狀態(tài)必須維持1ms-15ms之內(nèi),此信號會在1ms內(nèi)被主機接管,主機會繼續(xù)驅(qū)動喚醒信號直到20ms,并以低速EOP信號結(jié)尾。

主機復(fù)位設(shè)備或者設(shè)備對自己強行復(fù)位,設(shè)備也會從掛起狀態(tài)切換到默認狀態(tài)。

MM32F0270 設(shè)備被喚醒后,如果喚醒中斷使能(比如使用PA0的EXTI0),則會進入喚醒中斷,退出低功耗模式,然后清除USB_POWER寄存器的SUSPEND位,退出強制掛起操作。

操作上體現(xiàn)為PC Host主機同按主機KeyBoard或鼠標按鍵實現(xiàn)退出睡眠狀態(tài),從而喚醒MM32F0270的掛起狀態(tài)。

通過上述的步驟,簡單的演示了MM32F0270的USB 接收數(shù)據(jù),通過數(shù)據(jù)幀中的Start Bit喚醒MCU的功能。

Demo程序可登錄MindMotion的官網(wǎng)下載MM32F0270 lib_Samples

工程路徑如下:

~ MM32F0270_SamplesLibSamplesUSB

來源:靈動MM32MCU

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • mcu
    mcu
    +關(guān)注

    關(guān)注

    146

    文章

    16805

    瀏覽量

    349402
  • usb
    usb
    +關(guān)注

    關(guān)注

    60

    文章

    7851

    瀏覽量

    263347
  • 總線
    +關(guān)注

    關(guān)注

    10

    文章

    2851

    瀏覽量

    87847
  • 低功耗
    +關(guān)注

    關(guān)注

    10

    文章

    2333

    瀏覽量

    103464
收藏 人收藏

    評論

    相關(guān)推薦

    靈動微課堂 (第196講) | 使用MM32F0270 LPTIMSTOP模式喚醒

    了如何使用 MM32F0270的LPTIM來實現(xiàn)定時1sSTOP方式的低功耗模式喚醒。實現(xiàn)使用LPTIM1,在低功耗stop模式下定時1
    發(fā)表于 01-10 11:38

    靈動微課堂 (第197講) | MM32F0270 UART空閑中斷 + DMA接收不定長數(shù)據(jù)

    ,一旦接收的數(shù)據(jù)斷流,沒有接收到數(shù)據(jù),即產(chǎn)生空閑中斷。MM32F0270系列的UART支持空閑中斷功能。相關(guān)的寄存器包括UART中斷狀態(tài)寄存器(UART_ISR)、 UART中斷使能寄存器
    發(fā)表于 01-10 11:42

    靈動微課堂 (第198講) | 使用MM32F0270 LPUART從低功耗模式喚醒

    了如何使用 MM32F0270的LPUART來實現(xiàn)通過接收外部UART的信號,觸發(fā)MCUSleep/DeepSleep低功耗模式喚醒。1MM32
    發(fā)表于 01-17 13:24

    靈動微課堂 (第199講) | 使用MM32F0270 USBSuspend模式喚醒

    時,設(shè)備端口上的數(shù)據(jù)K狀態(tài)表示掛起狀態(tài)恢復(fù)。這意味著恢復(fù)信號是全速段中數(shù)據(jù)J狀態(tài)到數(shù)據(jù)K狀態(tài)的變化。2.3MM32F0270 USB支持
    發(fā)表于 02-18 13:32

    靈動微課堂 (第200講) | 使用MM32F0270 定時器DMA方式輸出PWM

    MM32F0270的定時器TIM1、TIM2、TIM3、TIM15、TIM16/17有DMA模式,能夠在發(fā)生單個事件時生成多個DMA 請求。主要目的是在沒有軟件開銷的情況下,多次重新編程定時器的一部分
    發(fā)表于 02-18 13:36

    靈動微課堂 (第200講) | 使用MM32F0270 定時器DMA方式輸出PWM

    MM32F0270的定時器TIM1、TIM2、TIM3、TIM15、TIM16/17有DMA模式,能夠在發(fā)生單個事件時生成多個DMA 請求。主要目的是在沒有軟件開銷的情況下,多次重新編程定時器的一部分
    發(fā)表于 03-17 17:26

    MM32F013x——RTC鬧鐘定時喚醒

    本文將重點介紹如何在MM32F013x上通過內(nèi)部RTC模塊的鬧鐘事件來喚醒處于停機模式下的MCU。
    發(fā)表于 02-08 17:02 ?17次下載
    <b class='flag-5'>MM32F</b>013x——RTC鬧鐘定時<b class='flag-5'>喚醒</b>

    MM32F0270 產(chǎn)品手冊(中文版)

    MM32F0270 產(chǎn)品手冊(中文版)
    發(fā)表于 02-23 18:36 ?0次下載
    <b class='flag-5'>MM32F0270</b> 產(chǎn)品手冊(中文版)

    MM32F0270 產(chǎn)品手冊(英文版)

    MM32F0270 產(chǎn)品手冊(英文版)
    發(fā)表于 02-23 18:37 ?0次下載
    <b class='flag-5'>MM32F0270</b> 產(chǎn)品手冊(英文版)

    MM32F0270 用戶手冊(中文版)

    MM32F0270 用戶手冊(中文版)
    發(fā)表于 02-23 18:37 ?0次下載
    <b class='flag-5'>MM32F0270</b> 用戶手冊(中文版)

    MM32F0270 用戶手冊(英文版)

    MM32F0270 用戶手冊(英文版)
    發(fā)表于 02-23 18:38 ?0次下載
    <b class='flag-5'>MM32F0270</b> 用戶手冊(英文版)

    MM32F0270 勘誤表(中文版)

    MM32F0270 勘誤表(中文版)
    發(fā)表于 02-23 18:38 ?0次下載
    <b class='flag-5'>MM32F0270</b> 勘誤表(中文版)

    MM32F0270 勘誤表(英文版)

    MM32F0270 勘誤表(英文版)
    發(fā)表于 02-23 18:39 ?0次下載
    <b class='flag-5'>MM32F0270</b> 勘誤表(英文版)

    使用MM32F0270 定時器DMA方式輸出PWM

    使用MM32F0270 定時器DMA方式輸出PWM
    的頭像 發(fā)表于 10-17 14:47 ?779次閱讀
    使用<b class='flag-5'>MM32F0270</b> 定時器DMA方式輸出PWM

    使用MM32F0270 LPTIMSTOP模式喚醒

    使用MM32F0270 LPTIMSTOP模式喚醒
    的頭像 發(fā)表于 10-26 16:46 ?895次閱讀
    使用<b class='flag-5'>MM32F0270</b> LPTIM<b class='flag-5'>從</b>STOP<b class='flag-5'>模式</b><b class='flag-5'>喚醒</b>