int platform_adc_start_sequence() { elua_adc_dev_state *d = adc_get_dev_state( 0 ); if( d->running != 1 ) { adc_update_dev_sequence( 0 ); // Start sampling on first channel d->seq_ctr = 0; ADC_ChannelCmd( LPC_ADC, d->ch_state[ d->seq_ctr ]->id, ENABLE ); ADC_IntConfig( LPC_ADC, d->ch_state[ d->seq_ctr ]->id, ENABLE ); d->running = 1; NVIC_EnableIRQ( ADC_IRQn ); if( d->clocked == 1 ) { ADC_StartCmd( LPC_ADC, adc_trig[ d->timer_id ] ); TIM_ResetCounter( tmr[ d->timer_id ] ); TIM_Cmd( tmr[ d->timer_id ], ENABLE ); } else ADC_StartCmd( LPC_ADC, ADC_START_NOW ); } return PLATFORM_OK; }
// Handle ADC interrupts // NOTE: This could probably be less complicated... void ADC_IRQHandler(void) { elua_adc_dev_state *d = adc_get_dev_state( 0 ); elua_adc_ch_state *s = d->ch_state[ d->seq_ctr ]; //int i; // Disable sampling & current sequence channel ADC_StartCmd( LPC_ADC, 0 ); ADC_ChannelCmd( LPC_ADC, s->id, DISABLE ); ADC_IntConfig( LPC_ADC, s->id, DISABLE ); if ( ADC_ChannelGetStatus( LPC_ADC, s->id, ADC_DATA_DONE ) ) { d->sample_buf[ d->seq_ctr ] = ( u16 )ADC_ChannelGetData( LPC_ADC, s->id ); s->value_fresh = 1; if ( s->logsmoothlen > 0 && s->smooth_ready == 0) adc_smooth_data( s->id ); #if defined( BUF_ENABLE_ADC ) else if ( s->reqsamples > 1 ) { buf_write( BUF_ID_ADC, s->id, ( t_buf_data* )s->value_ptr ); s->value_fresh = 0; } #endif if ( adc_samples_available( s->id ) >= s->reqsamples && s->freerunning == 0 ) platform_adc_stop( s->id ); } // Set up for next channel acquisition if we're still running if( d->running == 1 ) { // Prep next channel in sequence, if applicable if( d->seq_ctr < ( d->seq_len - 1 ) ) d->seq_ctr++; else if( d->seq_ctr == ( d->seq_len - 1 ) ) { adc_update_dev_sequence( 0 ); d->seq_ctr = 0; // reset sequence counter if on last sequence entry } ADC_ChannelCmd( LPC_ADC, d->ch_state[ d->seq_ctr ]->id, ENABLE ); ADC_IntConfig( LPC_ADC, d->ch_state[ d->seq_ctr ]->id, ENABLE ); if( d->clocked == 1 && d->seq_ctr == 0 ) // always use clock for first in clocked sequence ADC_StartCmd( LPC_ADC, adc_trig[ d->timer_id ] ); // Start next conversion if unclocked or if clocked and sequence index > 0 if( ( d->clocked == 1 && d->seq_ctr > 0 ) || d->clocked == 0 ) ADC_StartCmd( LPC_ADC, ADC_START_NOW ); } }
void __ISR(_ADC_VECTOR, ipl3) ADCInterruptHandler(void) { // Clear the ADC's interrupt flag. IFS1CLR = ADC_INT_FLAG; elua_adc_dev_state *d = adc_get_dev_state( 0 ); elua_adc_ch_state *s; if ( AD1CON1bits.DONE ) { d->seq_ctr = 0; while( d->seq_ctr < d->seq_len ) { s = d->ch_state[ d->seq_ctr ]; d->sample_buf[ d->seq_ctr ] = ( u16 )ReadADC10(0); s->value_fresh = 1; // Fill in smoothing buffer until warmed up if ( s->logsmoothlen > 0 && s->smooth_ready == 0) adc_smooth_data( s->id ); #if defined( BUF_ENABLE_ADC ) else if ( s->reqsamples > 1 ) { buf_write( BUF_ID_ADC, s->id, ( t_buf_data* )s->value_ptr ); s->value_fresh = 0; } #endif // If we have the number of requested samples, stop sampling if ( adc_samples_available( s->id ) >= s->reqsamples && s->freerunning == 0 ) platform_adc_stop( s->id ); d->seq_ctr++; } d->seq_ctr = 0; } if( d->running == 1 ) adc_update_dev_sequence( 0 ); if ( d->clocked == 0 && d->running == 1 ) { // start conversion AD1CON1SET = _AD1CON1_ASAM_MASK; AD1CON1SET = _AD1CON1_SAMP_MASK; } if(!d->running) { CloseADC10(); } }
int platform_adc_start_sequence() { elua_adc_dev_state *d = adc_get_dev_state( 0 ); // Only force update and initiate if we weren't already running // changes will get picked up during next interrupt cycle if ( d->running != 1 ) { // Bail if we somehow were trying to set up clocked conversion if( d->clocked == 1 ) return PLATFORM_ERR; d->running = 1; adc_update_dev_sequence( 0 ); } return PLATFORM_OK; }