static void adc_int_handler() { elua_adc_dev_state *d = adc_get_dev_state( 0 ); elua_adc_ch_state *s = d->ch_state[ d->seq_ctr ]; u32 tmp, dreg_t; tmp = AD0STAT; // Clear interrupt flag //AD0INTEN = 0; // Disable generating interrupts dreg_t = *( PREG )adc_dr[ s->id ]; if ( dreg_t & ( 1UL << 31 ) ) { d->sample_buf[ d->seq_ctr ] = ( u16 )( ( dreg_t >> 6 ) & 0x3FF ); AD0CR &= 0xF8FFFF00; // stop ADC, disable channels 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 ); } }
void platform_adc_set_timer( unsigned id, u32 timer ) { elua_adc_dev_state *d = adc_get_dev_state( 0 ); if ( d->timer_id != timer ) d->running = 0; platform_adc_stop( id ); d->timer_id = timer; }
// 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(); } }
u32 platform_adc_op( unsigned id, int op, u32 data ) { elua_adc_ch_state *s = adc_get_ch_state( id ); elua_adc_dev_state *d = adc_get_dev_state( 0 ); u32 res = 0; switch( op ) { case PLATFORM_ADC_GET_MAXVAL: res = pow( 2, ADC_BIT_RESOLUTION ) - 1; break; case PLATFORM_ADC_SET_SMOOTHING: res = adc_update_smoothing( id, ( u8 )intlog2( ( unsigned ) data ) ); break; case PLATFORM_ADC_SET_BLOCKING: s->blocking = data; break; case PLATFORM_ADC_IS_DONE: res = ( s->op_pending == 0 ); break; case PLATFORM_ADC_OP_SET_TIMER: if ( d->timer_id != data ) d->running = 0; platform_adc_stop( id ); d->timer_id = data; break; case PLATFORM_ADC_OP_SET_CLOCK: res = platform_adc_setclock( id, data ); break; case PLATFORM_ADC_SET_FREERUNNING: s->freerunning = data; break; } return res; }