/*! \file ADC.c * \brief Archivo que controlará el periférico ADC. * \author Nadia * \version 1.0.0.0 * \date 06/04/2021 Creation
* 07/04/2021 Modification * \copyright Copyright(C) 2020 SRW * */ /********************************************************** ** Archivos cabecera *********************************************************/ #include "App.h" /******************************************************//** ** Definición de Macros *********************************************************/ #define DEMO_ADC_BASE ADC0 #define DEMO_ADC_SAMPLE_CHANNEL_NUMBER 0U #define DEMO_ADC_CLOCK_DIVIDER 2U #define ChnSennal 5 #define ChnSen 6 #define ChnCos 0 /******************************************************//** ** Variables privadas *********************************************************/ static TaskHandle_t _tskADC; //< Manejador de la tarea de conversión del ADC static GenRxCallBack_t _rxCallBack; //< "Manejador" de función de Call-back para el reporte de datos static adc_result_info_t ValTen; /******************************************************//** ** Métodos privados *********************************************************/ //static void ADC_Configuration(void) //{ // adc_config_t adcConfigStruct; // adc_conv_seq_config_t adcConvSeqConfigStruct; // ///* Configure the converter. */ //#if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) & FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE // adcConfigStruct.clockMode = kADC_ClockSynchronousMode; /* Using sync clock source. */ //#endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE */ // adcConfigStruct.clockDividerNumber = DEMO_ADC_CLOCK_DIVIDER; //#if defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL // adcConfigStruct.resolution = kADC_Resolution12bit; //#endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL */ //#if defined(FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL) & FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL // adcConfigStruct.enableBypassCalibration = false; //#endif /* FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL */ //#if defined(FSL_FEATURE_ADC_HAS_CTRL_TSAMP) & FSL_FEATURE_ADC_HAS_CTRL_TSAMP // adcConfigStruct.sampleTimeNumber = 3U; //#endif /* FSL_FEATURE_ADC_HAS_CTRL_TSAMP */ //#if defined(FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE) & FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE // adcConfigStruct.enableLowPowerMode = false; //#endif /* FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE */ //#if defined(FSL_FEATURE_ADC_HAS_TRIM_REG) & FSL_FEATURE_ADC_HAS_TRIM_REG // adcConfigStruct.voltageRange = kADC_HighVoltageRange; //#endif /* FSL_FEATURE_ADC_HAS_TRIM_REG */ // ADC_Init(DEMO_ADC_BASE, &adcConfigStruct); // //#if !(defined(FSL_FEATURE_ADC_HAS_NO_INSEL) && FSL_FEATURE_ADC_HAS_NO_INSEL) // /* Use the temperature sensor input to channel 0. */ // ADC_EnableTemperatureSensor(DEMO_ADC_BASE, true); //#endif /* FSL_FEATURE_ADC_HAS_NO_INSEL. */ // // /* Enable channel DEMO_ADC_SAMPLE_CHANNEL_NUMBER's conversion in Sequence A. */ // adcConvSeqConfigStruct.channelMask = 0U; // // (1U << DEMO_ADC_SAMPLE_CHANNEL_NUMBER); /* Includes channel DEMO_ADC_SAMPLE_CHANNEL_NUMBER. */ // adcConvSeqConfigStruct.triggerMask = 0U; // adcConvSeqConfigStruct.triggerPolarity = kADC_TriggerPolarityPositiveEdge; // adcConvSeqConfigStruct.enableSingleStep = false; // adcConvSeqConfigStruct.enableSyncBypass = false; // adcConvSeqConfigStruct.interruptMode = kADC_InterruptForEachSequence; // ADC_SetConvSeqAConfig(DEMO_ADC_BASE, &adcConvSeqConfigStruct); // ADC_EnableConvSeqA(DEMO_ADC_BASE, true); /* Enable the conversion sequence A. */ // /* Clear the result register. */ // ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE); // while (!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER, &ValTen)) // { // } // ADC_GetChannelConversionResult(ADC0,ChnCos,&ValTen); // ADC_GetConvSeqAGlobalConversionResult(DEMO_ADC_BASE, &ValTen); //} /*! \fn static void _prcAdc(void) * \brief Tarea de tratamiento del evento de fin de conversión. * \return Nada. */ //static void _prcADC(void) __attribute__((noreturn)); //static void _prcADC (void) //{ //// adc_result_info_t ValTen; // ADC_savedat_t result; // // while(true) // { //// ulTaskNotifyTake(pdFALSE,portMAX_DELAY); // // ** Fuerza el arranque de la conversión de la secuencia A ** // ADC_DoSoftwareTriggerConvSeqA(ADC0); //// while (!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER, &ValTen)) //// { //// } // //// ADC_GetConvSeqAGlobalConversionResult() // ADC_GetChannelConversionResult(ADC0,ChnSennal,&ValTen); // result.resSenn = (uint16_t)ValTen.result; // ADC_GetChannelConversionResult(ADC0,ChnSen,&ValTen); // result.resSen = (uint16_t)ValTen.result; // ADC_GetChannelConversionResult(ADC0,ChnCos,&ValTen); // result.resCos = (uint16_t)ValTen.result; // // // // if (_rxCallBack != NULL) // _rxCallBack(&result, sizeof(ADC_savedat_t)); // // } //while(true) //} //void _prcADC (void) /*! \fn void AppMgrSetCallBack(GenRxCallBack_t callBack) * \brief Establece la función de call-back para reporte de datos. * \param[in] callBack Función que establecer. * \return Nada. */ //void AppMgrSetCallBack(GenRxCallBack_t callBack) //{ // _rxCallBack = callBack; // //} // AppMgrSetCallBack() static void ADC_ClockPower_Configuration(void) { /* SYSCON power. */ POWER_DisablePD(kPDRUNCFG_PD_VDDA); /* Power on VDDA. */ POWER_DisablePD(kPDRUNCFG_PD_ADC0); /* Power on the ADC converter. */ POWER_DisablePD(kPDRUNCFG_PD_VD2_ANA); /* Power on the analog power supply. */ POWER_DisablePD(kPDRUNCFG_PD_VREFP); /* Power on the reference voltage source. */ POWER_DisablePD(kPDRUNCFG_PD_TS); /* Power on the temperature sensor. */ CLOCK_EnableClock(kCLOCK_Adc0); /* SYSCON->AHBCLKCTRL[0] |= SYSCON_AHBCLKCTRL_ADC0_MASK; */ } static void ADC_Configuration(void) { adc_config_t adcConfigStruct; adc_conv_seq_config_t adcConvSeqConfigStruct; /* Configure the converter. */ #if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) & FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE adcConfigStruct.clockMode = kADC_ClockSynchronousMode; /* Using sync clock source. */ #endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE */ adcConfigStruct.clockDividerNumber = DEMO_ADC_CLOCK_DIVIDER; #if defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL adcConfigStruct.resolution = kADC_Resolution12bit; #endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL */ #if defined(FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL) & FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL adcConfigStruct.enableBypassCalibration = false; #endif /* FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL */ #if defined(FSL_FEATURE_ADC_HAS_CTRL_TSAMP) & FSL_FEATURE_ADC_HAS_CTRL_TSAMP adcConfigStruct.sampleTimeNumber = 0U; #endif /* FSL_FEATURE_ADC_HAS_CTRL_TSAMP */ #if defined(FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE) & FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE adcConfigStruct.enableLowPowerMode = false; #endif /* FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE */ #if defined(FSL_FEATURE_ADC_HAS_TRIM_REG) & FSL_FEATURE_ADC_HAS_TRIM_REG adcConfigStruct.voltageRange = kADC_HighVoltageRange; #endif /* FSL_FEATURE_ADC_HAS_TRIM_REG */ ADC_Init(DEMO_ADC_BASE, &adcConfigStruct); #if !(defined(FSL_FEATURE_ADC_HAS_NO_INSEL) && FSL_FEATURE_ADC_HAS_NO_INSEL) /* Use the temperature sensor input to channel 0. */ ADC_EnableTemperatureSensor(DEMO_ADC_BASE, true); #endif /* FSL_FEATURE_ADC_HAS_NO_INSEL. */ /* Enable channel DEMO_ADC_SAMPLE_CHANNEL_NUMBER's conversion in Sequence A. */ adcConvSeqConfigStruct.channelMask = (1U << DEMO_ADC_SAMPLE_CHANNEL_NUMBER); /* Includes channel DEMO_ADC_SAMPLE_CHANNEL_NUMBER. */ adcConvSeqConfigStruct.triggerMask = 0U; adcConvSeqConfigStruct.triggerPolarity = kADC_TriggerPolarityPositiveEdge; adcConvSeqConfigStruct.enableSingleStep = false; adcConvSeqConfigStruct.enableSyncBypass = false; adcConvSeqConfigStruct.interruptMode = kADC_InterruptForEachSequence; ADC_SetConvSeqAConfig(DEMO_ADC_BASE, &adcConvSeqConfigStruct); ADC_EnableConvSeqA(DEMO_ADC_BASE, true); /* Enable the conversion sequence A. */ /* Clear the result register. */ ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE); while (!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER, &ValTen)) { } ADC_GetConvSeqAGlobalConversionResult(DEMO_ADC_BASE, &ValTen); } /******************************************************//** ** Métodos públicos *********************************************************/ /*! \fn void ADCinit(void) * \brief Inicializa las conversiones AD. * \return Nada. */ void ADCinit(void) { //Inicializamos variables // BaseType_t xReturned; // _rxCallBack = NULL; ADC_ClockPower_Configuration(); #if !(defined(FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) && FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) uint32_t frequency = 0U; /* Calibration after power up. */ #if defined(FSL_FEATURE_ADC_HAS_CALIB_REG) && FSL_FEATURE_ADC_HAS_CALIB_REG DEMO_ADC_BASE->CTRL |= ADC_CTRL_BYPASSCAL_MASK; frequency = CLOCK_GetFreq(kCLOCK_BusClk); if (true == ADC_DoOffsetCalibration(DEMO_ADC_BASE, frequency)) #else #if defined(SYSCON_ADCCLKDIV_DIV_MASK) frequency = CLOCK_GetFreq(DEMO_ADC_CLOCK_SOURCE) / CLOCK_GetClkDivider(kCLOCK_DivAdcClk); #else frequency = CLOCK_GetFreq(DEMO_ADC_CLOCK_SOURCE); #endif /* SYSCON_ADCCLKDIV_DIV_MASK */ if (true == ADC_DoSelfCalibration(DEMO_ADC_BASE, frequency)) #endif /* FSL_FEATURE_ADC_HAS_CALIB_REG */ { //PRINTF("ADC Calibration Done.\r\n"); } else { //PRINTF("ADC Calibration Failed.\r\n"); } #endif /* FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC */ /* Configure the converter and work mode. */ ADC_Configuration(); #if defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL //PRINTF("ADC Full Range: %d\r\n", g_Adc_12bitFullRange); #endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL */ while (1) { /* Get the input from terminal and trigger the converter by software. */ GETCHAR(); ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE); //ADC_DoSoftwareTriggerConvSeqB(DEMO_ADC_BASE); //#if 1 //Rong wrote: it appears the lines is incorrect while(!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER, &ValTen)) {} ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER, &ValTen); #if 0 /* Wait for the converter to be done. */ while(!(ADC0->FLAGS& 0x10000000)) //test the ADC0->FLAGS[SEQA_INT], bit 28 { //PRINTF("In loop.\r\n"); } ADC0->FLAGS|=0x10000000; #endif //ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER, &ValTen); // if(!ModoConfig()) // { // //**Inicializamos el módulo ADC // POWER_DisablePD(kPDRUNCFG_PD_VDDA); /* Power on VDDA. */ // POWER_DisablePD(kPDRUNCFG_PD_ADC0); /* Power on the ADC converter. */ // POWER_DisablePD(kPDRUNCFG_PD_VD2_ANA); /* Power on the analog power supply. */ // POWER_DisablePD(kPDRUNCFG_PD_VREFP); /* Power on the reference voltage source. */ // POWER_DisablePD(kPDRUNCFG_PD_TS); /* Power on the temperature sensor. */ // // CLOCK_EnableClock(kCLOCK_Adc0); // // // //Añadido// //#if !(defined(FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) && FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) // uint32_t frequency = 0U; // /* Calibration after power up. */ //#if defined(FSL_FEATURE_ADC_HAS_CALIB_REG) && FSL_FEATURE_ADC_HAS_CALIB_REG // DEMO_ADC_BASE->CTRL |= ADC_CTRL_BYPASSCAL_MASK; // frequency = CLOCK_GetFreq(kCLOCK_BusClk); // if (true == ADC_DoOffsetCalibration(DEMO_ADC_BASE, frequency)) //#else //#if defined(SYSCON_ADCCLKDIV_DIV_MASK) // frequency = CLOCK_GetFreq(DEMO_ADC_CLOCK_SOURCE) / CLOCK_GetClkDivider(kCLOCK_DivAdcClk); //#else // frequency = CLOCK_GetFreq(DEMO_ADC_CLOCK_SOURCE); //#endif /* SYSCON_ADCCLKDIV_DIV_MASK */ // if (true == ADC_DoSelfCalibration(DEMO_ADC_BASE, frequency)) //#endif /* FSL_FEATURE_ADC_HAS_CALIB_REG */ // { // //PRINTF("ADC Calibration Done.\r\n"); // } // else // { // //PRINTF("ADC Calibration Failed.\r\n"); // // } //#endif /* FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC */ // //// // ** Crea y configura los componentes del OS ** //// xReturned = xTaskCreate((TaskFunction_t)_prcADC, "prcADC", 8 * configMINIMAL_STACK_SIZE, NULL, APP_TSK_MID_PRIORITY, &_tskADC); //// configASSERT(xReturned); // // } //if(!ModoConfig()) // // ADC_Configuration(); //// GETCHAR(); // ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE); // ///* Wait for the converter to be done. */ // while (!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER, &ValTen)) // { // } //} //void ADCinit(void) /*! \fn void AdcSetRxCallBack(GenRxCallBack_t callBack) * \brief Establece la función de call-back para reporte de datos. * \param[in] callBack Función de call-back que establecer. * \return Nada. */ //void AdcSetRxCallBack(GenRxCallBack_t callBack) //{ // _rxCallBack = callBack; // //} // AdcSetRxCallBack() ///*! \fn void ADC0_ADC_SEQ_A_IRQHANDLER(void) // * \brief Código interrupción ADC // * \return Nada. // */ //void ADC0_ADC_SEQ_A_IRQHANDLER(void) { // /* Get status flags */ // BaseType_t tskWoken; // // if (kADC_ConvSeqAInterruptFlag == (kADC_ConvSeqAInterruptFlag & ADC_GetStatusFlags(ADC0_PERIPHERAL))) // { // // /* Place your interrupt code here */ // // /* Clear status flags */ // ADC_ClearStatusFlags(ADC0_PERIPHERAL, kADC_ConvSeqAInterruptFlag); // // //En cuanto se detecta algo se notifica a la tarea de tratamiento // vTaskNotifyGiveFromISR(_tskADC,&tskWoken); // portYIELD_FROM_ISR(tskWoken); // } // // /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F // Store immediate overlapping exception return operation might vector to incorrect interrupt. */ // #if defined __CORTEX_M && (__CORTEX_M == 4U) // __DSB(); // #endif //} //void ADC0_ADC_SEQ_A_IRQHANDLER(void) /*! \fn void ADC0_ADC_SEQ_A_IRQHANDLER(void) * \brief Código interrupción ADC * \return Nada. */ /* ADC0_SEQA_IRQn interrupt handler */ //void ADC0_ADC_SEQ_A_IRQHANDLER(void) { // BaseType_t tskWoken; // /* Get status flags */ // if (kADC_ConvSeqAInterruptFlag == (kADC_ConvSeqAInterruptFlag & ADC_GetStatusFlags(ADC0_PERIPHERAL))) // { // // /* Place your interrupt code here */ // // /* Clear status flags */ // ADC_ClearStatusFlags(ADC0_PERIPHERAL, kADC_ConvSeqAInterruptFlag); // //En cuanto se detecta algo se notifica a la tarea de tratamiento // vTaskNotifyGiveFromISR(_tskADC,&tskWoken); // portYIELD_FROM_ISR(tskWoken); // } // // /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F // Store immediate overlapping exception return operation might vector to incorrect interrupt. */ // #if defined __CORTEX_M && (__CORTEX_M == 4U) // __DSB(); // #endif //} // // /********************************************************** ** -- Fin del archivo ADC.c -- **********************************************************/