2016年4月19日 星期二

USB Type-C Port Controller


USB Org defined the Port Controller and its architecture in Oct 2015. The Type-C
port Manager is moved out from PD controller.  The MCU or EC(embeded
controller) can be the Type-C port Manager, it can control many Type-C Port
Controllers by I2C at the same time.


The TCPM (Type-C Port Manger) is used to decide these Type-C PD port function
and behavior, The TCPC (Type-C Port Controller) is passive and is used for Type-C
logic and PD data transceiver. Many registers are defined in TCPC spec, the TCPM
can read /write these register to get status of Type-C port and control TCPC.


The following are how the TCPM and TCPC finish the Type-C connection and 
VBUS 5V to HighVoltage transition.  

DRP Type-C port initialize and CC connection.



1. Before the connection. TCPC set TCPC to be DRP.
Write ROLE_CONTROLROLE_CONTROL.DRP = 1b ;TCPM set TCPC to be DRP. 
ROLE_CONTROL.CC2=01b or 10b ;set initial status of CC1 and CC2 to be Rp or Rd.
ROLE_CONTROL.CC1=01b or 10b  
ROLE_CONTROL.CC1=ROLE_CONTROL.CC2
POWER_CONTROL.AutoDischargeDisconnect=0 ;set no autodischarge when CC Disconnect.
Write COMMAND.Look4Connection TCPM wrote Look4Connection to TCPC to ask TCPC start to detect connection according to Role_Control register setting and toggle Rp/Rd.
Set CC_STATUS.Looking4Connection=1b ;After TCPC received Look4Connection command, the TCPC register CC_STATUS.Looking4Connection would be "1b". And then TCPC start to toggling the CC.

2. After the connection.
Potential_Connect_as_Source ; When TCPC to be Source
Either CC line = Src.Rd or both CC lines = Src.Ra ; if  One of the CC pin voltage is vRd or both CC pin voltage are vRa.
for >tTCPCFilter  ;Debounce time(4~500us)
Set Source Status
CC_STATUS.Looking4Connnection=0b ;TCPC stop to detect connection.
CC_STATUS.ConnectResult=0b ; TCPC set this CC pin is to be Rp.


Potential_Connect_as_Sink ;When TCPC to be Sink
Either CC line != Snk.Open ;if  One of the CC pin voltage >vRa. 
for >tTCPCFilter  ;Debounce time(4~500us)
CC_STATUS.Looking4Connection=0b ;TCPC stop to detect connection.
CC_STATUS.ConnectResult=1b  ;TCPC set CC to be Rd.

3. TCPC alert the TCPM 
TCPC Set ALERT.CcStatus=1b   ;TCPC Alert register's b0 =>CC status=1 mean the status of CC has been changed.
TCPM read ALERT      ;TCPM detect Alert and then read the Alert register
TCPM check if "ALERT.CcStatus=1b?" ;check if the status of CC have been changed
Yes=>TCPM check if "C_STATUS.Looking4Connection=0 ?" ; If yes, check if TCPC stop to detect connection. If yes, enter debounce time.
Read CC_STATUSDebounce for tCCDebounce  ;Debounce time (100ms~200ms)
Write ROLE_CONTROL.CC1 & CC2 per decision ;TCPM set TCPC's Role_control register CC1 or CC2 to be Ra,Rd or Rp.
Write TCPC_CONTROl.PlugOrientation  ;TCPM set PlugOrientation of TCPC_control register to be CC1 or CC2. 
Write POWER_CONTROL.AutoDischargeDisconnect=1 & POWER_CONTROL.EnableVconnConnection
;TCPM enable TCPC VBUS Autodischarge, The TCPC would discharge VBUS when the VBUS was under vSafe0V(max) or VBUS_STOP_Discharge_Threshold. TCPM set TCPC to output VCONN if one of CC is Ra.
Write Alert.CcStatus=0b ;Clear the CcStatus of Alert register.

4.Connection Established, TCPM monitor the Alert signal




Support USB PD and change the VBUS voltage.



1. Currently the TCPC is output VBUS 5V
Sourcing 5V over VBUS ;VBUS output 5V
POWER_STATUS.SourcingVBUS=1  ;the status SourcingVBUS=1 mean this TCPC output VBUS 5V now.
POWER_STATUS.SourcingHighVoltage=0  ;the SourcingHighVoltage=0 mean the VBUS is 5V not high voltage now. 

2. After TCPM accepted the request from far end Sink side for High voltage VBUS. TCPM would send Vendor Defined command to set the target voltage of HighVoltage. 

3.Write command.SourceVbusHighVoltage ;TCPM write SourceVbusHighVoltage to command register 

4.After TCPC received the SourceVbusHighVoltage, TCPC change the VBUS from 5V to HighVoltage.And then..
 TCPC set POWER_STATUS.SourcingHighVoltage=1  ;TCPC set register Power_Status SourcingHighVoltage bit to be "1b"。
 TCPC set ALERT.PowerStatus     ;TCPC set register Alert Power status bit to be "1b".

5.TCPM read alert register and recognize the TCPC has finished the HighVoltage VBUS transition.




1.USB 3.1 spec http://www.usb.org/developers/docs/

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/

2014年12月21日 星期日

Arduino to Bluetooth module HC-06 for wireless control

Arduino經由BT module就可以做無線控制的功能,可以應用在IOT,遙控車。我在
淘寶買了一個BT module HC-06,花了大約20塊人民幣。我想先做個最簡單的功
能,也就是控制LED。由於還不會寫Android程式,所以先用PC內建的BT來做控
制。我在PC上的終端機,在BT的com port也就是UART,輸入L (light) or D (dark)
字元,然後透過BT傳送到Arduino板子的UART port,當Arduino板子接收到L or D
字元,就會去控制LED的亮暗。

1.由於寫程式需要用到UART port來燒錄,需要先將Arduino UART port接到 USB
   to UART的轉板,然後燒錄下面的程式。BT module對於Arduino的板子來說,
  只是一個UART介面的IC,所以Arduino MCU都是用Serial的函式來與BT module
  溝通。由於HC-06預設的Baud rate是9600bps,所以MUC需要用9600bps來跟
   HC-06來跟它溝通。另外我用到Arduino板子上的綠光LED,當MCU接收到"L"
   就將ledPin設置為1,LED就會亮。當接收到"D",就將ledPin設置為0,LED就會
   暗。

const int ledPin = 13; 
int incomingByte = 0;
void setup() 
{
  // open a serial connection
  pinMode(ledPin, OUTPUT); 
  Serial.begin(9600); 
 Serial.println("Control start, please press L or D");
}
void loop()
{
while (Serial.available()) 
{
  incomingByte=Serial.read();
if ( incomingByte=='L')
{
  digitalWrite(ledPin, 1);
  Serial.println("Turn on LED");
}
else if ( incomingByte=='D')
 {
   Serial.println("Turn off LED");
   digitalWrite(ledPin, 0);
 }
else
{
  Serial.println("Wrong input");
}
}
}

2.程式燒錄完後,就可以連接Arduino板子與HC-05,這時你的Arduino板子已經脫離
   你的PC了。我們只需要接VCC,GND,TXD,RXD 4條線,注意module的TXD要接到
    Arduino板子的RXD,module的RXD要接到Arduino板子的TXD。最後再供外部電
    源5V或3.3V給VCC pin,等於是同時供電給Arduino板子與HC-06。










3.最後我們打開電腦的BT,可以看到您附近有那些BT device,我們選擇連接到
    HC-06後,開啟終端機,就可以看到有一個Bluetooth serial port的選項,點選
    "OK"後,就會出現終端機畫面,這時你輸入keyboard的L或D會出現訊息,而
    LED也會隨著亮或暗。






















注:如果要修改BT module的設定,需要用AT command。我們用USB to UART轉板
        連接到BT module,只需要VCC,GND,TXD,RXD四條線,然後進到終端機模式
        輸入左邊第一排的command就可以來修改BT module的設定。例如輸入"
        AT+PIN1234"就是設定BT module的密碼為"1234",Baud rate也可以修改。
     
command
response
effect

AT+VERSION
OKlinvorV1.6
Gets the version info, no changes

AT+NAMExyz
OKsetname
Sets the module name to "xyz"

AT+PIN1234
OKsetPIN
Sets the module PIN to 1234

AT+BAUD7
OK57600
Sets the baud rate to 57600


Reference:
1.http://wiki.mikrokopter.de/en/HC-06

2014年12月12日 星期五

Arduino to Compass GY-273/HMC5883L 三軸電子羅盤

要在Arduino開發版載入電子羅盤很容易,在網路上有很多相關的網站提供Library與函式,減少入門者開發的時程。下面便是利用網路上的範例程式來驗証HMC5883L三軸電子羅盤。  


1.將Adruino的I2C pin A4,A5接到GY-273的SDA,SCL。GY-273的VCC可以直接接Arduino上的   5V,GY-273支援5~3V輸入。再連接上兩塊板子的GND,硬體設置便完成了。


2.找個blog[1]下載的Library,
3.在壓縮檔內還有一個範例程式HMC5883L_Example.ino,我們可以先用這個程式來驗証GY-273的功能。
4. 當你把程式成功upload到Arduino的板子後,再打開Serial Monitor視窗,就可以看到Arduino從HMC5883L讀到的數值。最左邊是三個軸的Raw data,中間的scaled是將Raw data轉成磁場強度,最右邊這排,便是將Raw data轉成磁角度。



在驗証Library的過程中,如果出現下面編輯的錯誤訊息
C:\Users\Documents\Arduino\libraries\HMC5883L\HMC5883L.cpp: In member function 'void HMC5883L::Write(int, int)':
C:\Users\Documents\Arduino\libraries\HMC5883L\HMC5883L.cpp:110: error: 'class TwoWire' has no member named 'send'
C:\Users\Documents\Arduino\libraries\HMC5883L\HMC5883L.cpp:111: error: 'class TwoWire' has no member named 'send'
C:\Users\Documents\Arduino\libraries\HMC5883L\HMC5883L.cpp: In member function 'uint8_t* HMC5883L::Read(int, int)':
C:\Users\Documents\Arduino\libraries\HMC5883L\HMC5883L.cpp:118: error: 'class TwoWire' has no member named 'send'
C:\Users\Documents\Arduino\libraries\HMC5883L\HMC5883L.cpp:129: error: 'class TwoWire' has no member named 'receive'
這是因為Arduino版本的問題,在舊版的arduino,Wire的函式是用send,receive指令來收發資料,但新的Arduino是用write,read。要修正這個問題,只要將  HMC5883L.cpp內的head檔
#include <WProgram.h>
改成下面這行, 就可以解決這個問題了。
#include <Arduino.h>




Reference
[1] http://bluelemonlabs.blogspot.tw/2013/08/arduino-simple-compass-with-hmc5883l.html

2014年10月31日 星期五

Arduino first step (by Arduino PRO Mini)


1.到Arduino官網下載IDE 程式編輯器,並安裝。
    http://arduino.cc/en/Main/Software
2. 確認您的Arduino編輯器是如何下載image到你的板子。我在淘寶買了CP2102 7.5塊人民幣,
    還有Arduino Pro Mini 15塊人民幣。由電腦的USB port接到CP2102,轉成UART訊號後燒
    錄到Arduino Pro Mini。


2.一開始先打開範例程式,在選單中的File -> Open,然後再Arduino的目錄底下,進到目錄              examples\01.basics, 我們先選一個最容易驗証的例子,在Blink目錄底下,選擇blink.ino。
3. 選擇所使用的Arduino硬體裝置,在工具列選Tools -> Board -> "Arduino PRO or Pro Mini                 (5V, 16MHz) w/ATmega328"   ,這關係到你用的是那一塊Arduino版子。
4.在打開程式後,可以發現程式非常的簡單,這是因為Arduino已經幫你把很多硬體相關的
   初始設定做掉了。你只需要偵對要做的功能來設定。
5.再來就是將程式燒錄到板子上,只要選擇File->Upload,就會進行燒錄了,同時板子的LED
   也會閃爍。
6. 燒錄完成後,就可以看到程式運行的結果。blink.ino的功能是讓LED亮暗,由於LED是接到                  MCU的pin 13,所以在程式裡,設定PIN13為output。在迴圈的開始,先設定pin13為 high
     經過1秒後,再設定為low,經過1秒後再重覆廻圈。LED便會每隔1秒改變一次狀態。

Reference
1. http://arduino.cc/en/Guide/Windows