CoreUARTapb

Enable FIFO → Edit IO and locked → Run program

Qertile 郭泰爾
9 min readDec 12, 2022

Fixed mode vs Programmable

Configuration of coreUARTapb

Fixed

在面板上配置參數。運行期間沒辦法更改

Programmable

利用 register 配置,或是用UART_init()在初始化時配置。

TxData: 放傳送的資料

RxData: 放接收的資料

Ctrl1: 設定baud value,利用baud value算出baud rate

Ctrl2: 設定# of bit, parity, parity even/odd, baud value

Ctrl3: 設定baud value fraction

baud value 總共13位元,8位元在Ctrl1,5位元在Ctrl2

FIFO mode

  • FIFO buffer
  • 必須開啟才會有buffer,沒開的話只收的到1byte的資料

Normal mode

  • 資料經過double-buffered 所以不會有loading延遲

Status Register

TXRDY: 等於0時表示FIFO/buffer不再接收新的傳輸資料

RXRDY: 等於1時表示FIFO/buffer裡的資料可以被讀取(取出)

PARITY_ERR: 等於1時表示parity error

OVERFLOW: 等於1時表示Rx FIFO/buffer已經溢位滿出來了

FRAMING_ERR: 等於1時表示接收到的格式錯誤

Driver functions

UART_send

  • 不能假設這個函式return的時候對方已經收到資料,此時可能還正在傳輸。可以釋放或再次使用tx buffer的記憶體空間,因為return時就表示tx buffer中的資料已經被轉移到硬體的tx FIFO

UART_get_rx

  • 不是在FIFO模式時,這個函式會記錄parity, framimg, and overflow錯誤,在FIFO模式只會紀錄overflow錯誤。因此必須使用interrupt來處理parity, framimg錯誤

UART_fill_tx_fifo

  • 用在interrupt-driven 的傳輸
  • 不能假設這個函式return的時候對方已經收到資料,此時可能還正在傳輸。可以釋放或再次使用tx buffer的記憶體空間,因為return時就表示tx buffer中的資料已經被轉移到硬體的tx FIFO

UART_get_rx_status

  • 用OR 結合rx status跟執行UART_get_rx() 時所累積的錯誤
  • 回傳自上次呼叫get_rx_status()以來的所有錯誤
  • 先get_rx_status(),確認沒問題再UART_get_rx()
  • 如果coreUARTapb是用fixed模式的話,UART_init()中的參數沒有作用
  • 也無法修改control register 當中的值
  • APB 介面允許存取內部暫存器、FIFO、內部記憶體

Memory Map

memory map of coreUARTapb

應該是兩組位址都可以用,但根據範例程式只有試過0x5開頭的那個位址可以用,0x3開頭的沒有試過。

Default CoreUART pinout

  • CoreUART_0
    RX → G22 → Not use in SOM
    TX → B22 → Not use in SOM
  • CoreUART_1
    RX → E21 → P2-65 → P13-7
    TX → F20 → P2-55 → P13-8

Fractional Baudrate

原生的core_uart_apb.c、core_uart_apb.h 以及 coreuartapb_regs.h 似乎沒有提供能夠修改fractional baudrate的function,必須先在Libero中啟用enable extra precision。以下是我依照原廠文件的配置修改的作法與邏輯分析儀的驗證。目標3M baudrate,主頻100MHz。

coreuartapb_regs.h

  • 新增 CTRL3_REG_OFFSET 0x14u
  • 新增 CTRL3_BAUDVALUE_MASK 0x07u

coreuartapb_regs.h

  • 新增 UART_set_frac_baud()

coreuartapb_regs.c

  • 新增函式如下
UART_set_frac_baud() in core_uart_apg.c
transmitt without seting fractional baudrate(left), after setting fractional baudrate(right)

Singal Issue

Signal captured by logical analyzer

傳送0x87的資料,但邏輯分析儀收到的是0xC3。推測可能是baud value設定不正確導致baudrate不相符造成資料接收錯誤。

baud value by coreUART handbook and user guide

設定baudrate是57600,clk為system clock 50MHz。因此得到baud value = 53.2534,設定為53。baud value原廠說明如下。

The term baudval must be rounded to the nearest integer and must be greater than or equal to 1 or less than or equal to 8191.

solution

  • 計算baud value的clock是依照FIC_0_CLK,所以在這邊是100MHz
  • 9600, 28800 is good,接近被100MHz整除,baurate的誤差比較小
  • 57600 need to set baud value as 107, not 108
FIC_0_CLK
APB Slaves in the FPGA Fabric Connected to the MSS

ERROR

在CoreUARTapb_1中配置兩組UART,在Place and route時出現以下錯誤,後來改成只各配置一組就解決這個錯誤。

Unable to find a legal assignment of I/O bank voltages which permits all I/Os to be placed

Rx Issue

UART_get_rx() 只能接收到一個byte的資料

Solution

一定要打開 FIFO mode,去IO constrain固定好pin腳,然後lock住腳位

Interrupt Issue — 1

程式無法進入ISR

Solution

範例程式用的是FabricIrq3_IRQHandler,但libero裡的配置是0,1這兩組,對應到coreUART0和coreUART1。

MSS_INT_F2M預設是開啟的,開啟後才能使用FPGA Fabric的interrupt,只有[15:0],共16組可以使用

在 Design Hierarchy 中,右鍵選擇Conver to SmartDesign,即可將system builder建立好的top module平面化(就是攤開來的意思啦),下面第二章圖從左到右。

利用System builder建立的Top module(左),Convert to SmartDesign(右)

攤開之後對著MSS點兩下,或是右鍵configure就可以出現下面的microcontroller配置圖,上面講到的interrupt management就是在這裡

如果要包裝回去的話(上圖從右到左),一樣右鍵Conver to System Builder就好,然後別忘記要set as root,不然IO Constrain裡面會是以MSS為目標,而且在place and route的時候會出現錯誤。

Interrupt Issue — 2

程式卡在IRQHandler裡面,沒辦法離開回到main

  • 從ISR結束離開之後 (0xFFFFFFF9 EXC_RETURN),PC 會回到 NVIC_EnableIRQ裡面, 然後可能是什麼東西又觸發一次 IRQ

Solution

  • Mark the “TXRDY” unused or inverted, since it is high when FIFO is available for transmit data. So it will constantly triggered the interrupt
Mark TXRDY unused, and the TXRDY discription

參考資料

CoreUARTapb v5.6 Handbook

CoreUARTapb Driver UG (UG0130)

UG0331 FIIC

什麼是UART中的FIFO ?

--

--

Qertile 郭泰爾

學習路上順便做點筆記留下痕跡OUO,怕以後忘了曾經所學的這些知識。