This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello,
I wanted to create DMA transfer from ADC based on this thread: "Is there any alternate way to read ADC result data using DMA other than FIFO incase if multiple channels are configured in single group". This is working for ADC1 Group 1 and Group 2 and actually the DMA part is working well with ADC1 Event group as well. But when I checked the memory I found that the event group memory is not good:
0xFF3E0000 0x000014AB 0x00002000 0x0000A000 0x0000A000 0x00008000 0x00008000 0x00008000
0xFF3E001C 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E0038 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E0054 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E0070 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E008C 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E00A8 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E00C4 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E00E0 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E00FC 0x00008000 0x00001000 0x00002000 0x0000A000 0x0000A000 0x00008000 0x00008000
0xFF3E0118 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E0134 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E0150 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E016C 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E0188 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E01A4 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
0xFF3E01C0 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
The above memory should be similar to group2:
0xFF3E0070 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x000014A0
0xFF3E008C 0x00002000 0x0000A000 0x00001498 0x00002000 0x0000A000 0x00001494 0x00002000
0xFF3E00A8 0x0000A000 0x000014A5 0x00002000 0x0000A002 0x000014AA 0x00002000 0x0000A000
0xFF3E00C4 0x000014A4 0x00002000 0x0000A000 0x00001000 0x00002000 0x0000A000 0x00001000
0xFF3E00E0 0x00002000 0x0000A000 0x00001000 0x00002000 0x0000A000 0x0000148F 0x00002000
0xFF3E00FC 0x0000A000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000 0x00008000
I attached the ADC configuration and here is my DMA config as well:
dmaEnable(); // dma config for ADC Channel 0 dma_config.SADD = (uint32_t)0xFF3E0000; dma_config.DADD = (uint32_t) ADC_DATA0; dma_config.CHCTRL = 0; // chain to next channel dma_config.FRCNT = 1; dma_config.ELCNT = transfer_size; dma_config.ELDOFFSET = 0; dma_config.ELSOFFSET = 12; dma_config.FRDOFFSET = 0; dma_config.FRSOFFSET = 0; dma_config.PORTASGN = 4; dma_config.RDSIZE = ACCESS_32_BIT; dma_config.WRSIZE = ACCESS_32_BIT; dma_config.TTYPE = FRAME_TRANSFER; dma_config.ADDMODERD = ADDR_OFFSET; dma_config.ADDMODEWR = ADDR_INC1; dma_config.AUTOINIT = AUTOINIT_ON; // setting dma control packets for ADC Channel 0 dmaSetCtrlPacket(DMA_CH0, dma_config); // dma config for ADC Channel 1 dma_config.SADD = (uint32_t)0xFF3E0004; dma_config.DADD = (uint32_t) ADC_DATA1; dma_config.CHCTRL = 0; // chain to next channel dma_config.FRCNT = 1; dma_config.ELCNT = transfer_size; dma_config.ELDOFFSET = 0; dma_config.ELSOFFSET = 12; dma_config.FRDOFFSET = 0; dma_config.FRSOFFSET = 0; dma_config.PORTASGN = 4; dma_config.RDSIZE = ACCESS_32_BIT; dma_config.WRSIZE = ACCESS_32_BIT; dma_config.TTYPE = FRAME_TRANSFER; dma_config.ADDMODERD = ADDR_OFFSET; dma_config.ADDMODEWR = ADDR_INC1; dma_config.AUTOINIT = AUTOINIT_ON; // setting dma control packets for ADC Channel 1 dmaSetCtrlPacket(DMA_CH1, dma_config); // dma config for ADC Channel 2 dma_config.SADD = (uint32_t)0xFF3E0008; dma_config.DADD = (uint32_t) ADC_DATA2; dma_config.CHCTRL = 0; // chain to next channel dma_config.FRCNT = 1; dma_config.ELCNT = transfer_size; dma_config.ELDOFFSET = 0; dma_config.ELSOFFSET = 12; dma_config.FRDOFFSET = 0; dma_config.FRSOFFSET = 0; dma_config.PORTASGN = 4; dma_config.RDSIZE = ACCESS_32_BIT; dma_config.WRSIZE = ACCESS_32_BIT; dma_config.TTYPE = FRAME_TRANSFER; dma_config.ADDMODERD = ADDR_OFFSET; dma_config.ADDMODEWR = ADDR_INC1; dma_config.AUTOINIT = AUTOINIT_ON; // setting dma control packets for ADC Channel 2 dmaSetCtrlPacket(DMA_CH2, dma_config); dmaReqAssign(0,7); // MIBADC1 G1 is connected to reqline 10. Map Reqline 10 to DMA channel 0 dmaReqAssign(1,7); // MIBADC1 G1 is connected to reqline 10. Map Reqline 10 to DMA channel 1 dmaReqAssign(2,7); // MIBADC1 G1 is connected to reqline 10. Map Reqline 10 to DMA channel 2 dmaSetChEnable(0,DMA_HW); // Enable DMA channel 0 dmaSetChEnable(1,DMA_HW); // Enable DMA channel 1 dmaSetChEnable(2,DMA_HW); // Enable DMA channel 2 adcStartConversion(adcREG1,adcGROUP0);
So the question is why not working adc event group well?
Thank you!
Kind regards,
Keno
/** @file adc.c * @brief ADC Driver Source File * @date 08-Feb-2017 * @version 04.06.01 * * This file contains: * - API Functions * - Interrupt Handlers * . * which are relevant for the ADC driver. */ /* * Copyright (C) 2009-2016 Texas Instruments Incorporated - www.ti.com * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* USER CODE BEGIN (0) */ /* USER CODE END */ /* Include Files */ #include "adc.h" #include "sys_vim.h" /* USER CODE BEGIN (1) */ /* USER CODE END */ /** @fn void adcInit(void) * @brief Initializes ADC Driver * * This function initializes the ADC driver. * */ /* USER CODE BEGIN (2) */ /* USER CODE END */ /* SourceId : ADC_SourceId_001 */ /* DesignId : ADC_DesignId_001 */ /* Requirements : HL_SR185 */ void adcInit(void) { /* USER CODE BEGIN (3) */ /* USER CODE END */ /** @b Initialize @b ADC1: */ /** - Reset ADC module */ adcREG1->RSTCR = 1U; adcREG1->RSTCR = 0U; /** - Enable 12-BIT ADC */ adcREG1->OPMODECR |= 0x80000000U; /** - Setup prescaler */ adcREG1->CLOCKCR = 7U; /** - Setup memory boundaries */ adcREG1->BNDCR = (uint32)((uint32)15U << 16U) | (15U + 15U); adcREG1->BNDEND = (adcREG1->BNDEND & 0xFFFF0000U) | (2U); /** - Setup event group conversion mode * - Setup data format * - Enable/Disable channel id in conversion result * - Enable/Disable continuous conversion */ adcREG1->GxMODECR[0U] = (uint32)ADC_12_BIT | (uint32)0x00000030U | (uint32)0x00000002U; /** - Setup event group hardware trigger * - Setup hardware trigger edge * - Setup hardware trigger source */ adcREG1->EVSRC = (uint32)0x00000000U | (uint32)ADC1_RTI_COMP0; /** - Setup event group sample window */ adcREG1->EVSAMP = 3318U; /** - Setup event group sample discharge * - Setup discharge prescaler * - Enable/Disable discharge */ adcREG1->EVSAMPDISEN = (uint32)((uint32)0U << 8U) | (uint32)0x00000000U; /** - Setup group 1 conversion mode * - Setup data format * - Enable/Disable channel id in conversion result * - Enable/Disable continuous conversion */ adcREG1->GxMODECR[1U] = (uint32)ADC_12_BIT | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)0x00000000U; /** - Setup group 1 hardware trigger * - Setup hardware trigger edge * - Setup hardware trigger source */ adcREG1->G1SRC = (uint32)0x00000008U | (uint32)ADC1_RTI_COMP0; /** - Setup group 1 sample window */ adcREG1->G1SAMP = 3318U; /** - Setup group 1 sample discharge * - Setup discharge prescaler * - Enable/Disable discharge */ adcREG1->G1SAMPDISEN = (uint32)((uint32)0U << 8U) | (uint32)0x00000000U; /** - Setup group 2 conversion mode * - Setup data format * - Enable/Disable channel id in conversion result * - Enable/Disable continuous conversion */ adcREG1->GxMODECR[2U] = (uint32)ADC_12_BIT | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)0x00000000U; /** - Setup group 2 hardware trigger * - Setup hardware trigger edge * - Setup hardware trigger source */ adcREG1->G2SRC = (uint32)0x00000000U | (uint32)ADC1_RTI_COMP0; /** - Setup group 2 sample window */ adcREG1->G2SAMP = 3318U; /** - Setup group 2 sample discharge * - Setup discharge prescaler * - Enable/Disable discharge */ adcREG1->G2SAMPDISEN = (uint32)((uint32)0U << 8U) | (uint32)0x00000000U; /** - ADC1 EVT pin output value */ adcREG1->EVTOUT = 0U; /** - ADC1 EVT pin direction */ adcREG1->EVTDIR = 0U; /** - ADC1 EVT pin open drain enable */ adcREG1->EVTPDR = 0U; /** - ADC1 EVT pin pullup / pulldown selection */ adcREG1->EVTPSEL = 1U; /** - ADC1 EVT pin pullup / pulldown enable*/ adcREG1->EVTDIS = 0U; /** - Enable ADC module */ adcREG1->OPMODECR |= 0x80140001U; /** - Wait for buffer initialization complete */ /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */ while (((adcREG1->BNDEND & 0xFFFF0000U) >> 16U ) != 0U) { } /* Wait */ /** - Setup parity */ adcREG1->PARCR = 0x00000005U; /* USER CODE BEGIN (4) */ adcREG1->EVDMACR=0x001E0005; /* USER CODE END */ } /* USER CODE BEGIN (5) */ /* USER CODE END */ /** - s_adcSelect is used as constant table for channel selection */ static const uint32 s_adcSelect[2U][3U] = { {0x00000000U | 0x00000002U | 0x00000004U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000400U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U, 0x00000000U | 0x00000002U | 0x00000004U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000400U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U, 0x00000000U | 0x00000002U | 0x00000004U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U}, {0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U , 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U, 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U | 0x00000000U} }; /** - s_adcFiFoSize is used as constant table for channel selection */ static const uint32 s_adcFiFoSize[2U][3U] = { {30U, 30U, 4U}, {16U, 16U, 16U} }; /* USER CODE BEGIN (6) */ /* USER CODE END */ /** @fn void adcStartConversion(adcBASE_t *adc, uint32 group) * @brief Starts an ADC conversion * @param[in] adc Pointer to ADC module: * - adcREG1: ADC1 module pointer * - adcREG2: ADC2 module pointer * @param[in] group Hardware group of ADC module: * - adcGROUP0: ADC event group * - adcGROUP1: ADC group 1 * - adcGROUP2: ADC group 2 * * This function starts a conversion of the ADC hardware group. * */ /* SourceId : ADC_SourceId_002 */ /* DesignId : ADC_DesignId_002 */ /* Requirements : HL_SR186 */ void adcStartConversion(adcBASE_t *adc, uint32 group) { uint32 index = (adc == adcREG1) ? 0U : 1U; /* USER CODE BEGIN (7) */ /* USER CODE END */ /** - Setup FiFo size */ adc->GxINTCR[group] = s_adcFiFoSize[index][group]; /** - Start Conversion */ adc->GxSEL[group] = s_adcSelect[index][group]; /** @note The function adcInit has to be called before this function can be used. */ /* USER CODE BEGIN (8) */ /* USER CODE END */ } /* USER CODE BEGIN (9) */ /* USER CODE END */ /** @fn void adcStopConversion(adcBASE_t *adc, uint32 group) * @brief Stops an ADC conversion * @param[in] adc Pointer to ADC module: * - adcREG1: ADC1 module pointer * - adcREG2: ADC2 module pointer * @param[in] group Hardware group of ADC module: * - adcGROUP0: ADC event group * - adcGROUP1: ADC group 1 * - adcGROUP2: ADC group 2 * * This function stops a conversion of the ADC hardware group. * */ /* SourceId : ADC_SourceId_003 */ /* DesignId : ADC_DesignId_003 */ /* Requirements : HL_SR187 */ void adcStopConversion(adcBASE_t *adc, uint32 group) { /* USER CODE BEGIN (10) */ /* USER CODE END */ /** - Stop Conversion */ adc->GxSEL[group] = 0U; /** @note The function adcInit has to be called before this function can be used. */ /* USER CODE BEGIN (11) */ /* USER CODE END */ } /* USER CODE BEGIN (12) */ /* USER CODE END */ /** @fn void adcResetFiFo(adcBASE_t *adc, uint32 group) * @brief Resets FiFo read and write pointer. * @param[in] adc Pointer to ADC module: * - adcREG1: ADC1 module pointer * - adcREG2: ADC2 module pointer * @param[in] group Hardware group of ADC module: * - adcGROUP0: ADC event group * - adcGROUP1: ADC group 1 * - adcGROUP2: ADC group 2 * * This function resets the FiFo read and write pointers. * */ /* SourceId : ADC_SourceId_004 */ /* DesignId : ADC_DesignId_004*/ /* Requirements : HL_SR188 */ void adcResetFiFo(adcBASE_t *adc, uint32 group) { /* USER CODE BEGIN (13) */ /* USER CODE END */ /** - Reset FiFo */ adc->GxFIFORESETCR[group] = 1U; /** @note The function adcInit has to be called before this function can be used.\n * the conversion should be stopped before calling this function. */ /* USER CODE BEGIN (14) */ /* USER CODE END */ } /* USER CODE BEGIN (15) */ /* USER CODE END */ /** @fn uint32 adcGetData(adcBASE_t *adc, uint32 group, adcData_t * data) * @brief Gets converted a ADC values * @param[in] adc Pointer to ADC module: * - adcREG1: ADC1 module pointer * - adcREG2: ADC2 module pointer * @param[in] group Hardware group of ADC module: * - adcGROUP0: ADC event group * - adcGROUP1: ADC group 1 * - adcGROUP2: ADC group 2 * @param[out] data Pointer to store ADC converted data * @return The function will return the number of converted values copied into data buffer: * * This function writes a ADC message into a ADC message box. * */ /* SourceId : ADC_SourceId_005 */ /* DesignId : ADC_DesignId_005 */ /* Requirements : HL_SR189 */ uint32 adcGetData(adcBASE_t *adc, uint32 group, adcData_t * data) { uint32 i; uint32 buf; uint32 mode; uint32 index = (adc == adcREG1) ? 0U : 1U; uint32 intcr_reg = adc->GxINTCR[group]; uint32 count = (intcr_reg >= 256U) ? s_adcFiFoSize[index][group] : (s_adcFiFoSize[index][group] - (uint32)(intcr_reg & 0xFFU)); adcData_t *ptr = data; /* USER CODE BEGIN (16) */ /* USER CODE END */ mode = (adc->OPMODECR & ADC_12_BIT_MODE); if(mode == ADC_12_BIT_MODE) { /** - Get conversion data and channel/pin id */ for (i = 0U; i < count; i++) { buf = adc->GxBUF[group].BUF0; /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */ ptr->value = (uint16)(buf & 0xFFFU); ptr->id = (uint32)((buf >> 16U) & 0x1FU); /*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */ ptr++; } } else { /** - Get conversion data and channel/pin id */ for (i = 0U; i < count; i++) { buf = adc->GxBUF[group].BUF0; /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */ ptr->value = (uint16)(buf & 0x3FFU); ptr->id = (uint32)((buf >> 10U) & 0x1FU); /*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */ ptr++; } } adc->GxINTFLG[group] = 9U; /** @note The function adcInit has to be called before this function can be used.\n * The user is responsible to initialize the message box. */ /* USER CODE BEGIN (17) */ /* USER CODE END */ return count; } /* USER CODE BEGIN (18) */ /* USER CODE END */ /** @fn uint32 adcIsFifoFull(adcBASE_t *adc, uint32 group) * @brief Checks if FiFo buffer is full * @param[in] adc Pointer to ADC module: * - adcREG1: ADC1 module pointer * - adcREG2: ADC2 module pointer * @param[in] group Hardware group of ADC module: * - adcGROUP0: ADC event group * - adcGROUP1: ADC group 1 * - adcGROUP2: ADC group 2 * @return The function will return: * - 0: When FiFo buffer is not full * - 1: When FiFo buffer is full * - 3: When FiFo buffer overflow occurred * * This function checks FiFo buffer status. * */ /* SourceId : ADC_SourceId_006 */ /* DesignId : ADC_DesignId_006 */ /* Requirements : HL_SR190 */ uint32 adcIsFifoFull(adcBASE_t *adc, uint32 group) { uint32 flags; /* USER CODE BEGIN (19) */ /* USER CODE END */ /** - Read FiFo flags */ flags = adc->GxINTFLG[group] & 3U; /** @note The function adcInit has to be called before this function can be used. */ /* USER CODE BEGIN (20) */ /* USER CODE END */ return flags; } /* USER CODE BEGIN (21) */ /* USER CODE END */ /** @fn uint32 adcIsConversionComplete(adcBASE_t *adc, uint32 group) * @brief Checks if Conversion is complete * @param[in] adc Pointer to ADC module: * - adcREG1: ADC1 module pointer * - adcREG2: ADC2 module pointer * @param[in] group Hardware group of ADC module: * - adcGROUP0: ADC event group * - adcGROUP1: ADC group 1 * - adcGROUP2: ADC group 2 * @return The function will return: * - 0: When is not finished * - 8: When conversion is complete * * This function checks if conversion is complete. * */ /* SourceId : ADC_SourceId_007 */ /* DesignId : ADC_DesignId_007 */ /* Requirements : HL_SR191 */ uint32 adcIsConversionComplete(adcBASE_t *adc, uint32 group) { uint32 flags; /* USER CODE BEGIN (22) */ /* USER CODE END */ /** - Read conversion flags */ flags = adc->GxINTFLG[group] & 8U; /** @note The function adcInit has to be called before this function can be used. */ /* USER CODE BEGIN (23) */ /* USER CODE END */ return flags; } /* USER CODE BEGIN (24) */ /* USER CODE END */ /** @fn void adcCalibration(adcBASE_t *adc) * @brief Computes offset error using Calibration mode * @param[in] adc Pointer to ADC module: * - adcREG1: ADC1 module pointer * - adcREG2: ADC2 module pointer * This function computes offset error using Calibration mode * */ /* SourceId : ADC_SourceId_008 */ /* DesignId : ADC_DesignId_010 */ /* Requirements : HL_SR194 */ void adcCalibration(adcBASE_t *adc) { /* USER CODE BEGIN (25) */ /* USER CODE END */ uint32 conv_val[5U]={0U,0U,0U,0U,0U}; uint32 loop_index=0U; uint32 offset_error=0U; uint32 backup_mode; /** - Backup Mode before Calibration */ backup_mode = adc->OPMODECR; /** - Enable 12-BIT ADC */ adc->OPMODECR |= 0x80000000U; /* Disable all channels for conversion */ adc->GxSEL[0U]=0x00U; adc->GxSEL[1U]=0x00U; adc->GxSEL[2U]=0x00U; for(loop_index=0U;loop_index<4U;loop_index++) { /* Disable Self Test and Calibration mode */ adc->CALCR=0x0U; switch(loop_index) { case 0U : /* Test 1 : Bride En = 0 , HiLo =0 */ adc->CALCR=0x0U; break; case 1U : /* Test 1 : Bride En = 0 , HiLo =1 */ adc->CALCR=0x0100U; break; case 2U : /* Test 1 : Bride En = 1 , HiLo =0 */ adc->CALCR=0x0200U; break; case 3U : /* Test 1 : Bride En = 1 , HiLo =1 */ adc->CALCR=0x0300U; break; default : break; } /* Enable Calibration mode */ adc->CALCR|=0x1U; /* Start calibration conversion */ adc->CALCR|=0x00010000U; /* Wait for calibration conversion to complete */ /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */ while((adc->CALCR & 0x00010000U)==0x00010000U) { } /* Wait */ /* Read converted value */ conv_val[loop_index]= adc->CALR; } /* Disable Self Test and Calibration mode */ adc->CALCR=0x0U; /* Compute the Offset error correction value */ conv_val[4U]=conv_val[0U]+ conv_val[1U] + conv_val[2U] + conv_val[3U]; conv_val[4U]=(conv_val[4U]/4U); offset_error=conv_val[4U]-0x7FFU; /*Write the offset error to the Calibration register */ /* Load 2;s complement of the computed value to ADCALR register */ offset_error=~offset_error; offset_error=offset_error & 0xFFFU; offset_error=offset_error+1U; adc->CALR = offset_error; /** - Restore Mode after Calibration */ adc->OPMODECR = backup_mode; /** @note The function adcInit has to be called before using this function. */ /* USER CODE BEGIN (26) */ /* USER CODE END */ } /** @fn void adcMidPointCalibration(adcBASE_t *adc) * @brief Computes offset error using Mid Point Calibration mode * @param[in] adc Pointer to ADC module: * - adcREG1: ADC1 module pointer * - adcREG2: ADC2 module pointer * @return This function will return offset error using Mid Point Calibration mode * * This function computes offset error using Mid Point Calibration mode * */ /* SourceId : ADC_SourceId_009 */ /* DesignId : ADC_DesignId_011 */ /* Requirements : HL_SR195 */ uint32 adcMidPointCalibration(adcBASE_t *adc) { /* USER CODE BEGIN (27) */ /* USER CODE END */ uint32 conv_val[3U]={0U,0U,0U}; uint32 loop_index=0U; uint32 offset_error=0U; uint32 backup_mode; /** - Backup Mode before Calibration */ backup_mode = adc->OPMODECR; /** - Enable 12-BIT ADC */ adc->OPMODECR |= 0x80000000U; /* Disable all channels for conversion */ adc->GxSEL[0U]=0x00U; adc->GxSEL[1U]=0x00U; adc->GxSEL[2U]=0x00U; for(loop_index=0U;loop_index<2U;loop_index++) { /* Disable Self Test and Calibration mode */ adc->CALCR=0x0U; switch(loop_index) { case 0U : /* Test 1 : Bride En = 0 , HiLo =0 */ adc->CALCR=0x0U; break; case 1U : /* Test 1 : Bride En = 0 , HiLo =1 */ adc->CALCR=0x0100U; break; default : break; } /* Enable Calibration mode */ adc->CALCR|=0x1U; /* Start calibration conversion */ adc->CALCR|=0x00010000U; /* Wait for calibration conversion to complete */ /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */ while((adc->CALCR & 0x00010000U)==0x00010000U) { } /* Wait */ /* Read converted value */ conv_val[loop_index]= adc->CALR; } /* Disable Self Test and Calibration mode */ adc->CALCR=0x0U; /* Compute the Offset error correction value */ conv_val[2U]=(conv_val[0U])+ (conv_val[1U]); conv_val[2U]=(conv_val[2U]/2U); offset_error=conv_val[2U]-0x7FFU; /* Write the offset error to the Calibration register */ /* Load 2's complement of the computed value to ADCALR register */ offset_error=~offset_error; offset_error=offset_error+1U; offset_error=offset_error & 0xFFFU; adc->CALR = offset_error; /** - Restore Mode after Calibration */ adc->OPMODECR = backup_mode; return(offset_error); /** @note The function adcInit has to be called before this function can be used. */ /* USER CODE BEGIN (28) */ /* USER CODE END */ } /* USER CODE BEGIN (29) */ /* USER CODE END */ /** @fn void adcEnableNotification(adcBASE_t *adc, uint32 group) * @brief Enable notification * @param[in] adc Pointer to ADC module: * - adcREG1: ADC1 module pointer * - adcREG2: ADC2 module pointer * @param[in] group Hardware group of ADC module: * - adcGROUP0: ADC event group * - adcGROUP1: ADC group 1 * - adcGROUP2: ADC group 2 * * This function will enable the notification of a conversion. * In single conversion mode for conversion complete and * in continuous conversion mode when the FiFo buffer is full. * */ /* SourceId : ADC_SourceId_010 */ /* DesignId : ADC_DesignId_008 */ /* Requirements : HL_SR192 */ void adcEnableNotification(adcBASE_t *adc, uint32 group) { uint32 notif = (((uint32)(adc->GxMODECR[group]) & 2U) == 2U) ? 1U : 8U; /* USER CODE BEGIN (30) */ /* USER CODE END */ adc->GxINTENA[group] = notif; /** @note The function adcInit has to be called before this function can be used.\n * This function should be called before the conversion is started */ /* USER CODE BEGIN (31) */ /* USER CODE END */ } /* USER CODE BEGIN (32) */ /* USER CODE END */ /** @fn void adcDisableNotification(adcBASE_t *adc, uint32 group) * @brief Disable notification * @param[in] adc Pointer to ADC module: * - adcREG1: ADC1 module pointer * - adcREG2: ADC2 module pointer * @param[in] group Hardware group of ADC module: * - adcGROUP0: ADC event group * - adcGROUP1: ADC group 1 * - adcGROUP2: ADC group 2 * * This function will disable the notification of a conversion. */ /* SourceId : ADC_SourceId_011 */ /* DesignId : ADC_DesignId_009 */ /* Requirements : HL_SR193 */ void adcDisableNotification(adcBASE_t *adc, uint32 group) { /* USER CODE BEGIN (33) */ /* USER CODE END */ adc->GxINTENA[group] = 0U; /** @note The function adcInit has to be called before this function can be used. */ /* USER CODE BEGIN (34) */ /* USER CODE END */ } /** @fn void adcSetEVTPin(adcBASE_t *adc, uint32 value) * @brief Set ADCEVT pin * @param[in] adc Pointer to ADC module: * - adcREG1: ADC1 module pointer * @param[in] value Value to be set: 0 or 1 * * This function will set the ADC EVT pin if configured as an output pin. */ /* SourceId : ADC_SourceId_020 */ /* DesignId : ADC_DesignId_014 */ /* Requirements : HL_SR529 */ void adcSetEVTPin(adcBASE_t *adc, uint32 value) { adc->EVTOUT = value; } /** @fn uint32 adcGetEVTPin(adcBASE_t *adc) * @brief Set ADCEVT pin * @param[in] adc Pointer to ADC module: * - adcREG1: ADC1 module pointer * @return Value of the ADC EVT pin: 0 or 1 * * This function will return the value of ADC EVT pin. */ /* SourceId : ADC_SourceId_021 */ /* DesignId : ADC_DesignId_015 */ /* Requirements : HL_SR529 */ uint32 adcGetEVTPin(adcBASE_t *adc) { return adc->EVTIN; } /** @fn void adc1GetConfigValue(adc_config_reg_t *config_reg, config_value_type_t type) * @brief Get the initial or current values of the configuration registers * * @param[in] *config_reg: pointer to the struct to which the initial or current * value of the configuration registers need to be stored * @param[in] type: whether initial or current value of the configuration registers need to be stored * - InitialValue: initial value of the configuration registers will be stored * in the struct pointed by config_reg * - CurrentValue: initial value of the configuration registers will be stored * in the struct pointed by config_reg * * This function will copy the initial or current value (depending on the parameter 'type') * of the configuration registers to the struct pointed by config_reg * */ /* SourceId : ADC_SourceId_012 */ /* DesignId : ADC_DesignId_012 */ /* Requirements : HL_SR203 */ void adc1GetConfigValue(adc_config_reg_t *config_reg, config_value_type_t type) { if (type == InitialValue) { config_reg->CONFIG_OPMODECR = ADC1_OPMODECR_CONFIGVALUE; config_reg->CONFIG_CLOCKCR = ADC1_CLOCKCR_CONFIGVALUE; config_reg->CONFIG_GxMODECR[0U] = ADC1_G0MODECR_CONFIGVALUE; config_reg->CONFIG_GxMODECR[1U] = ADC1_G1MODECR_CONFIGVALUE; config_reg->CONFIG_GxMODECR[2U] = ADC1_G2MODECR_CONFIGVALUE; config_reg->CONFIG_G0SRC = ADC1_G0SRC_CONFIGVALUE; config_reg->CONFIG_G1SRC = ADC1_G1SRC_CONFIGVALUE; config_reg->CONFIG_G2SRC = ADC1_G2SRC_CONFIGVALUE; config_reg->CONFIG_BNDCR = ADC1_BNDCR_CONFIGVALUE; config_reg->CONFIG_BNDEND = ADC1_BNDEND_CONFIGVALUE; config_reg->CONFIG_G0SAMP = ADC1_G0SAMP_CONFIGVALUE; config_reg->CONFIG_G1SAMP = ADC1_G1SAMP_CONFIGVALUE; config_reg->CONFIG_G2SAMP = ADC1_G2SAMP_CONFIGVALUE; config_reg->CONFIG_G0SAMPDISEN = ADC1_G0SAMPDISEN_CONFIGVALUE; config_reg->CONFIG_G1SAMPDISEN = ADC1_G1SAMPDISEN_CONFIGVALUE; config_reg->CONFIG_G2SAMPDISEN = ADC1_G2SAMPDISEN_CONFIGVALUE; config_reg->CONFIG_PARCR = ADC1_PARCR_CONFIGVALUE; } else { config_reg->CONFIG_OPMODECR = adcREG1->OPMODECR; config_reg->CONFIG_CLOCKCR = adcREG1->CLOCKCR; config_reg->CONFIG_GxMODECR[0U] = adcREG1->GxMODECR[0U]; config_reg->CONFIG_GxMODECR[1U] = adcREG1->GxMODECR[1U]; config_reg->CONFIG_GxMODECR[2U] = adcREG1->GxMODECR[2U]; config_reg->CONFIG_G0SRC = adcREG1->EVSRC; config_reg->CONFIG_G1SRC = adcREG1->G1SRC; config_reg->CONFIG_G2SRC = adcREG1->G2SRC; config_reg->CONFIG_BNDCR = adcREG1->BNDCR; config_reg->CONFIG_BNDEND = adcREG1->BNDEND; config_reg->CONFIG_G0SAMP = adcREG1->EVSAMP; config_reg->CONFIG_G1SAMP = adcREG1->G1SAMP; config_reg->CONFIG_G2SAMP = adcREG1->G2SAMP; config_reg->CONFIG_G0SAMPDISEN = adcREG1->EVSAMPDISEN; config_reg->CONFIG_G1SAMPDISEN = adcREG1->G1SAMPDISEN; config_reg->CONFIG_G2SAMPDISEN = adcREG1->G2SAMPDISEN; config_reg->CONFIG_PARCR = adcREG1->PARCR; } } /* USER CODE BEGIN (35) */ /* USER CODE END */
Hello Keno,
I didn't find any problem from your code. The ADC DMA is enabled. The ADC generates DAM request wen it writes 30 buffers to ADC memory.
You said it works for group1, group2 and Event group with/without DMA. What should be the correct value in ADC memory? How many channels in event groups are sampled?
Hi QJ,
It works for group1, group2, but the ADC conversion for event group is wrong. 3 channels are sampled in event group (same as group1 or group2) and the ADC memory should be the same as group1 or group2. It seems to me event group ADC conversion is working wrongly. Thank you!
Kind regards,
Norbert