2015年10月27日 星期二

USB Power delivery for Alternative mode



USB PD除了電源需求的溝通,也可以用來溝通彼此的信號需求,例如使用原來
Type-C USB3.x的通道,用來傳輸Displayport,PCIE等高速訊號。

下面是DFP端與UFP端交握的過程,DFP端利用PD的protocol,來得知對方是什麼
樣的裝置,UFP端也會讓DFP端知道它支援那些高速訊號,再由DFP端來決定要
提供USB或Displayport或PCIE給UFP端。




1.Discover Identity VDM command

 Send VDM 1xxFh,FF00h,8001h
 Receive VDM from UFP side and check if ACK bits is “01”h
 Check device or Cable spec


2. Discover SVIDs VDM command

   Send VDM,1xxFh,FF00h,8002h
  Receive VDM from UFP side and check if ACK bits is “01”h
  Check device SVID


3.Discover Modes VDM command
Send VDM,1xxFh,xxxxh (SVID),8003h
Receive VDM from UFP side and check if ACK bits is “01”h
Check device Mode


4.Enter Mode


Check which mode you want to enter.
Send VDM,1xxFh,xxxxh (SVID),8x04h (x is object mode position)
Receive VDM from UFP side and check if ACK bits is “01”h


5.Control Mux

Control the Super speed Mux by MCU or PD IC. Depend
on the mode you want to enter.





Reference
1. USB PD 2.0
2. VESA, DisplayPort Technology Update
https://www.vesa.org/wp-content/uploads/2015/07/VESA-Taiwan-Press-61115.pdf












2015年4月16日 星期四

USB Power Delivery for USB Type C

這篇文章是來解釋USB PD在TypeC是如何來進行的。TypeC與Type A/B在流程
上不同的是,Type-C需要先建透過CC pin去建立兩端DFP與UFP。而TypeA/B
的角色從Connector的公母端,就已經確定的,而TypeAB則是用ID pin來判斷
誰是DFP或UFP。當DFP與UFP透過Type-C連接,會先進行下面四點,這個在
我的另一篇網誌有解釋過了。

1. Detect attach of USB ports, e.g. a DFP to a UFP
2. Resolve cable orientation and twist connections to establish USB data 
    bus routing
3. Establish DFP and UFP roles between two attached ports
4. Configure VBUS: USB Type-C Current modes

在上面四點完成後,便開始進行USB PD的連接與溝通,這時VBUS電壓是5V,
電流是依照Type-C current mode,再來便是進行Power Negotiation 
(PD spec 8.3.2.3)。
1.Power Source會周期性的持續送Source Capabilities messages,
2.當Source收到SINK送出的GoodCRC,表示兩端PD已連接。
3. 連接後,SINK會送出Request message,裡面包括
4.Source認可SINK的Request後,發Accept給UFP。
5.Source轉換到SINK Request的電壓後,發PS_RDY給SINK。。
6.Power Negotiation完成,SINK開始依照新的供電來運作。

PD Negotiation的第3個動作,如果Source的Capabilities不能滿走SINK在電壓
或電流的需求,SINK送出的Request message (Table 6-13)便會設置Capability
Mismatch bitSource端在接收到後,Source端可以送出Get Sink Capabilities
,來得到SINK再回Sink Capabilities。之後Source再去確認,是否它可以得到更
大的供電能力來提供SINK。






2015年1月6日 星期二

Arduino power consumption reduction

要試著將我手上的Arduino Pro Mini功耗降到最低,我上網查了一些文章,
也做了一些實驗。結果就是讓板子在進到power down mode時,功耗為
18.7uA/3.3V。如果有那位大大知道如何讓功耗再往下降,請不吝指教。


在一開始我參考下面reference列的那個網址,在進到power down mode
的功耗是112uA,後來去修改register MCUCR去關掉BOD,功耗降到
106uA。後來再去修改register PRR,將Timer0~2,TWI,SPI,USART0,
ADC關掉,才讓功耗降到18uA。此外原本reference code是用函式
sleep_mode()來進到sleep mode,但這個函式會去打開一些前面關掉的
設定,所以要改用函式sleep_cpu()來進sleep mode。

為了去降低功耗,也需要硬體去配合,我將Arduino Pro Mini上的U2
LDO拆掉,還有紅色的LED1也拿掉。另外將INT0 pin接到一個button
,當系統開機後3秒,會自動進到sleep mode,這時再按下button,
就可以觸發 attachInterrupt事件,來喚醒MCU。
#include <avr/sleep.h>
#include <avr/power.h>       
void setup(void)
{
    // the GPIO comprise 3 part, B,C,D.
    DDRD &= B00000011;       // set Arduino pins 2 to 7 as inputs, leaves 0 & 1
    DDRB = B00000000;        // (RX & TX) as is set pins 8 to 13 as inputs
    PORTD = B00000100;      // disable pullups on pins 3 to 7
    PORTB = B00000000;      // disable pullups on pins 8 to 13
    pinMode(13,OUTPUT);      // set pin 13 as an output so we can use LED to monitor
    digitalWrite(13,HIGH);   // turn pin 13 LED on
    Serial.begin(9600); 
}
                //
void loop(void)
{
    // Stay awake for 1 second, then sleep.
    // LED turns off when sleeping, then back on upon wake.
    delay(3000);
    sleepNow();
}
                //
void sleepNow(void)
{
   Serial.println("Go to sleep");
    
    // Set pin 2 as interrupt and attach handler:
    attachInterrupt(0, pinInterrupt, LOW);
    delay(100);
    //
    // Choose our preferred sleep mode:
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    //
    // Set sleep enable (SE) bit:
    sleep_enable();
    digitalWrite(13,LOW);   // turn LED off to indicate sleep
    // Put the device to sleep:
     MCUCR |= bit(BODSE) | bit(BODS); // timed sequence
     MCUCR = (MCUCR & ~bit(BODSE)) | bit(BODS);
  
     ADCSRA &= ~(1 << ADEN);
     PRR = 0xFF;
     sleep_cpu();
    //sleep_mode();

    // Upon waking up, sketch continues from this point.
    sleep_disable();
    Serial.println("sleep disable");
    digitalWrite(13,HIGH);   // turn LED on to indicate awake
    PRR = 0x00;
   //  delay(10000);
}
                //
void pinInterrupt(void)
{
    Serial.println("Interrupt");
    detachInterrupt(0);
}

下表為各個power mode,它有那些block是開著或關掉。


我們利用下面的函式就可以改變sleep mode,在各個sleep mode可以得到不同的功耗。
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
VCC=3.3V
ACTIVE_MODE                         8.0mA
SLEEP_MODE_IDLE                1.56mA
SLEEP_MODE_ADC                1,.02mA
SLEEP_MODE_PWR_SAVE    0.65mA
SLEEP_MODE_STANDBY       0.65mA
SLEEP_MODE_PWR_DOWN  18.7uA.





Reference.
http://www.engblaze.com/hush-little-microprocessor-avr-and-arduino-sleep-mode-basics/