/******************************************************************************* * Function Name: ADC_Sleep ******************************************************************************** * * Summary: * Stops the operation of the block and saves the user configuration. * * Parameters: * None * * Return: * None * * Global variables: * ADC_backup: The structure field 'enableState' is modified * depending on the enable state of the block before entering to sleep mode. * *******************************************************************************/ void ADC_Sleep(void) { /* Save ADC enable state */ if((ADC_ACT_PWR_DEC_EN == (ADC_PWRMGR_DEC_REG & ADC_ACT_PWR_DEC_EN)) && (ADC_ACT_PWR_DSM_EN == (ADC_PWRMGR_DSM_REG & ADC_ACT_PWR_DSM_EN))) { /* Component is enabled */ ADC_backup.enableState = ADC_ENABLED; if((ADC_DEC_CR_REG & ADC_DEC_START_CONV) != 0u) { /* Conversion is started */ ADC_backup.enableState |= ADC_STARTED; } /* Stop the configuration */ ADC_Stop(); } else { /* Component is disabled */ ADC_backup.enableState = ADC_DISABLED; } /* Save the user configuration */ ADC_SaveConfig(); }
/******************************************************************************* * Function Name: ADC_Sleep ******************************************************************************** * * Summary: * Stops the ADC operation and saves the configuration registers and component * enable state. Should be called just prior to entering sleep. * * Parameters: * None. * * Return: * None. * * Global Variables: * ADC_backup - modified. * *******************************************************************************/ void ADC_Sleep(void) { /* During deepsleep/ hibernate mode keep SARMUX active, i.e. do not open * all switches (disconnect), to be used for ADFT */ ADC_SAR_DFT_CTRL_REG |= ADC_ADFT_OVERRIDE; if((ADC_SAR_CTRL_REG & ADC_ENABLE) != 0u) { if((ADC_SAR_SAMPLE_CTRL_REG & ADC_CONTINUOUS_EN) != 0u) { ADC_backup.enableState = ADC_ENABLED | ADC_STARTED; } else { ADC_backup.enableState = ADC_ENABLED; } ADC_StopConvert(); ADC_Stop(); /* Disable the SAR internal pump before entering the chip low power mode */ if((ADC_SAR_CTRL_REG & ADC_BOOSTPUMP_EN) != 0u) { ADC_SAR_CTRL_REG &= (uint32)~ADC_BOOSTPUMP_EN; ADC_backup.enableState |= ADC_BOOSTPUMP_ENABLED; } } else { ADC_backup.enableState = ADC_DISABLED; } }
/******************************************************************************* Function Name : ADC_Start Description : start the ADC sampling scan *******************************************************************************/ void ADC_Start(void) { ADC_Stop(); // disable DMA1 ScanSegment = 0; // scan buffer has three virtual segments (pre-fetch, trig-seek and post-fetch) ScanMode = 1; // 0=idle, 1=pre-fetch, 2=trig-seek, 3=post-fetch DMA_CPAR1 = ADC1_DR_ADDR; // base address of the peripheral's data register for DMA1 DMA_CMAR1 = (u32)Scan_Buffer; DMA_CNDTR1 = SEGMENT_SIZE; DMA_CCR1 = 0x00003583; // enable DMA1 }
void Do_Keys_Rate (keycodes key){ s16 tmp, step; s16 cursor; Display_Info("Do_Keys_Rate", 0); cursor = confp->rate_cursor; switch (key){ case KEYCODE_PLAY: stop = !stop; if(stop) ADC_Stop(); else ADC_Start(); break; case KEYCODE_M: confp->rtn_mode = confp->mode; confp->mode = MENU; Display_Menu(confp->menu_index); break; case KEYCODE_UP: // no zoom in rate mode break; case KEYCODE_DOWN: // no zoom in rate mode break; case KEYCODE_RIGHT: step = 2; cursor += step; if(cursor >= confp->graph_width){ // stop on far right side cursor = confp->graph_width - 1; } Display_Rate(); break; case KEYCODE_LEFT: step = 2; cursor -= step; if(cursor < 0){ // stop on far right side cursor = 0; } Display_Rate(); break; } confp->rate_cursor = cursor; }
void Scan_Samples(void){ fixed ybox[7]; // array box car derivative s16 bin; // index into peak height array fixed dt, tau, *yp0, *yp1, y, y_i; fixed threshold; // trigger level for leading edge fixed deriv; fixed alpha, beta, gamma, peak; s16 i; configurations *cp = &configuration; ADC_Stop(); tail = head = Get_Scan_Pos(); // get current absolute position in adc buffer /* if(cp->sig_filter){ // Set up Butterworth low pass filter dt = FIXED_HALF; // sample time 0.5 uS tau = fixed_from_int(cp->sig_filter); // filter time in uS alpha = fixed_div(dt, tau + dt); } */ ADC_Start(); while(TRUE){ if(tail == head){ head = Get_Scan_Pos(); // recalculate filter elements in case changed /* if(cp->sig_filter){ // Set up Butterworth low pass filter in case of changes dt = FIXED_HALF; // sample time 0.5 uS tau = fixed_from_int(cp->sig_filter); // filter time in uS alpha = fixed_div(dt, tau + dt); } */ } if(tail == head) continue; // track live time if(samp_cntr++ >= SAMP_PER_MS){ live_time++; samp_cntr = 0; } // get new value, adjust for zero and inversion at same time y = fixed_from_int(zero - scan_buffer[tail++]); if(tail >= SCAN_BUFFER_SZ){ tail = 0; } // filter signal if needed /* if(cp->sig_filter){ // Butterworth low pass filter y = *yp0 + fixed_mul(alpha, (y - *yp0)); } */ // shift the boxcar window and find derivative yp0 =&ybox[0]; yp1 = &ybox[1]; for(i = 6; i > 0; i--){ // last box slot gets new y value *yp0++ = *yp1++; } *yp0 = y; // place latest sample in end of boxcar // compute the derivative deriv = 0; yp0 =&ybox[0]; deriv -= *yp0++; deriv -= *yp0++; alpha = *yp0; deriv -= *yp0++; beta = *yp0++; gamma = *yp0; deriv += *yp0++; deriv += *yp0++; deriv += *yp0++; // process depending on state switch(scan_state){ case RESTART: scan_state = LEADING; //cp->scope_valid = FALSE; break; case LEADING: if(cp->sig_type == PULSE_POS && deriv > cp->sig_dvdt_lim){ scan_state = PEAK; break; } if(cp->sig_type == PULSE_NEG && deriv < cp->sig_dvdt_lim){ scan_state = PEAK; break; } // if no pulse then check the zero avg_zero = (avg_zero * 20 + y)/21; break; case PEAK: // reverse derivative indicates peak if(cp->sig_type == PULSE_POS && deriv < 0){ scan_state = TAIL; } if(cp->sig_type == PULSE_NEG && deriv > 0){ scan_state = TAIL; } if(scan_state == TAIL){ // handle gaussian approximation if enabled if(cp->sig_gaussian){ // p = ((a - g)/(a -2b + g))/2 = position of peak peak = (fixed_div((alpha - gamma),(alpha - (2 * beta) + gamma))) / 2; // y(p) = b - ((a - g) * p)/4 = peak value peak = beta - (fixed_mul((alpha - gamma), peak) / 4); } else { peak = (alpha + beta + gamma) / 3; } if(cp->sig_type == PULSE_NEG){ peak = -peak; } // peak now always positive if( peak > cp->sig_lo_lim && peak < cp->sig_hi_lim){ bin = fixed_to_int(peak); pulse_height[bin]++; // increment count in spectrum array cur_cnt++; // handle rate meter beeping if(cp->rate_beep && !alarm_on){ Beep(BEEP_500Hz, 10); } } } break; case TAIL: // find where curve turns back to baseline if(cp->sig_type == PULSE_POS && deriv >= 0){ scan_state = LEADING; } if(cp->sig_type == PULSE_NEG && deriv <= 0){ scan_state = LEADING; } break; } // switch(scan_state) } // while ring buffer not empty }
int main (void) { uint32_t execution_cycle; //actual execution cycle char ch; #ifdef CMSIS // If we are conforming to CMSIS, we need to call start here start(); #endif printf("\n\rRunning the LQRUG_bme_ex2 project.\n\r"); if (RCM_SRS0 & RCM_SRS0_WAKEUP_MASK) { printf("Wakeup initialization flow\n\r"); systick_init(); cnt_start_value = SYST_CVR; Init_BME_GPIO(); ADC_BME_Trigger(); //Set LPTMR to timeout about 1 second Lptmr_BME_Init(1000, LPOCLK); ADC_BME_Init(); Calibrate_BME_ADC(); ADC_BME_Init(); ADC_Start(ADC0_CHANB); // Enable the ADC interrupt in NVIC #ifdef CMSIS enable_irq(ADC0_IRQn) ; // ready for this interrupt. enable_irq(LPTimer_IRQn); #else enable_irq(ADC0_irq_no) ; // ready for this interrupt. enable_irq(LPTMR0_irq_no); #endif cnt_end_value = SYST_CVR; execution_cycle = cnt_start_value - cnt_end_value - overhead; systick_disable(); #ifdef DEBUG_PRINT printf("Systick start value: 0x%x\n\r", cnt_start_value); printf("Systick end value: 0x%x\n\r", cnt_end_value); printf("Actual execution cycle for initialization phase in normal C code: 0x%x\n\r", execution_cycle); #endif } else { printf("Normal initialization flow\n\r"); //make sure the two printf has the same characters to output systick_init(); cnt_start_value = SYST_CVR; Init_GPIO(); ADC_Trigger(); //Set LPTMR to timeout about 1 second Lptmr_Init(1000, LPOCLK); ADC_Init(); Calibrate_ADC(); ADC_Init(); ADC_Start(ADC0_CHANB); // Enable the ADC interrupt in NVIC #ifdef CMSIS enable_irq(ADC0_IRQn) ; // ready for this interrupt. enable_irq(LPTimer_IRQn); #else enable_irq(ADC0_irq_no) ; // ready for this interrupt. enable_irq(LPTMR0_irq_no); #endif cnt_end_value = SYST_CVR; execution_cycle = cnt_start_value - cnt_end_value - overhead; systick_disable(); #ifdef DEBUG_PRINT printf("Systick start value: 0x%x\n\r", cnt_start_value); printf("Systick end value: 0x%x\n\r", cnt_end_value); printf("Actual execution cycle for initialization phase in normal C code: 0x%x\n\r", execution_cycle); #endif } Lptmr_Start(); #ifndef FREEDOM printf("ADC conversion for potentiometer started, press any key to stop ADC conversion\n\r"); #else printf("No potentiometer or LED on FREEDOM board, press any key to stop ADC conversion\n\r"); #endif while(!char_present()) { #ifndef FREEDOM if (cycle_flags == ADC0A_DONE) { printf("\r R0A=%8d",result0A); cycle_flags &= ~ADC0A_DONE ; } #endif } in_char(); //Read out any available characters ADC_Stop(); printf("ADC conversion stopped, press 'l' to enter VLLS1 mode\n\r"); #ifndef FREEDOM printf("Press SW3 or SW4(Reset button) on TWR-KL25Z48M to exit VLLS1 mode\n\r"); #else printf("Press SW1(Reset button) on FREEDOM board to exit VLLS1 mode\n\r"); #endif while(1) { ch = in_char(); //out_char(ch); if(ch != 'l') printf("Incorrect character input, Press 'l' to enter VLLS1 mode\n\r"); else break; } llwu_configure(0x0080/*PTC3*/, LLWU_PIN_FALLING, 0x0); /* Configure SW3 - init for GPIO PTC3/LLWU_P7/UART1_RX/FTM0_CH2/CLKOUT*/ PORTC_PCR3 = ( PORT_PCR_MUX(1) | PORT_PCR_PE_MASK | PORT_PCR_PFE_MASK | PORT_PCR_PS_MASK); enter_vlls1(); }
int main(void){ float Es,E; unsigned int i, j; unsigned int doa_aux[3]; int diff[3]; #ifdef _FLASH memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); #endif /*------------------------------------------------------*/ /* Inicialización */ /*------------------------------------------------------*/ InitSysCtrl(); InitSysPll(XTAL_OSC,IMULT_20,FMULT_0,PLLCLK_BY_2); EDIS; InitGpio(); InitPieCtrl(); IER = 0x0000; IFR = 0x0000; InitPieVectTable(); //Configura operación del ADC-A ADC_Configure(ADCA,16000); //Configura los canales 2,3,4 y 5 del ADC-A ADC_Init(ADCA, 2); ADC_Init(ADCA, 3); ADC_Init(ADCA, 4); //La interrupción del ADC-A se da cuando termine el canal 4 ADC_Int(ADCA, 4); hnd_cfft->OutPtr = CFFToutBuff; // Apuntador al Buffer de salida hnd_cfft->Stages = STAGE; // Número de etapas de la FFT hnd_cfft->FFTSize = N; // Tamaño de la FFT hnd_cfft->CoefPtr = CFFTF32Coef; // Auntador a los coeficientes de Fourier CFFT_f32_sincostable(hnd_cfft); // Calcula los factores de Fourier //Configura el puerto serial Serial_Init(); Serial_Configure(BR9600); Serial_Start(); ADC_Start(ADCA); //Inicia la conversión del ADC-A cont = 0; //calculo de la energía del silencio (que filosófico suena esto) EINT; Es = 0; while(cont<(N<<1)); ServiceDog(); cont = 0; Es = energy(x); while(cont<(N<<1)); ServiceDog(); cont = 0; Es += energy(x); Es = Es/2; doaG = 0; while(1){ #ifndef DEBUG init = false; while(!init); #endif E = Es; for(j=0;j<3;j++){ //recibe datos y verifica si es ruido o no do{ ADC_Start(ADCA); while(cont<(N<<1)); cont = 0; //Una vez llenos los buffers de datos procedemos a realizar el algoritmo ADC_Stop(ADCA); //detiene la adquisición para obtener las FFT ServiceDog(); }while(!vad(x,E)); //FFT mic 1 hnd_cfft->InPtr = x1; CFFT_f32u(hnd_cfft); for(i=0;i<(N<<1);i++){ xw1[i] = hnd_cfft->CurrentInPtr[i]; } //FFT mic 2 hnd_cfft->InPtr = x2; CFFT_f32u(hnd_cfft); for(i=0;i<(N<<1);i++){ xw2[i] = hnd_cfft->CurrentInPtr[i]; } //FFT mic 3 hnd_cfft->InPtr = x3; CFFT_f32u(hnd_cfft); for(i=0;i<(N<<1);i++){ xw3[i] = hnd_cfft->CurrentInPtr[i]; } ServiceDog(); doa_aux[j] = doa_est(xw1,xw2,xw3,30); //50 //doaG +=doa_aux[j]; DELAY_US(100000); //retraso de 100ms ServiceDog(); E = 0.8*E; }//for j diff[0] = doa_aux[0]-doa_aux[1]; //diferencia entre primer y segundo frame diff[1] = doa_aux[1]-doa_aux[2]; //diferencia entre segundo y tercer frame diff[2] = doa_aux[0]-doa_aux[2]; //diferencia entre primer y tercer frame if(diff[0]<0) diff[0] = -diff[0]; if(diff[1]<0) diff[1] = -diff[1]; if(diff[2]<0) diff[2] = -diff[2]; if( diff[0]<=diff[1] && diff[0]<=diff[2] ) doaG = (doa_aux[0]+doa_aux[1])>>1; else if ( diff[1]<=diff[0] && diff[1]<=diff[2] ) doaG = (doa_aux[1]+doa_aux[2])>>1; else
void Do_Keys_PHA (keycodes key){ s16 tmp, step, channels; s16 cursor_hi, cursor_lo, window_hi, window_lo, zoom; Display_Info("Do_Keys_PHA", 0); channels = confp->pha_channels; cursor_hi = confp->pha_cursor_hi; cursor_lo = confp->pha_cursor_lo; window_hi = confp->pha_window_hi; window_lo = confp->pha_window_lo; zoom = confp->pha_zoom; if(zoom >= 8) step = 1; else step = (window_hi - window_lo) / 64; // Handle keys here as mode dependant switch (key){ case KEYCODE_PLAY: stop = !stop; if(stop) ADC_Stop(); else ADC_Start(); break; case KEYCODE_M: confp->rtn_mode = confp->mode; confp->mode = MENU; Display_Menu(confp->menu_index); break; case KEYCODE_UP: // zoom in on cursor by factor of 2 if(confp->pha_zoom >= (MAX_CHANNELS / confp->graph_width)) break; // limit zoom in zoom *= 2; // shrink window by 2 tmp = channels / zoom; window_hi = cursor_hi + (tmp / 2); if(window_hi > channels) window_hi = channels - 1; window_lo = cursor_lo - (tmp / 2); if(window_lo < 0) window_lo = 0; Display_Spectrum(); break; case KEYCODE_DOWN: // zoom out by factor of 2 if(confp->pha_zoom <= 1) break; // limit zoom in zoom /= 2; // shrink window by 2 if(zoom <= 1){ // compensate for division truncation window_hi = confp->pha_channels; window_lo = 0; break; } tmp = channels / zoom; window_hi = cursor_hi + (tmp / 2); if(window_hi > channels) window_hi = channels - 1; window_lo = cursor_lo - (tmp / 2); if(window_lo < 0) window_lo = 0; Display_Spectrum(); break; case KEYCODE_RIGHT: tmp = cursor_hi - cursor_lo; cursor_hi += step; if(cursor_hi >= channels){ // stop on far right side cursor_hi = channels - 1; } cursor_lo = cursor_hi - tmp; tmp = window_hi - window_lo; if(cursor_hi > window_hi){ // adjust window when cursor hits end window_hi = cursor_hi; window_lo = window_hi - tmp; } Display_Spectrum(); break; case KEYCODE_LEFT: tmp = cursor_hi - cursor_lo; cursor_lo -= step; if(cursor_lo < 0){ // stop on far right side cursor_lo = 0; } cursor_hi = cursor_lo + tmp; tmp = window_hi - window_lo; if(cursor_lo < window_lo){ // adjust window when cursor hits end window_lo = cursor_lo; window_hi = window_lo + tmp; } Display_Spectrum (); break; } confp->pha_cursor_hi = cursor_hi; confp->pha_cursor_lo = cursor_lo; confp->pha_window_hi = window_hi; confp->pha_window_lo = window_lo; confp->pha_zoom = zoom; }