//----------------------------------------------------------------------------- #include "typedefs.h" #include "application.h" #include "spi_master.h" #include "ad7719_adc.h" #include "atmega_adc.h" #include "usart.h" #include "macros.h" #include "interpol.h" //#include "w5100_spi_interface.h" #include #include #include //----------------------------------------------------------------------------- // definition of some functions: // these function are implemented in this file, this is not doog coding style. // sooner or later, they will be moved into more apropriate files. U08 increase_adc (U08 channel); U08 increase_ad7719 (U08 channel); void Set_V_Muxer (U08 channel); void Set_T_Muxer(U08 channel); void talk(void);// never used up to now. void ad7719_output(U08 channel, U32 data); void adc_output(U08 channel, U08 data); void adc_output_all(); void parse(); //doesn't do anything at the moment void check_if_measured_all() ; void print_ad7719_nicely(); void print_adc_nicely(); void print_temp_nicely(); // end of function definition: //----------------------------------------------------------------------------- // MAIN WORKFLOW GLOBAL VARIABLES bool verbose; bool heartbeat_enable; // USART global variables U08 usart_rx_buffer[USART_RX_BUFFER_SIZE]; U08 usart_tx_buffer[USART_TX_BUFFER_SIZE]; U08 usart_received_chars; U08 usart_rx_buffer_index = 0; U08 usart_tx_buffer_index = 0; U08 usart_last_char; // last received char // USART FLAGS bool usart_tx_buffer_overflow = false; // true if usart_tx_buffer was full. bool usart_rx_ready = false; // EOL was received, parser needs to be called // TIMER global variable volatile U32 local_ms = 0; // AD7719 global variables #define TEMP_CHANNELS 64 #define CHANNEL_BITMAP 8 #define AD7719_READINGS_UNTIL_SETTLED 3 // bei3:480ms U32 ad7719_values[TEMP_CHANNELS]; U08 ad7719_enables[CHANNEL_BITMAP]; U08 ad7719_channels_ready[CHANNEL_BITMAP]; U08 ad7719_readings_since_last_muxing = 0; U08 ad7719_current_channel = 0; U32 ad7719_current_reading = 0; bool ad7719_measured_all = false; // ATMEGA ADC global variables #define V_CHANNELS 40 #define I_CHANNELS 40 #define H_CHANNELS 4 #define V_BITMAP 5 #define I_BITMAP 5 #define H_BITMAP 1 #define ADC_READINGS_UNTIL_SETTLED 1 U08 adc_values[V_CHANNELS + I_CHANNELS + H_CHANNELS]; // stores measured voltage in steps of 16mV U08 adc_enables[V_BITMAP + I_BITMAP + H_BITMAP]; U08 adc_channels_ready[V_BITMAP + I_BITMAP + H_BITMAP]; U08 adc_readings_since_last_muxing = 0; U08 adc_current_channel = 0; U08 adc_current_reading = 0; bool adc_measured_all = false; bool once_told_you = true; bool debug_mode = false; //----------------------------------------------------------------------------- // M A I N --- M A I N --- M A I N --- M A I N --- M A I N //----------------------------------------------------------------------------- int main(void) { app_init(); // Setup: Watchdog and I/Os usart_init(); // Initialize serial interface spi_init(); // Initialize SPI interface as master ad7719_init(); // Initialize AD7719 ADC as SPI slave atmega_adc_init(); // TIMER2 is used as local clock: // configure timer 2 TCCR2 = (1< counts up every 8us OCR2 = 125-1; // --> output compare interrupt occurs every 125 x 8us = 1ms // Compare Interrupt erlauben TIMSK |= (1< heartbeat //---------------------------------------------------------------------------- //IF we need to send away one byte, and ready to send if ( (usart_tx_buffer_index > 0) && (UCSRA & (1< looking at the voltage channels // channel 40..79 --> looking at the current channels // channel 80..83 --> looking at the humidities void Set_V_Muxer (U08 channel){ U08 SB = 0; // voltages if (channel < 40) { if (channel < 36) SB = channel*2; else SB = (channel+1)*2; } // currents else if (channel < 80) { channel -= 40; if (channel < 36) SB = channel*2+1; else SB = (channel+1)*2+1; } // humidities else if (channel < 84) { channel -= 80; switch (channel) { case 0: SB = 0x48; //0100.1000 break; case 1: SB = 0x49; //0100.1001 break; case 2: SB = 0x58; //0101.0010 break; case 3: SB = 0x58; //0101.0011 break; } // end of switch-case } // end of if (channel < some_number) PORTC = (PORTC & 0x80) | (0x7F & SB); // Here the muxer is switched. } void Set_T_Muxer(U08 channel) { U08 SA = 0x00; switch (channel/16) { case 0: SA |= 1<<4; // 0001.0000 break; case 1: break; // 0000.0000 case 2: SA |= (1<<4)|(1<<5); // 0011.0000 break; case 3: SA |= 1<<5; // 0010.0000 break; } SA = SA | (channel%16); PORTA = (PORTA & 0xC0) | (0x3F & SA); // Here the muxer is switched. } void talk(void){ /* // makes no sense to declare the 'new_measurement' vars here // but maybe the whole function will be deleted, anyway ... // I'm thinking about it. bool ad7719_new_measurement; bool atmega_adc_new_measurement; if (verbose == true) { // somebody wants to read every new measured value, even if it is trash! // do not actually send away data ! // just prepare the data to be send away. if ( ad7719_new_measurement == true ) { add_str_to_output_stream("ad7719: reading:"); add_dec_to_output_stream(reading_since_last_muxer_switch,1); add_str_to_output_stream(" temperature channel:"); add_dec_to_output_stream(current_temperature_channel,2); add_str_to_output_stream(" = "); add_float_to_output_stream(current_ad7719_value,4,3); add_str_to_output_stream("\n"); } if (atmega_adc_new_measurement == true) { add_str_to_output_stream("atmega_adc: reading:"); add_dec_to_output_stream(reading_since_last_muxer_switch,1); add_str_to_output_stream(" voltage channel:"); add_dec_to_output_stream(current_voltage_channel,2); add_str_to_output_stream(" = "); add_float_to_output_stream(current_atmega_adc_value,4,3); add_str_to_output_stream("\n"); } } // end of: if verbose */ } // end of talk() // this function generates some output. void ad7719_output(U08 channel, U32 data) { float value = 0; usart_write_str((pU08)"R:"); //R for resistance usart_write_char('A'+channel/8); // Letters A,B,C,D,E,F,G,H //usart_write_char(' '); usart_write_U08(channel%8+1,1); // Numbers 1...8 usart_write_char(':'); value = (6.25 * data) / ((U32)1 << 25); usart_write_float(value, 3,6); //usart_write_U32_hex(data); //data } void adc_output(U08 channel, U08 data) { // if (channel < 40) // usart_write_str((pU08)"V:"); // else if (channel < 80) // usart_write_str((pU08)"I:"); // else if (channel < 84) // usart_write_str((pU08)"H:"); if (channel <80) { switch ((channel%40)/4) { case 0: case 1: usart_write_char('A'); break; case 2: case 3: usart_write_char('B'); break; case 4: case 5: usart_write_char('C'); break; case 6: case 7: usart_write_char('D'); break; case 8: usart_write_char('E'); break; case 9: usart_write_char('F'); break; default: usart_write_char('?'); break; } } else // channel 80..83 { usart_write_char('H'); } //usart_write_char(' '); if ( (channel%40)/4 == 9) usart_write_U08((channel)%4+1,1); // Numbers 1...4 else usart_write_U08((channel)%8+1,1); // Numbers 1...8 //usart_write_U08(channel,2); // Numbers 1...8 usart_write_char(':'); usart_write_U16((U16)data*16, 4); //data } void adc_output_all() { print_adc_nicely(); print_ad7719_nicely(); } // this method parses the data, // which came in via USART // later it might as well parse the data from ethernet. void parse() { U08 command = usart_rx_buffer[0]; // look at first byte // I hope, I can manage to use one byte commands usart_rx_buffer[USART_RX_BUFFER_SIZE-1] = 0; usart_write_str((pU08)"got:"); usart_write_str(usart_rx_buffer); switch (command) { case 'E': // AD7719 enable bitmaps may be set usart_write_str((pU08)"\n set enable bits of AD7719 Port "); if ((usart_rx_buffer_index>=5) && (usart_rx_buffer[2] >= 'A' && usart_rx_buffer[2] <= 'H')) { usart_write_char(usart_rx_buffer[2]); usart_write_str((pU08)" to "); usart_write_U08_hex(usart_rx_buffer[4]); usart_write_char('\n'); ad7719_enables[usart_rx_buffer[2]-'A']=usart_rx_buffer[4]; ad7719_channels_ready[usart_rx_buffer[2]-'A']=0x00; } else if ((usart_rx_buffer_index=3) && (usart_rx_buffer[1] >= 'A' && usart_rx_buffer[1] <= 'H')) { usart_write_char(usart_rx_buffer[1]); if (usart_rx_buffer[2]!='0') { usart_write_str((pU08)" to 0xFF\n"); ad7719_enables[usart_rx_buffer[1]-'A']=0xFF; } else { usart_write_str((pU08)" to 0x00\n"); ad7719_enables[usart_rx_buffer[1]-'A']=0x00; } ad7719_channels_ready[usart_rx_buffer[1]-'A']=0x00; } else { usart_write_str((pU08)"\n something wrong\n"); usart_write_str((pU08)"usart_rx_buffer_index: "); usart_write_U08(usart_rx_buffer_index, 3); usart_write_str((pU08)"\n usart_rx_buffer[2]: "); usart_write_char(usart_rx_buffer[2]); usart_write_str((pU08)"\n usart_rx_buffer[4]: "); usart_write_U08_hex(usart_rx_buffer[4]); usart_write_char('\n'); } break; case 'e': // ATmega internal ADC enable bitmaps may be set usart_write_str((pU08)"\n setting ADC enable registers all"); if (usart_rx_buffer[1] == '0'){ usart_write_str((pU08)"OFF \n"); for ( U08 i=0; i