[Aurix TC275] ADC - 4

사이킷·2025년 1월 18일

AURIX MCU

목록 보기
6/13

이번에는 ADC 초기화중 Channel 초기화 코드 부분을 살펴보겠다.

ADC Channel 초기화 코드

    /* channel init */
    for (chnIx = 0; chnIx < 5; ++chnIx) {
        IfxVadc_Adc_initChannelConfig(&adcChannelConfig[chnIx], &g_VadcAutoScan.adcGroup);

        adcChannelConfig[chnIx].channelId = (IfxVadc_ChannelId)(chnIx);
        adcChannelConfig[chnIx].resultRegister = (IfxVadc_ChannelResult)(chnIx);

        /* initialize the channel*/
        IfxVadc_Adc_initChannel(&adcChannel[chnIx], &adcChannelConfig[chnIx]);

        /* add to scan */
        unsigned channels = ( 1 << adcChannelConfig[chnIx].channelId);
        unsigned mask = channels;
        IfxVadc_Adc_setScan(&g_VadcAutoScan.adcGroup,channels,mask);


    }

채널 0 번 부터 4번까지 순차적으로 초기화한다.

Channel Configuration

        IfxVadc_Adc_initChannelConfig(&adcChannelConfig[chnIx], &g_VadcAutoScan.adcGroup);

        adcChannelConfig[chnIx].channelId = (IfxVadc_ChannelId)(chnIx);
        adcChannelConfig[chnIx].resultRegister = (IfxVadc_ChannelResult)(chnIx);

마찬가지로 초기값을 IfxVadc_Adc_initChannelConfig() 함수를 통해 가져온다.

void IfxVadc_Adc_initChannelConfig(IfxVadc_Adc_ChannelConfig *config, const IfxVadc_Adc_Group *group)
{
    static const IfxVadc_Adc_ChannelConfig IfxVadc_Adc_defaultChannelConfig = {
        .channelId           = IfxVadc_ChannelId_0,
        .group               = NULL_PTR,
        .inputClass          = IfxVadc_InputClasses_group0,
        .reference           = IfxVadc_ChannelReference_standard,
        .resultRegister      = IfxVadc_ChannelResult_0,
        .globalResultUsage   = FALSE,
        .lowerBoundary       = IfxVadc_BoundarySelection_group0,
        .upperBoundary       = IfxVadc_BoundarySelection_group0,
        .boundaryMode        = IfxVadc_BoundaryExtension_standard,
        .limitCheck          = IfxVadc_LimitCheck_noCheck,
        .synchonize          = FALSE,
        .backgroundChannel   = FALSE,
        .rightAlignedStorage = FALSE,
        .resultPriority      = 0,
        .resultSrcNr         = IfxVadc_SrcNr_group0,
        .resultServProvider  = IfxSrc_Tos_cpu0,
        .channelPriority     = 0,
        .channelSrcNr        = IfxVadc_SrcNr_group0,
        .channelServProvider = IfxSrc_Tos_cpu0
    };
    *config       = IfxVadc_Adc_defaultChannelConfig;
    config->group = group;
}

다음으로 우리가 가져온 Configuration 수정 부분을 보겠다.

        adcChannelConfig[chnIx].channelId = (IfxVadc_ChannelId)(chnIx);
        adcChannelConfig[chnIx].resultRegister = (IfxVadc_ChannelResult)(chnIx);

먼저 채널 ID 이다. for 문을 통해 channel id는 0부터4까지 입력된다.
다음으로는 resultRegister 부분이다.
변환 결과를 저장할 결과 레지스터를 지정하는 부분이다.
똑같이 0부터4까지 입력된다.

Channel Initialization

 IfxVadc_Adc_initChannel(&adcChannel[chnIx], &adcChannelConfig[chnIx]);
IfxVadc_Status IfxVadc_Adc_initChannel(IfxVadc_Adc_Channel *channel, const IfxVadc_Adc_ChannelConfig *config)
{
    IfxVadc_Status    Status = IfxVadc_Status_noError;
    Ifx_VADC         *vadc   = IfxVadc_Adc_getVadcFromGroup(config->group);
    Ifx_VADC_G       *vadcG  = IfxVadc_Adc_getGroupRegsFromGroup(config->group);

    channel->group = config->group;
    IfxVadc_GroupId   groupIndex   = channel->group->groupId;
    IfxVadc_ChannelId channelIndex = config->channelId;

    /* Request Access to configuration registers */
    IfxVadc_enableAccess(vadc, (IfxVadc_Protection)(IfxVadc_Protection_channelControl0 + groupIndex));

    /* Configure Channel */
    {
        IfxVadc_setReferenceInput(vadcG, channelIndex, config->reference);
        IfxVadc_storeGroupResult(vadcG, channelIndex, config->resultRegister);
        IfxVadc_setLowerBoundary(vadcG, channelIndex, config->lowerBoundary);
        IfxVadc_setUpperBoundary(vadcG, channelIndex, config->upperBoundary);
        IfxVadc_setSyncRequest(vadcG, channelIndex, config->synchonize);
        IfxVadc_setChannelInputClass(vadcG, channelIndex, config->inputClass);
        IfxVadc_setChannelLimitCheckMode(vadcG, channelIndex, config->limitCheck);
        IfxVadc_setResultPosition(vadcG, channelIndex, config->rightAlignedStorage);
        IfxVadc_setBackgroundResultTarget(vadcG, channelIndex, config->globalResultUsage);
        IfxVadc_setBoundaryMode(vadcG, channelIndex, config->boundaryMode);
    }

살펴볼 레지스터는
IfxVadc_storeGroupResult(vadcG, channelIndex, config->resultRegister);
에서 설정한 레지스터만 살펴보겠다.

IFX_INLINE void IfxVadc_storeGroupResult(Ifx_VADC_G *vadcG, IfxVadc_ChannelId channelIndex, IfxVadc_ChannelResult resultRegister)
{
    vadcG->CHCTR[channelIndex].B.RESREG = resultRegister;
}

해당 설정은 resultRegister의 값을 설정한다. 0번 채널부터 4번채널까지 0~4이다.

CHCTR 레지스터의 RESREG 필드에 값을 쓴다.


0~4를 입력하면 해당 필드에 0~4가 들어가고
G0RES0 ~ G0RES4 레지스터에 값이 저장된다는 의미이다.

Add to Scan

        /* add to scan */
        unsigned channels = ( 1 << adcChannelConfig[chnIx].channelId);
        unsigned mask = channels;
        IfxVadc_Adc_setScan(&g_VadcAutoScan.adcGroup,channels,mask);
void IfxVadc_setScan(Ifx_VADC_G *group, uint32 channels, uint32 mask)
{
    /* select channels which should take part in the scan sequence */
    /* the mask allows to specify the channels which should be enabled/disabled */
    group->ASSEL.U = (group->ASSEL.U & ~mask) | (channels & mask);
}

ASSEL 레지스터에 값을 입력한다.

디버깅

CHCTR



0~2번 채널까지만 확인해봤는데 RESREG 필드에 0~2의 값이 정확히 들어간것을 확인할 수 있었다.

ASSEL


0x0000001F
00000000 00000000 00000000 00011111
로 0번 채널부터 4번채널까지 정확히 입력된것을 볼 수 있다.

G0RESx

변환 결과가 저장된 레지스터이다.

참조

https://cafe.naver.com/binaryembedded

profile
공부한거 정리, 잘못된 정보 태클은 언제나 환영입니다.

0개의 댓글