diff --git a/firmware/src/adc.c b/firmware/src/adc.c index 2b0679a..9f240fb 100644 --- a/firmware/src/adc.c +++ b/firmware/src/adc.c @@ -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) @@ -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 @@ -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); - } /** diff --git a/firmware/src/adc.h b/firmware/src/adc.h index 7f53054..4499d8b 100644 --- a/firmware/src/adc.h +++ b/firmware/src/adc.h @@ -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_ */ diff --git a/firmware/src/conf.h b/firmware/src/conf.h index 89c0549..80ae08b 100644 --- a/firmware/src/conf.h +++ b/firmware/src/conf.h @@ -27,7 +27,7 @@ // MODULES ACTIVATION #define USART_ON -#define CAN_ON +//#define CAN_ON //#define CAN_DEPENDENT #define ADC_ON #define MACHINE_ON @@ -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 @@ -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 //>>RUNNING STATE\n")); state_machine = STATE_RUNNING; + reset_measurements(); } /** @@ -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')); @@ -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)); @@ -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"); } /** @@ -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(); @@ -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; diff --git a/firmware/src/machine.h b/firmware/src/machine.h index 1093c1d..b084deb 100644 --- a/firmware/src/machine.h +++ b/firmware/src/machine.h @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include "conf.h" @@ -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); diff --git a/firmware/src/main.c b/firmware/src/main.c index ddbf5f8..56a1687 100644 --- a/firmware/src/main.c +++ b/firmware/src/main.c @@ -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 @@ -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 @@ -107,7 +109,7 @@ int main(void) { init(); - for(;;){ + for(;;){ #ifdef WATCHDOG_ON wdt_reset(); #endif @@ -122,7 +124,6 @@ int main(void) } } - /** * @brief se em debug, fica chaveando os pinos de debugs até o reset do watchdog */ @@ -140,4 +141,3 @@ ISR(BADISR_vect) #endif } } - diff --git a/firmware/src/sleep.h b/firmware/src/sleep.h index 36ac95e..eed30f4 100644 --- a/firmware/src/sleep.h +++ b/firmware/src/sleep.h @@ -17,7 +17,7 @@ void sleep_init(void) { - set_sleep_mode(SLEEP_MODE_IDLE); + set_sleep_mode(SLEEP_MODE_ADC); } #endif /* ifndef SLEEP_H */ diff --git a/firmware/src/usart.c b/firmware/src/usart.c index e8ea898..bab4f46 100644 --- a/firmware/src/usart.c +++ b/firmware/src/usart.c @@ -1,5 +1,27 @@ #include "usart.h" +/** + * @brief starts the usart. + * @param ubrr is the baudrate + * @param rx enables the receive + * @param tx enables the transmit + * it is recommended to use the following defines: + * @code + * #define USART_BAUD 9600 + * #define MYUBRR F_CPU/16/USART_BAUD-1 + * usart_init(MYUBRR,1,1); + * @endcode + */ +inline void usart_init(uint16_t ubrr, uint8_t rx, uint8_t tx) +{ + // set BAUDRATE + UBRR0H = (uint8_t)(ubrr >>8); + UBRR0L = (uint8_t)ubrr; + + // Enable RX and TX + UCSR0B = ((rx&1)<>8); - UBRR0L = (uint8_t)ubrr; + #define LEN 22 // length of the string w/ null terminator + #define BASE 10 // string as a decimal base + #define FILL '0' // character to fill non-used algarisms. - // Enable RX and TX - UCSR0B = ((rx&1)<