Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fast adc #1

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 16 additions & 39 deletions firmware/src/adc.c
Original file line number Diff line number Diff line change
@@ -1,32 +1,18 @@
#include "adc.h"

/**
* @brief Changes ADC channel
* @param __ch is the channel to be switched to
* @return return the selected channel
*/
inline uint8_t adc_select_channel(adc_channels_t __ch)
{
if(__ch < ADC_LAST_CHANNEL ) adc.select = __ch;

ADMUX = (ADMUX & 0xF8) | adc.select; // clears the bottom 3 bits before ORing
return adc.select;
}

/**
* @brief inicializa o ADC, configurado para conversão engatilhada com o timer0.
*/
void adc_init(void)
{
adc.ready = 0;
adc.select = ADC0;

//clr_bit(PRR0, PRADC); // Activates clock to adc

// configuracao do ADC
PORTC = 0b00000000; // disables pull-up for adcs pins
DDRC = 0b00000000; // all adcs as inputs
DIDR0 = 0b11111111; // ADC0 to ADC2 as adc (digital disable)
DIDR0 = 0b11111111; // digital disable for all adcs

ADMUX = (0 << REFS1) // AVcc with external capacitor at AREF pin
| (1 << REFS0)
Expand All @@ -40,7 +26,7 @@ void adc_init(void)
| (1 << ADTS1)
| (1 << ADTS0);

adc_select_channel(ADC0); // Choose admux
ADMUX = (ADMUX & 0xF8) | 0; // Choose admux
ADCSRA = (1 << ADATE) // ADC Auto Trigger Enable
| (1 << ADIE) // ADC Interrupt Enable
| (1 << ADEN) // ADC Enable
Expand Down Expand Up @@ -89,30 +75,21 @@ void adc_init(void)
*/
ISR(ADC_vect)
{

#ifdef FAKE_ADC_ON
adc.channel[adc.select].sum += FAKE_ADC;
#else // FAKE_ADC_ON
#ifdef ADC_8BITS
adc.channel[adc.select].sum += ADCH;
#else // ADC_8BITS
adc.channel[adc.select].sum += ADC;
#endif // ADC_8BITS
#endif // FAKE_ADC_ON

if(++adc.select > ADC_LAST_CHANNEL){
adc.select = ADC0; // recycles

if(++adc.samples >= ADC_AVG_SIZE_10){
adc.channel[0].avg = adc.channel[0].sum >> ADC_AVG_SIZE_2;

adc.samples = adc.channel[0].sum = 0;
adc.ready = 1;
}
#ifdef FAKE_ADC_ON
adc.sum += FAKE_ADC;
#else // FAKE_ADC_ON
#ifdef ADC_8BITS
adc.sum += ADCH;
#else // ADC_8BITS
adc.sum += ADC;
#endif // ADC_8BITS
#endif // FAKE_ADC_ON

if(++adc.samples >= ADC_AVG_SIZE_10){
adc0.ready = 1;
adc0.value = adc.sum;
adc.samples = adc.sum = 0;
}

adc_select_channel(adc.select);

}

/**
Expand Down
25 changes: 9 additions & 16 deletions firmware/src/adc.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,23 @@
// Note the resolution. For example.. at 150hz, ICR1 = PWM_TOP = 159, so it
//#define QUOTIENT (((uint32_t)MACHINE_TIMER_PRESCALER)*((uint32_t)MACHINE_TIMER_FREQUENCY))
//#define ADC_TIMER_TOP (0.5*(F_CPU)/QUOTIENT)
#define ADC_TIMER_FREQUENCY ((uint32_t)(ADC_FREQUENCY)*(uint8_t)(ADC_LAST_CHANNEL +1))
#define ADC_TIMER_FREQUENCY ((uint32_t)(ADC_FREQUENCY))
#define ADC_TIMER_TOP ((F_CPU/(2*ADC_TIMER_PRESCALER))/(ADC_TIMER_FREQUENCY) -1)

typedef enum adc_channels{
ADC0, ADC1 ,ADC2, ADC3, ADC4, ADC5
} adc_channels_t; //*< the adc_channel type

#define ADC_LAST_CHANNEL ADC0

typedef struct{
uint32_t sum;
uint16_t avg;
} adc_channel_t;
typedef struct _adc{
uint64_t sum;
uint16_t samples;
uint8_t ready;
} _adc_t;

typedef struct adc{
adc_channel_t channel[ADC_LAST_CHANNEL+1];
adc_channels_t select;
uint16_t samples;
uint64_t value;
uint8_t ready;
} adc_t;

volatile adc_t adc;
static volatile _adc_t adc;
volatile adc_t adc0;

uint8_t adc_select_channel(adc_channels_t __ch);
void adc_init(void);

#endif /* ifndef _ADC_H_ */
13 changes: 5 additions & 8 deletions firmware/src/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

// MODULES ACTIVATION
#define USART_ON
#define CAN_ON
//#define CAN_ON
//#define CAN_DEPENDENT
#define ADC_ON
#define MACHINE_ON
Expand All @@ -39,13 +39,10 @@
#ifdef ADC_ON
// ADC CONFIGURATION
// note that changing ADC_FREQUENCY may cause problems with avg_sum_samples
#define ADC_FREQUENCY 10000 // 20000
#define ADC_FREQUENCY 500000
#define ADC_TIMER_PRESCALER 8
#define ADC0_AVG adc.channel[ADC0].avg
#define ADC0_ANGULAR_COEF 10000 //(40000/((4/5)*1024))
#define ADC0_LINEAR_COEF 0
#define ADC_AVG_SIZE_2 7 // in base 2
#define ADC_AVG_SIZE_10 128 // in base 10
#define ADC_AVG_SIZE_2 10 // in base 2
#define ADC_AVG_SIZE_10 4096 // in base 10

//#define FAKE_ADC_ON
#ifdef FAKE_ADC_ON
Expand All @@ -57,7 +54,7 @@

#ifdef MACHINE_ON
// The machine frequency may not be superior of ADC_FREQUENCY/ADC_AVG_SIZE_10
#define MACHINE_TIMER_FREQUENCY 300 //<! machine timer frequency in Hz
#define MACHINE_TIMER_FREQUENCY 1000 //<! machine timer frequency in Hz
#define MACHINE_TIMER_PRESCALER 1024 //<! machine timer prescaler
#define MACHINE_CLK_DIVIDER_VALUE ((uint64_t)(uint32_t)MACHINE_TIMER_FREQUENCY*(uint32_t)ADC_AVG_SIZE_10)/(ADC_FREQUENCY) //<! machine_run clock divider
#define MACHINE_FREQUENCY (MACHINE_TIMER_FREQUENCY)/(MACHINE_CLK_DIVIDER_VALUE)
Expand Down
59 changes: 36 additions & 23 deletions firmware/src/machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ inline void set_state_running(void)
{
VERBOSE_MSG_MACHINE(usart_send_string("\n>>>RUNNING STATE\n"));
state_machine = STATE_RUNNING;
reset_measurements();
}

/**
Expand All @@ -101,11 +102,11 @@ inline void print_configurations(void)
{
VERBOSE_MSG_MACHINE(usart_send_string("CONFIGURATIONS:\n"));

VERBOSE_MSG_MACHINE(usart_send_string("\nadc_f: "));
VERBOSE_MSG_MACHINE(usart_send_uint16( ADC_FREQUENCY ));
VERBOSE_MSG_MACHINE(usart_send_char(','));
VERBOSE_MSG_MACHINE(usart_send_string("\nadc_freq: "));
VERBOSE_MSG_MACHINE(usart_send_uint32( ADC_FREQUENCY ));
VERBOSE_MSG_MACHINE(usart_send_string("\nadc_avg_size: "));
VERBOSE_MSG_MACHINE(usart_send_uint16( ADC_AVG_SIZE_10 ));
VERBOSE_MSG_MACHINE(usart_send_string("\nmachine_f: "));
VERBOSE_MSG_MACHINE(usart_send_string("\nmachine_freq: "));
VERBOSE_MSG_MACHINE(usart_send_uint16( MACHINE_FREQUENCY ));

VERBOSE_MSG_MACHINE(usart_send_char('\n'));
Expand Down Expand Up @@ -188,7 +189,6 @@ inline void task_error(void)
}
#endif


total_errors++; // incrementa a contagem de erros
VERBOSE_MSG_ERROR(usart_send_string("The error code is: "));
VERBOSE_MSG_ERROR(usart_send_uint16(error_flags.all));
Expand Down Expand Up @@ -257,7 +257,33 @@ inline void reset_measurements(void)
measurements.adc0_avg_sum_count = 0;
measurements.adc0_avg_sum = 0;
measurements.adc0_max = 0;
measurements.adc0_min = 1023;
measurements.adc0_min = 65535; // should start at maximum possible value
}


inline void compute_adc0_avg(void)
{
// avg
measurements.adc0_avg = adc0.value * (500000000.0f / (1024.f * ADC_AVG_SIZE_10));

// max avg
if(measurements.adc0_avg < measurements.adc0_min)
measurements.adc0_min = measurements.adc0_avg;
// min avg
if(measurements.adc0_avg > measurements.adc0_max)
measurements.adc0_max = measurements.adc0_avg;

// avg for canbus msgs
measurements.adc0_avg_sum_count++;
measurements.adc0_avg_sum += measurements.adc0_avg;

// usart_send_uint32(adc0);
// usart_send_uint32(measurements.adc0_avg);
// usart_send_char(',');
// usart_send_uint32(measurements.adc0_avg_sum);
// usart_send_char(',');
// usart_send_uint16(measurements.adc0_avg_sum_count);
// usart_send_string("\n\n\n\n");
}

/**
Expand All @@ -267,24 +293,14 @@ inline void machine_run(void)
{
//print_infos();


if(machine_clk){
machine_clk = 0;
#ifdef ADC_ON
if(adc.ready){
adc.ready = 0;

measurements.adc0_avg = ADC0_AVG;
//* ADC0_ANGULAR_COEF
//+ ADC0_LINEAR_COEF;

if(measurements.adc0_avg < measurements.adc0_min)
measurements.adc0_min = measurements.adc0_avg;
if(measurements.adc0_avg > measurements.adc0_max)
measurements.adc0_max = measurements.adc0_avg;
#ifdef ADC_ON
if(adc0.ready){
adc0.ready = 0;

measurements.adc0_avg_sum_count++;
measurements.adc0_avg_sum += measurements.adc0_avg;
compute_adc0_avg();

if(error_flags.all){
print_system_flags();
Expand Down Expand Up @@ -329,10 +345,7 @@ ISR(TIMER2_COMPA_vect)
{
if(machine_clk_divider++ == MACHINE_CLK_DIVIDER_VALUE){
/*if(machine_clk){
for(;;){
pwm_reset();
VERBOSE_MSG_ERROR(if(machine_clk) usart_send_string("\nERROR: CLOCK CONFLICT!!!\n"));
}
}*/
machine_clk = 1;
machine_clk_divider = 0;
Expand Down
5 changes: 4 additions & 1 deletion firmware/src/machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <math.h>

#include "conf.h"

Expand Down Expand Up @@ -56,13 +58,14 @@ typedef union error_flags{
}error_flags_t;

typedef struct measurements{
uint16_t adc0_avg; // average value of ADC0
uint32_t adc0_avg; // average value of ADC0
uint16_t adc0_avg_sum_count;
uint64_t adc0_avg_sum; // average value of ADC0
uint16_t adc0_min; // period minimum value of ADC0
uint16_t adc0_max; // period maximum value of ADC0
}measurements_t;

void compute_adc0_avg(void);

// machine checks
void check_buffers(void);
Expand Down
8 changes: 4 additions & 4 deletions firmware/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

void init(void)
{
cli();

#ifdef USART_ON
usart_init(MYUBRR,1,1); // inicializa a usart
usart_init(MYUBRR,0,1); // inicializa a usart
VERBOSE_MSG_INIT(usart_send_string("\n\n\nUSART... OK!\n"));
#endif

Expand Down Expand Up @@ -40,6 +41,7 @@ void init(void)
VERBOSE_MSG_INIT(usart_send_string("CAN filters..."));
can_static_filter(can_filter);
VERBOSE_MSG_INIT(usart_send_string(" OK!\n"));
cli();
#else
VERBOSE_MSG_INIT(usart_send_string("CAN... OFF!\n"));
#endif
Expand Down Expand Up @@ -107,7 +109,7 @@ int main(void)
{
init();

for(;;){
for(;;){
#ifdef WATCHDOG_ON
wdt_reset();
#endif
Expand All @@ -122,7 +124,6 @@ int main(void)
}
}


/**
* @brief se em debug, fica chaveando os pinos de debugs até o reset do watchdog
*/
Expand All @@ -140,4 +141,3 @@ ISR(BADISR_vect)
#endif
}
}

2 changes: 1 addition & 1 deletion firmware/src/sleep.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

void sleep_init(void)
{
set_sleep_mode(SLEEP_MODE_IDLE);
set_sleep_mode(SLEEP_MODE_ADC);
}

#endif /* ifndef SLEEP_H */
Loading