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 |