代碼片段解析
while(DSI_REG->DSI_INTSTA.BUSY); // 等待 BUSY 旗標清零
OUTREGBIT(DSI_START_REG, DSI_REG->DSI_START, DSI_START, 1); // 啟動操作
while(DSI_REG->DSI_INTSTA.CMD_DONE == 0); // 等待 CMD_DONE 置位
OUTREGBIT(DSI_INT_STATUS_REG, DSI_REG->DSI_INTSTA, CMD_DONE, 0); // 清除旗標
逐行詳解
DSI_REG:指向硬體暫存器基址的結構體指標 (volatile 修飾)。
DSI_INTSTA:中斷狀態暫存器結構體,包含 BUSY、CMD_DONE 等位元欄位。
while(DSI_REG->DSI_INTSTA.BUSY);:自旋等待,只要 BUSY=1 (硬體忙碌) 就空轉,直到硬體清零表示可接受新命令。
OUTREGBIT(...):巨集函式,將指定暫存器位元寫入 1 (啟動 DSI 傳輸)。
while(DSI_REG->DSI_INTSTA.CMD_DONE == 0);:自旋等待命令完成旗標。
OUTREGBIT(..., CMD_DONE, 0);:軟體清除完成旗標 (寫 1 清零或寫 0 視硬體定義),準備下一次傳輸。
關鍵特性
- volatile 語意:防止編譯器優化掉讀取,確保每次從記憶體/暫存器取最新值。
- 輪詢:適用於無中斷、簡單阻塞等待的驅動程式。
- 共享資源:暫存器可能被 DMA、其他核心修改,故需輪詢而非單次讀取。
優化建議
- 加入 **超時機制** 防止硬體死鎖導致系統卡死:
for (int t=0; tBUSY; t++) udelay(1);
- 若系統支援中斷,改用 **中斷+信號量** 釋放 CPU,提升效能。