본문 바로가기
Embedded SW/[Infineon] Embedded SW Project

[Infineon] 16.2. Aurix (TC23x) UART 초기화 코드 분석

by 방구석 임베디드 2021. 6. 25.
반응형

Infineon Aurix MCU에는 ASCLIN 모듈이 있고, 이 모듈에서 UART를 지원해 준다.

이 모듈의 Block Diagram은 아래와 같다.

우리는 Clock설정에서 fspb Clock을 100MHz로 설정 하였다.

https://embeddedchallenge.tistory.com/34

 

[Infineon] 13. Aurix (TC23x) Clock Setting

임베디드 SW 개발에 있어서 가장 중요하다는 부분이 Clock Setting이라고 생각한다. 모든 주변기기의 동작은 Clock을 받아 동작하기 때문에 몇 Hz의 Clock이 주변기기로 들어오는지를 정확히 알아야 한

embeddedchallenge.tistory.com

 

그리고 fclc clock을 사용할것이다.

uart 통신에 있어서, 확인해야할 설정 값은 무엇일까?

우선 인피니언에서 제공하는 초기화 코드를 살펴 보도록 하자!

static void DrvAsc0Init(void)
{
    /* create module config */
    IfxAsclin_Asc_Config ascConfig;
    IfxAsclin_Asc_initModuleConfig(&ascConfig, &MODULE_ASCLIN0);

    /* set the desired baudrate */
    ascConfig.baudrate.prescaler    = 1;
    ascConfig.baudrate.baudrate     = 9600; /* FDR values will be calculated in initModule */
    ascConfig.baudrate.oversampling = IfxAsclin_OversamplingFactor_4;

    /* ISR priorities and interrupt target */
    ascConfig.interrupt.txPriority    = ISR_PRIORITY_ASC_0_TX;
    ascConfig.interrupt.rxPriority    = ISR_PRIORITY_ASC_0_RX;
    ascConfig.interrupt.erPriority    = ISR_PRIORITY_ASC_0_EX;
    ascConfig.interrupt.typeOfService = (IfxSrc_Tos)IfxCpu_getCoreIndex();

    /* FIFO configuration */
    ascConfig.txBuffer     = g_AsclinAsc.ascBuffer.tx;
    ascConfig.txBufferSize = ASC_TX_BUFFER_SIZE;

    ascConfig.rxBuffer     = g_AsclinAsc.ascBuffer.rx;
    ascConfig.rxBufferSize = ASC_RX_BUFFER_SIZE;

    /* pin configuration */    
    const IfxAsclin_Asc_Pins pins = {
        NULL_PTR,                     IfxPort_InputMode_pullUp,        // CTS pin not used
        &IfxAsclin0_RXB_P15_3_IN, IfxPort_InputMode_pullUp,        // Rx pin
        NULL_PTR,                     IfxPort_OutputMode_pushPull,     //RTS pin not used
        &IfxAsclin0_TX_P15_2_OUT, IfxPort_OutputMode_pushPull,     // Tx pin
        IfxPort_PadDriver_cmosAutomotiveSpeed1
    };        
    ascConfig.pins = &pins;

    /* initialize module */
    IfxAsclin_Asc_initModule(&g_AsclinAsc.drivers.asc0, &ascConfig);

    g_AsclinAsc.count = 1;    
}

위의 코드를 보면 ascConfig 구조체에 설정값을 넣고

IfxAsclin_Asc_initModule 함수를 통하여 UART의 레지스터값을 입력하여 넣고 있는 것을 볼수 있다.

 

UART에서 가장 중요한 부분은 baudrate을 설정하는 부분이다.

위의 코드는 9600bps 설정하고 있다.

1초에 9600개의 비트를 전송한다는 의미이다.

 

UART통신 규격을 살펴보면 아래와 같은 통신 속도를 설정할수 있는것을 확인할수 있다.

결국 저 ILLD를 통해서 레지스터 Setting이 이루어 지고 있는 것이다.

그렇다면 한번 살펴 보도록 하자!

이렇게 나타나고 있는것을 확인할수 있다.

그렇다면 계산을 해보도록 하자!

PRESACLER = 0

NUMERATOR = 1

DENOMINATOR = 0xA2C = 2604

OVERSAMPLING = 4

 

BaudRate = (100Mhz * 1) / (1*2604*4)

= 9600

이 나오는 것을 볼수 있다.

인피니언은 저렇게 ILLD를 제공하여 파라미터값만 넣어서 손쉽게 레지스터값을 변경할수 있다.

 

또 중요한 Spec 가운데 아래 정보를 살펴볼 필요가 있다.

이것의 의미는 무엇일까?

예를들어 5바이트 정보를 보내면  FIFO 버퍼에 5개를 넣어서 한번에 보낼수 있다.

16바이트 정보까지도 16개를 한번에 보낼수 있는 Hardware를 가지고 있다.

하지만 17개를 보낸다면

16개를보내고, 

그대음에 나머지 1개를 보낸다.

 

따라서 아래와 같은 코드를 살펴 보면

void DrvAsc_Test1(void)
{
    int i;
    
    g_AsclinAsc.count = 17;

    for(i=0;i<17;i++)
    {
        g_AsclinAsc.txData[i] = i;
    }
    
    /* Transmit data */
    IfxAsclin_Asc_write(&g_AsclinAsc.drivers.asc0, g_AsclinAsc.txData, &g_AsclinAsc.count, TIME_INFINITE);
}

 

16개를 보내고 아래와 같이 한번 다보냈으니까 ISR이 뜬다.

그리고 아래 API를 이용하여 나머지 1개를 보낸다.

이렇게 16개씩 태워 보내는 구조라는 것을 알수 있다.

void ASCTxInt0Handler(void)
{
    IfxAsclin_Asc_isrTransmit(&g_AsclinAsc.drivers.asc0);
}

 

구현하는 방식은 DMA, 인터럽트, 폴링 여러가지가 있지만

16개의 FIFO 버퍼를 가지고 있다는 의미는 이렇게 해석할수 있다.

 

그렇다면 한번 움직임을 살펴 보도록 하자!

 

코드가 필요하신 분은 다운받으세요 ^^

1) 인피니언에서 제공해주는 예제 코드

AsclinAscDemo.zip
0.02MB

2) 1개의 버퍼를 이용하여 Tx 하는 UART 예제 (9600bps)

MyProject.zip
0.00MB

반응형

댓글