예제 #1
0
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 );      
    }
  }
예제 #2
0
파일: common.c 프로젝트: louismdavis/elua
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;
}
예제 #3
0
파일: platform.c 프로젝트: ARMinARM/elua
// 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 );
  }
}
예제 #4
0
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();
  }
}
예제 #5
0
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;
}