- [[Linux_BSP] Week1。Linux架構、 Boot、kernel、driver、device tree 筆記](https://hackmd.io/@YungHuiHsu/ryZ1i45dT)
- [[Linux_BSP] Week2。UART與GPIO控制](https://hackmd.io/@YungHuiHsu/B1e_heHt6)
- [[Linux_BSP] Week3_1。I2C 通訊、GMSL2 Camera](https://hackmd.io/@YungHuiHsu/HkaQBH0K6)
- [[Linux_BSP] Week3_2。GMSL2 Camera](https://hackmd.io/@YungHuiHsu/Hyjmb5V96)
- [[Linux_BSP] Week4。HPC Debug](https://hackmd.io/@YungHuiHsu/HknGTEw9p)
---
## BSP Week3任務
1. - [x] 學習 I2C 通訊
:::success
1. 了解 I2C 通訊的原理
2. 學習使用 Linux I2C 工具進行通訊
3. 透過 I2C 控制 MPQ7920輸出對應訊號,可以直接使用 I2C 工具或程式實現,方式不限,MPQ7920的輸出訊號需求如下
(1) Buck#1: 0.7V
(2) Buck#2: 2.0V
(3) Buck#3: 1.0V
(4) Buck#4: 0.8V
:::
> 2. - [ ] 學習與應用:GMSL2 Camera
> :::success
> 學習並了解 GMSL2 camera:
> 1. 與 USB camera、MIPI camera 的差異
> 2. 與 SERDES(Serializer、Deserializer)的關係
> 需要輸出文件描述學習心得 (文件格式為投影片)
> :::
>
> 3. - [ ] 評核驗收
> :::success
> 1. 串接 econ-System 的 camera module 到 Nvidia Xavier Kit
> 2. 根據 Vendor 文件,porting camera driver 到Xavier Kit
> 3. 透過 Gstreamer 指令串接 camera driver,將camera capture 的影像輸出至 HDMI 螢幕
> :::
---
# 1. 學習 I2C(Inter-Integrated Circuit) 通訊
### 1.0 通信領域的資料傳輸 Data Communications
Electronic transfer of information via wired and wireless mediums.
通過有線和無線媒介進行電子信息傳輸
#### 序列與並行傳輸(Serial and parallel transmission)

> - 並行傳輸(Parallel Transmission):
> - 多位數據同時傳輸,通常用於計算機內部或距離較短的通信。
> - 需要多條數據線,每條線同時傳輸一位數據,如圖中同時傳輸D0至D7。
> - 序列傳輸(Serial Transmission)
> - 數據一位一位(bitwise)地順序傳輸。
> - 通常用於距離較遠的通信,因為它需要較少的傳輸線。
> - 數據在一條通道上逐個傳輸,如圖中所示的單個數據位D0至D7依序排列。
>
#### 同步與異步傳輸(Synchronous / Asynchronous)

- 同步傳輸(Synchronous Transmission):
- 數據在**固定的時間間隔**內傳輸,通過時鐘信號來同步發送器和接收器eg:I2C。
- 數據傳輸效率高,因為發送方和接收方都在相同的時序下工作。
- 例如,在圖片中數據串`1000111001110001110110000111101`為一個完整的塊傳輸。
- 異步傳輸(Asynchronous Transmission):
- 數據以**獨立的小組分批**傳輸,每個小組通常由起始位和停止位來界定,eg:UART。
- 不需要時鐘信號來同步,每個數據單位的開始和結束由特定的起始位和停止位標記。
- 例如,在圖片中可以看到數據`1000111010`和`1111011000`分別作為兩個獨立的單元傳輸,中間可能有間隙。
#### 雙工(Duplex)
在通信領域,半雙工(Half-Duplex)和全雙工(Full-Duplex)是兩種不同的數據傳輸模式:
| 中文名稱 | 描述 |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| 半雙工<br>(Half-Duplex) | 通信設備在同一時間只能執行發送或接收其中一種操作。當一方發送數據時,另一方必須等待接收。例如,無線對講機就是半雙工通信的一個例子。<br>eg:I2C |
| 全雙工<br>(Full-Duplex) | 通信設備可以同時進行數據的發送和接收。這意味著兩個通信端點可以同時進行雙向通信,如當代大多數的電話網絡。<br>eg:UART、SPI |
全雙工通信提供了更有效率的數據傳輸方式,因為它允許同時雙向通信,而不需要在發送和接收之間進行切換。

[source: 成大資工wiki。Universal Asynchronous Receiver/Transmitter (USART)](https://wiki.csie.ncku.edu.tw/embedded/USART)
> 半/全雙工、同步/非同步 & Serial bus 示意圖
#### 常見的3種標準通訊協定 Communications Protocols

[image source: UART - UWARG/PICpilot GitHub Wiki](https://github.com/UWARG/PICpilot/wiki/UART)
[2018。mbtechworks。Raspberry Pi I2C/SPI/UART Communications](https://www.mbtechworks.com/hardware/raspberry-pi-UART-SPI-I2C.html)
| 特性 / 通訊協議 | I2C<br>(Inter-Integrated Circuit) | UART<br>(Universal Asynchronous Receiver/Transmitter) | SPI<br>(Serial Peripheral Interface) |
| ----------------- | ---------------------------------------------------- | ---------------------------------------------------- | --------------------------------------------------------------- |
| **數據傳輸模式** | 半雙工 | 全雙工 | 全雙工 |
| **速度** | 較慢,標準模式下最高100Kbps,高速模式下最高3.4Mbps | 慢,速度範圍廣泛,<br>但通常在數Mbps以下 | 較快,可以達到數十Mbp |
| **硬體複雜度** | 線路較簡單,只需要兩條線(SDA和SCL) | 線路最簡單,<br>只需要兩條線(RX和TX) | 線路較複雜,至少需要三條線,<br>通常是四條(MISO、MOSI、SCK、CS) |
| **主從模式** | 支持多主從模式 | 無主從概念,點對點通訊 | 通常一主多從,但不支持多主模式 |
| **地址/選擇機制** | 每個從設備有唯一地址 | 不需要地址,因為是點對點通訊 | 通過片選線(CS)選擇特定的從設備 |
| **同步機制** | 時鐘同步(SCL線) | 非同步 | 時鐘同步(SCK線) |
| **錯誤檢測** | 內建的應答機制,可用於錯誤檢測 | 通常有奇偶校驗位,<br>但錯誤檢測較弱 | 無內建的錯誤檢測,需要軟體支持 |
| **適用情境** | 適用於板上短距離通訊,如感測器數據讀取 | 適用於長距離或<br>簡單的點對點序列通訊 | 適用於需高速且可靠性要求高<br>的短距離通訊,如閃存 |
## 1.1 了解 I2C 通訊的原理
> I²C(Inter-Integrated Circuit)是內部整合電路的稱呼,是一種串列通訊匯流排,由Philips公司在1980年代為了讓主機板、手機及嵌入式系統用以連接低速周邊裝置而發展,主要應用在board-to-board,它的設計並不能應用到長距離裝置的通訊。不過,I2C bus 可以被應用在各種控制架構上,如系統管理匯流排(System Management Bus, SMBus)、電源管理匯流排(Power Management Bus, PMBus)、智慧平台管理介面(Intelligent Platform Management Interface, IPMI)、顯示數據通道(Display Data Channel, DDC)、先進電信運算架構(Advanced Telecom Computing Architecture, ATCA)。 - 成大資工 Wiki
### I2C資料傳送
#### I2C Communication 概述
- I2C工作原理

[source: I2C Communication Interface](https://newhavendisplay.com/blog/i2c-communication-interface/)
I2C(Inter-Integrated Circuit)是一種序列通訊協議,由兩條線組成:
- **SDA (Serial Data Line)**:用來傳輸數據
- **SCL (Serial Clock Line)**:提供時鐘信號以同步數據傳輸
- I2C通訊包含兩種類型的設備:
- 主設備(Master)/controller:發起通訊並提供SCL線的時鐘信號
- 從屬設備(Slave)/peripheral:備接收主設備的指令並響應。
### I2C數據通訊過程

[source: I2C Communication Interface](https://newhavendisplay.com/blog/i2c-communication-interface/)
> I2C serial data communication process.
- I2C的數據通訊過程涉及以下幾個關鍵步驟:
1. 匯流排閒置(匯流排自由)狀態Bus idle (bus free) condition:
- 在任何通信開始之前,SDA(Serial Data Line)和SCL(Serial Clock Line)保持高電平,表示匯流排處於閒置狀態( bus is idle)。
2. 啟動條件:
- 由Master發起,啟動條件發生在SDA線從高電平變為低電平,同時SCL線保持高電平。這向所有Slave發出信號,表示通信即將開始。
3. 發送地址:
- 地址幀`address frame`由8-bit sequence組成
- **7 Address bit**: master向要通信的slave發送7位元地址(7-bit address)。
- **1 R/W bit**:接著是是第8位元(8th bit),也就是讀/寫(R/W)位元,用來指示操作方向:`0表示寫入,1表示讀取`。
- 如果是10位元地址(**10-bit addresses**)的特殊情況:
master會發送2個位元組(bytes)
- 第一個位元組以11110開頭,然後是10位元地址的第9位和第8位,接著是R/W位元。
- 第二個位元組將包含10位元地址的第7位到第0位。
4. 確認(ACK)位元 Acknowledgment bit:
- 在發送地址和R/W位元(address and R/W bits)之後,master釋放SDA Line。被定址的slave將SDALine拉低(ACK bit),以確認已成功接收其地址並準備進行通信。
5. 數據傳輸Data transfer:
- 對於寫入操作,master向slave發送一個數據位元組(a byte of data)。slave通過在一個時鐘脈衝期間(one clock pulse)將SDA線拉低以確認接收。
- 對於讀操作,slave向master發送一個數據位元組(a byte of data)。master確認接收,但在讀操作期間的最後一個位元組後會釋放SDA線(NACK或無確認),向slave發出停止發送數據的信號。
6. 停止條件:
- 為了結束通信會話,master通過在SCL線保持高電平的情況下將SDA線從低電平轉換為高電平來生成停止條件。在停止條件之後,匯流排返回閒置狀態。
- master還可以生成重複的啟動條件,以保持對匯流排的控制,進行另一個讀取或寫入操作。這通常用於更複雜的操作,例如在不釋放匯流排的情況下更改數據方向。
此外,I2C協議還有一些進階功能,如:
- **多從設備(Addressing Multiple Slaves)**:通過不同的地址,允許多個從設備連接到同一條I2C總線上。
- **時鐘伸展(Clock Stretching)**:從設備(slave )可以控制時鐘信號,延遲主設備的時鐘,從而獲得更多處理接收到的數據的時間。
- **總線仲裁(Bus Arbitration for Multi-Master)**:當有多個主設備試圖控制總線時,總線仲裁機制確保只有一個主設備可以控制總線。
- **I2C仲裁過程(I2C Arbitration Procedure)**:如果兩個主設備同時開始通訊,它們會監聽總線並比較發送的數據與總線上的數據。一旦檢測到不一致,輸的一方將停止傳輸。
- I2C Communication細節
- [2016。aticleworld。I2C Communication Protocol, Bus and Interface](https://aticleworld.com/i2c-bus-protocol-and-interface/)



- I2C write operation


- I2C Read operation

## 1.2 學習使用 Linux I2C 工具進行通訊、透過 I2C 控制 MPQ7920輸出對應訊號
:::success
- **操作步驟**:
* 安裝 I2C 工具
* 確認硬體連接
* 掃描 I2C 裝置並確認 MPQ7920 的地址
* 讀取 MPQ7920 寄存器值來確認通訊成功
* 根據 MPQ7920 數據手冊設置 Buck 輸出電壓
* 確認設置是否正確反映在寄存器值上
:::
這邊必須把Master(這裡是Nvidia Jetson AGX Xavier)與Slave(這裡是MPQ7920)之間透過 I2C實際連接才能進行通訊,需要確保系統中已經安裝了必要的 I2C 工具,並且硬體連接正確。以下是步驟:
### 1.2.1. 確認硬體連接
確保 AGX Xavier 與 MPQ7920 之間的物理連接正確無誤。通常這會涉及到確認連接線是否正確連接到對應的 I2C 數據 (SDA) 和時鐘 (SCL) 針腳,以及是否有適當的電源和接地。
#### Nvidia AGX Xavier 平台的 I2C接口
參考硬體規格配置文件
- [Jetson Xavier Developer Kit Carrier Board Specification](chrome-extension://mhnlakgilnojmhinhkckjpncpbhabphi/pages/pdf/web/viewer.html?file=https%3A%2F%2Fstatic5.arrow.com%2Fpdfs%2F2018%2F12%2F12%2F12%2F23%2F1%2F848262%2Fnvda_%2Fmanual%2Fjetson_xavier_developer_kit_carrier_board_specification.pdf)
找出版上的I2C接口



> Jetson AGX Xavier Pin 1([source: 2018。
JetsonHacks。JETSON AGX XAVIER J30 GPIO EXPANSION HEADER PINOUT](https://jetsonhacks.com/nvidia-jetson-agx-xavier-gpio-header-pinout/))
> :warning: 注意:top是左邊,不然針腳會插反
- 先在Master端安裝 Linux I2C 工具
在大多數基於 Debian 的 Linux 發行版上,可以使用以下命令安裝 I2C 工具:
```bash
sudo apt-get update
sudo apt-get install i2c-tools
```
- `i2cdetect` 是一個用於掃描和列出I2C匯流排上連接的設備地址的工具。主要用於檢測和識別I2C設備
#### NMPQ7920的 I2C接口
[MPQ7920 doc](chrome-extension://mhnlakgilnojmhinhkckjpncpbhabphi/pages/pdf/web/viewer.html?file=https%3A%2F%2Fwww.monolithicpower.com%2Fen%2Fdocumentview%2Fproductdocument%2Findex%2Fversion%2F2%2Fdocument_type%2FDatasheet%2Flang%2Fen%2Fsku%2FMPQ7920GRM-AEC1%2F)
|  |  |
| -------- | -------- |
> NMPQ7920的I2C數據SDA和SCL針腳
- I2C Bus Slave Address
The slave address is a 7-bit address followed by an 8th read or write (R/W) data direction bit.

- By default, the **slave address is 0x69, A[7:1] = 110 1001**
- *The A5 to A1bits can be configured by the MTP e-Fuse
- 補充
:::spoiler
1. **MTP e-Fuse(多次可編程電子保險絲)**:
- MTP(Multi-Time Programmable)e-Fuse是一種特殊的記憶體技術,用於存儲配置或校準數據等非揮發性信息。允許數據在芯片生產後被多次編程或修改。
- 與傳統的一次性可編程(OTP)保險絲不同,MTP e-Fuse可以在初始編程後進行重寫或更新,這提供了更大的靈活性。
- MTP e-Fuse通常用於設備配置、功能啟用/禁用、校準數據存儲等。即使在多次編程後也能保持數據完整。
2. **A5到A1位可通過MTP e-Fuse配置**:
- 在I2C總線從屬地址(slave address)範例中,地址為0x69,二進制表示為110 1001。這裡的A[7:1]表示7位地址,其中A7到A1分別代表不同的位。
- 「A5到A1位可通過MTP e-Fuse配置」指這7位地址中,從A5到A1的位可以使用MTP e-Fuse技術進行配置。這允許設備製造商或使用者根據需要設定這些位的值。
- 這種配置的靈活性允許同一種設備在不同的應用中有不同的地址設置,或者在一個系統中容納多個相同的設備而不會發生地址衝突。
- 例如,如果一個系統中有多個相同的I2C設備,通過改變每個設備的A5到A1位,可以賦予它們不同的從屬地址,從而在同一總線上實現共存。
:::
### 1.2.2 NMPQ7920電源供電
|  |  |
| -------- | -------- |
| 連接示意圖 | 電源連接 |
| ------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|  | MPQ7920需要2.7V至5.5V的輸入電壓範圍<br>,通過其VIN引腳供電。<br>在這次的設置中,要將MPQ7920的VIN引腳與<br>Nvidia Jetson AGX Xavier開發板的5V電源相連。<br>~~為了確保電源穩定,使用寬的PCB走線,<br>並在VIN引腳旁邊並聯了陶瓷電容器以去耦~~ |
- I2C通訊
成功供電後,試著使用I2C通訊協議來控制MPQ7920。
- 在Nvidia Jetson AGX Xavier上使用命令`i2cdetect -y -r 8`
- 掃描到了地址為0x69的I2C裝置,確認了MPQ7920已正確連接至I2C總線。
```bash=
$ sudo i2cdetect -y -r 8
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- 69 -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
```
:::warning
- [2018。JetsonHacks。JETSON AGX XAVIER J30 GPIO EXPANSION HEADER PINOUT](https://jetsonhacks.com/nvidia-jetson-agx-xavier-gpio-header-pinout/))
天外飛來一個幫把先查看AGX-Xavier的I2C 匯流排編號都查好的資訊,不用土炮一個個查了
- Pins 3 and 5 are on I2C bus 8. For detection:
$ `sudo i2cdetect -y -r 8`
- Pins 27 and 28 are on I2C bus 1. For detection:
$ `sudo i2cdetect -y -r 1`
:::
#### 土砲查找AGX-Xavier的I2C 匯流排編號過程(記得先讓參考1.2.2 NMPQ7920電源供電)
:::spoiler
- 先查看AGX-Xavier的I2C匯流排`ls /dev/i2c-*`
- 有11個
- 一個是用圖法煉鋼的方式,使用`sudo i2cdetect -y 0`、`sudo i2cdetect -y 1`、..土炮人工查找
```bash=
/dev/i2c-0 /dev/i2c-101 /dev/i2c-2 /dev/i2c-4 /dev/i2c-6 /dev/i2c-8
/dev/i2c-1 /dev/i2c-102 /dev/i2c-3 /dev/i2c-5 /dev/i2c-7
```
- `sudo i2cdetect -l`
```bash=
i2c-3 i2c 3190000.i2c I2C adapter
i2c-1 i2c c240000.i2c I2C adapter
i2c-101 i2c 15210000.display I2C adapter
i2c-8 i2c 31e0000.i2c I2C adapter
i2c-6 i2c 31c0000.i2c I2C adapter
i2c-4 i2c Tegra BPMP I2C adapter I2C adapter
i2c-2 i2c 3180000.i2c I2C adapter
i2c-0 i2c 3160000.i2c I2C adapter
i2c-102 i2c 15220000.display I2C adapter
i2c-7 i2c c250000.i2c I2C adapter
i2c-5 i2c 31b0000.i2c I2C adapter
```
- 根據關鍵字"31e0000"去檢視device tree文件
- 在source code的目錄下查找`~/Linux_for_Tegra$ grep -rnw --include=*.dts --include=*.dtsi '.' -e 'i2c@31e0000'`
```bash=
./source/public/hardware/nvidia/platform/t19x/common/kernel-dts/t19x-common-modules/tegra194-super-module-e2614.dtsi:10: i2c@31e0000 {
./source/public/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-super-module-e2614-p2888-0000.dtsi:24: i2c@31e0000 {
./source/public/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-p2888-0001-p2822-0000-common.dtsi:355: hdr40_i2c1: i2c@31e0000 {
./source/public/hardware/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-super-module-e2614.dtsi:19: i2c@31e0000 {
```
- 使用`dmesg | grep /dev/i2c-*`查看是否有新的i2c設備被識別
```bash=
grep: /dev/i2c-1: Remote I/O error
grep: /dev/i2c-101: Bad address
grep: /dev/i2c-102: Bad address
grep: /dev/i2c-2: Remote I/O error
grep: /dev/i2c-3: Connection timed out
grep: /dev/i2c-4: Invalid argument
grep: /dev/i2c-5: Connection timed out
grep: /dev/i2c-6: Connection timed out
grep: /dev/i2c-7: Remote I/O error
grep: /dev/i2c-8: Remote I/O error
```
- 使用 `i2cdetect` 工具來掃描 I2C 匯流排上的裝置
目的是確定 MPQ7920 的 I2C 地址
- results
- 所有地址都是"--",表示在這些地址上沒有發現任何I2C裝置。
根據以上輸出,並沒有顯示MPQ7920的I2C地址。這可能意味著MPQ7920未連接到I2C總線1上 :warning:因為沒有接電:warning:
```bash=
yh@AGX-Xavier:~$ sudo i2cdetect -y -r 8
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
```
:::
- 讀取 I2C 裝置數據
確認了 MPQ7920 的地址後,可以使用 `i2cget` 命令來讀取裝置的數據:
- 成功地讀取了來自channel 8、address:0x69的數據,為0x00
```bash=
yh@AGX-Xavier:~$ sudo i2cget -y 8 0x69
0x00
```
- 寫入 I2C 裝置數據
要控制 MPQ7920 的輸出電壓,需要根據 MPQ7920 的數據手冊提供的寄存器地址和值來設置相應的 Buck 輸出。假設已經知道要設置的寄存器地址和電壓對應的值,可以使用 `i2cset`:
```bash
sudo i2cset -y 1 0x地址 寄存器地址值
```
這將會設置特定寄存器的值。需要替換 `0x地址`,`寄存器地址` 和 `值` 為實際的數值。
### 1.2.3 MPQ7920 控制
#### `i2cdump`命令
- 用於從指定的I2C設備中讀取數據並在終端上顯示該數據的16進制表示。它的主要功能包括以下幾個方面:
1. 讀取I2C設備的數據:`i2cdump`通過指定I2C總線的編號和設備地址,可以從特定的I2C設備中讀取數據
2. 顯示16進制表示:讀取的數據以16進制表示在終端上顯示。每個字節(8位)的數據都以兩個16進制數字的形式呈現,並以空格分隔
3. 以表格形式顯示:`i2cdump`以表格形式顯示數據,其中每一行代表I2C設備的16個連續字節。表格的左側顯示了地址索引
4. 支持字節大小設定:你可以選擇指定讀取的字節數,以便只讀取特定範圍的數據。默認情況下,它使用字節數據訪問
- results
- 位址: 左側的數字(00、10、20等)代表了每一行的起始位址,稱為高位位址。頂部的數字(0、1、2等)表示每一列的低位位址。
- 數據: 表中的每個數字代表了該位址的當前值。例如,如果你在位址0x00(第一行第一列)處看到0x2a,這表示設備在位址0x00的註冊中存儲了值0x2a。
:::spoiler
```bash=?
yh@AGX-Xavier:~$ sudo i2cdump -y 8 0x69
No size specified (using byte-data access)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: a2 58 03 3c 70 c4 00 58 70 c4 66 3c 70 d4 00 70 ?X?<p?.Xp?f<p?.p
10: 70 d4 66 e8 70 29 77 70 20 77 38 20 77 70 20 99 p?f?p)wp w8 wp ?
20: 00 87 ff 03 01 00 00 ff 00 85 00 00 00 00 00 ff .?.??....?......
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
40: ff 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .?..............
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
80: 75 4c e8 a4 1c 9b c0 75 75 75 75 75 75 75 75 75 uL?????uuuuuuuuu
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
a0: 00 00 00 00 50 00 00 00 00 40 00 00 00 00 00 00 ....P....@......
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
```
:::
#### MPQ7920註冊表解讀

:::success
- 每個Buck轉換器的VREF(電壓參考)註冊位址分別是:
- Buck1: 0x03位址,VREF值範圍是0.4V到3.5875V/12.5mV或0.4V到2.2V/7.4mV。
- Buck2: 0x07位址,VREF值範圍同Buck1。
- Buck3: 0x0B位址,VREF值範圍同Buck1。
- Buck4: 0x0F位址,VREF值範圍同Buck1。
- 為了控制每個Buck的輸出電壓,需要寫入相應的VREF值到這些註冊位址中。這些值應該基於的輸出需求來計算
```python=
# 計算步進數
step_count = (target_voltage - base_voltage) / voltage_step
# 計算十六進位制的VREF值
vref_value_hex = hex(int(step_count))
```
:::
- **VREF**:電壓參考(**Voltage Reference**值
:::info
參考電壓用於設置或調節其他電壓的值,並且通常是精準和穩定的。在MPQ7920這樣的集成電路中,VREF用於確定降壓轉換器(Buck Converter)的輸出電壓。
具體來說,對於MPQ7920:
- **VREF值**表示該Buck轉換器可以設置的輸出電壓參考範圍。這是一個可編程的值,用戶可以通過I2C命令修改這個值以改變Buck轉換器的輸出電壓。
- **VREF註冊**提供了一種通過I2C協議來控制這個參考電壓的機制。根據提供的表格,Buck1、Buck2、Buck3和Buck4的VREF值可以在0.4V至3.5875V或0.4V至2.2V的範圍內調節,並且註冊位址分別是`0x03`、`0x07`、`0x0B`和`0x0F`。
要控制這些Buck轉換器的輸出電壓,需要通過I2C寫入適當的數值到對應的VREF註冊位址中。這個數值通常是基於特定的分辨率計算出來的。分辨率是指最小的可調節電壓增量,如12.5mV或7.4mV。例如,如果分辨率是12.5mV,並且想要設置輸出電壓為1V,那麼需要計算1V對應到多少個12.5mV的增量,並將這個值寫入到VREF註冊中。
最後,這些設置在MPQ7920的**MTP**(多次可編程記憶體)中是持久化的,意味著即使在斷電後,這些設置仍然會被保留。在進行這些設置時,應該遵循IC的數據手冊和規範,以確保準確性和裝置的安全。
:::
- 位址之間的間隔剛好是4個字節(bytes)
1. **數據結構對齊(Data Structure Alignment)**:在許多系統中,數據結構對齊是為了提高存取效率。對齊可以確保數據結構位於其自然邊界上,這樣處理器可以更有效率地存取數據。
2. **避免資源衝突(Resource Conflict Avoidance)**:在硬件設計中,將不同的功能或模塊分配到不同的位址空間,可以避免資源衝突。這樣的間隔確保每個模塊有足夠的位址空間,不會與其他模塊發生重疊。
3. **擴展性(Scalability)**:這種設計允許未來的擴展。例如,如果每個Buck轉換器需要更多的配置位址空間,這種間隔設計可以方便地在現有的結構中添加新的功能或模塊。
4. **簡化設計(Design Simplification)**:固定的間隔可以簡化硬件和軟件的設計。對於軟件開發者來說,這意味著可以使用一致的模式來存取不同的硬件模塊,從而簡化了程式碼的編寫和維護。
接下來使用Linux已經寫好的工具來進行i2c的設定
#### 使用Linux的`i2cset`命令來設定註冊值
- 使用直流(DC)測量
- 需要為每一個Buck轉換器重複這樣的命令,只是更改對應的註冊地址和值
```python=?
# 設定Buck #1的輸出電壓為0.7V
# 步進數:(0.7V - 0.4V) / 12.5mV = 300 / 12.5 = 24
# 將步進數轉換為十六進位制: 128 = 0x18
sudo i2cset -y 8 0x69 0x03 0x18
# 設定Buck #2的輸出電壓為2.0V
# 步進數:(2.0V - 0.4V) / 12.5mV = 1600 / 12.5 = 128
# 將步進數轉換為十六進位制: 128 = 0x80
sudo i2cset -y 8 0x69 0x07 0x80
# 設定Buck #3的輸出電壓為1.0V
# 步進數:(1.0V - 0.4V) / 12.5mV = 600 / 12.5 = 48
# 十六進位制: 48 = 0x30
sudo i2cset -y 8 0x69 0x0B 0x30
# 設定Buck #4的輸出電壓為0.8V
# 步進數:(0.8V - 0.4V) / 12.5mV = 600 / 12.5 = 32
# 十六進位制: 32 = 0x20
sudo i2cset -y 8 0x69 0x0F 0x20
```
| port | Buck1 | Buck2 | Buck3 | Buck4 |
|:-----------:|:------------------------------------------------------------:|:------------------------------------------------------------:|:------------------------------------------------------------:|:------------------------------------------------------------:|
| Address | 0x03 | 0x07 | 0x0B | 0x0F |
| Base_V(V) | 0.4 | 0.4 | 0.4 | 0.4 |
| V_Step(mV) | 12.5 | 12.5 | 12.5 | 12.5 |
| Target_V(V) | 0.7 | 2.0 | 1.0 | 0.8 |
| Step_Count | (0.7V - 0.4V) / 12.5mV <br>= 300 / 12.5 <br>= 24 | (2.0V - 0.4V) / 12.5mV <br>= 1600 / 12.5 <br>= 128 | (1.0V - 0.4V) / 12.5mV <br>= 600 / 12.5 <br>= 48 | (0.8V - 0.4V) / 12.5mV <br>= 600 / 12.5 <br>= 32 |
| HEX(Count) | 0x18 | 0x80 | 0x30 | 0x20 |
| Measure |  |  |  |  |
#### 使用`i2cget`命令或者的程式來讀取註冊值,確認電壓已經被正確設定
```bash=
yh@AGX-Xavier:~$ sudo i2cget -y 8 0x69 0x03
0x18
yh@AGX-Xavier:~$ sudo i2cget -y 8 0x69 0x07
0x80
yh@AGX-Xavier:~$ sudo i2cget -y 8 0x69 0x0B
0x30
yh@AGX-Xavier:~$ sudo i2cget -y 8 0x69 0x0F
0x20
```
## Task 1 參考資料
#### [2022。科技咖啡館。I2C]
#### [成大資工 Wiki。I2C: Inter-Integrated Circuit](https://wiki.csie.ncku.edu.tw/embedded/I2C)
內有詳細完整介紹與控制程式碼
#### [2016.12。陸向陽 。【Maker進階】認識UART、I2C、SPI三介面特性](https://makerpro.cc/2016/07/learning-interfaces-about-uart-i2c-spi/)
#### [2021。Rahul Iyer。Arduino初學者指南-Arduino通訊協議教學](https://micro.rohm.com/tw/deviceplus/how-tos/arduino-guide/arduino-communication-protocols-tutorial/)

> Arduino上的UART、SPI、I2C介面接腳位置(綠框)
- UART
- 不是具體介面,只提供雛形基礎,以此基礎再加搭電路與軟體,才可以實現不同的介面
- RS-232介面只允許兩個裝置直接對接
- 老舊電腦的RS-232介面(在電腦領域稱為串列埠,Serial Port)
> UART僅適合兩個裝置對接,圖為微控制器晶片(uC)與全球定位系統(GPS)的對接。
# 2. 學習與應用: GMSL2 Camera
## 2.1 GMSL2 camera與 USB camera、MIPI camera 的差異
- **USB Camera**:
- 直接通過 USB 接口連接。
- 適用於距離較短,即插即用。
- 數據傳輸速度受限於 USB 標準。
- **MIPI Camera**:
- 使用 MIPI CSI(Camera Serial Interface)。
- 高速,專為移動設備設計。
- 通常內建於裝置中,如手機。
- **GMSL2 Camera**:
- 使用 GMSL(Gigabit Multimedia Serial Link)接口。
- 支持更長的傳輸距離和更高的數據傳輸速率。
- 適用於汽車和工業應用。
## 2.2 與SERDES(Serializer、Deserializer)的關係
- **SERDES**:
- 將平行數據序列化(Serializer),以及將序列數據轉回平行數據(Deserializer)。
- GMSL2 使用 SERDES 技術進行高速數據傳輸。
# 3. 評核驗收
## 3.1 串接 econ-System 的 camera module 到 Nvidia Xavier Kit
:::success
- **操作步驟**:
1. 確認 camera module 和 Xavier Kit 的接口相容性。
2. 將 camera module 連接到 Xavier Kit。
3. 驗證連接成功,如通過命令行檢查。
:::
## 3.2 根據 Vendor 文件,porting camera driver 到Xavier Kit
:::success
- **操作步驟**:
1. 下載並閱讀 vendor 提供的 camera driver 文件。
2. 根據文件說明,在 Xavier Kit 上編譯並安裝 driver。
3. 驗證 driver 安裝成功並正常運作。
:::
## 3.3 透過 Gstreamer 指令串接 camera driver,將camera capture 的影像輸出至 HDMI 螢幕
:::success
- **操作步驟**:
1. 確認 Gstreamer 已在 Xavier Kit 上安裝。
2. 使用 Gstreamer 命令行構建 pipeline,從 camera 接收數據。
3. 將接收到的影像數據輸出到 HDMI 顯示器。
:::