論壇總覽 BeagleV-beta RISC-V 開源單板電腦 UART8250 與 NS16550 深入剖析

標籤: , , , ,

正在檢視 1 篇文章 - 1 至 1 (共計 1 篇)
  • 作者
    文章
  • #681
    johnson
    管理員
      @johnson

      UART 8250是最早的UART IC,由美國國家半導體生產製造,後繼IC有UART8250A,NS16550等等。他們修復初代晶片的Bug,如CTS若無即時下拉會導致字元重複輸出等等的問題。

      在Intel8086時代,每個週邊界面都有獨立的界面IC,常見的除了UART之外,GPIO,ADC,DAC等等都有專用晶片。在現今則是將個晶片的矽智財(IP)與主要控制器整合在同一個晶片包裝內,讓電路體積可以更小,更容易被開發。

      下圖是NS18550(與UART8250) 的基本示範電路圖。從圖中可以觀察到,左上角D7-D0是資料匯流排,負責傳送轉換過後的資料給CPU做運算,右方的SOUT與SIN代表著串列輸出Serial out與串列輸入Serial In。與UART通訊協議相容的還有RS232, RS485兩種通訊協定,他們與UART不同之處在於訊號電壓準為不同,但資料格式是相容的,因此右方EIA Driver就是界面轉換電路。

       

      NS16550 腳位介紹:

      A0,A1,A2:晶片位址,可以設定UART8250 位址,搭配CS腳位可選擇要啟用的UART晶片,並可以控制資料流向與型態。

      /ADS: 位址閃爍腳,當其為高態時,會將A0-A2位址訊號以及CS腳位的致能訊號訊栓鎖住。

      /BAUDOUT:鮑率輸出腳,輸出串列訊號的16倍時脈訊號,此時脈訊號等於系統振盪器頻率除上特定除頻值。

      CS0,/CS1,/CS2:晶片致能腳,當CS0高態,CS1與CS2低態時,晶片會被啟用。若/ADS腳位一直處於低態狀態,則就算CS訊號改變,亦不影響晶片狀態。

      /CTS: Clear to Send,當低態時表示資料傳輸裝置(如modem)已經準備好交換資料。作為測試,可以命令CPU讀取bit 4 (CTS)檢查是否與/CTS腳的資料相反。

      D7-D0:資料匯流排,提供CPU與UART晶片雙向的資料流。

      /DCD:Data Carrier Detect資料載體偵測,當它低電位時,表示外部裝置偵測到資料載體(如磁片)。作為測試,可並令CPU讀取bit 7 (DCD)檢查是否與/DCD訊號相反。

      DDIS:Driver Disable驅動裝置關閉,此腳位低電位時表示CPU正在從UART讀取資料。此腳位能夠控制資料匯流排在CPU與UART的資料流向或關閉匯流排。

      /DSR:Data set Ready資料集已準備,當此腳位低電位時,表示MODEM或資料設備已經準備好與UART建立通訊。作為測試,可命令CPU讀取bit 5(DSR),檢查是否與/DSR訊號相反。

      /DTR:Data Terminal Ready資料準備傳輸,低電位時通知MODEM或資料裝置主端已經準備好建立資料連結,/DTR可透過寫入DTR為0設為低態觸發。

      INTR:中斷腳位,此腳位為常態高電位,但當以下狀況發生會轉態為低電位:接收端旗標錯誤,接收訊號可得,超時(僅FIFO模式),傳輸保持存器清空,以及MODEM狀態歸零。

      MR:Master Reset 主端重置腳,當此腳位為高電位,將會重設所有暫存器(除了接收端暫存器,傳送保持暫存器以及拴鎖),並控制UART邏輯狀態。

      /OUT1:第一輸出腳,為使用者自定義輸出,可透過寫入programming bit 2來控制,當MR設定時,輸出為高電位,並進只做動。

      /OUT2:第二輸出腳,為使用者自訂輸出,可透過寫入programming bit 3來控制,當MR設定時,輸出為高電位,並進只做動。

      RCLK:接收器時脈訊號,輸入16倍鮑率時脈。

      RD,/RD:讀取腳,當RD為高電位或/RD為低電位時,CPU可讀取UART經掭暫存器之資料。

      /RI:Ring Indicator響鈴指示,當低電位時,表示MODEM會資料裝置接收到電話鈴響訊號。/RI為MODEM狀態輸入,可藉由CPU讀取bit 6 (RI)來測試,而bit 2(TERI)則表示/RI腳之輸入是否從低電位轉為高電位。

      /RTS:Request to Send請求傳送,當低電位時,通知MODEM或資料裝置UART已經準備好交換資料,/RTS腳位可藉由programming bit 1(RTS)設為低態觸發。

      SIN:Serial Input串列輸入,為串列資料輸入接腳。

      SOUT:Serial Output串列輸出,為串列資料輸出接腳。

      /TXRDY, /RXRDY:傳輸器與接收器可以透過這兩隻腳進行DMA(直接記憶體存取)。當工作在FIFO模式時,可透過FRC3暫存器選擇一種或兩種DMA訊號模式。當工作在NS16450模式時,只能允許DMA在mode 0,而mode 0支援CPU匯流排週期單DMA傳輸

      Vcc:電源腳,接到+5V輸入。

      Vss:接地腳,接到0V參考電位。

      WR,/WR:資料寫入腳,當WR為高電位或/WR為低電位時,且晶片選擇,CPU可以寫入控制位元或資料到UART暫存器。

      XIN:外部振盪器時脈輸入,此腳位與XOUT搭配,連接至鮑率時脈產生器回授電路。當鮑率產生器時脈由外部產生,由此腳位輸入訊號。

      XOUT:外部振盪器時脈輸入,此腳位與XIN搭配,連接至鮑率時脈產生器回授電路。當鮑率產生器時脈由外部產生,由此腳位輸入訊號。

      NS16550的腳位配置圖:

      NS16550 暫存器介紹

      下一步要介紹NS16550的內部暫存器,雖然硬體腳位我們搞清楚了,但軟體的部份卻是整個UART串列不通訊裡面最重要的一環。

      NS16550總共有12個暫存器負責控制/傳送資料,下圖是暫存器列表與個暫存器的說明:

      Recieve Buffer Register接收緩衝暫存器(RBR):儲存接收到的8位元串列訊號資料。

      Trnsmitter Holding Register傳送暫保持存器(THR):儲存下一次要傳送的8位元資料。

      Interrupt Enable Register中斷啟用暫存器(IER):啟用中斷功能的暫存器。

      Interuupt Ident Register (Read only)中斷認知暫存器(IIR):當中斷被啟用且系統進入中斷時,IIR對應位元會轉換狀態。

      FIFO Control Register(Write Only)FIFO控制暫存器(FCR):控制新進先出堆疊(FIFO)之暫存器。

      Line Control Rgister線路控制暫存器(LCR):控制線路要接收的資料參數,如字元長度,停止位元等等。

      身為一位程式設計師,設計的程式碼是給CPU而不是給N16550,要如何存取16550中的暫存器資料,我們可以透過API或組合語言達成。

      但在這之前,我們需要了解每個暫存器中的數值代表的意義以及設定暫存器所需要的數值。

      暫存器詳細說明

      NS16550每個暫存器都是8-bit,因此會對各個暫存器作簡略的介紹,詳細使用說明依然以datasheet為準。

      Line Control Register線路控制暫存器(LCR)

      bit1, bit 0: 決定字元長度,00為5,01為6,10為7,11為8

      bit2: 決定停止位元長度,0時傳送資料會包含停止位元,為1且字元長度為5,傳送半個停止位元,為1且字元長度為6、7、8

      時送兩個停止位元。

      bit3:  奇偶校驗啟用位元,為0時關閉奇偶校驗,為1時開啟奇偶校驗,包含傳輸與接收。

      bit4: 偶校驗選擇位元,當bit3為1時且bit4為0,會傳送奇數個1或檢查奇數個1被接收,當bit3為1且bit4為1,會傳送偶數個1並檢查偶數個1被接收。

      bit5: 奇偶設定相依位元,當bit3,bit4,bit5個別為111時,此位元為0,當bit3,bit4,bit5個別為101時,此位元為1,當bit5為0時,奇偶校驗關閉。

      bit6: 休息控制位元,控制晶片輸出訊號狀態,為1時串列輸出(SOUT)會強制為0,為0時啟用傳列輸出。

      bit7: 除頻栓鎖存取位元,此位元必須設為1才能夠修改鮑綠產生器的除頻器,此位元需設為0才能夠修改接收暫存緩衝器、傳輸維持暫存器以及中斷啟用暫存器。

      Line Status Register線路狀態暫存器(LSR)

      bit0: 接收器資料預備指示位元(DR),當其由0變為1時,表示字元完成接收並轉移到接收暫存器(RBR)或堆疊(FIFO),當RBR或FIFO資料完整送出後,此位元為1。

      bit1: 超載錯誤位元,此位元為1時表示RBR中資料尚未被CPU讀取,且新字元已經傳送進來,會破壞上一個資料。若UART為FIFO模式,此位元會在FIFO滿出時為1,當CPU讀取LSR時重設為0。

      bit2: 校驗錯誤位元,為1時表示奇同位或偶同位校驗錯誤,當CPU讀取LSR時重設為0。

      bit3: 資料框架錯誤位元,為1時表示接收到的資料缺少停止位元,當CPU讀取LSR時重設為0。

      bit4: 休息中斷指示位元,當晶片處於休息狀態但接收到資料時,此位元為1,當CPU讀取LSR時重設為0。

      bit5: 傳輸保持暫存器清空指示位元,當THR清空可傳輸新字元時,此位元為1,此外,此位元通知CPU進入中斷程式,當THR被CPU填滿後,此位元被設為0。

      bit6: 傳輸器清空指示位元,當THR與TSR為0時,此位元為1,當THR或TSR有資料進入,則為0。

      bit7: 錯誤接收(僅FIFO模式),當晶片工作在NS16550模式時為0,當FIFO模式時,校驗錯誤、資料框架錯誤或休息錯誤發生時,此位元為1。當CPU讀取LSR時重設為0。

      FIFO Control Register FIFO控制暫存器(FCR)

      bit0: FRC0,寫入為1時啟用XMIT與RCVR FIFO,設為0時會將上述兩個暫存器清0。

      bit1: FRC1,寫入為1時,會重置XMIT與RCVR FIFO,但位移暫存器不會被重置。

      bit2: FRC2,寫入為1時,只重置XMIT FIFO1並重設計數計數值,位移暫存器內容不被重置。

      bit3: FRC3,寫入為1時,RXRDY與TXRDY會從模式0轉變為模式1。

      bit4-bit5: FCR4,保留位元。

      bit6-bit7: FCR5,用來選擇接收FIFO觸發中斷的數值,00為1(bytes),01為4(bytes),10為8(bytes),11為14(bytes)。

      Interrupt Identification Register 中斷指示暫存器(IIR)

      bit0: 中斷指示位元,用來指示中斷優先與代辦狀態,為0時表示有中斷代辦,IIR會被作為中斷向量服務的函式指標,為1時表示沒有中斷。

      bit1-bit2: 中斷代辦優先權指示,表示目前代辦的中段優先順序,如下表所示:
      IIR暫存器表格

      bit5-bit6: 保留位元,為0。

      bit6-bit7: 當FCR0=1時為1。

      MODEM Control Register MODEM控制暫存器(MCR)

      bit0: 資料終端預備位元,當為1時,/DTR輸出低態,當為0時,/DTR輸出高態。

      bit1: 要求傳送位元,當為1時,/RTS輸出低態,當為0時,/RTS輸出高態。

      bit2: 自訂輸出1,控制/OUT1輸出狀態,行為與bit0相同。

      bit3: 自訂輸出2,控制/OUT2輸出狀態,行為與bit0相同。

      bit4: 回授檢查位元,當設為1時啟用loopback檢查,為0時停用。

      bit5-bit7: 保留位元。

      MODEM Status Register MODEM狀態暫存器(MSR)

      bit0: CTS變化指示位元,當/CTS腳位從CPU上次讀取以來發生變化,此位元為1。

      bit1: DSR變化指示位元,當/DSR腳位從CPU上次讀取以來發生變化,此位元為1。

      bit2: 資料尾端變化位元,當/RI輸入從低態轉高態時,此位元為1。

      bit3: DCD變化指示位元,當/DCD腳位從CPU上次讀取以來發生變化,此位元為1。

      bit4: /CTS互補位元,當MCR bit4為1時,此位元與MCR的RTS位元等效。

      bit5: /DSR互補位元,當MCR bit4為1時,此位元與MCR的DTR位元等效。

      bit6: /RI互補位元,當MCR bit4為1時,此位元與MCR的OUT1位元等效。

      bit7: /DCD互補位元,當MCR bit4為1時,此位元與MCR的OUT2位元等效。

      以上就是NS16550能夠設定與讀取的暫存器簡介,但詳細的暫存器行為還是要以Datasheet中的內容為準。

       

      RISC-V Core 原始碼

      知道這麼多東西,到底與我們的BeagleV有甚麼關係呢?
      先前有提到,OpenSBI是一個RISC-V架構的標準二進制啟動介面,它包含各種需要的啟動韌體,舉凡DDRInit,FileSystem以及傳列傳輸裝置。
      在BeagleV使用的Soc VIC7100中,使用的是NS16550的矽核心,換句話說就是把NS16550包在CPU裡面。
      透過研究NS16550的鎮存器行為與邏輯,我們可以循著線索找到原始碼中關於傳六補ˋ通訊的宣告與處理。
      在github上我們可以找到OpenSBI的原始碼,其中在/lib/utils/serial/uart8250.c中,我們可以發現在一開始就宣告各個暫存器的偏移量(Offset),也就是資料手冊上的暫存器位址。

      仔細比對可以發現,接收暫存器(RBR)與傳送暫存器(THR)的偏移量0,對比到資料手冊鎮存器位址也是0;而中斷辨識暫存器(IIR)與FIFO控制暫存器(FCR)的偏移量是2,對應到資料手冊的記憶體位址也是2。

      所以整個UART轉換器的暫存器設定就在這個檔案裡,詳細的說明就參考下一篇文章~~

      附加檔案:
      你必須 登入 才能查看附件檔案。
    正在檢視 1 篇文章 - 1 至 1 (共計 1 篇)
    • 需要以回覆此篇主題...