| 1 | void ADCInit(){
 | 
| 2 |   GPIO_InitTypeDef GPIO_InitStructure;
 | 
| 3 |   ADC_CommonInitTypeDef ADC_CommonInitStructure;
 | 
| 4 |   ADC_InitTypeDef ADC_InitStructure;
 | 
| 5 |   DMA_InitTypeDef DMA_InitStructure;
 | 
| 6 |   NVIC_InitTypeDef NVIC_InitStructure;
 | 
| 7 | 
 | 
| 8 |   adcBuffer.bufFFT=0;  // no buffer assigned -> no execution
 | 
| 9 |   for(int i=0;i<ADC_BUFFER_LENGTH;i++){
 | 
| 10 |     adcBuffer.bufA[i]=0;
 | 
| 11 |     adcBuffer.bufB[i]=0;
 | 
| 12 |   }
 | 
| 13 |   adcBuffer.streamAEnabled = FALSE;
 | 
| 14 |   adcBuffer.streamBEnabled = FALSE;
 | 
| 15 | 
 | 
| 16 |   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
 | 
| 17 |   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
 | 
| 18 | 
 | 
| 19 |   // initialize I/O's
 | 
| 20 |   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
 | 
| 21 |   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
 | 
| 22 |   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
 | 
| 23 |   GPIO_Init(GPIOA, &GPIO_InitStructure);
 | 
| 24 | 
 | 
| 25 |   // initialize common ADC
 | 
| 26 |   ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
 | 
| 27 |   ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
 | 
| 28 |   ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
 | 
| 29 |   ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
 | 
| 30 |   ADC_CommonInit(&ADC_CommonInitStructure);
 | 
| 31 | 
 | 
| 32 |   // initialize ADC1 & ADC2
 | 
| 33 |   ADC_InitStructure.ADC_Resolution = ADC_Resolution_10b;
 | 
| 34 |   ADC_InitStructure.ADC_ScanConvMode = DISABLE;
 | 
| 35 |   ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
 | 
| 36 |   ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
 | 
| 37 |   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;
 | 
| 38 |   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
 | 
| 39 |   ADC_InitStructure.ADC_NbrOfConversion = 1;
 | 
| 40 |   ADC_Init(ADC1, &ADC_InitStructure);
 | 
| 41 |   ADC_Init(ADC2, &ADC_InitStructure);
 | 
| 42 | 
 | 
| 43 |   // ADC1 & ADC2 regular channel configuration
 | 
| 44 |   // ADC1: CH0 at pin A0
 | 
| 45 |   // ADC2: CH1 at pin A1
 | 
| 46 |   ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_3Cycles);
 | 
| 47 |   ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_3Cycles);
 | 
| 48 | 
 | 
| 49 |   // enable DMA request after last transfer
 | 
| 50 |   ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
 | 
| 51 | 
 | 
| 52 |   // initialize DMA streams
 | 
| 53 |   // both streams are filling the buffers circular
 | 
| 54 |   // the half transfer interrupt is used to switch the pointers
 | 
| 55 |   // second DMA stream starts, when first stream has filled half buffer
 | 
| 56 |   DMA_Cmd(DMA2_Stream0, DISABLE);
 | 
| 57 |   DMA_Cmd(DMA2_Stream4, DISABLE);
 | 
| 58 |   DMA_DeInit(DMA2_Stream0);
 | 
| 59 |   DMA_DeInit(DMA2_Stream4);
 | 
| 60 |     DMA_InitStructure.DMA_Channel = DMA_Channel_0;
 | 
| 61 |     DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC->CDR;
 | 
| 62 |     DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(&adcBuffer.bufA);
 | 
| 63 |     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
 | 
| 64 |     DMA_InitStructure.DMA_BufferSize = ADC_BUFFER_LENGTH;
 | 
| 65 |     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
 | 
| 66 |     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
 | 
| 67 |     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 16 bit
 | 
| 68 |     DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;    // 16bit per Transfer
 | 
| 69 |     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
 | 
| 70 |     DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
 | 
| 71 |     DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
 | 
| 72 |     DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;  // may replace by FULL
 | 
| 73 |     DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
 | 
| 74 |     DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
 | 
| 75 |     DMA_Init(DMA2_Stream0, &DMA_InitStructure);
 | 
| 76 |     DMA_InitStructure.DMA_Channel = DMA_Channel_0;
 | 
| 77 |     DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(&adcBuffer.bufB);
 | 
| 78 |     DMA_Init(DMA2_Stream4, &DMA_InitStructure);
 | 
| 79 | 
 | 
| 80 |     // configure DMA half transfer complete interrupt
 | 
| 81 |   NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
 | 
| 82 |   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 | 
| 83 |   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_DMA2_STREAM0;
 | 
| 84 |   NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_SUBPRIORITY_DMA2_STREAM0;
 | 
| 85 |   NVIC_Init(&NVIC_InitStructure);
 | 
| 86 | 
 | 
| 87 |   NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream4_IRQn;
 | 
| 88 |   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 | 
| 89 |   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_DMA2_STREAM4;
 | 
| 90 |   NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_SUBPRIORITY_DMA2_STREAM4;
 | 
| 91 |   NVIC_Init(&NVIC_InitStructure);
 | 
| 92 | 
 | 
| 93 |   // enable DMA half transfer complete interrupt
 | 
| 94 |   DMA_ITConfig(DMA2_Stream0, DMA_IT_HT, ENABLE);
 | 
| 95 |   DMA_ITConfig(DMA2_Stream4, DMA_IT_HT, ENABLE);
 | 
| 96 | 
 | 
| 97 |   // enable DMA streams
 | 
| 98 |   adcBuffer.streamAEnabled = TRUE;
 | 
| 99 |   DMA_Cmd(DMA2_Stream0, ENABLE);
 | 
| 100 |   DMA_Cmd(DMA2_Stream4, ENABLE);    // enabled during HT interrupt of other channel
 | 
| 101 | 
 | 
| 102 |   // enable ADC
 | 
| 103 |   ADC_Cmd(ADC1, ENABLE);
 | 
| 104 |   ADC_Cmd(ADC2, ENABLE);
 | 
| 105 | 
 | 
| 106 |   // sampling will start as soon as timer generates trigger
 | 
| 107 | }
 | 
| 108 | 
 | 
| 109 | void DMA2_Stream0_IRQHandler(void){
 | 
| 110 |   // transfer complete interrupt
 | 
| 111 |   if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_HTIF0)==SET){
 | 
| 112 |     // clear pending interrupt
 | 
| 113 |     DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_HTIF0);
 | 
| 114 |     // enable other channel
 | 
| 115 |     DMA_Cmd(DMA2_Stream4, ENABLE);
 | 
| 116 |     // change buffer pointer to corresponding buffer
 | 
| 117 |     adcBuffer.bufFFT = adcBuffer.bufA;
 | 
| 118 | 
 | 
| 119 |     // print buffer
 | 
| 120 |     usart2Printf("bufA HT\n\r");
 | 
| 121 |     for(int i=0;i<ADC_BUFFER_LENGTH;i++){
 | 
| 122 |       itoa(adcBuffer.bufA[i],tmp,10);
 | 
| 123 |       usart2Printf(tmp);
 | 
| 124 |       usart2Printf("\t");
 | 
| 125 |       itoa(adcBuffer.bufB[i],tmp,10);
 | 
| 126 |       usart2Printf(tmp);
 | 
| 127 |       usart2Printf("\n\r");
 | 
| 128 |     }
 | 
| 129 |   }
 | 
| 130 | }
 | 
| 131 | 
 | 
| 132 | void DMA2_Stream4_IRQHandler(void){
 | 
| 133 |   // transfer complete interrupt
 | 
| 134 |   if(DMA_GetITStatus(DMA2_Stream4, DMA_IT_HTIF4)==SET){
 | 
| 135 |     // clear pending interrupt
 | 
| 136 |     DMA_ClearITPendingBit(DMA2_Stream4, DMA_IT_HTIF4);
 | 
| 137 |     // enable other channel
 | 
| 138 |     DMA_Cmd(DMA2_Stream0, ENABLE);
 | 
| 139 |     // change buffer pointer to corresponding buffer
 | 
| 140 |     adcBuffer.bufFFT = adcBuffer.bufB;
 | 
| 141 | 
 | 
| 142 |     // print buffer
 | 
| 143 |     usart2Printf("bufB HT\n\r");
 | 
| 144 |     for(int i=0;i<ADC_BUFFER_LENGTH;i++){
 | 
| 145 |       itoa(adcBuffer.bufA[i],tmp,10);
 | 
| 146 |       usart2Printf(tmp);
 | 
| 147 |       usart2Printf("\t");
 | 
| 148 |       itoa(adcBuffer.bufB[i],tmp,10);
 | 
| 149 |       usart2Printf(tmp);
 | 
| 150 |       usart2Printf("\n\r");
 | 
| 151 |     }
 | 
| 152 |   }
 | 
| 153 | }
 |