Changeset 10109
- Timestamp:
- 01/19/11 15:44:25 (14 years ago)
- Location:
- firmware/FSC/src
- Files:
-
- 2 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
firmware/FSC/src/FSC.c
r10106 r10109 2 2 #include "typedefs.h" 3 3 #include "application.h" 4 #include "spare_outs.h"5 4 #include "spi_master.h" 6 #include "ad7719_adc.h" 5 #include "ad7719_adc.h" 6 #include "atmega_adc.h" 7 7 #include "usart.h" 8 8 #include "macros.h" … … 13 13 #include <stdlib.h> 14 14 15 #include "tests.h" 15 16 16 //----------------------------------------------------------------------------- 17 17 // definition of some functions: 18 // these function are implemented below the main() 19 // here in FSC.c 20 // 21 // sooner or later, they will be moved into more apropriate files. 22 U08 increase_adc (U08 channel); 23 U08 increase_ad7719 (U08 channel); 24 void Set_V_Muxer (U08 channel); 25 void Set_T_Muxer(U08 channel); 26 void talk(void);// never used up to now. 27 void ad7719_output(U08 channel, U32 data); 28 void adc_output(U08 channel, U08 data); 29 void adc_output_all(); 30 void parse(); //doesn't do anything at the moment 31 void check_if_measured_all() ; 32 // end of function definition: 33 //----------------------------------------------------------------------------- 34 35 // MAIN WORKFLOW GLOBAL VARIABLES 36 bool verbose; 37 bool heartbeat_enable; 38 39 // USART global variables 40 U08 usart_rx_buffer[USART_RX_BUFFER_SIZE]; 41 U08 usart_tx_buffer[USART_TX_BUFFER_SIZE]; 42 U08 usart_rx_buffer_index = 0; 43 U08 usart_tx_buffer_index = 0; 44 U08 usart_last_char; // last received char 45 46 // USART FLAGS 47 bool usart_tx_buffer_overflow = false; // true if usart_tx_buffer was full. 48 bool usart_rx_ready = false; // EOL was received, parser needs to be called 49 50 // TIMER global variable 51 volatile U32 local_ms = 0; 52 53 // AD7719 global variables 54 #define TEMP_CHANNELS 64 55 #define CHANNEL_BITMAP 8 56 #define AD7719_READINGS_UNTIL_SETTLED 1 // bei3:480ms 57 U32 ad7719_values[TEMP_CHANNELS]; 58 U08 ad7719_enables[CHANNEL_BITMAP]; 59 U08 ad7719_channels_ready[CHANNEL_BITMAP]; 60 U08 ad7719_readings_since_last_muxing = 0; 61 U08 ad7719_current_channel = 0; 62 U32 ad7719_current_reading = 0; 63 bool ad7719_measured_all = false; 64 65 // ATMEGA ADC global variables 66 #define V_CHANNELS 40 67 #define I_CHANNELS 40 68 #define H_CHANNELS 4 69 #define V_BITMAP 5 70 #define I_BITMAP 5 71 #define H_BITMAP 1 72 #define ADC_READINGS_UNTIL_SETTLED 1 73 U32 adc_values[V_CHANNELS + I_CHANNELS + H_CHANNELS]; // stores measured voltage in steps of 16mV 74 U08 adc_enables[V_BITMAP + I_BITMAP + H_BITMAP]; 75 U08 adc_channels_ready[V_BITMAP + I_BITMAP + H_BITMAP]; 76 U08 adc_readings_since_last_muxing = 0; 77 U08 adc_current_channel = 0; 78 U08 adc_current_reading = 0; 79 bool adc_measured_all = false; 80 81 //----------------------------------------------------------------------------- 82 // M A I N --- M A I N --- M A I N --- M A I N --- M A I N 83 //----------------------------------------------------------------------------- 18 84 int main(void) 19 85 { 20 // U08 IDN_STR[] = "16ch Pt1000 logger; firmware version of 07.11.10. DN"; // Identity string 21 22 spare_outs_init(); //set spare out pin I/O modes 23 app_init(); // Setup software modules 24 usart_init(); // Initialize serial interface 86 app_init(); // Setup: Watchdog and I/Os 87 usart_init(); // Initialize serial interface 25 88 spi_init(); // Initialize SPI interface as master 26 adc_init(); // Initialize AD7719 ADC as SPI slave 27 // usart_write_crlf(); 28 // usart_writeln_flash_str(IDN_STR); // Write string to USART interface 29 // usart_write_crlf(); 89 ad7719_init(); // Initialize AD7719 ADC as SPI slave 90 atmega_adc_init(); 91 92 // TIMER2 is used as local clock: 93 // configure timer 2 94 TCCR2 = (1<<WGM21); // CTC Modus 95 TCCR2 |= (1<<CS21) | (1<<CS20); // Prescaler 64 --> counts up every 8us 96 OCR2 = 125-1; // --> output compare interrupt occurs every 125 x 8us = 1ms 97 // Compare Interrupt erlauben 98 TIMSK |= (1<<OCIE2); 30 99 31 100 // Enable interrupts 32 101 sei(); 33 34 35 // temperature muxer pins init: 36 // SA - pins 37 DDRA |= 0x3F; // set all SA-pins as outputs 38 39 40 // voltage, current, humidity - muxer pins: 41 // SB - pins 42 DDRC |= 0x7F; // set all SB - pins as outputs 43 44 // SB - muxer test 45 // DDRA |= 1<<PA6 ; // set D0-0 lina as output. for tests only !!! 46 // PORTA |= 1<<PA6; // set D0-0 line high. for tests only !!! 47 DDRA &= ~(1<<PA6); 48 49 //ADC einschalten 50 ADMUX = 0x26; //0010.0110 // interne Referenzspannung nutzen 51 ADCSRA = (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler 52 ADCSRA |= (1<<ADEN); // ADC aktivieren 53 ADCSRA |= (1<<ADSC); 54 55 56 57 // Main loop 58 //float temperature; 102 103 for ( U08 i=0; i<CHANNEL_BITMAP; ++i ) { 104 ad7719_enables[i]=0xFF; 105 ad7719_channels_ready[i]=0; 106 } 107 for ( U08 i=0; i<V_BITMAP + I_BITMAP + H_BITMAP; ++i ) { 108 adc_enables[i]=0xFF; 109 adc_channels_ready[i]=0; 110 } 111 static U08 welcome[]="\n\nwelcome to FACT FSC commandline interface v0.1\nready?"; 112 usart_write_str(welcome); 113 114 115 //MAIN LOOP 116 while (1) 117 { 118 if (heartbeat_enable) PORTB ^= (1<<PB3); // toggle Out2_spare --> heartbeat 119 //---------------------------------------------------------------------------- 120 //IF we need to send away one byte, and ready to send 121 122 if ( (usart_tx_buffer_index > 0) && (UCSRA & (1<<UDRE)) ) { 123 UDR = usart_tx_buffer[0]; 124 // THis is shit 125 for (U08 i=0 ; i < USART_TX_BUFFER_SIZE; ++i) { 126 usart_tx_buffer[i] = usart_tx_buffer[i+1]; 127 } 128 usart_tx_buffer_index--; 129 } 130 //---------------------------------------------------------------------------- 131 132 //IF we just received one byte, and there is enough space in the RX_buffer 133 if ( (UCSRA & (1<<RXC)) && (usart_rx_buffer_index < USART_RX_BUFFER_SIZE) ){ 134 usart_last_char = UDR; 135 if (usart_last_char == '\n'){ // if EOL was received 136 usart_rx_ready = true; 137 }else { 138 usart_rx_buffer[usart_rx_buffer_index] = usart_last_char; 139 usart_rx_buffer_index++; 140 } 141 // here is still something strange .... better send an enter automatically 142 } else if (UCSRA & (1<<RXC)) { // if there is no scace in the buffer; read anyway. 143 usart_last_char = UDR; 144 usart_rx_buffer_index =0; 145 } 146 //---------------------------------------------------------------------------- 147 148 //IF USART DOR bit is set, PC is sending data to fast!!! 149 if ( UCSRA & (1<<DOR) ){ 150 // flush TX_buffer and write warning message in 151 // maybe even switch off every measurement. ? 152 } 153 //---------------------------------------------------------------------------- 154 155 //IF TX_BUFFER was overrun. 156 if (usart_tx_buffer_overflow) { 157 // flash TX_buffer and write warning message in 158 // maybe even switch off every measurement. ? 159 // 160 // this should only happen, in verbose mode and with low baudrates. 161 } 162 //---------------------------------------------------------------------------- 163 164 //IF one command was received. 165 // -It is not allowed to send more than one command between two '\n' 166 if (usart_rx_ready){ 167 parse(); 168 usart_rx_buffer_index = 0; 169 usart_rx_ready = false; 170 } 171 //---------------------------------------------------------------------------- 172 173 //IF ATmega internal ADC did finish a conversion --every 200us 174 if ( (ADCSRA & (1<<ADIF)) && !adc_measured_all) { 175 adc_current_reading = ADCH; 176 if (adc_readings_since_last_muxing == ADC_READINGS_UNTIL_SETTLED) { 177 adc_values[adc_current_channel] = adc_current_reading; 178 adc_readings_since_last_muxing=0; 179 // note that this channel is ready, now and 180 adc_output(adc_current_channel, adc_current_reading); 181 // proceed to the next enabled channel. 182 adc_channels_ready[adc_current_channel/8] |= (1<<(adc_current_channel%8)); 183 adc_current_channel = increase_adc (adc_current_channel); 184 Set_V_Muxer(adc_current_channel); 185 } else { // the ADC did not settle yet, we discard the reading 186 ++adc_readings_since_last_muxing; 187 // current reading is not used for anything else 188 } 189 } 190 //---------------------------------------------------------------------------- 191 192 //IF AD7719 ADC just finished a conversion -- every 60ms 193 194 if (AD7719_IS_READY()) { 195 ad7719_current_reading = read_adc(); // --takes at 4MHz SCLK speed about 6us 196 // AD7719 is only read out if settled. saves time. 197 if (ad7719_readings_since_last_muxing == AD7719_READINGS_UNTIL_SETTLED) { 198 ad7719_values[ad7719_current_channel] = ad7719_current_reading; 199 ad7719_readings_since_last_muxing=0; 200 // now prepare the data to be send away via USART. 201 //ad7719_output(ad7719_current_channel, ad7719_current_reading); 202 // note that this channel is ready, now and 203 // proceed to the next enabled channel. 204 ad7719_channels_ready[ad7719_current_channel/8] |= (1<<(ad7719_current_channel%8)); 205 ad7719_current_channel = increase_ad7719 (ad7719_current_channel); 206 Set_T_Muxer(ad7719_current_channel); 207 } else { // the AD7719 did not settle yet, we discard the reading 208 ++ad7719_readings_since_last_muxing; 209 210 // current reading is not used for anything else 211 } 212 } 213 //---------------------------------------------------------------------------- 214 //IF one of the ADC measured all channels, we wanted to know. 215 check_if_measured_all(); 216 217 if (ad7719_measured_all && adc_measured_all) 218 adc_output_all(); 219 220 //---------------------------------------------------------------------------- 221 /* 222 if (verbose == true) 223 // talk() was just defined so the 224 // code is not at this place ... look down. 225 talk(); 226 */ 227 228 } // end of MAIN LOOP 229 //----------------------------------------------------------------------------- 230 // E N D E N D E N D E N D E N D E N D E N D 231 //----------------------------------------------------------------------------- 232 233 234 59 235 float resistance; 60 BOOL heartbeat_enable = TRUE; 61 62 U08 SA_mux_val = 0x16; 236 237 U08 SA_mux_val = 0x00; 63 238 U08 SB_mux_val = 0x00; 64 239 … … 69 244 while (TRUE) 70 245 { 71 // this heartbeat shows how long one single run of this while loop takes 72 // measure with a scope. 73 if (heartbeat_enable) PORTB ^= (1<<PB3); // toggle Out2_spare --> heartbeat 74 adc_init(); 246 75 247 76 248 ++Res_or_Volt; … … 121 293 122 294 123 startconv( );124 125 126 while (!AD C_IS_READY())295 startconv(0); 296 297 298 while (!AD7719_IS_READY()) 127 299 { 128 300 // just wait until ADC is redy -- really bad code here! … … 141 313 //_delay_ms(200); 142 314 143 startconv( );144 145 while (!AD C_IS_READY())315 startconv(0); 316 317 while (!AD7719_IS_READY()) 146 318 { 147 319 // just wait until ADC is redy -- really bad code here! … … 255 427 256 428 for (U08 counter = 0; counter < 1; ++counter) { 257 ADCSRA |= (1<<ADSC);258 429 while (ADCSRA & (1<<ADSC) ); // wait until internal ADC is ready 259 430 float voltage; … … 362 533 363 534 364 535 ISR (TIMER2_COMP_vect) 536 { 537 ++local_ms; 538 } 539 540 541 U08 increase_adc (U08 channel){ 542 bool valid_ch_found = false; 543 while (!valid_ch_found){ 544 545 // just increase 'channel' or turnover to zero. 546 ++channel; 547 if (channel == V_CHANNELS + I_CHANNELS + H_CHANNELS) 548 channel = 0; 549 550 // check if this channel is enabled in the bitmap 551 if (adc_enables[channel/8] & (1<<channel%8)) 552 valid_ch_found = true; 553 } // end of while loop 554 return channel; 555 } // end if increase_adc; 556 557 U08 increase_ad7719 (U08 channel){ 558 bool valid_ch_found = false; 559 while (!valid_ch_found){ 560 561 // just increase 'channel' or turnover to zero. 562 ++channel; 563 if (channel == TEMP_CHANNELS) 564 channel = 0; 565 566 // check if this channel is enabled in the bitmap 567 if (ad7719_enables[channel/8] & (1<<channel%8)) 568 valid_ch_found = true; 569 } // end of while loop 570 return channel; 571 } // end if increase_adc; 572 573 574 // Sets voltage Muxer to current channel 575 // this is a Muxing, and therefor the adc might need some time to settle. 576 // Since there are: 577 // - 40 voltage monitor channels 578 // - 40 current monitor channels 579 // - 4 humidity monitor channels 580 // the muxer is set as follows. 581 // channel 00..39 --> looking at the voltage channels 582 // channel 40..79 --> looking at the current channels 583 // channel 80..83 --> looking at the humidities 584 void Set_V_Muxer (U08 channel){ 585 U08 SB = 0; 586 // voltages 587 if (channel < 40) { 588 if (channel < 36) 589 SB = channel*2; 590 else 591 SB = (channel+1)*2; 592 } 593 // currents 594 else if (channel < 80) { 595 channel -= 40; 596 if (channel < 36) 597 SB = channel*2+1; 598 else 599 SB = (channel+1)*2+1; 600 } 601 // humidities 602 else if (channel < 84) { 603 channel -= 80; 604 switch (channel) { 605 case 0: 606 SB = 0x48; //0100.1000 607 break; 608 case 1: 609 SB = 0x49; //0100.1001 610 break; 611 case 2: 612 SB = 0x58; //0101.0010 613 break; 614 case 3: 615 SB = 0x58; //0101.0011 616 break; 617 } // end of switch-case 618 } // end of if (channel < some_number) 619 620 PORTC = (PORTC & 0x80) | (0x7F & SB); // Here the muxer is switched. 621 } 622 623 void Set_T_Muxer(U08 channel) { 624 U08 SA = 0x00; 625 626 switch (channel/16) { 627 case 0: 628 SA |= 1<<4; // 0001.0000 629 break; 630 case 1: 631 break; // 0000.0000 632 case 2: 633 SA |= (1<<4)|(1<<5); // 0011.0000 634 break; 635 case 3: 636 SA |= 1<<5; // 0010.0000 637 break; 638 } 639 640 SA = SA | (channel%16); 641 642 PORTA = (PORTA & 0xC0) | (0x3F & SA); // Here the muxer is switched. 643 } 644 645 void talk(void){ 646 647 /* 648 // makes no sense to declare the 'new_measurement' vars here 649 // but maybe the whole function will be deleted, anyway ... 650 // I'm thinking about it. 651 bool ad7719_new_measurement; 652 bool atmega_adc_new_measurement; 653 if (verbose == true) { 654 // somebody wants to read every new measured value, even if it is trash! 655 // do not actually send away data ! 656 // just prepare the data to be send away. 657 if ( ad7719_new_measurement == true ) { 658 add_str_to_output_stream("ad7719: reading:"); 659 add_dec_to_output_stream(reading_since_last_muxer_switch,1); 660 add_str_to_output_stream(" temperature channel:"); 661 add_dec_to_output_stream(current_temperature_channel,2); 662 add_str_to_output_stream(" = "); 663 add_float_to_output_stream(current_ad7719_value,4,3); 664 add_str_to_output_stream("\n"); 665 } 666 if (atmega_adc_new_measurement == true) { 667 add_str_to_output_stream("atmega_adc: reading:"); 668 add_dec_to_output_stream(reading_since_last_muxer_switch,1); 669 add_str_to_output_stream(" voltage channel:"); 670 add_dec_to_output_stream(current_voltage_channel,2); 671 add_str_to_output_stream(" = "); 672 add_float_to_output_stream(current_atmega_adc_value,4,3); 673 add_str_to_output_stream("\n"); 674 } 675 } // end of: if verbose 676 */ 677 } // end of talk() 678 679 // this function generates some output. 680 void ad7719_output(U08 channel, U32 data) { 681 usart_write_str((pU08)"R:"); //R for resistance 682 usart_write_char('A'+channel/8); // Letters A,B,C,D,E,F,G,H 683 usart_write_char(' '); 684 usart_write_U08(channel%8+1,1); // Numbers 1...8 685 usart_write_char(':'); 686 usart_write_U32_hex(data); //data 687 usart_write_char('\n'); 688 } 689 690 void adc_output(U08 channel, U08 data) { 691 692 if (channel < 40) 693 usart_write_str((pU08)"V:"); //V for Vendetta 694 else if (channel < 80) 695 usart_write_str((pU08)"I:"); //I for Irregular verbs 696 else if (channel < 84) 697 usart_write_str((pU08)"H:"); //H for Huurrray!!! 698 699 switch (channel/16) { 700 case 0: 701 usart_write_char('A'); //V for Vendetta 702 case 1: 703 usart_write_char('B'); //V for Vendetta 704 case 2: 705 usart_write_char('D'); //V for Vendetta 706 case 3: 707 usart_write_char('C'); //V for Vendetta 708 case 4: 709 usart_write_char('EF'); //V for Vendetta 710 } 711 usart_write_char(' '); 712 usart_write_U08((channel/2)%8+1,1); // Numbers 1...8 713 usart_write_char(':'); 714 usart_write_U16((U16)data*16,5); //data 715 usart_write_char('\n'); 716 717 718 } 719 720 721 void adc_output_all() { 722 // output all values, which are enabled 723 for (U08 i=0 ; i<40; ++i){ 724 if (i==0) usart_write_str((pU08)"voltages:(in units of 16mV)\n"); 725 if (i==40) usart_write_str((pU08)"currents:\n"); 726 if (i==80) usart_write_str((pU08)"humidities:\n"); 727 if (adc_enables[i/8] & i%8){ 728 usart_write_U08(adc_values[i],3); 729 usart_write_char('\t'); 730 } 731 if (i%8==7) usart_write_char('\n'); 732 if (i==83) usart_write_char('\n'); 733 } 734 } 735 736 737 // this method parses the data, 738 // which came in via USART 739 // later it might as well parse the data from ethernet. 740 void parse() { 741 U08 command = usart_rx_buffer[0]; 742 // look at first byte 743 // I hope, I can manage to use one byte commands 744 usart_rx_buffer[USART_RX_BUFFER_SIZE-1] = 0; 745 usart_write_str((pU08)"got:"); 746 usart_write_str(usart_rx_buffer); 747 748 749 750 switch (command) { 751 case 'E': // AD7719 enable bitmaps may be set 752 for ( U08 i=0; i<CHANNEL_BITMAP; ++i ) { 753 ad7719_enables[i]=usart_rx_buffer[i+1]; 754 ad7719_channels_ready[i]=0; 755 } 756 break; 757 case 'e': // ATmega internal ADC enable bitmaps may be set 758 for ( U08 i=0; i<V_BITMAP + I_BITMAP + H_BITMAP; ++i ) { 759 adc_enables[i]=usart_rx_buffer[i+1]; 760 adc_channels_ready[i]=0; 761 } 762 break; 763 case 'h': 764 usart_write_str((pU08)"\nheartbeat "); 765 heartbeat_enable = true; 766 if (usart_rx_buffer[1] == '0'){ 767 heartbeat_enable = false; 768 usart_write_str((pU08)"off\n"); 769 } else { 770 usart_write_str((pU08)"on\n"); 771 } 772 break; 773 case 'G': // GET the Temperature channels, which are enabled 774 for ( U08 i=0; i<CHANNEL_BITMAP; ++i ) { 775 ad7719_channels_ready[i]=0; 776 } 777 break; 778 case 'g': // GET the voltage/current/humidity channels, which are enabled 779 for ( U08 i=0; i<V_BITMAP + I_BITMAP + H_BITMAP; ++i ) { 780 adc_channels_ready[i]=0; 781 } 782 break; 783 case 's': 784 usart_write_char('\n'); 785 for (U08 i=0; i< CHANNEL_BITMAP;++i) { 786 usart_write_U08_bin(ad7719_enables[i]); 787 usart_write_char('\t'); 788 } 789 usart_write_char('\n'); 790 for (U08 i=0; i< CHANNEL_BITMAP;++i){ 791 usart_write_U08_bin(ad7719_channels_ready[i]); 792 usart_write_char('\t'); 793 } 794 usart_write_char('\n'); 795 usart_write_U32_hex(local_ms); 796 break; 797 } 798 usart_write_str((pU08)"\nready?"); 799 for (U08 i=0; i<USART_RX_BUFFER_SIZE; ++i) 800 usart_rx_buffer[i] = 0; 801 } 802 803 void check_if_measured_all() { 804 adc_measured_all = true; 805 for ( U08 i=0; i<V_BITMAP + I_BITMAP + H_BITMAP; ++i ) { 806 if ((adc_enables[i] ^ adc_channels_ready[i]) != 0x00) { 807 adc_measured_all = false; 808 break; 809 } 810 } 811 ad7719_measured_all = true; 812 for ( U08 i=0; i<CHANNEL_BITMAP; ++i ) { 813 if ((ad7719_enables[i] ^ ad7719_channels_ready[i]) != 0x00) { 814 ad7719_measured_all = false; 815 break; 816 } 817 } 818 819 820 } -
firmware/FSC/src/ad7719_adc.c
r10106 r10109 6 6 //----------------------------------------------------------------------------- 7 7 8 void ad c_init(void)8 void ad7719_init(void) 9 9 { 10 11 SET_BIT(ADC_DDR,DDD4); // ADC_RST is uP Output12 CLR_BIT(ADC_PRT,ADC_RST); // Reset ADC (active low)13 SET_BIT(ADC_PRT,ADC_RST); // Stop Reset ADC14 15 16 //Init Configure and Initialize AD771917 //http://designtools.analog.com/dt/adc/codegen/ad7719.html18 19 U8 IOCON1 = 0xC3; // power switches P1 and P2 switch to PWRGND. I-sources I1 and I2 are switched on.20 U8 IOCON2 = 0x08; // 0x08 makes no sense... P4 is set HIGH, but is no output.21 // U8 FILTER = 0x45; //0x45 global use 50Hz = -66dB and 60Hz = -117dB Rejectjon22 U8 FILTER = 0x52; //0x52 euro use 50Hz = -171dB and 60Hz = -58dB Rejectjon Updaterate = 4Hz23 24 U8 AD1CON = 0x51;25 // ARN bit is set->AUS ADC range is: +-REFIN226 // ACHo and ACH2 are set --> not defined. ???27 // AD1EN is not set. so aux ADC is not enabled anyway.28 29 U8 AD0CON = 0x8E;30 // AD0EN is set. main ADC operates according to content of mode register31 // U/#B is set. unipolar encoding. zero is 0x000000. both full scales will be 0xFFFFFF32 // RN2..0 = 1 ,1 ,0 --> multiplication factor 8, maybe ??33 34 U8 MODE = 0x02; // single conversion35 10 36 11 // ADC communiaction works like this: … … 46 21 // A3-A0 denote the address of the next register. 47 22 48 const U8 WR_TO_IOCON = 0x07; 49 const U8 WR_TO_FILTER = 0x04; 50 const U8 WR_TO_AD1CON = 0x03; 51 const U8 WR_TO_AD0CON = 0x02; 52 const U8 WR_TO_MODE = 0x01; 53 const U8 RD_FROM_FILTER = 0x44; 23 24 CLR_BIT(ADC_PRT,ADC_RST); // Reset ADC (active low) 25 SET_BIT(ADC_PRT,ADC_RST); // Stop Reset ADC 26 27 28 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low 29 spi_transfer_byte(FILTER_RD); // Next Operation is write to IOCON 30 SET_BIT(PORTD,SPI_AD_CS); 31 32 _delay_us(50); 33 34 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low 35 spi_transfer_byte(0); // Next Operation is write to IOCON 36 SET_BIT(PORTD,SPI_AD_CS); 37 38 _delay_us(50); 39 40 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low 41 spi_transfer_byte(IOCON_WR); // Next Operation is write to IOCON 42 SET_BIT(PORTD,SPI_AD_CS); 43 44 _delay_us(50); 45 46 CLR_BIT(PORTD,SPI_AD_CS); 47 spi_transfer_byte(IOCON_INIT_HIGH); // Write to IOCON1 48 SET_BIT(PORTD,SPI_AD_CS); 49 _delay_us(50); 50 CLR_BIT(PORTD,SPI_AD_CS); 51 spi_transfer_byte(IOCON_INIT_LOWBYTE); // Write to IOCON2 52 SET_BIT(PORTD,SPI_AD_CS); // Set CS high 53 54 _delay_us(50); 54 55 55 56 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low 56 spi_transfer_byte(RD_FROM_FILTER); // Next Operation is write to IOCON1 and IOCON2 Start SPI 57 spi_transfer_byte(0xFF); // Next Operation is write to IOCON1 and IOCON2 Start SPI 57 spi_transfer_byte(FILTER_WR); // Next Operation is write to FILTER Start SPI 58 SET_BIT(PORTD,SPI_AD_CS); 59 60 _delay_us(50); 61 CLR_BIT(PORTD,SPI_AD_CS); 62 63 spi_transfer_byte(FILTER_INIT); // Write to FILTER 64 SET_BIT(PORTD,SPI_AD_CS); // Set CS high 65 _delay_us(50); 66 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low 67 spi_transfer_byte(AD1CON_WR); // Next Operation is write to AD1CON Start SPI 68 SET_BIT(PORTD,SPI_AD_CS); 69 70 _delay_us(50); 71 72 CLR_BIT(PORTD,SPI_AD_CS); 73 spi_transfer_byte(AD1CON_INIT); // Write to AD1CON 58 74 SET_BIT(PORTD,SPI_AD_CS); // Set CS high 59 75 76 _delay_us(50); 77 78 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low 79 spi_transfer_byte(AD0CON_WR); // Next Operation is write to AD0CON Start SPI 80 SET_BIT(PORTD,SPI_AD_CS); 81 82 _delay_us(50); 83 84 CLR_BIT(PORTD,SPI_AD_CS); 85 spi_transfer_byte(AD0CON_INIT); // Write to AD0CON 86 SET_BIT(PORTD,SPI_AD_CS); // Set CS high 87 88 _delay_us(50); 89 90 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low 91 spi_transfer_byte(MODE_WR); // Next Operation is write to MODE Start SPI 92 SET_BIT(PORTD,SPI_AD_CS); 93 94 _delay_us(50); 95 96 CLR_BIT(PORTD,SPI_AD_CS); 97 spi_transfer_byte(MODE_CONT); // Write to MODE 98 SET_BIT(PORTD,SPI_AD_CS); // Set CS high 99 100 _delay_us(50); 101 102 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low 103 spi_transfer_byte(FILTER_RD); // Next Operation is write to IOCON 104 SET_BIT(PORTD,SPI_AD_CS); 105 106 _delay_us(50); 107 108 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low 109 spi_transfer_byte(0); // Next Operation is write to IOCON 110 SET_BIT(PORTD,SPI_AD_CS); 111 112 _delay_us(50); 60 113 61 114 62 63 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low64 spi_transfer_byte(WR_TO_IOCON); // Next Operation is write to IOCON1 and IOCON2 Start SPI65 SET_BIT(PORTD,SPI_AD_CS); // Set CS high66 67 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low68 spi_transfer_byte(IOCON1); // Write to IOCON169 spi_transfer_byte(IOCON2); // Write to IOCON270 SET_BIT(PORTD,SPI_AD_CS); // Set CS high71 72 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low73 spi_transfer_byte(WR_TO_FILTER); // Next Operation is write to FILTER Start SPI74 SET_BIT(PORTD,SPI_AD_CS); // Set CS high75 76 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low77 spi_transfer_byte(FILTER); // Write to FILTER78 SET_BIT(PORTD,SPI_AD_CS); // Set CS high79 80 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low81 spi_transfer_byte(WR_TO_AD1CON); // Next Operation is write to AD1CON Start SPI82 SET_BIT(PORTD,SPI_AD_CS); // Set CS high83 84 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low85 spi_transfer_byte(AD1CON); // Write to AD1CON86 SET_BIT(PORTD,SPI_AD_CS); // Set CS high87 88 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low89 spi_transfer_byte(WR_TO_AD0CON); // Next Operation is write to AD0CON Start SPI90 SET_BIT(PORTD,SPI_AD_CS); // Set CS high91 92 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low93 spi_transfer_byte(AD0CON); // Write to AD0CON94 SET_BIT(PORTD,SPI_AD_CS); // Set CS high95 96 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low97 spi_transfer_byte(WR_TO_MODE); // Next Operation is write to MODE Start SPI98 SET_BIT(PORTD,SPI_AD_CS); // Set CS high99 100 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low101 spi_transfer_byte(MODE); // Write to MODE102 SET_BIT(PORTD,SPI_AD_CS); // Set CS high103 115 } 104 116 105 void startconv(void) 106 { 107 U8 COM = 0x01; 108 U8 SERIAL = 0x02; 117 void startconv(U08 continuous) 118 { 109 119 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low 110 spi_transfer_byte(COM); // Next Operation is write to Mode Register 111 spi_transfer_byte(SERIAL); // Start new A/D conversion 120 spi_transfer_byte(MODE_WR); // Next Operation is write to Mode Register 121 SET_BIT(PORTD,SPI_AD_CS); 122 CLR_BIT(PORTD,SPI_AD_CS); 123 if (continuous) spi_transfer_byte(MODE_SINGLE); // Start new A/D conversion 124 else spi_transfer_byte(MODE_CONT); // Start continous conversion mode 112 125 SET_BIT(PORTD,SPI_AD_CS); 113 COM = 0x45; 126 } 127 128 void stopconv(void) 129 { 114 130 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low 115 spi_transfer_byte(COM); // Next Operation is read from Main ADC Data Register 116 SET_BIT(PORTD,SPI_AD_CS); // Set CS high 117 } 131 spi_transfer_byte(MODE_WR); // Next Operation is write to Mode Register 132 SET_BIT(PORTD,SPI_AD_CS); 133 CLR_BIT(PORTD,SPI_AD_CS); 134 spi_transfer_byte(MODE_IDLE); 135 SET_BIT(PORTD,SPI_AD_CS); 136 } 118 137 119 U32 read_adc(void) 120 { CLR_BIT(PORTD,SPI_AD_CS); // Set CS low 121 U32 value=0; // actually a 24bit value is returned 122 value |= spi_transfer_byte(0) ; 123 value =value<<8; 124 value |= spi_transfer_byte(0) ; 125 value =value<<8; 126 value |= spi_transfer_byte(0) ; 127 SET_BIT(PORTD,SPI_AD_CS); // Set CS high 128 return value; 129 } 138 139 U32 read_adc(void) 140 { 141 CLR_BIT(PORTD,SPI_AD_CS); // Set CS low 142 spi_transfer_byte(AD0DAT_RD); // Next Operation is read from Main ADC Data Register 143 SET_BIT(PORTD,SPI_AD_CS); 144 _delay_us(50); 145 146 CLR_BIT(PORTD,SPI_AD_CS); 147 U32 value=0; // actually a 24bit value is returned 148 value |= spi_transfer_byte(0) ; 149 value =value<<8; 150 value |= spi_transfer_byte(0) ; 151 value =value<<8; 152 value |= spi_transfer_byte(0) ; 153 SET_BIT(PORTD,SPI_AD_CS); // Set CS high 154 return value; 155 } 130 156 131 157 -
firmware/FSC/src/ad7719_adc.h
r10102 r10109 10 10 #define ADC_RDY PD6 11 11 #define ADC_RST PD7 12 #define AD C_IS_READY() !(PIND & (1<<PD6)) // TRUE if PD6=0 AD_RDY is inverted logic.12 #define AD7719_IS_READY() (!(PIND & (1<<PD6))) // TRUE if PD6=0 AD_RDY is inverted logic. 13 13 14 14 // Port Definitions … … 17 17 #define ADC_PIN PIND 18 18 19 void adc_init(void); 20 void startconv(void); 19 20 // ON CHIP REGISTER ADDRESSES 21 #define STATUS_RD 0x40 22 23 #define MODE_WR 0x01 24 #define MODE_RD 0x41 25 26 #define AD0CON_WR 0x02 27 #define AD0CON_RD 0x42 28 29 #define AD1CON_WR 0x03 30 #define AD1CON_RD 0x43 31 32 #define FILTER_WR 0x04 33 #define FILTER_RD 0x44 34 35 #define AD0DAT_RD 0x45 36 #define AD1DAT_RD 0x46 37 38 #define IOCON_WR 0x07 39 #define IOCON_RD 0x47 40 41 #define AD0OFS_WR 0x08 42 #define AD0OFS_RD 0x48 43 44 #define AD1OFS_WR 0x09 45 #define AD1OFS_RD 0x49 46 47 #define AD0GAIN_WR 0x0A 48 #define AD0GAIN_RD 0x4A 49 50 #define AD1GAIN_WR 0x0B 51 #define AD1GAIN_RD 0x4B 52 53 #define ID_RD 0x4F 54 55 // REGISTER INIT VALUES 56 57 //Init Configure and Initialize AD7719 58 //http://designtools.analog.com/dt/adc/codegen/ad7719.html 59 60 #define IOCON_INIT_HIGH 0x03 //0000.0011 // I-sources I1 and I2 are switched on, thats all 61 #define IOCON_INIT_LOWBYTE 0x00 62 63 #define FILTER_INIT 0x52 //0x52 euro use 50Hz = -171dB and 60Hz = -58dB Rejectjon Updaterate = 4Hz 64 // 0x52=82 decimal. f_ADC=16.6Hz; t_ADC=60ms; t_settle = 120ms 65 66 #define AD1CON_INIT 0x31 //0011.0001 67 // AD1EN is set --> AUX ADc is used for Temp measurement. 68 // ACH = 011 --> Tempsensor 69 // U/#B = 0 --> bipolar, but i'm not entirely sure if this is correct. 70 // ARN = 1 --> input range is REFIN2 , but when tempsensor is chosen, internal ref is used ... 71 72 #define AD0CON_INIT 0x8E // 1000.1110 73 // AD0EN is set 74 // WL is cleared --> 24bit 75 // CH = 00 --> AIN1 , AIN2 used 76 // U/#B = 1 --> unipolar 77 // RN=110 --> input range = +-1.28V --> whatever this means in ratiometric measurements. 78 79 80 #define MODE_IDLE 0x01 81 #define MODE_SINGLE 0x02 82 #define MODE_CONT 0x03 83 #define MODE_INTERNAL_ZERO_CAL 0x04 // not tested 84 #define MODE_INTERNAL_FULL_CAL 0x05 // not tested 85 86 // since the ADC is chopped, one should wait 3 conversions 87 // after the muxer was switched, until the reading is okay. 88 #define READINGS_UNTIL_AD7719_SETTLED 3 89 90 void ad7719_init(void); 91 void startconv(U08 continuous); 92 void stopconv(void); 21 93 U32 read_adc(void); 22 94 //----------------------------------------------------------------------------- -
firmware/FSC/src/application.c
r10108 r10109 4 4 #include <avr/wdt.h> 5 5 6 //7 6 8 7 //----------------------------------------------------------------------------- … … 16 15 MCUSR = 0x00; // Clear reset source for next reset cycle 17 16 17 18 // Dangerous here: I still do not know much about the watchdog. 19 // This code is still from Udo Juerss. 20 18 21 // The watchdog timer is disabled by default ("startup.asm") 19 #ifdef USE_WATCHDOG 20 WDTCSR = WDTOE | (1 << WDE); // Enable watchdog reset (~16ms) 21 #endif 22 23 #ifndef F_CPU 24 #define F_CPU 8000000UL //cpu frequency 25 #endif 22 #ifdef USE_WATCHDOG 23 WDTCSR = WDTOE | (1 << WDE); // Enable watchdog reset (~16ms) 24 #endif 26 25 27 //#ifdef (F_CPU == 16000000UL) 28 /*#else 29 #warning *** Compiling for _MCU_CLOCK_FREQUENCY_ Hz 30 #error *** Invalid clock selected! *** 31 #endif*/ 32 // Tell the user the operating frequency 33 //#warning *** Compiling for DF_CPU Hz 34 /* 35 // Set selected CPU clock 36 #if (_MCU_CLOCK_FREQUENCY_ == 16000000) 37 CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR 38 CLKPR = 0; // Set clock prescaler to division by 1 (16MHz clock with 16MHz crystal) 39 #elif (_MCU_CLOCK_FREQUENCY_ == 8000000) 40 CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR 41 CLKPR = 1; // Set clock prescaler to division by 2 (8MHz clock with 16MHz crystal) 42 #elif (_MCU_CLOCK_FREQUENCY_ == 4000000) 43 CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR 44 CLKPR = 2; // Set clock prescaler to division by 4 (4MHz clock with 16MHz crystal) 45 #elif (_MCU_CLOCK_FREQUENCY_ == 2000000) 46 CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR 47 CLKPR = 3; // Set clock prescaler to division by 8 (2MHz clock with 16MHz crystal) 48 #elif (_MCU_CLOCK_FREQUENCY_ == 1000000) 49 CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR 50 CLKPR = 4; // Set clock prescaler to division by 16 (1MHz clock with 16MHz crystal) 51 #else 52 #warning *** Compiling for _MCU_CLOCK_FREQUENCY_ Hz 53 #error *** Invalid clock selected! *** 54 #endif 26 // define PORTS 27 // USART 28 DDRD &= ~(1<<PD0); // PD0 = RXD is input 29 DDRD |= 1<<PD1; // PD1 = TXD is output 30 55 31 56 // Tell the user the operating frequency 57 #warning *** Compiling for _MCU_CLOCK_FREQUENCY_ Hz 32 // SPARE OUT/-INPUTS 33 DDRB |= (1<<PB2) | (1<<PB3); // set Out1_spare & out2_spare as outputs 34 DDRA &= ~(1<<PA7); // set In1_spare as input 35 DDRC &= ~(1<<PC7); // set In2_spare as input 36 PORTA |= (1<<PA7); // swtich on pullup on In1_spare 37 PORTC |= (1<<PC7); // swtich on pullup on In2_spare 58 38 59 */ 39 // ATmega internal ADC input 40 DDRA &= ~(1<<PA6); 60 41 61 /* (ATmega32 has no prescaler) 62 // Set selected CPU clock 63 #if (F_CPU == 16000000) 64 CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR 65 CLKPR = 0; // Set clock prescaler to division by 1 (16MHz clock with 16MHz crystal) 66 #elif (F_CPU == 8000000) 67 CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR 68 CLKPR = 1; // Set clock prescaler to division by 2 (8MHz clock with 16MHz crystal) 69 #elif (F_CPU == 4000000) 70 CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR 71 CLKPR = 2; // Set clock prescaler to division by 4 (4MHz clock with 16MHz crystal) 72 #elif (F_CPU == 2000000) 73 CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR 74 CLKPR = 3; // Set clock prescaler to division by 8 (2MHz clock with 16MHz crystal) 75 #elif (F_CPU == 1000000) 76 CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR 77 CLKPR = 4; // Set clock prescaler to division by 16 (1MHz clock with 16MHz crystal) 78 #else 79 #warning *** Compiling for F_CPU Hz 80 #error *** Invalid clock selected! *** 81 #endif 42 // MUXER ADDRESS OUTs 43 DDRA |= 0x3F; // SA-pins -> output 44 DDRC |= 0x7F; // SB-pins -> output 45 46 // SPI 47 // set all CS's: output 48 DDRB |= (1 << SPI_E_CS); 49 DDRD |= (1 << SPI_AD_CS) |(1 << SPI_M_CS) |(1 << SPI_A_CS); 50 51 // set all Chips selects HIGH 52 PORTB |= (1 << SPI_E_CS); 53 PORTD |= (1 << SPI_AD_CS) |(1 << SPI_M_CS) |(1 << SPI_A_CS); 54 55 // set MOSI and SCK: output & // set MISO: input 56 SPI_DDR |= (1 << SPI_MOSI); 57 SPI_DDR |= (1 << SPI_SCLK); 58 SPI_DDR &= ~(1 << SPI_MISO); 59 60 // set MOSI, SCK: HIGH. MISO leave alone. 61 SPI_PRT |= (1 << SPI_MOSI); 62 SPI_PRT |= (1 << SPI_SCLK); 63 SPI_PRT |= (1 << SPI_MISO); 64 65 // ADC 66 DDRD &= ~(1<<PD6); // PD6 is AD_READY input 67 DDRD |= 1<<PD7; // PD7 is AD_RESET output 68 69 // ACCELEROMETER 70 DDRD &= ~(1<<PD2); // PD2 is ACC_READY input 71 72 //MAX6662 <--- not assembled anymore 73 // DDRB &= ~(1<<PB0); // PB0 is over temperature alert input 74 // DDRB &= ~(1<<PB1); // PB1 is general temperature altert input 82 75 83 76 84 85 // Tell the user the operating frequency86 #warning *** Compiling for F_CPU Hz87 88 89 // Turn off unused modules for this application90 PRR =91 (92 #ifndef USE_TWI93 TWEN // I2C module94 #warning *** Module "TWI" not enabled!95 #endif96 97 (ATmega32 Can't disable TIMER modules)98 #ifndef USE_TIMER299 | PRTIM2 // Timer2100 #warning *** Module "TIMER2" not enabled!101 #endif102 #ifndef USE_TIMER1103 | PRTIM1 // Timer1104 #warning *** Module "TIMER1" not enabled!105 #endif106 #ifndef USE_TIMER0107 | PRTIM0 // Timer0108 #warning *** Module "TIMER0" not enabled!109 #endif110 111 #ifndef USE_USART0112 | PRUSART0 // USART0113 #warning *** Module "USART0" not enabled!114 #endif115 116 #ifndef USE_SPI117 | SPE // SPI118 #warning *** Module "SPI" not enabled!119 #endif120 121 #ifndef USE_ADC122 | ADEN // ADC123 #warning *** Module "ADC" not enabled!124 #endif125 );126 127 #ifndef USE_ACO // Analog comparator128 ACSR = ACME;129 #warning *** Module "ACO" not enabled!130 #endif131 132 PORTC |= PC6; // Enable pullup for PC6_RESET133 134 // Initialize switches S1, S2 and S3135 //S1_INIT(); // Set S1 pin to input136 //S2_INIT(); // Set S2 pin to input137 //S3_INIT(); // Set S3 pin to input138 */139 77 } 140 78 -
firmware/FSC/src/application.h
r10102 r10109 6 6 //----------------------------------------------------------------------------- 7 7 8 //#define F_CPU (_MCU_CLOCK_FREQUENCY_) 9 #define F_CPU_KHZ (F_CPU / 1000) 10 #define F_CPU_MHZ (F_CPU_KHZ / 1000) 11 //----------------------------------------------------------------------------- 12 13 // Definitions of hardware modules used by application 14 // Comment out all unused hardware modules 15 16 //#define USE_TWI // I2C module used? 17 //#define USE_TIMER2 // Timer2 used? 18 //#define USE_TIMER1 // Timer1 used? 19 //#define USE_TIMER0 // Timer0 used? 20 //#define USE_SPI // SPI used? 21 //#define USE_USART // USART0 used? 22 //#define USE_ADC // ADC used? 23 //#define USE_ACO // Analog Comparator used? 24 //#define USE_WATCHDOG // Comment out to disable watchdog timer 25 //----------------------------------------------------------------------------- 26 27 // USART0 definitions 28 #define USART_RX_BUFFER_SIZE 64 // Receive buffer size 8 #define USART_RX_BUFFER_SIZE 32 // Receive buffer size 9 #define USART_TX_BUFFER_SIZE 255 // Receive buffer size. MUST not be larger 255 29 10 30 11 #define USART_BAUDRATE 9600 // USART baudrate original 31 32 12 #define USART_USE_TX // Transmitter used? 33 13 #define USART_USE_RX // Receiver used? 34 #define USART_USE_RX_IRQ // RX interrupt used?14 //#define USART_USE_RX_IRQ // RX interrupt used? 35 15 #define USART_USE_UPPERCASE // Convert received chars to uppercase? 36 16 //----------------------------------------------------------------------------- 37 17 18 // SPI DEFINITIONS 19 // Port Definitions 20 #define SPI_PRT PORTB 21 #define SPI_DDR DDRB 22 23 // Bit Definitions 24 #define SPI_SCLK PB7 25 #define SPI_MOSI PB5 26 #define SPI_MISO PB6 27 28 #define SPI_E_CS PB4 29 #define SPI_AD_CS PD3 30 #define SPI_M_CS PD4 31 #define SPI_A_CS PD5 32 33 34 35 36 //----------------------------------------------------------------------------- 38 37 extern volatile U08 app_reset_source; 39 38 //----------------------------------------------------------------------------- -
firmware/FSC/src/spare_outs.c
r10094 r10109 1 #include "spare_outs.h"2 #include <avr/io.h>3 4 void spare_outs_init(void)5 {6 DDRB |= (1<<PB2) | (1<<PB3); // set Out1_spare & out2_spare as outputs7 8 DDRA &= ~(1<<PA7); // set In1_spare as input9 DDRC &= ~(1<<PC7); // set In2_spare as input10 PORTA |= (1<<PA7); // swtich on pullup on In1_spare11 PORTC |= (1<<PC7); // swtich on pullup on In2_spare12 13 } -
firmware/FSC/src/spare_outs.h
r10094 r10109 1 #ifndef __SPARE_OUTS_H2 #define __SPARE_OUTS_H3 4 void spare_outs_init(void);5 6 #endif //__SPARE_OUTS_H -
firmware/FSC/src/spi_master.c
r10102 r10109 20 20 void spi_init(void) 21 21 { 22 23 // set all CS's: output 24 DDRB |= (1 << SPI_E_CS); 25 DDRD |= (1 << SPI_AD_CS) |(1 << SPI_M_CS) |(1 << SPI_A_CS); 26 27 // set all Chips selects HIGH 28 PORTB |= (1 << SPI_E_CS); 29 PORTD |= (1 << SPI_AD_CS) |(1 << SPI_M_CS) |(1 << SPI_A_CS); 30 31 // set MOSI and SCK: output & // set MISO: input 32 SPI_DDR |= (1 << SPI_MOSI); 33 SPI_DDR |= (1 << SPI_SCLK); 34 SPI_DDR &= ~(1 << SPI_MISO); 35 36 // set MOSI, SCK: HIGH. MISO leave alone. 37 SPI_PRT |= (1 << SPI_MOSI); 38 SPI_PRT |= (1 << SPI_SCLK); 39 SPI_PRT |= (1 << SPI_MISO); 40 41 42 43 spi_clock_index = 4; // Set Clockindex for lowest clock speed (F_CPU / 128) 44 spi_dord = 0; // Data Order MSB first dord = 0 45 spi_cpol = 1; 46 spi_cpha = 1; // mode=3 needed by ADC ... lets see whats next. 22 // there are a total of 4 devices on the SPI bus: 23 // 1.) Ethernet Modul WIZ812MJ 24 // 2.) AD7719 24bit ADC 25 // 3.) LIS3LV accelerometer 26 // 4.) MAX6662 temp sensor <---- not assembled! 27 28 // We check if they all can live with the same SPI settings: 29 // 1.) Ethernet modul: 30 // supports spi mode=0 or mode=3 --> eighther cpol=cpha=0 or cpol=cpha=1 31 // MSB first 32 // SCLK time 70ns minimum --> 14.2MHz maximum 33 // 34 // 2.) AD7719 35 // supports mode=3 --> cpol=cpha=1 36 // MSB first 37 // SCLK time 200ns minimum --> 5MHz maximum 38 // 39 // 3.) LIS3LV 40 // SPI CLK idles high --> cpol=1 41 // data valid at rising edge. --> cpha=1 as well 42 // ==> mode 3 is supported only. 43 // MSB first, but take take at multi byte transfers. LSbyte first 44 // SCLK time - is not mentioned in the datasheet 45 // 46 // 4.) MAX6662 Tempsensor 47 // since it is not assembled, this information is not necessary. 48 49 // fastes SPI CLK frequency can be --> F_CPU/2 = 4MHz 50 // slowest can be --> F_CPU/128 = 62.5KHz 51 52 // Lets try with the fastest! 53 spi_clock_index = 0; // Set Clockindex for lowest clock speed (F_CPU / 128) 54 55 spi_dord = 0; // Data Order MSB first dord = 0 --> good for all devices 56 spi_cpol = 1; spi_cpha = 1; // SPI mode=3 --> good for all devices 47 57 spi_setup(); // Setup SPI bits and clock speed 48 58 -
firmware/FSC/src/spi_master.h
r10102 r10109 7 7 #include "usart.h" 8 8 //----------------------------------------------------------------------------- 9 10 // Port Definitions11 #define SPI_PRT PORTB12 #define SPI_DDR DDRB13 14 // Bit Definitions15 #define SPI_SCLK PB716 #define SPI_MOSI PB517 #define SPI_MISO PB618 // #define SPI_SS PB4 // not in this application!!! danger19 #define SPI_E_CS PB4 //device 020 #define SPI_AD_CS PD3 //device 121 #define SPI_M_CS PD4 //device 222 #define SPI_A_CS PD5 //device 323 24 9 #define SPI_READ_BUFFER_SIZE 16 25 10 #define SPI_WRITE_BUFFER_SIZE 16 26 11 27 #define SPI_MAX_SLAVE_INDEX 2 28 #define SPI_MAX_CLOCK_INDEX 6 29 12 #define SPI_MAX_SLAVE_INDEX 2 //? 13 #define SPI_MAX_CLOCK_INDEX 6 //? 30 14 //----------------------------------------------------------------------------- 31 32 15 extern volatile U08 spi_clock_index; 33 16 extern volatile U08 spi_cpol; -
firmware/FSC/src/typedefs.h
r10094 r10109 93 93 typedef U08 BOOL; 94 94 typedef BOOL *pBOOL; 95 typedef U08 bool; 95 96 96 97 //typedef U08 __flash *fpU08; //geht nicht mit gcc -
firmware/FSC/src/usart.c
r10094 r10109 2 2 3 3 #include "usart.h" 4 5 4 #include <avr/interrupt.h> 6 5 //----------------------------------------------------------------------------- … … 46 45 void usart_write_char(U08 data) 47 46 { 48 while (!(UCSRA & (1 << UDRE))) ; // Wait until tx register is empty 49 50 UDR = data; 47 // while (!(UCSRA & (1 << UDRE))) ; // Wait until tx register is empty 48 // UDR = data; 49 50 if ( usart_tx_buffer_index < USART_TX_BUFFER_SIZE-1){ 51 usart_tx_buffer[usart_tx_buffer_index] = data; 52 ++usart_tx_buffer_index; 53 } else { 54 usart_tx_buffer_overflow = true; 55 } 51 56 } 52 57 //----------------------------------------------------------------------------- … … 167 172 ISR(SIG_USART_RECV) 168 173 { 169 174 if (ISR_toggle_out) PORTB ^= (1<<PB3); // toggle Out2_spare when starting ISR 170 175 171 176 usart_receive_char = UDR; … … 227 232 usart_writeln_str(usart_rx_buffer); 228 233 } 229 #endif 234 230 235 //usart_write_char(usart_rx_buffer[usart_rx_buffer_index]); 231 236 //usart_writeln_str(usart_rx_buffer); … … 235 240 //usart_write_char(usart_rx_buffer); 236 241 } 237 242 #endif 238 243 /* 239 244 #define uart_maxstrlen 64 -
firmware/FSC/src/usart.h
r10094 r10109 20 20 ((U32)br * 16) - 1)) 21 21 //----------------------------------------------------------------------------- 22 22 /* 23 23 extern U08 usart_rx_buffer[]; 24 24 extern volatile BOOL usart_rx_ready; 25 25 extern volatile BOOL ISR_toggle_out; 26 26 extern U08 usart_received_chars; 27 */ 28 extern bool usart_tx_buffer_overflow; 29 extern U08 usart_tx_buffer_index; 30 extern U08 usart_tx_buffer[USART_TX_BUFFER_SIZE]; 27 31 //----------------------------------------------------------------------------- 28 32
Note:
See TracChangeset
for help on using the changeset viewer.