mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-06-02 21:37:24 +08:00
167 lines
3.7 KiB
C
167 lines
3.7 KiB
C
/*
|
|
* Paparazzi AVR adc functions
|
|
*
|
|
* Copyright (C) 2006 Pascal Brisset, Antoine Drouin, Michel Gorraz
|
|
*
|
|
* This file is part of paparazzi.
|
|
*
|
|
* paparazzi is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* paparazzi is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with paparazzi; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*
|
|
*/
|
|
|
|
//// ADC3 MVSUP
|
|
//// ADC6 MVSERVO
|
|
|
|
|
|
#include <avr/signal.h>
|
|
#include <avr/interrupt.h>
|
|
#include <avr/io.h>
|
|
#include "adc.h"
|
|
#include "std.h"
|
|
|
|
|
|
static struct adc_buf* buffers[NB_ADC];
|
|
|
|
void adc_buf_channel(uint8_t adc_channel, struct adc_buf* s, uint8_t av_nb_sample) {
|
|
buffers[adc_channel] = s;
|
|
s->av_nb_sample = av_nb_sample;
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
#if defined (__AVR_ATmega8__)
|
|
|
|
|
|
#define VOLTAGE_TIME 0x07
|
|
#define ANALOG_PORT PORTC
|
|
#define ANALOG_PORT_DIR DDRC
|
|
|
|
|
|
#ifdef IMU_ANALOG
|
|
#define ANALOG_VREF _BV(REFS0)
|
|
#else
|
|
#define ANALOG_VREF _BV(REFS0) | _BV(REFS1)
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
* Called when the voltage conversion is finished
|
|
*
|
|
* 8.913kHz on mega128 16MHz 1kHz/channel ??
|
|
*/
|
|
SIGNAL( SIG_ADC )
|
|
{
|
|
uint8_t adc_input = ADMUX & 0x7;
|
|
struct adc_buf* buf = buffers[adc_input];
|
|
uint16_t adc_value = ADCW;
|
|
|
|
if (buf) {
|
|
uint8_t new_head = buf->head + 1;
|
|
if (new_head >= buf->av_nb_sample) new_head = 0;
|
|
buf->sum -= buf->values[new_head];
|
|
buf->values[new_head] = adc_value;
|
|
buf->sum += adc_value;
|
|
buf->head = new_head;
|
|
}
|
|
|
|
/* Find the next input */
|
|
adc_input++;
|
|
if (adc_input == 4)
|
|
adc_input = 6; // ADC 4 and 5 for i2c
|
|
if( adc_input >= 8 ) {
|
|
adc_input = 0;
|
|
#ifdef CTL_BRD_V1_2
|
|
adc_input = 1; // WARNING ADC0 is for rservo driver reset on v1.2.0
|
|
#endif /* CTL_BRD_V1_2 */
|
|
}
|
|
/* Select it */
|
|
ADMUX = adc_input | ANALOG_VREF;
|
|
/* Restart the conversion */
|
|
sbi( ADCSR, ADSC );
|
|
}
|
|
|
|
#endif /* (__AVR_ATmega8__) */
|
|
|
|
|
|
|
|
|
|
/************************************************************************/
|
|
#if defined (__AVR_ATmega128__)
|
|
|
|
#define VOLTAGE_TIME 0x07
|
|
#define ANALOG_PORT PORTF
|
|
#define ANALOG_PORT_DIR DDRF
|
|
|
|
|
|
#define ANALOG_VREF _BV(REFS0)
|
|
|
|
|
|
/**
|
|
* Called when the voltage conversion is finished
|
|
*
|
|
* 8.913kHz on mega128 16MHz 1kHz/channel ??
|
|
*/
|
|
SIGNAL( SIG_ADC )
|
|
{
|
|
uint8_t adc_input = ADMUX & 0x7;
|
|
struct adc_buf* buf = buffers[adc_input];
|
|
uint16_t adc_value = ADCW;
|
|
|
|
if (buf) {
|
|
uint8_t new_head = buf->head + 1;
|
|
if (new_head >= buf->av_nb_sample) new_head = 0;
|
|
buf->sum -= buf->values[new_head];
|
|
buf->values[new_head] = adc_value;
|
|
buf->sum += adc_value;
|
|
buf->head = new_head;
|
|
}
|
|
|
|
/* Find the next input */
|
|
adc_input++;
|
|
if( adc_input >= 8 )
|
|
adc_input = 0;
|
|
/* Select it */
|
|
ADMUX = adc_input | ANALOG_VREF;
|
|
/* Restart the conversion */
|
|
sbi( ADCSR, ADSC );
|
|
}
|
|
#endif /* (__AVR_ATmega128__) */
|
|
|
|
|
|
|
|
void adc_init( void ) {
|
|
uint8_t i;
|
|
/* Ensure that our port is for input with no pull-ups */
|
|
ANALOG_PORT = 0x00;
|
|
ANALOG_PORT_DIR = 0x00;
|
|
|
|
/* Select our external voltage ref */
|
|
ADMUX = ANALOG_VREF;
|
|
|
|
/* Select out clock, turn on the ADC interrupt and start conversion */
|
|
ADCSRA = 0
|
|
| VOLTAGE_TIME
|
|
| _BV(ADEN )
|
|
| _BV(ADIE )
|
|
| _BV(ADSC );
|
|
|
|
/* Init to 0 (usefull ?) */
|
|
for(i = 0; i < NB_ADC; i++)
|
|
buffers[i] = (struct adc_buf*)0;
|
|
}
|
|
|