기존에는 App 단에서 IfxVadc_Adc_startScan(&g_VadcAutoScan.adcGroup); 하면 설정한 그룹내 채널들을 자동으로 돌면서 아날로그 값을 디지털 값으로 변환을 수행하고 값을 바로 가져오는 형식이었다.
이번장에서는 App단에서는
IfxVadc_Adc_startScan(&g_VadcAutoScan.adcGroup);
을 통해 ADC 작업 요청을 하지만 값을 가져오는건 Interrupt를 통해 가져오는 코드를 분석해 보겠다.
adcGroupConfig.scanRequest.autoscanEnabled = FALSE;
autoscanEnabled를 TRUE에서 FALSE로 변경한다.
/* 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);
adcChannelConfig[chnIx].resultSrcNr = IfxVadc_SrcNr_group1;
/* 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);
}
adcChannelConfig[chnIx].resultSrcNr = IfxVadc_SrcNr_group1; 가 추가되었다.
resultSrcNr 는
IfxVadc_SrcNr resultSrcNr; /**< \brief Service node of the result trigger */
VADC 모듈의 Service Node 번호로 인터럽트 또는 서비스 요청을 처리하는 연결지점이다.
IfxVadc_SrcNr_group0 = 0, /**< \brief service request line 0 of group */
IfxVadc_SrcNr_group1 = 1, /**< \brief service request line 1 of group */
IfxVadc_SrcNr_group2 = 2, /**< \brief service request line 2 of group */
IfxVadc_SrcNr_group3 = 3, /**< \brief service request line 3 of group */
4개의 그룹이 있다.
resultSrcNr는 IfxVadc_Adc_initChannel() 함수에서 다음과 같이 사용된다.
IfxVadc_Status IfxVadc_Adc_initChannel(IfxVadc_Adc_Channel *channel, const IfxVadc_Adc_ChannelConfig *config)
{
...
if (config->resultRegister < IfxVadc_ChannelResult_8)
{
IfxVadc_setResultNodeEventPointer0(vadcG, config->resultSrcNr, config->resultRegister);
}
else
{
IfxVadc_setResultNodeEventPointer1(vadcG, config->resultSrcNr, config->resultRegister);
}
...
IFX_INLINE void IfxVadc_setResultNodeEventPointer0(Ifx_VADC_G *vadcG, IfxVadc_SrcNr resultSrcNr, IfxVadc_ChannelResult resultRegister)
{
vadcG->REVNP0.U &= ~(IFX_VADC_G_REVNP0_REV0NP_MSK << (resultRegister * 4));
vadcG->REVNP0.U |= (resultSrcNr << (resultRegister * 4));
}
REVNP0 레지스터를 수정하게 된다.

Group x의 Result Event Node Pointer Register 0 이다.
이 레지스터는 resultRegister 의 결과 이벤트 트리거를 Service Request Line으로 연결하는데 사용된다.
즉 내 설정으로 따르면 ADC 변환이 완료되면 1번 Service Node로 전달된다.
모든 채널을 초기화하면서
adcG->REVNP0.U |= (resultSrcNr << (resultRegister * 4));
이게 실행되니 모든 채널의 변환 완료를 1번 Service Node로 전달한다는 뜻이다.

디버거로 확인해보니 0번부터 4번까지 0x1 로 초기화 되었다.
IfxVadc_enableServiceRequest(g_VadcAutoScan.adcGroup.group, IfxVadc_ChannelResult_4);
/* ADC SRC Setting*/
SRC_VADCG0SR1.B.SRPN = 80u;
SRC_VADCG0SR1.B.TOS = 0u;
SRC_VADCG0SR1.B.SRE = 1u;
IfxVadc_enableServiceRequest(g_VadcAutoScan.adcGroup.group, IfxVadc_ChannelResult_4);
IfxVadc_ChannelResult_4, 즉 4번채널의 변환이 완료되면 인터럽트를 요청하라는 함수이다.
즉 0번부터 4번까지 순차적으로 변환하는데 마지막 4번이 변환이 완료되면 인터럽트가 걸린다.
IFX_INLINE void IfxVadc_enableServiceRequest(Ifx_VADC_G *vadcG, IfxVadc_ChannelResult resultRegister)
{
vadcG->RCR[resultRegister].B.SRGEN = 1;
}


SRGEN 필드를 1로 바꾸면 result event 가 발생하면 인터럽트 서비스를 발생시킨다고 한다.
다음으로는 SRC_VADCGxRy 레지스터를 설정한다.
x는 그룹 넘버 y는 service request line(0-3) 이다.
위에서 IfxVadc_SrcNr_group1을 설정했기 때문에 y = 1이다.


SRPN : 인터럽트 우선순위
TOS : 어떤 CPU에게 인터럽트를 걸지
SRE : 인터럽트 활성화
IFX_INTERRUPT(ADC_G0SR1IntHandler,0,80u);
void ADC_G0SR1IntHandler(void)
{
uint32 chnIx;
Ifx_VADC_RES conversionResult;
IfxCpu_enableInterrupts();
for(chnIx = 0; chnIx < 5u; ++chnIx)
{
conversionResult = IfxVadc_Adc_getResult(&adcChannel[chnIx]);
adcDataResult[chnIx] = conversionResult.B.RESULT;
}
}

static void AppTask10ms(void)
{
stTestCnt.u32nuCnt10ms++;
Unit_Mode();
/*ADC Test*/
//Driver_Adc0_DataObtain();
Driver_Adc0_ConvStart();
}
변환 요청만 하면 인터럽트에 의해서 값을 잘 불러온다