TI/TDA3

UART2 추가 가이드

728x90

테스트 환경

  • Ubuntu 22.04
  • TDA3XEVM
  • PROCESSOR_SDK_VISION_03_08_00_00

TDA3xx Vision SDK 환경에서 UART2(SOC_UART2_BASE)를 통신 전용으로 추가하는 방법을 설명한다.
기존 디버그 UART(UART3, devId=2)는 그대로 유지하고, UART2를 CSL 레벨 폴링 방식으로 별도 구현한다.

┌──────────────┐     BSP GIO Driver      ┌─────────────┐
│  Debug Host  │◄────────────────────────►│ UART3       │  디버그 콘솔
│  (PC 터미널)  │     (인터럽트 방식)        │ devId=2     │  Vps_printf
└──────────────┘                          └─────────────┘

┌──────────────┐     CSL Polling Driver   ┌─────────────┐
│  UART        │◄────────────────────────►│ UART2       │  통신
│  외부 장치     │     (레지스터 직접 제어)     │ SOC_UART2   │  
└──────────────┘                          └─────────────┘

 

UART를 활성화 하기 전에 해당 핀에 대한 클럭을 활성화 해야한다.

UART2 클럭은 SBL 부트로더가 활성화한다.
(`sbl_utils_tda3xx.c`의 `gModuleEnableTable`에 UART1/UART2 포함)

✔ UART2 클럭은 부트로더(SBL)에서 이미 활성화
➡ PRCM 별도 설정 불필요

✔ 하지만 핀 MUX 설정은 반드시 코드에서 직접 설정해야 함
→ UART2_RXD/PAD, UART2_TXD/PAD 각각 muxmode/pull-up 설정 필요

| 핀 | PAD 레지스터 오프셋 | 설정값 | 의미 |
|----|-------------------|--------|------|
| UART2_RXD | 0x4A003400 + 0x1CC | 0x00060000 | inputenable=1, pulluden=1, muxmode=0 |
| UART2_TXD | 0x4A003400 + 0x1D0 | 0x00000000 | muxmode=0 |

HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE + 0x1ccU, 0x00060000U);
HW_WR_REG32(SOC_CORE_PAD_IO_REGISTERS_BASE + 0x1d0U, 0x00000000U);

 

코드는 아래 ti에서 제공하는 기본 예제를 참고하였음

PROCESSOR_SDK_VISION_03_08_00_00/ti_components/drivers/pdk_01_10_04_05/packages/ti/drv/stw_lld/uartconsole/src/uartconsole.c

 

위 코드는 아래와 같은 순서로 초기화 (baud = 38400)

┌───────────────────────────────────────────┐
│                                           │
│  ① UARTModuleReset(base)                  │
│     → UART 모듈 소프트 리셋                   │
│                                            │
│  ② UARTFIFOConfig(base, fifoConfig)       │
│     → TX/RX FIFO 활성화 및 클리어             │
│     → TX trigger: 56바이트, RX trigger: 1   │
│                                            │
│  ③ UARTDivisorValCompute(48MHz, baud, 16x) │
│     → divisor = 48000000 / (16 × 38400)    │
│     → divisor = 78                         │
│                                            │
│  ④ UARTDivisorLatchWrite(base, 78)         │
│     → DLL = 78 & 0xFF = 0x4E               │
│     → DLH = 0x00                           │
│                                            │
│  ⑤ UARTRegConfigModeEnable(MODE_B)         │
│     → LCR = 0xBF (EFR 접근용)                │
│                                             │
│  ⑥ UARTLineCharacConfig(8N1)               │
│     → 8비트 데이터, 1 스톱비트, 패리티 없음       │ 
│                                             │
│  ⑦ UARTDivisorLatchDisable()               │
│     → DLAB 비트 클리어                        │
│                                             │
│  ⑧ UARTBreakCtl(DISABLE)                   │
│     → Break condition 비활성화                │
│                                             │
│  ⑨ UARTOperatingModeSelect(UART16x)         │
│     → MDR1[2:0] = 0 (UART 16x 모드)          │
│                                             │
└─────────────────────────────────────────────┘
| 레지스터 | 오프셋 | 역할 |
|---------|--------|------|
| RBR (Receive Buffer) | 0x00 | 수신 데이터 읽기 (DLAB=0) |
| THR (Transmit Holding) | 0x00 | 송신 데이터 쓰기 (DLAB=0) |
| DLL / DLH | 0x00 / 0x04 | Baud rate 분주기 (DLAB=1) |
| LCR (Line Control) | 0x0C | 8N1 설정 + DLAB 제어 |
| LSR (Line Status) | 0x14 | DR(bit0)=수신있음, THRE(bit5)=송신가능 |
| MDR1 (Mode Definition) | 0x20 | 동작모드 (0=UART16x) |
| SYSS (System Status) | 0x54 | RESETDONE(bit0) |

 

함수 내용은 아래 파일에서 확인 가능하다.

PROCESSOR_SDK_VISION_03_08_00_00/ti_components/drivers/pdk_01_10_04_05/packages/ti/csl/src/ip/uart/V1/priv/uart.c

 

파일안에 UARTCharPut을 통해 Write, UARTCharGet을 통해 Read 작업을 수행하면 된다.

void UARTCharPut(uint32_t baseAddr, uint8_t byteTx)
{
    uint32_t lcrRegValue = 0;

    /* Switching to Register Operational Mode of operation. */
    lcrRegValue = UARTRegConfigModeEnable(baseAddr, UART_REG_OPERATIONAL_MODE);

    /*
    ** Waits indefinitely until the THR and Transmitter Shift Registers are
    ** empty.
    */
    while (((uint32_t) UART_LSR_TX_SR_E_MASK |
            (uint32_t) UART_LSR_TX_FIFO_E_MASK) !=
           (HW_RD_REG32(baseAddr + UART_LSR) &
            ((uint32_t) UART_LSR_TX_SR_E_MASK |
             (uint32_t) UART_LSR_TX_FIFO_E_MASK)))
    {
        /* Do nothing - Busy wait */
    }

    HW_WR_REG32(baseAddr + UART_THR, (uint32_t) byteTx);

    /* Restoring the value of LCR. */
    HW_WR_REG32(baseAddr + UART_LCR, lcrRegValue);
}

 

/**
 * \brief    This API waits indefinitely for the arrival of a byte in
 *           the receiver FIFO. Once a byte has arrived, it returns that
 *           byte.
 *
 * \param    baseAddr     Memory address of the UART instance being used.
 *
 * \return   This returns the read byte.
 */

int8_t UARTCharGet(uint32_t baseAddr)
{
    uint32_t lcrRegValue = 0;
    int8_t   retVal      = 0;
    uint32_t tempRetVal  = 0;

    /* Switching to Register Operational Mode of operation. */
    lcrRegValue = UARTRegConfigModeEnable(baseAddr, UART_REG_OPERATIONAL_MODE);

    /* Waits indefinitely until a byte arrives in the RX FIFO(or RHR). */
    while ((uint32_t) UART_LSR_RX_FIFO_E_RX_FIFO_E_VALUE_0 ==
           (HW_RD_REG32(baseAddr + UART_LSR) &
            UART_LSR_RX_FIFO_E_MASK))
    {
        /* Do nothing - Busy wait */
    }

    tempRetVal = HW_RD_REG32(baseAddr + UART_RHR);
    retVal     = ((int8_t) tempRetVal);

    /* Restoring the value of LCR. */
    HW_WR_REG32(baseAddr + UART_LCR, lcrRegValue);

    return retVal;
}

 

728x90

'TI > TDA3' 카테고리의 다른 글

Draw2D를 이용해 한글 표시  (0) 2025.12.31
I2C SLAVE MODE  (0) 2025.06.03
Vision SDK Usecase 사용 방법  (0) 2025.04.16
CSL Example 프로그램 사용 방법  (0) 2025.04.12
TDA3-EVM PDK Build  (0) 2025.04.12