コード例 #1
0
int main(void) {

  POWER_ON();											// Turn the regulator ON
  PWRMODE_SETUP();										// Setup PWRMODE jumper input
  lcd_init();											// init LCD
  
  uint8_t tmp;
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);		// Enable ADC, set Prescale to 8
  
  unsigned int rhval = eeprom_read_word(&R_H_VAL);		// R_H
  unsigned int rlval = eeprom_read_word(&R_L_VAL);		// R_L
  
  ctmode = eeprom_read_byte(&CapTestMode);				// Compile time choice of test modes (0x22)
  cp1 = (ctmode & 12) >> 2;							// Capacitor pin 1, DEFAULT 0
  cp2 = ctmode & 3;										// Capacitor pin 2, DEFAULT 2
  ctmode = (ctmode & 48) >> 4;							// Capacitor test mode, DEFAULT is 0x02 for all 6 cap tests.
  
  wdt_disable();										// Disable watch dog timer.
  
  if(MCU_STATUS_REG & (1<<WDRF)) {						// Examine for Watchdog RESETs That enters, if the Watchdog 2s were not put back Can occur, 
    lcd_clear();                                                    // if the program in a continuous loop " itself; tangled" has.
    lcd_eep_string(TestTimedOut);						// Message - "Timeout!"
    _delay_ms(3000);                                	// Wait 3 sec
	wdt_enable(WDTO_2S);								// Wait two seconds; if on power it will reset; on battery it will turn itself off
    while(1) {
		POWER_OFF();									// Power down in BAT mode or RESET in PWR mode
	}
  }
  
  LCDLoadCustomChar();									// Custom indication Diode symbol into LCD load
  lcd_eep_string(DiodeIcon);							// Message - diode icon
  Line1();												// jump to start of first line

start:													// re-entry point, if button is re-pressed
  #ifdef WDT_enabled
    wdt_enable(WDTO_2S);								// Watchdog Timer on, 2 seconds?
  #endif

  PartFound 	= PART_NONE;							// Default all results
  tmpPartFound 	= PART_NONE;							//		  "    " 
  NumOfDiodes 	= 0;									//			||
  PartReady 	= 0;									//			||
  PartMode 		= 0;									//			||
  ca 			= 0;									//			||
  cb 			= 0;									//			\/

											//	->	// Startup Message ////////////////////////////////////////
  lcd_clear();										// 
  lcd_eep_string(StartupMessage);					// LCD: ACT v#.#    [XXX]


  
											//	->	// Power selection and Battery Testing ////////////////////

  if(PWRMODE_GET()) {								// Get the PWRMODE jumper logic
	PowerMode = PWR_9V;								// Set powermode to PWR_9V
	_delay_us(250);
	
	ReadADC(5 | (1<<REFS1));						// Measure the 9V battery Supply ( - diode drop)
	hfe[0] = ReadADC(5 | (1<<REFS1));				// if in battery mode.
	
	lcd_eep_string(BatMode);						// Tell user device in BAT mode
	Line2();
	
	if (hfe[0] < BAT_WEAK) {						// Compare 9v reading with BAT_WEAK variable
		
		if(hfe[0] < BAT_DEAD) {					// If the batter is considered dead then
			lcd_eep_string(Bat);					
			lcd_eep_string(BatEmpty);				// Tell the user battery is DEAD
			_delay_ms(3000);						// Wait a bit.
			while(1) {								// Forever loop
				POWER_OFF();						// keep trying to kill the power forever.
			}
		}
		
		lcd_clear();			
		lcd_eep_string(Bat);						// Battery isnt dead; its just weak
		lcd_eep_string(BatWeak);					// tell the user; but keep testing...
		Line2();									// Start second line
	  }
  } else {
	PowerMode = PWR_5V;								// Power mode is constent v5, skip battery check.
    lcd_eep_string(PwrMode);						// Tell user we are running in PWR mode.
	Line2();
  }
 
											//	->	// Begin testing sequince. ///////////////////////////////
	
  lcd_eep_string(TestRunning);						// Tell user the testing has begun...
  
  UpdateProgress("00%");							// Progress at 00% and Testing
  
  CheckPins(TP1, TP2, TP3);							//			||
  UpdateProgress("16%");							//			\/
  
  CheckPins(TP1, TP3, TP2);							//		TESTING...
  UpdateProgress("33%");							//

  CheckPins(TP2, TP1, TP3);							//			||
  UpdateProgress("50%");							//			\/
  
  CheckPins(TP2, TP3, TP1);							//		TESTING...
  UpdateProgress("66%");							//
  
  CheckPins(TP3, TP2, TP1);							//			||
  UpdateProgress("83%");							//			\/
  
  CheckPins(TP3, TP1, TP2);							//	   Almost there!
  UpdateProgress("99%");							// Testing Completed or 99%
  

//---------------------------------------------CAPACITOR---------------------------------------
									// Separate measurement to the test on condenser
  if(((PartFound == PART_NONE) || (PartFound == PART_RESISTOR) || (PartFound == PART_DIODE)) && (ctmode > 0)) {
									// Condenser unload; otherwise possibly no measurement is possible
    R_PORT = 0;
    R_DDR = (1<<(TP1 * 2)) | (1<<(TP2 * 2)) | (1<<(TP3 * 2));
    _delay_ms(10);
    R_DDR = 0;

    if(ctmode == NORMAL_CAP_TESTS) {					// see if we want to do all 6 Cap Tests
      ReadCapacity(cp1, cp2);						// No - just read the pins both ways.
      ReadCapacity(cp2, cp1);
    } else {								// DEFAULT ctmode == 0x02  to do all tests
	Line2();
	lcd_eep_string(TestCapV);
	UpdateProgress("00%");
	
	ReadCapacity(TP3, TP1);
	UpdateProgress("16%");
	
	ReadCapacity(TP3, TP2);
	UpdateProgress("33%");
	
	ReadCapacity(TP2, TP3);
	UpdateProgress("50%");
	
	ReadCapacity(TP2, TP1);
	UpdateProgress("66%");
	
	ReadCapacity(TP1, TP3);
	UpdateProgress("83%");
	
	ReadCapacity(TP1, TP2);
	UpdateProgress("99%");
      }
   }

  lcd_clear();								// Finished, now evaluate, the results

//---------------------------------------------DIODE------------------------------------------------  
  if(PartFound == PART_DIODE) {
    if(NumOfDiodes == 1) {						// Standard-Diode
      lcd_eep_string(Diode);						// Message - "Diode: "
      lcd_eep_string(Anode);						// Message - "A="
      lcd_data(GetPinAlias(diodes[0].Anode + ASCII_1));				// Display 1, 2, or 3
      lcd_eep_string(NextK);						// Message - ";C="
      lcd_data(GetPinAlias(diodes[0].Cathode + ASCII_1));				// Display 1, 2, or 3
      Line2();								// Start second line
      lcd_eep_string(Uf);						// Message - "Uf="
      lcd_string(itoa(diodes[0].Voltage, outval, 10));
      lcd_eep_string(mV);						// Message - "mV"
      goto end;
    } else if(NumOfDiodes == 2) {					// dual diode
	if(diodes[0].Anode == diodes[1].Anode) {			// Common Anode
	  lcd_eep_string(DualDiode);					// Message - "Double diode €"
	  lcd_eep_string(CA);						// Message - "CA"
	  Line2();							// Start second line
	  lcd_eep_string(Anode);					// Message - "A="
	  lcd_data(GetPinAlias(diodes[0].Anode + ASCII_1));				// Display 1, 2, or 3
	  lcd_eep_string(K1);						// Message - ";C1="
	  lcd_data(GetPinAlias(diodes[0].Cathode + ASCII_1));				// Display 1, 2, or 3
	  lcd_eep_string(K2);						// Message - ";C2="
	  lcd_data(GetPinAlias(diodes[1].Cathode + ASCII_1));			// Display 1, 2, or 3
	  goto end;
	} else if(diodes[0].Cathode == diodes[1].Cathode) {		// Common Cathode
	    lcd_eep_string(DualDiode);					// Message - "Double diode €"
	    lcd_eep_string(CC);						// Message - "CC"
	    Line2(); 							// Start second line
	    lcd_eep_string(K);						// Message - "C="
	    lcd_data(GetPinAlias(diodes[0].Cathode + ASCII_1));			// Display 1, 2, or 3
	    lcd_eep_string(A1);						// Message - ";A1="
	    lcd_data(GetPinAlias(diodes[0].Anode + ASCII_1));			// Display 1, 2, or 3
	    lcd_eep_string(A2);						// Message - ";A2="
	    lcd_data(GetPinAlias(diodes[1].Anode + ASCII_1));			// Display 1, 2, or 3
	    goto end;
	  } else if ((diodes[0].Cathode == diodes[1].Anode) && \
		     (diodes[1].Cathode == diodes[0].Anode)) {		// Antiparallel
	      lcd_eep_string(TwoDiodes);				// Message - "2 diodes"
	      Line2(); 							// Start second line
	      lcd_eep_string(Antiparallel);				// Message - "anti-parallel"
	      goto end;
	    }
    } else if(NumOfDiodes == 3) { 					// Series connection from 2 diodes; as 3 diodes one recognizes
	b = 3;
	c = 3;
									// Check to see if it is series connection of 2 diodes.
									// But 2 cathodes, and 2 anodes must agree.
									// Then the 2 diodes are a single dual-diode.
	if((diodes[0].Anode == diodes[1].Anode) || (diodes[0].Anode == diodes[2].Anode)) 
	  b = diodes[0].Anode;

	if(diodes[1].Anode == diodes[2].Anode) 
	  b = diodes[1].Anode;

	if((diodes[0].Cathode == diodes[1].Cathode) || (diodes[0].Cathode == diodes[2].Cathode)) 
	  c = diodes[0].Cathode;

	if(diodes[1].Cathode == diodes[2].Cathode) 
	  c = diodes[1].Cathode;

	if((b<3) && (c<3)) {
	  lcd_eep_string(TwoDiodes);					// Message - "2 diodes"
	  Line2();							// Start second line
	  lcd_eep_string(InSeries);					// Message - "serial A=€€"
	  lcd_data(GetPinAlias(b + ASCII_1));					// Display 1, 2, or 3
	  lcd_eep_string(NextK);					// Message - ";C="
	  lcd_data(GetPinAlias(c + ASCII_1));					// Display 1, 2, or 3
	  goto end;
	}
      }
  } 
  	
//---------------------------------------------TRANSISTOR--------------------------------------------
    else if (PartFound == PART_TRANSISTOR) {
      if(PartReady == 0) {						// 2nd examination never made, e.g. a transistor with protection diode.
	hfe[1] = hfe[0];
	uBE[1] = uBE[0];
      }

      if((hfe[0]>hfe[1])) {						// If the amplification factor with the first test was higher: swap C and E
	hfe[1] = hfe[0];
	uBE[1] = uBE[0];
	tmp = c;
	c = e;
	e = tmp;
      }

      if(PartMode == PART_MODE_NPN) 
	lcd_eep_string(NPN);						// Message - "NPN"
      else 
	lcd_eep_string(PNP);						// Message - "PNP"

      lcd_eep_string(bstr);						// Message - " B="
      lcd_data(GetPinAlias(b + ASCII_1));						// Display 1, 2, or 3
      
      lcd_eep_string(cstr);						// Message - ";C="
      lcd_data(GetPinAlias(c + ASCII_1));						// Display 1, 2, or 3
      
      lcd_eep_string(estr);						// Message - ";E="
      lcd_data(GetPinAlias(e + ASCII_1));						// Display 1, 2, or 3
      
      Line2(); 								// Start second line
									// Amplification factor compute, hFE = Emitter current/base current
      lhfe = hfe[1];
      lhfe *= (((unsigned long)rhval * 100) / (unsigned long)rlval);	// 500000/750 = 666.666r
      

      if(uBE[1]<11) 
	uBE[1] = 11;

      lhfe /= uBE[1];
      hfe[1] = (unsigned int) lhfe;
      lcd_eep_string(hfestr);						// Message - "hFE="
      lcd_string(utoa(hfe[1], outval, 10));
      SetCursor(2,7);							// Cursor on line 2, character 7

      if(NumOfDiodes > 2) 						// Transistor with protection diode
	lcd_data(LCD_CHAR_DIODE);					// Diode indicate
      else
	lcd_data(' ');

      for(c=0;c<NumOfDiodes;c++) {
	if(( (diodes[c].Cathode == e) && (diodes[c].Anode == b) && \
	     (PartMode == PART_MODE_NPN)) || ((diodes[c].Anode == e) && \
	     (diodes[c].Cathode == b) && (PartMode == PART_MODE_PNP))) {
	  lcd_eep_string(Uf);						// Message - "Uf="
	  lcd_string(itoa(diodes[c].Voltage, outval, 10));
	  lcd_data('m');
	  goto end;
	}
      }

      goto end;
      } 

//---------------------------------------------FET---------------------------------------------------     
	else if (PartFound == PART_FET) {				// JFET or MOSFET
	  if(PartMode & 1)						// N-channel
	    lcd_data('N');
	  else 
	    lcd_data('P');						// P-channel

	  if((PartMode == PART_MODE_N_D_MOS) || (PartMode == PART_MODE_P_D_MOS)) {
	    lcd_eep_string(dmode);					// Message - "-D"
	    lcd_eep_string(mosfet);					// Message - "-MOS"
	    } else {
		if((PartMode == PART_MODE_N_JFET) || (PartMode == PART_MODE_P_JFET)) 
		  lcd_eep_string(jfet);					// Message - "-JFET"
		else {
		  lcd_eep_string(emode);				// Message - "-E"
		  lcd_eep_string(mosfet);				// Message - "-MOS"
		}
	    }
									// Gate capacity
	  if(PartMode < 3) {						// Enrichment MOSFET
	    lcd_eep_string(GateCap);					// Message - " C="
	    ReadCapacity(b,e);						// Measurement
	    hfe[0] = (unsigned int)cv;

	    if(hfe[0]>2) 
	      hfe[0] -= 3;

	    utoa(hfe[0], outval2, 10);
	    tmpval = strlen(outval2);
	    tmpval2 = tmpval;

	    if(tmpval>4) 
	      tmpval = 4;						// If capacity > 100nF drop fractional part to fit on the LCD

	    lcd_show_format_cap(outval2, tmpval, tmpval2);
	    lcd_data('n');
	  }

	  Line2();							// Start second line
	  lcd_eep_string(gds);						// Message - "GDS="
	  lcd_data(GetPinAlias(b + ASCII_1));					// Display 1, 2, or 3
	  lcd_data(GetPinAlias(c + ASCII_1));					// Display 1, 2, or 3
	  lcd_data(GetPinAlias(e + ASCII_1));					// Display 1, 2, or 3

	  if((NumOfDiodes > 0) && (PartMode < 3))			// MOSFET with protection diode; it gives only with enrichment FETs 
	    lcd_data(LCD_CHAR_DIODE);					// Diode indicate
	  else 
	    lcd_data(' ');						// Blank

	  if(PartMode < 3) {						// Enrichment MOSFET
	    gthvoltage=(gthvoltage/8);
	    lcd_eep_string(vt);						// Message - "Vt="
	    lcd_string(utoa(gthvoltage, outval, 10));			// Gate threshold voltage, was determined before
	    lcd_data('m');
	  }

	  goto end;


      } 

//---------------------------------------------THYRISTOR---------------------------------------------     
	else if (PartFound == PART_THYRISTOR) {
	  lcd_eep_string(Thyristor);			 		// Message - "Thyristor"
	  Line2();						 	// Start second line
	  lcd_eep_string(GAK);				 		// Message - "GAC="
	  lcd_data(GetPinAlias(b + ASCII_1));					// Display 1, 2, or 3
	  lcd_data(GetPinAlias(c + ASCII_1));					// Display 1, 2, or 3
	  lcd_data(GetPinAlias(e + ASCII_1));					// Display 1, 2, or 3
	  goto end;

	} 

//---------------------------------------------TRIAC-------------------------------------------------	
	  else if (PartFound == PART_TRIAC) {
	    lcd_eep_string(Triac);					// Message - "Triac"
	    Line2();							// Start second line
	    lcd_eep_string(Gate);					// Message - "G="
	    lcd_data(GetPinAlias(b + ASCII_1));					// Display 1, 2, or 3
	    lcd_eep_string(A1);						// Message - ";A1="
	    lcd_data(GetPinAlias(e + ASCII_1));					// Display 1, 2, or 3
	    lcd_eep_string(A2);						// Message - ";A2="
	    lcd_data(GetPinAlias(c + ASCII_1));					// Display 1, 2, or 3
	    goto end;

	  } 

//---------------------------------------------RESISTOR----------------------------------------------	  
	    else if(PartFound == PART_RESISTOR) {
	      lcd_eep_string(Resistor);					// Message - "Resistor: €€"
	      lcd_data(GetPinAlias(ra + ASCII_1));					// Display 1, 2, or 3 Pin data
	      lcd_data('-');
	      lcd_data(GetPinAlias(rb + ASCII_1));					// Display 1, 2, or 3
	      Line2();							// Start second line

	      if(rv[0] > HALF_ADC_RANGE) 				// Examine, how far the Voltages across the test resistances deviate from 512 
		hfe[0] = (rv[0] - HALF_ADC_RANGE);
	      else 
		hfe[0] = (HALF_ADC_RANGE - rv[0]);

	      if(rv[1] > HALF_ADC_RANGE) 
		hfe[1] = (rv[1] - HALF_ADC_RANGE);
	      else 
		hfe[1] = (HALF_ADC_RANGE - rv[1]);

	      if(hfe[0] > hfe[1])  {
		radcmax[0] = radcmax[1];
		rv[0] = rv[1];						// Result use, which is more near because of 512 (accuracy improves)
		rv[1] = rhval;						// High - Test resistance
	      } else 
		  rv[1] = rlval;					// Low - Test resistance

	      if(rv[0] == 0) 
		rv[0] = 1;

	      lhfe = (unsigned long)((unsigned long)((unsigned long)rv[1] * \
	                             (unsigned long)rv[0]) / (unsigned long)((unsigned long)radcmax[0] - (unsigned long)rv[0]));	// Resistance compute
	      ultoa(lhfe,outval,10);

	      if(rv[1] == rhval) {					// 470k- Resisted?
		ra = strlen(outval);					// Necessarily, in order to indicate comma

		for(rb=0;rb<ra;rb++) {
		  lcd_data(outval[rb]);

		  if(rb == (ra-2)) 
		    lcd_data(',');					// comma
		}

		lcd_data ('K');						// Kilo ohm, if 470k uses resistance
	      } else 
		  lcd_string(outval);
		    
	      lcd_data(LCD_CHAR_OMEGA);					// Omega for ohms 
	      goto end;

	    } 

//---------------------------------------------CAPACITOR---------------------------------------------	    
	      else if(PartFound == PART_CAPACITOR) {			// Capacitor measurement
		lcd_eep_string(Capacitor);				// Message - "Capacitor: €€"
		lcd_data(GetPinAlias(ca + ASCII_1));					// Display 1, 2, or 3 Pin - Data
		lcd_data('-');
		lcd_data(GetPinAlias(cb + ASCII_1));					// Display 1, 2, or 3
		Line2();						// Start second line
		tmpval2 = 'n';						// n for nF
		    
		if(cv > 99999) {					// Too big
		  cv /= 1000;						// convert to Micro Farads

		  tmpval2 = LCD_CHAR_U;					// change n to greek char for micro
		}

		ultoa(cv, outval, 10);					// outval now a string version of cv
		tmpval = strlen(outval); 
		lcd_show_format_cap(outval, tmpval, tmpval); 
		lcd_data(tmpval2);					// display the SI Suffix
		lcd_data('F');						// F for Farads
		goto end;
	      }

//---------------------------------------------NOT-FOUND-OR-DAMAGED---------------------------------------------------------	

		if(NumOfDiodes == 0) {						// Nothing found. Tell user.
				lcd_eep_string(TestFailed1);
				Line2();
				lcd_eep_string(TestFailed2);
			} else {								// Data found but bad result or no positive ident
				lcd_eep_string(BadResult1);
				Line2();
				lcd_eep_string(BadResult2);
				lcd_data(NumOfDiodes + ASCII_0);
				lcd_data(LCD_CHAR_DIODE);
		}

		end:

		while(!(ON_PIN_REG & (1<<RST_PIN)));			// wait, to tracers released
		  _delay_ms(200);

		for(hfe[0] = 0;hfe[0]<10000;hfe[0]++) {			// 10 Seconds untill power off.

		  if(!(ON_PIN_REG & (1<<RST_PIN)))			// if the button is pressed, start all over
		    goto start;

		  wdt_reset();						// We want to wait the full 10 Seconds
		  _delay_ms(1);						// 1mS 10,000 times = 10 seconds
		}

	if(PowerMode==PWR_9V) {				// If in battery mode; try to turn off; otherwise wait for a reset
		POWER_OFF();
	}
	
	wdt_disable();						// Watchdog out
										// Continuous loop, no timer
  while(1) {
    if(!(RESET_GET()))					// only one reaches, if the automatic disconnection was not inserted
      goto start;
  }
  
  return 0;
}									// End of main()
コード例 #2
0
ファイル: CDC.cpp プロジェクト: houzhenggang/Arduino-3
bool CDC_Setup(USBSetup& setup)
{
	u8 r = setup.bRequest;
	u8 requestType = setup.bmRequestType;

	if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
	{
		if (CDC_GET_LINE_CODING == r)
		{
			USB_SendControl(0,(void*)&_usbLineInfo,7);
			return true;
		}
	}

	if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
	{
		if (CDC_SEND_BREAK == r)
		{
			breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
		}

		if (CDC_SET_LINE_CODING == r)
		{
			USB_RecvControl((void*)&_usbLineInfo,7);
		}

		if (CDC_SET_CONTROL_LINE_STATE == r)
		{
			_usbLineInfo.lineState = setup.wValueL;
		}

		if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r)
		{
			// auto-reset into the bootloader is triggered when the port, already 
			// open at 1200 bps, is closed.  this is the signal to start the watchdog
			// with a relatively long period so it can finish housekeeping tasks
			// like servicing endpoints before the sketch ends

#ifndef MAGIC_KEY
#define MAGIC_KEY 0x7777
#endif
#ifndef MAGIC_KEY_POS
#define MAGIC_KEY_POS 0x0800
#endif

			// We check DTR state to determine if host port is open (bit 0 of lineState).
			if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
			{
#if MAGIC_KEY_POS != (RAMEND-1)
				*(uint16_t *)(RAMEND-1) = *(uint16_t *)MAGIC_KEY_POS;
				*(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY;
#else
				// for future boards save the key in the inproblematic RAMEND
				// which is reserved for the main() return value (which will never return)
				*(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY;
#endif
				wdt_enable(WDTO_120MS);
			}
			else
			{
				// Most OSs do some intermediate steps when configuring ports and DTR can
				// twiggle more than once before stabilizing.
				// To avoid spurious resets we set the watchdog to 250ms and eventually
				// cancel if DTR goes back high.

				wdt_disable();
				wdt_reset();
#if MAGIC_KEY_POS != (RAMEND-1)
				*(uint16_t *)MAGIC_KEY_POS = *(uint16_t *)(RAMEND-1);
#else
				*(uint16_t *)MAGIC_KEY_POS = 0x0000;
#endif
			}
		}
		return true;
	}
	return false;
}
コード例 #3
0
ファイル: main.c プロジェクト: BrzTit/Bus_Pirate
//the main function waits for all the bytes in the STK500v2 packet, 
//then sends for processing in the above functions
int main(void)
{
        unsigned char ch;
        unsigned char prev_ch=0;
        //unsigned char chr_nl=0; //unused
        unsigned char msgparsestate;
        unsigned char cksum=0;
        unsigned char seqnum=0;
        int msglen=0;
        int i=0;
        uart_init();
        //wd_init();
        LED_INIT;
        LED_OFF;
        //sei(); //enable AVR interrupts
        msgparsestate=MSG_IDLE;
		// default values:
		CONFIG_PARAM_SW_MINOR=D_CONFIG_PARAM_SW_MINOR;
		CONFIG_PARAM_SW_MAJOR=D_CONFIG_PARAM_SW_MAJOR;

        while(1){
                if (msgparsestate==MSG_IDLE){
                        ch=uart_getchar(1);
                }else{
                        ch=uart_getchar(0); //getting extra bytes, use timeout
                }
                // parse message according to appl. note AVR068 table 3-1:
                if (msgparsestate==MSG_IDLE && ch == MESSAGE_START){
                        msgparsestate=MSG_WAIT_SEQNUM;
                        cksum = ch^0;
                        continue;
                }


                if (msgparsestate==MSG_WAIT_SEQNUM){
                        seqnum=ch;
                        cksum^=ch;
                        msgparsestate=MSG_WAIT_SIZE1;
                        continue;
                }

                if (msgparsestate==MSG_WAIT_SIZE1){
                        cksum^=ch;
                        msglen=ch<<8;
                        msgparsestate=MSG_WAIT_SIZE2;
                        continue;
                }

                if (msgparsestate==MSG_WAIT_SIZE2){
                        cksum^=ch;
                        msglen|=ch;
                        msgparsestate=MSG_WAIT_TOKEN;
                        continue;
                }

                if (msgparsestate==MSG_WAIT_TOKEN){
                        cksum^=ch;
                        if (ch==TOKEN){
                                msgparsestate=MSG_WAIT_MSG;
                                i=0;
                        }else{
                                msgparsestate=MSG_IDLE;
                        }
                        continue;
                }

                if (msgparsestate==MSG_WAIT_MSG && i<msglen && i<280){
                        cksum^=ch;
                        msg_buf[i]=ch;
                        i++;
						wdt_reset(); //wd_kick();
                        if (i==msglen){
                                msgparsestate=MSG_WAIT_CKSUM;
                        }
                        continue;
                }
                
				if (msgparsestate==MSG_WAIT_CKSUM){
                        if (ch==cksum && msglen > 0){
                                // message correct, process it
                                wdt_reset(); //wd_kick();
                                programcmd(seqnum);
                        }else{
                                msg_buf[0] = ANSWER_CKSUM_ERROR;
                                msg_buf[1] = STATUS_CKSUM_ERROR;
                                transmit_answer(seqnum,2);
                        }
                        // no continue here, set state=MSG_IDLE
                }
                msgparsestate=MSG_IDLE;
                msglen=0;
                seqnum=0;
				prev_ch=0;
                i=0;
        }
	return(0);
}
コード例 #4
0
ファイル: ieee.c プロジェクト: Flaviowebit/openCBM
/* 
 * Write bytes to the drive via the CBM default protocol.
 * Returns number of successful written bytes or 0 on error.
 */
static uint16_t 
ieee_raw_write(uint16_t len, uint8_t flags)
{
    uint8_t atn, talk, data, device, sa;
    uint16_t rv;

    rv = len;
    atn = flags & XUM_WRITE_ATN;
    talk = flags & XUM_WRITE_TALK;

    eoi = 0;
    ieee_status = 0;

    usbInitIo(len, ENDPOINT_DIR_OUT);

    if(atn && len >= 1)
    {
        // get device# from USB 
        if (usbRecvByte(&device) != 0) 
        {
            return 0;
        }
        len--;
        if(len == 0 || ((device & 0x1f) == 0x1f))
        {
            // unlisten, untalk
            if (device & 0x40) 
            {
                IeeeUntalk();
            }
            if (device & 0x20) 
            {
                IeeeUnlisten();
            }
        }
        else
        {
            // get secondary-address from USB
            if (usbRecvByte(&sa) != 0) 
            {
                return 0;
            }
            len--;

            if (talk) 
            {
                IeeeTalk(device, sa);
                len = 0;
            }
            else if(len > 2)
            {
                // open
            }
            else switch(sa & 0xf0)
            {
              case 0xE0:
                // close
                IeeeClose(device, sa);
                break;
              case 0xF0:
                // open
                IeeeOpen(device, sa, NULL);
                break;
              case 0x60:
                // listen
                IeeeListen(device, sa);
                break;
              default:
                // error????
                break;
            }
        }
    }


    // send data
    //
    while (len != 0) {
        // Get a data byte from host, quitting if it signalled an abort.
        if (usbRecvByte(&data) != 0) 
        {
            rv = 0;
            break;
        }
        if (IeeeBsout(data)) 
        {
            rv = 0;
            break;
        } 
        len--;

        // watchdog
        wdt_reset();
    }
    usbIoDone();

    return rv;
}
コード例 #5
0
ファイル: iec.c プロジェクト: Flaviowebit/openCBM
static uint16_t
iec_raw_read(uint16_t len)
{
    uint8_t ok, bit, b;
    uint16_t to, count;

    DEBUGF(DBG_INFO, "crd %d\n", len);
    usbInitIo(len, ENDPOINT_DIR_IN);
    count = 0;
    do {
        to = 0;

        /* wait for clock to be released. typically times out during: */
        /* directory read */
        while (iec_get(IO_CLK)) {
            if (to >= 50000 || !TimerWorker()) {
                /* 1.0 (50000 * 20us) sec timeout */
                DEBUGF(DBG_ERROR, "rd to\n");
                usbIoDone();
                return 0;
            }
            to++;
            DELAY_US(20);
        }

        // XXX is this right? why treat EOI differently here?
        if (eoi) {
            usbIoDone();
            return 0;
        }

        /* release DATA line */
        iec_release(IO_DATA);

        /* use special "timer with wait for clock" */
        iec_wait_clk();

        // Is the talking device signalling EOI?
        if (iec_get(IO_CLK) == 0) {
            eoi = 1;
            iec_set(IO_DATA);
            DELAY_US(70);
            iec_release(IO_DATA);
        }

        /*
         * Disable IRQs to make sure the byte transfer goes uninterrupted.
         * This isn't strictly needed since the only interrupt we use is the
         * one for USB control transfers.
         */
        cli();

        // Wait up to 2 ms for CLK to be asserted
        ok = iec_wait_timeout_2ms(IO_CLK, IO_CLK);

        // Read all 8 bits of a byte
        for (bit = b = 0; bit < 8 && ok; bit++) {
            // Wait up to 2 ms for CLK to be released
            ok = iec_wait_timeout_2ms(IO_CLK, 0);
            if (ok) {
                b >>= 1;
                if (iec_get(IO_DATA) == 0)
                    b |= 0x80;

                // Wait up to 2 ms for CLK to be asserted
                ok = iec_wait_timeout_2ms(IO_CLK, IO_CLK);
            }
        }

        sei();

        if (ok) {
            // Acknowledge byte received ok
            iec_set(IO_DATA);

            // Send the data byte to host, quitting if it signalled an abort.
            if (usbSendByte(b))
                break;
            count++;
            DELAY_US(50);
        }

        wdt_reset();
    } while (count != len && ok && !eoi);

    if (!ok) {
        DEBUGF(DBG_ERROR, "read io err\n");
        count = 0;
    }

    DEBUGF(DBG_INFO, "rv=%d\n", count);
    usbIoDone();
    return count;
}
コード例 #6
0
ファイル: main.c プロジェクト: Mehanik/i2c-servo-controller
void main (void)
{
    io_init();
    servo_init();
    timers_init();
    i2c_init();
    wdt_enable(WDTO_15MS);
    sei();
    start_timers();

    flags.new_buf_ready = 0;
    flags.i2c_first_byte = 0;
    flags.servo_pd_changed = 0;
    flags.servo_minmaxpd_cnahged = 0;

#ifdef MEGADEBUG
    struct {
        uint8_t sw1 : 1;
        uint8_t sw2 : 1;
    } ss;

    UTILS_DDR_CLR(I2CSCL_PORT, I2CSCL_PIN);
    UTILS_DDR_CLR(I2CSDA_PORT, I2CSDA_PIN);
    UTILS_PORT_SET(I2CSCL_PORT, I2CSCL_PIN);
    UTILS_PORT_SET(I2CSDA_PORT, I2CSDA_PIN);
#endif

    for (;;)
    {
#ifdef MEGADEBUG
        if (!UTILS_PIN_VALUE(I2CSCL_PORT, I2CSCL_PIN))
        {
            if (!ss.sw1)
            {
                servo[0].target += 16;
            }
            ss.sw1 = 1;
        }
        else
        {
            ss.sw1 = 0;
        }

        if (!UTILS_PIN_VALUE(I2CSDA_PORT, I2CSDA_PIN))
        {
            if (!ss.sw2)
            {
                servo[0].target -= 16;
            }
            ss.sw2 = 1;
        }
        else
        {
            ss.sw2 = 0;
        }
#endif

#ifndef MEGADEBUG
        // i2c
        if (TWCR & _BV(TWINT))
        {
            // i2c 
            switch (TWSR)
            {
                case TW_SR_SLA_ACK: // i2c start
                    flags.i2c_first_byte = 1;
                    break;
                case TW_SR_DATA_ACK: // i2c byte received
                    if (flags.i2c_first_byte)
                    {
                        i2cMemAddr = TWDR;
                        flags.i2c_first_byte = 0;
                    }
                    else
                    {
                        i2c_read();
                        i2cMemAddr ++;
                    }
                    break;
                case TW_ST_DATA_ACK:
                    i2c_write();
                    i2cMemAddr ++;
                    break;
            }

            TWCR |= _BV(TWINT);
        }
#endif

        // servo.position 
        if (UTILS_AGGL(TIFR, ITIMER) & _BV(UTILS_AGGL2(OCF, ITIMER, A)))
        {
            // Timer ITIMER compare match A
            UTILS_AGGL(TIFR, ITIMER) |= _BV(UTILS_AGGL2(OCF, ITIMER, A)); 

            for (uint8_t i = 0; i < SERVO_NUM; i ++)
            {
                if (servo[i].position != servo[i].target)
                {
                    UTILS_PORT_SET(LED_PORT, LED_PIN);
                    if (servo[i].speed == 0)
                    {
                        // Change position immediately
                        servo[i].position = servo[i].target;
                        servo_find_pd(i);
                        flags.servo_pd_changed = 1;
                    }
                    else
                    {
                        if (servo[i].speed_counter == servo[i].speed)
                        {
                            // Change position
                            if (servo[i].position < servo[i].target)
                                servo[i].position ++;
                            else
                                servo[i].position --;
                            servo_find_pd(i);
                            flags.servo_pd_changed = 1;
                            servo[i].speed_counter = 0;
                        }
                        else
                            servo[i].speed_counter ++;
                    }
                }
                else
                {
                    UTILS_PORT_CLR(LED_PORT, LED_PIN);
                }
            }

            if (flags.servo_minmaxpd_cnahged)
            {
                for (uint8_t i = 0; i < SERVO_NUM; i ++)
                {
                    servo_find_pd(i);
                }
                flags.servo_pd_changed = 1;
                flags.servo_minmaxpd_cnahged = 0;
            }

            if (flags.servo_pd_changed)
            {
                servo_sort();
                outstate_gen();
                flags.servo_pd_changed = 0;
            }
        }

        wdt_reset();
    }
}
コード例 #7
0
ファイル: main.c プロジェクト: jaseg/avr-uip
int main(void) {
    sei();
    uint8_t resetSource = MCUSR;
    MCUSR = 0;
    wdt_reset();
    wdt_disable();

    wdt_enable(WDTO_1S);
    WDTCSR |= (1 << WDIE);  //enable watchdog interrupt
    wdt_reset();
    cli();

    clock_init();
    usart_init(1000000, 9600);
    stdout = &uart_str;
    stderr = &uart_str;
    stdin = &uart_str;

    uip_ipaddr_t ipaddr;
    struct timer periodic_timer, arp_timer;
    uint16_t timer_OW, timer_Simple, timer_Count, timer_EEProm, timer_SendData, timer_IOalarm, timer_network;
    timer_OW = 0;
    timer_Simple = 0;
    timer_Count = 0;
    timer_EEProm = 0;
    timer_SendData = 0;
    timer_IOalarm = 0;
    timer_network = 0;
    
    if(resetSource & (1<<WDRF))
    {
        printf("Mega was reset by watchdog...\r\n");
    }

    if(resetSource & (1<<BORF))
    {
        printf("Mega was reset by brownout...\r\n");
    }

    if(resetSource & (1<<EXTRF))
    {
        printf("Mega was reset by external...\r\n");
    }

    if(resetSource & (1<<PORF))
    {
        printf("Mega was reset by power on...\r\n");
    }

//else jtag (disabled)

    //sensorScan = (uint8_t*) & tempbuf;

    if (eepromReadByte(0) == 255 || eepromReadByte(11) == 255)
    {
            printf_P(PSTR("Setting default values\r\n"));
            //Set defaults
            eepromWriteByte(0, 0); //init

            myip[0] = 192;
            myip[1] = 168;
            myip[2] = 1;
            myip[3] = 67; //47 in final versions

            netmask[0] = 255;
            netmask[1] = 255;
            netmask[2] = 255;
            netmask[3] = 0;

            gwip[0] = 192;
            gwip[1] = 168;
            gwip[2] = 1;
            gwip[3] = 1;

            dnsip[0] = 8;
            dnsip[1] = 8;
            dnsip[2] = 8;
            dnsip[3] = 8;

            eepromWriteByte(29, 80);  //web port
            eepromWriteByte(10, 0);  //dhcp off

            save_ip_addresses();
            wdt_reset();

            eepromWriteStr(200, "SBNG", 4);  //default password
            eepromWriteByte(204, '\0');
            eepromWriteByte(205, '\0');
            eepromWriteByte(206, '\0');
            eepromWriteByte(207, '\0');
            eepromWriteByte(208, '\0');
            eepromWriteByte(209, '\0');

            eepromWriteByte(100, 1); //Analog port 0 = ADC
            eepromWriteByte(101, 1); //Analog port 1 = ADC
            eepromWriteByte(102, 1); //Analog port 2 = ADC
            eepromWriteByte(103, 1); //Analog port 3 = ADC
            eepromWriteByte(104, 1); //Analog port 4 = ADC
            eepromWriteByte(105, 1); //Analog port 5 = ADC
            eepromWriteByte(106, 1); //Analog port 6 = ADC
            eepromWriteByte(107, 1); //Analog port 7 = ADC

            eepromWriteByte(110, 0); //Digital port 0 = OUT
            eepromWriteByte(111, 0); //Digital port 1 = OUT
            eepromWriteByte(112, 0); //Digital port 2 = OUT
            eepromWriteByte(113, 0); //Digital port 3 = OUT

      	    wdt_reset();
            for (uint8_t alarm=1; alarm<=4; alarm++)
            {
                    uint16_t pos = 400 + ((alarm-1)*15); //400 415 430 445

                    eepromWriteByte(pos+0, 0); //enabled
                    eepromWriteByte(pos+1, 0); //sensorid
                    eepromWriteByte(pos+2, 0); //sensorid
                    eepromWriteByte(pos+3, 0); //sensorid
                    eepromWriteByte(pos+4, 0); //sensorid
                    eepromWriteByte(pos+5, 0); //sensorid
                    eepromWriteByte(pos+6, 0); //sensorid
                    eepromWriteByte(pos+7, 0); //sensorid
                    eepromWriteByte(pos+8, 0); //sensorid
                    eepromWriteByte(pos+9, '<'); //type
                    eepromWriteByte(pos+10, 0); //value
                    eepromWriteByte(pos+11, 0); //target
                    eepromWriteByte(pos+12, 0); //state
                    eepromWriteByte(pos+13, 0); //reverse
                    eepromWriteByte(pos+14, 0); //not-used
            }

            eepromWriteByte(1, EEPROM_VERSION);
    }
/*
    findSystemID(systemID);

    if (systemID[0] == 0) {
        printf_P(PSTR("No system id found, add a DS2401 or use old software"));
//        fprintf(&lcd_str, "?f?y0?x00No system id found?nAdd a DS2401 or use old software?n");
        wdt_disable();
        wdt_reset();
        while (true);
    } else {
*/    
        //MAC will be 56 51 99 36 14 00 with example system id
        mymac[1] = systemID[1];
        mymac[2] = systemID[2];
        mymac[3] = systemID[3];
        mymac[4] = systemID[4];
        mymac[5] = systemID[5];
//    }
//    fprintf(&lcd_str, "?y1?x00ID: %02X%02X%02X%02X%02X%02X%02X%02X?n", systemID[0], systemID[1], systemID[2], systemID[3], systemID[4], systemID[5], systemID[6], systemID[7]);

    loadSimpleSensorData();

    //Set digital pins based on selections...
    for (uint8_t i=8; i<=11; i++)
    {
            if (simpleSensorTypes[i] == 0)
            {
                    //output
                    SETBIT(DDRC, (i-6));
            } else {
                    //input
                    CLEARBIT(DDRC, (i-6));
            }
    }


    network_init();

    timer_set(&periodic_timer, CLOCK_SECOND / 2);
    timer_set(&arp_timer, CLOCK_SECOND * 10);

    uip_init();

    //sættes hvert for sig for uip og enc, skal rettes til en samlet setting, så vi kan bruge mymac
    struct uip_eth_addr mac = { {UIP_ETHADDR0, UIP_ETHADDR1, UIP_ETHADDR2, UIP_ETHADDR3, UIP_ETHADDR4, UIP_ETHADDR5} };
//    struct uip_eth_addr mac = {mymac[0], mymac[1], mymac[2], mymac[3], mymac[4], mymac[5]};

    uip_setethaddr(mac);
    httpd_init();
    /*
    #ifdef __DHCPC_H__
            dhcpc_init(&mac, 6);
    #else
     */
    uip_ipaddr(ipaddr, myip[0], myip[1], myip[2], myip[3]);
    uip_sethostaddr(ipaddr);
    uip_ipaddr(ipaddr, gwip[0], gwip[1], gwip[2], gwip[3]);
    uip_setdraddr(ipaddr);
    uip_ipaddr(ipaddr, netmask[0], netmask[1], netmask[2], netmask[3]);
    uip_setnetmask(ipaddr);
    //#endif /*__DHCPC_H__*/

    printf("Setting ip to %u.%u.%u.%u \r\n", myip[0], myip[1], myip[2], myip[3]);

    resolv_init();
    uip_ipaddr(ipaddr, dnsip[0], dnsip[1], dnsip[2], dnsip[3]);
    resolv_conf(ipaddr);
    webclient_init();

    printf("Stokerbot NG R3 ready  -  Firmware %u.%u ...\r\n", SBNG_VERSION_MAJOR, SBNG_VERSION_MINOR);
//    fprintf(&lcd_str, "?y2?x00Firmware %u.%u ready.", SBNG_VERSION_MAJOR, SBNG_VERSION_MINOR);

//    SPILCD_init();

    wdt_reset();

    while (1) {
        //Only one event may fire per loop, listed in order of importance
        //If an event is skipped, it will be run next loop
        if (tickDiff(timer_Count) >= 1) {
            timer_Count = tick;
            wdt_reset(); //sikre at watchdog resetter os hvis timer systemet fejler, vi når her hvert 2ms
            updateCounters(); //bør ske i en interrupt istedet, for at garentere 2ms aflæsning
        } else if (tickDiffS(timer_IOalarm) >= 5) {
            printf("Timer : IO alarm \r\n");
            timer_IOalarm = tickS;
            timedAlarmCheck();
        } else if (tickDiffS(timer_OW) >= 2) {
            printf("Timer : OW \r\n");
            timer_OW = tickS;
            updateOWSensors();
        } else if (tickDiffS(timer_Simple) >= 5) {
            printf("Timer : Simple\r\n");
            timer_Simple = tickS;
            updateSimpleSensors();
        } else if (tickDiffS(timer_SendData) >= 59) {
            printf("Timer : webclient \r\n");
            timer_SendData = tickS;
            webclient_connect();
        } else if (tickDiffS(timer_EEProm) >= 60 * 30) {
            printf("Timer : eeprom \r\n");
            timer_EEProm = tickS;
            timedSaveEeprom();
        }

        //Net handling below



        if (tickDiff(timer_network) >= 1)
        {
            timer_network = tick;
            uip_len = network_read();

            if (uip_len > 0) {
                if (BUF->type == htons(UIP_ETHTYPE_IP)) {
                    uip_arp_ipin();
                    uip_input();
                    if (uip_len > 0) {
                        uip_arp_out();
                        network_send();
                    }
                } else if (BUF->type == htons(UIP_ETHTYPE_ARP)) {
                    uip_arp_arpin();
                    if (uip_len > 0) {
                        network_send();
                    }
                }

            } else if (timer_expired(&periodic_timer)) {
                timer_reset(&periodic_timer);
                //FLIPBIT(PORTC,5);
    //            printf("Timers : %u %u \r\n", tick, tickS);

                for (uint8_t i = 0; i < UIP_CONNS; i++) {
                    uip_periodic(i);
                    if (uip_len > 0) {
                        uip_arp_out();
                        network_send();
                    }
                }

    #if UIP_UDP
                for (uint8_t i = 0; i < UIP_UDP_CONNS; i++) {
                    uip_udp_periodic(i);
                    if (uip_len > 0) {
                        uip_arp_out();
                        network_send();
                    }
                }
    #endif /* UIP_UDP */

                if (timer_expired(&arp_timer)) {
                    timer_reset(&arp_timer);
                    uip_arp_timer();
                }
            }
        }
    }
    return 0;
}
コード例 #8
0
ファイル: cap.c プロジェクト: gojimmypi/ComponentTester
uint16_t MeasureESR(Capacitor_Type *Cap)
{
  uint16_t          ESR = 0;       /* return value */
  uint16_t          U_1;           /* voltage at probe 1 with pos. pulse unloaded */
  uint16_t          U_2;           /* voltage at probe 2 with pos. pulse loaded */
  uint16_t          U_3;           /* voltage at probe 2 with neg. pulse unloaded */
  uint16_t          U_4;           /* voltage at probe 1 with neg. pulse loaded */
  uint8_t           Probe1;        /* probe #1 */
  uint8_t           Probe2;        /* probe #2 */
  uint8_t           ADC_Mask;      /* bit mask for ADC */
  uint8_t           n;             /* counter */
  uint8_t           muCycles;      /* MCU cycles per µs */
  uint8_t           PulseCycles;   /* MCU cycles for a half pulse */
  uint32_t          Sum_1;         /* sum #1 */
  uint32_t          Sum_2;         /* sum #2 */
  uint32_t          Value;

  #define LOOP_RUNS      255

  /* check for a capacitor >= 0.18µF */
  if ((Cap == NULL) ||
      (CmpValue(Cap->Value, Cap->Scale, 180, -9) < 0)) return ESR;


  /*
   *  init stuff
   */

  DischargeProbes();                    /* try to discharge probes */
  if (Check.Found == COMP_ERROR) return ESR;   /* skip on error */

  Probe1 = Cap->A;       /* probe facing Gnd */
  Probe2 = Cap->B;       /* probe facing Vcc */

  UpdateProbes(Probe1, Probe2, 0);      /* update probes */

  /* init variables */
  Sum_1 = 1;             /* 1 to prevent division by zero */
  Sum_2 = 1;             /* 1 to prevent division by zero */

  Probe1 |= (1 << REFS1) | (1 << REFS0);     /* select bandgap reference */
  Probe2 |= (1 << REFS1) | (1 << REFS0);     /* select bandgap reference */

  /* bitmask to enable and start ADC (ADC clock: 125kHz / 8µs) */
  ADC_Mask = (1 << ADSC) | (1 << ADEN) | (1 << ADIF) | ADC_CLOCK_DIV;

  /* delay for pulse */
  muCycles = (CPU_FREQ / 1000000);      /* MCU cycles per µs */

  /*
   *  We have to create a delay to shift the middle of the puls to the ADC's
   *  S&H. S&H happens at 1.5 ADC clock cycles after starting the conversion.
   *  We synchronize to a dummy conversion done directly before, so we'll got
   *  2.5 ADC clock cycles to S&H. The time between the completed dummy
   *  conversion and S&H of the next conversion is:
   *    2.5 ADC clock cycles (2.5 * 1/125kHz = 20µs)
   *    - MCU cycles for waiting loop for completion of dummy conversion (4)
   *    - MCU cycles for starting next conversion (2)
   *    - 5µs delay
   *    - MCU cycles for enabling pulse (4)
   *
   *  That time is the first half of the puls. So we have to double the time
   *  for a full pulse. Half pulse for 8MHz MCU clock is about 13.5µs.
   */

  PulseCycles = muCycles * 15;          /* MCU cycles for 15µs (20µs S/H - 5µs delay) */
  PulseCycles -= 10;                    /* substract other cycles */

  /* setup delay timer */
  if (SetupDelayTimer(PulseCycles) == 0) return ESR;   /* skip on error */


  /*
   *  charge capacitor with a negative pulse of half length
   *  pulse: GND -- probe 2 / probe 1 -- Rl -- 5V
   */

  ADC_PORT = 0;               /* set ADC port to low */
  ADMUX = Probe1;             /* set input channel to probe 1 & set bandgap ref */
  wait10ms();                 /* time for voltage stabilization */
  ADC_DDR = Probes.ADC_2;     /* pull down probe 2 directly */
  R_PORT = Probes.Rl_1;       /* pull up probe 1 via Rl */
  R_DDR = Probes.Rl_1;        /* enable resistor */
  DelayTimer();               /* wait 1/2 pulse */
  R_PORT = 0;                 /* set resistor port to low */
  R_DDR = 0;                  /* set resistor port to HiZ */


  /*
   *  measurement loop:
   *  - simulate AC by positive and negative pulses
   *  - measure start voltage (no load)
   *  - measure pulse voltage (with load)
   */  

  n = LOOP_RUNS;
  while (n > 0)
  {
    /*
     *  forward mode, probe 1 only (probe 2 in HiZ mode)
     *  get voltage at probe 1 (facing Gnd)
     *  set probes: GND -- probe 1 -- Rl -- 5V / probe 2 -- HiZ
     */

    ADC_DDR = Probes.ADC_1;        /* pull down probe 1 directly to GND */
    R_PORT = Probes.Rl_1;          /* pull up probe 1 via Rl */
    R_DDR = Probes.Rl_1;           /* enable resistor */
    ADMUX = Probe1;                /* set input channel to probe 1 & set bandgap ref */
    wdt_reset();                   /* reset watchdog */
    /* run dummy conversion for ADMUX change */
    ADCSRA = ADC_Mask;             /* start conversion */
    while (ADCSRA & (1 << ADSC));  /* wait until conversion is done */
    /* real conversion */
    ADCSRA = ADC_Mask;             /* start conversion */
    while (ADCSRA & (1 << ADSC));  /* wait until conversion is done */
    U_1 = ADCW;                    /* save ADC value */


    /*
     *  forward mode, positive charging pulse
     *  get voltage at probe 2 (facing Vcc)
     *  set probes: GND -- probe 1 / probe 2 -- Rl -- 5V
     */

    ADMUX = Probe2;                /* set input channel to probe 2 & set bandgap ref */
    /* run dummy conversion for ADMUX change */
    ADCSRA = ADC_Mask;             /* start conversion */
    while (ADCSRA & (1 << ADSC));  /* wait until conversion is done */

    /* read ADC in the mid of a positive charging pulse */
    ADCSRA = ADC_Mask;             /* start conversion with next ADC clock cycle */
    wait5us();
    R_PORT = Probes.Rl_2;          /* pull up probe 2 via Rl */
    R_DDR = Probes.Rl_2;           /* enable resistor */
    DelayTimer();                  /* wait 1/2 pulse */
    DelayTimer();                  /* wait another 1/2 pulse */
    R_PORT = 0;                    /* set resistor port to low */
    R_DDR = 0;                     /* set resistor port to HiZ */
    while (ADCSRA & (1 << ADSC));  /* wait until conversion is done */
    U_2 = ADCW;                    /* save ADC value */


    /*
     *  reverse mode, probe 2 only (probe 1 in HiZ mode)
     *  get voltage at probe 2 (facing Gnd)
     *  set probes: GND -- probe 2 -- Rl -- 5V / probe 1 -- HiZ
     */

    ADC_DDR = Probes.ADC_2;        /* pull down probe 2 directly */
    R_PORT = Probes.Rl_2;          /* pull up probe 2 via Rl */
    R_DDR = Probes.Rl_2;           /* enable resistor */
    ADMUX = Probe2;                /* set input channel to probe 2 & set bandgap ref */
    wdt_reset();                   /* reset watchdog */
    /* run dummy conversion for ADMUX change */
    ADCSRA = ADC_Mask;             /* start conversion */
    while (ADCSRA & (1 << ADSC));  /* wait until conversion is done */
    /* real conversion */
    ADCSRA = ADC_Mask;             /* start conversion */
    while (ADCSRA & (1 << ADSC));  /* wait until conversion is done */
    U_3 = ADCW;                    /* save ADC value */


    /*
     *  reverse mode, negative charging pulse
     *  get voltage at probe 1 (facing Vcc)
     *  set probes: GND -- probe 2 / probe 1 -- Rl -- 5V
     */

    ADMUX = Probe1;                /* set input channel to probe 1 & set bandgap ref */
    /* run dummy conversion for ADMUX change */
    ADCSRA = ADC_Mask;             /* start conversion */
    while (ADCSRA & (1 << ADSC));  /* wait until conversion is done */

    /* read ADC in the mid of a negatve charging pulse */
    ADCSRA = ADC_Mask;             /* start conversion with next ADC clock cycle */
    wait5us();
    R_PORT = Probes.Rl_1;          /* pull up probe 1 via Rl */
    R_DDR = Probes.Rl_1;           /* enable resistor */
    DelayTimer();                  /* wait 1/2 pulse */
    DelayTimer();                  /* wait another 1/2 pulse */
    R_PORT = 0;                    /* set resistor port to low */
    R_DDR = 0;                     /* set resistor port to HiZ */
    while (ADCSRA & (1 << ADSC));  /* wait until conversion is done */
    U_4 = ADCW;                    /* save ADC value */


    /*
     *  manage measured values
     */

    U_1 += U_3;          /* sum of both measurements without pulses/load */
    Sum_1 += U_1;        /* add to total no-load sum */
    U_2 += U_4;          /* sum of both measurements with pulses/load */
    Sum_2 += U_2;        /* add to total with-load sum */


    /*
     *  prevent runaway of cap's charge
     */

    if (U_4 <= 100)           /* <= 107mV */
    {
      /* charge cap a little bit more (negative pulse) */

      /* set probes: GND -- probe 2 / probe 1 -- Rl -- 5V */
      /* probe 2 is still pulled down directly */
      R_PORT = Probes.Rl_1;        /* pull up probe 1 via Rl */
      R_DDR = Probes.Rl_1;         /* enable pull up */
      wait2us();
      R_DDR = 0;                   /* disable any pull up */      
      R_PORT = 0;                  /* reset probe resistors */
    }

    if (U_2 <= 100)
    {
      /* charge cap a little bit more (positive pulse) */

      /* set probes: GND -- probe 1 / probe 2 -- Rl -- 5V */
      ADC_DDR = Probes.ADC_1;      /* pull down probe 1 directly */
      R_PORT = Probes.Rl_2;        /* pull up probe 2 via Rl */
      R_DDR = Probes.Rl_2;         /* enable pull up */
      wait2us();
      DelayTimer();                /* wait 1/2 pulse */
      DelayTimer();                /* wait another 1/2 pulse */
      R_DDR = 0;                   /* disable any pull up */      
      R_PORT = 0;                  /* reset probe resistors */
    }

    n--;                 /* next loop run */
  }


  /*
   *  process measurements
   */

  /* calculate voltage across the DUT */
  if (Sum_2 > Sum_1)               /* valid measurement */
  {
    Sum_2 -= Sum_1;                /* subtract voltage at DUT's low side (RiL) */
  }
  else                             /* invalid measurement */
  {
    Sum_2 = 0;
  }


  /*
   *  calculate ESR
   *  - ESR = U_ESR / I_ESR
   *    with U_ESR = (U2 or U4) and I_ESR = (U1 or U3)/RiL
   *    ESR = (U2 or U4) * RiL / (U1 or U3)
   *  - since we devide (U2 or U4) by (U1 or U3) we don't need to convert
   *    the ADC value into a voltage and desample the sums.
   *  - so ESR = Sum_2 * RiL / Sum_1
   *  - for a resolution of 0.01 Ohms we have to scale RiL to 0.01 Ohms
   */

  Value = (uint32_t)(NV.RiL * 10);      /* RiL in 0.01 Ohms */
  Value *= Sum_2;
  Value /= Sum_1;
  U_1 = (uint16_t)Value;

  /* consider probe resistance */
  if (U_1 > NV.RZero)
  {
    U_1 -= NV.RZero;               /* subtract offset */
    ESR = U_1;                     /* we got a valid result */
  }

  /* update Uref flag for next ADC run */
  Config.RefFlag = (1 << REFS1);        /* set REFS1 bit flag */

  return ESR;

  #undef LOOP_RUNS 
}
コード例 #9
0
ファイル: cap.c プロジェクト: gojimmypi/ComponentTester
uint8_t LargeCap(Capacitor_Type *Cap)
{
  uint8_t           Flag = 3;      /* return value */
  uint8_t           TempByte;      /* temp. value */
  uint8_t           Mode;          /* measurement mode */
  int8_t            Scale;         /* capacitance scale */
  uint16_t          TempInt;       /* temp. value */
  uint16_t          Pulses;        /* number of charging pulses */
  uint16_t          U_Zero;        /* voltage before charging */
  uint16_t          U_Cap;         /* voltage of DUT */
  uint16_t          U_Drop = 0;    /* voltage drop */
  uint32_t          Raw;           /* raw capacitance value */
  uint32_t          Value;         /* corrected capacitance value */

  /* setup mode */
  Mode = FLAG_10MS | FLAG_PULLUP;       /* start with large caps */


  /*
   *  We charge the DUT with up to 500 pulses each 10ms long until the
   *  DUT reaches 300mV. The charging is done via Rl. This method is
   *  suitable for large capacitances from 47uF up to 100mF. If we find a 
   *  lower capacitance we'll switch to 1ms charging pulses and try again
   *  (4.7µF up to 47µF).
   *
   *  Problem:
   *  ReadADC() needs about 5ms (44 runs). We charge the DUT for 10ms and
   *  measure for 5ms. During that time the voltage will drop due to
   *  resistive losses of the DUT and the measurement itself. So the DUT
   *  seems to need more time to reach 300mV causing a higher capacitance
   *  be calculated.
   *
   *  Remark:
   *  The Analog Input Resistance of the ADC is 100MOhm typically.
   */

large_cap:

  /* prepare probes */
  DischargeProbes();                    /* try to discharge probes */
  if (Check.Found == COMP_ERROR) return 0;     /* skip on error */

  /* setup probes: Gnd -- probe 1 / probe 2 -- Rl -- Vcc */
  ADC_PORT = 0;                    /* set ADC port to low */
  ADC_DDR = Probes.ADC_2;          /* pull-down probe 2 directly */
  R_PORT = 0;                      /* set resistor port to low */
  R_DDR = 0;                       /* set resistor port to HiZ */
  U_Zero = ReadU(Probes.Pin_1);    /* get zero voltage (noise) */

  /* charge DUT with up to 500 pulses until it reaches 300mV */
  Pulses = 0;
  TempByte = 1;
  while (TempByte)
  {
    Pulses++;
    PullProbe(Probes.Rl_1, Mode);       /* charging pulse */
    U_Cap = ReadU(Probes.Pin_1);        /* get voltage */

    /* zero offset */
    if (U_Cap > U_Zero)            /* voltage higher than zero offset */
      U_Cap -= U_Zero;                  /* subtract zero offset */
    else                           /* shouldn't happen but you never know */
      U_Cap = 0;                        /* assume 0V */

    /* end loop if charging is too slow */
    if ((Pulses == 126) && (U_Cap < 75)) TempByte = 0;
    
    /* end loop if 300mV are reached */
    if (U_Cap >= 300) TempByte = 0;

    /* end loop if maximum pulses are reached */
    if (Pulses == 500) TempByte = 0;

    wdt_reset();                        /* reset watchdog */
  }

  /* if 300mV are not reached DUT isn't a cap or much too large (>100mF) */
  /* we can ignore that for mid-sized caps */
  if (U_Cap < 300)
  {
    Flag = 1;
  }

  /* if 1300mV are reached with one pulse we got a small cap */
  if ((Pulses == 1) && (U_Cap > 1300))
  {
    if (Mode & FLAG_10MS)                    /* 10ms pulses (>47µF) */
    {
      Mode = FLAG_1MS | FLAG_PULLUP;         /* set mode to 1ms charging pulses (<47µF) */
      goto large_cap;                        /* and re-run */
    }
    else                                     /* 1ms pulses (<47µF) */
    {
      Flag = 2;                              /* signal low capacitance (<4.7µF) */
    }
  }


  /*
   *  check if DUT sustains the charge and get the voltage drop
   *  - run the same time as before minus the 10ms charging time
   *  - this gives us the approximation of the self-discharging
   */

  if (Flag == 3)
  {
    /* check self-discharging */
    TempInt = Pulses;
    while (TempInt > 0)
    {
      TempInt--;                        /* descrease timeout */
      U_Drop = ReadU(Probes.Pin_1);     /* get voltage */
      U_Drop -= U_Zero;                 /* zero offset */
      wdt_reset();                      /* reset watchdog */
    }

    /* calculate voltage drop */
    if (U_Cap > U_Drop) U_Drop = U_Cap - U_Drop;
    else U_Drop = 0;

    /* if voltage drop is too large consider DUT not to be a cap */
    if (U_Drop > 100) Flag = 0;
  }


  /*
   *  calculate capacitance
   *  - use factor from pre-calculated LargeCap_table
   *  - ignore NV.CapZero since it's in the pF range
   */

  if (Flag == 3)
  {
    Scale = -9;                           /* factor is scaled to nF */
    /* get interpolated factor from table */
    Raw = GetFactor(U_Cap + U_Drop, TABLE_LARGE_CAP);
    Raw *= Pulses;                        /* C = pulses * factor */
    if (Mode & FLAG_10MS) Raw *= 10;      /* *10 for 10ms charging pulses */

    if (Raw > (UINT32_MAX / 1000))        /* scale down if C >4.3mF */
    {
      Raw /= 1000;                        /* scale down by 10^3 */
      Scale += 3;                         /* add 3 to the exponent */
    }

    Value = Raw;                          /* copy raw value */

    /* it seems that we got a systematic error */
    Value *= 100;
    if (Mode & FLAG_10MS) Value /= 109;   /* -9% for large cap */
    else Value /= 104;                    /* -4% for mid cap */

    /* copy data */
    Cap->A = Probes.Pin_2;    /* pull-down probe pin */
    Cap->B = Probes.Pin_1;    /* pull-up probe pin */
    Cap->Scale = Scale;       /* -9 or -6 */
    Cap->Raw = Raw;
    Cap->Value = Value;       /* max. 4.3*10^6nF or 100*10^3µF */ 
  }

  return Flag;
}
コード例 #10
0
/** Main Loop */
void do_loop()
{
  static ulong last_time = 0;
  static ulong last_minute = 0;

  byte bid, sid, s, pid, qid, bitvalue;
  ProgramStruct prog;

  os.status.mas = os.options[OPTION_MASTER_STATION];
  os.status.mas2= os.options[OPTION_MASTER_STATION_2];
  time_t curr_time = os.now_tz();
  // ====== Process Ethernet packets ======
#if defined(ARDUINO)  // Process Ethernet packets for Arduino
  uint16_t pos=ether.packetLoop(ether.packetReceive());
  if (pos>0) {  // packet received
    handle_web_request((char*)Ethernet::buffer+pos);
  }
  wdt_reset();  // reset watchdog timer
  wdt_timeout = 0;

  ui_state_machine();

#else // Process Ethernet packets for RPI/BBB
  EthernetClient client = m_server->available();
  if (client) {
    while(true) {
      int len = client.read((uint8_t*) ether_buffer, ETHER_BUFFER_SIZE);
      if (len <=0) {
        if(!client.connected()) {
          break;
        } else {
          continue;
        }
      } else {
        m_client = &client;
        ether_buffer[len] = 0;  // put a zero at the end of the packet
        handle_web_request(ether_buffer);
        m_client = 0;
        break;
      }
    }
  }
#endif  // Process Ethernet packets

  // if 1 second has passed
  if (last_time != curr_time) {
    last_time = curr_time;
    if (os.button_timeout) os.button_timeout--;
    
#if defined(ARDUINO)
    if (!ui_state)
      os.lcd_print_time(os.now_tz());       // print time
#endif

    // ====== Check raindelay status ======
    if (os.status.rain_delayed) {
      if (curr_time >= os.nvdata.rd_stop_time) {  // rain delay is over
        os.raindelay_stop();
      }
    } else {
      if (os.nvdata.rd_stop_time > curr_time) {   // rain delay starts now
        os.raindelay_start();
      }
    }

    // ====== Check controller status changes and write log ======
    if (os.old_status.rain_delayed != os.status.rain_delayed) {
      if (os.status.rain_delayed) {
        // rain delay started, record time
        os.raindelay_start_time = curr_time;
      } else {
        // rain delay stopped, write log
        write_log(LOGDATA_RAINDELAY, curr_time);
      }
      os.old_status.rain_delayed = os.status.rain_delayed;
    }

    // ====== Check rain sensor status ======
    if (os.options[OPTION_SENSOR_TYPE] == SENSOR_TYPE_RAIN) { // if a rain sensor is connected
      os.rainsensor_status();
      if (os.old_status.rain_sensed != os.status.rain_sensed) {
        if (os.status.rain_sensed) {
          // rain sensor on, record time
          os.sensor_lasttime = curr_time;
        } else {
          // rain sensor off, write log
          if (curr_time>os.sensor_lasttime+10) {  // add a 10 second threshold
                                                  // to avoid faulty rain sensors generating
                                                  // too many log records
            write_log(LOGDATA_RAINSENSE, curr_time);
          }
        }
        os.old_status.rain_sensed = os.status.rain_sensed;
      }
    }
    // ====== Schedule program data ======
    ulong curr_minute = curr_time / 60;
    boolean match_found = false;
    RuntimeQueueStruct *q;
    // since the granularity of start time is minute
    // we only need to check once every minute
    if (curr_minute != last_minute) {
      last_minute = curr_minute;
      // check through all programs
      for(pid=0; pid<pd.nprograms; pid++) {
        pd.read(pid, &prog);
        if(prog.check_match(curr_time)) {
          // program match found
          // process all selected stations
          for(sid=0;sid<os.nstations;sid++) {
            bid=sid>>3;
            s=sid&0x07;
            // skip if the station is a master station (because master cannot be scheduled independently
            if ((os.status.mas==sid+1) || (os.status.mas2==sid+1))
              continue;

            // if station has non-zero water time and the station is not disabled
            if (prog.durations[sid] && !(os.station_attrib_bits_read(ADDR_NVM_STNDISABLE+bid)&(1<<s))) {
              // water time is scaled by watering percentage
              ulong water_time = water_time_resolve(water_time_decode(prog.durations[sid]));
              // if the program is set to use weather scaling
              if (prog.use_weather) {
                byte wl = os.options[OPTION_WATER_PERCENTAGE];
                water_time = water_time * wl / 100;
                if (wl < 20 && water_time < 10) // if water_percentage is less than 20% and water_time is less than 10 seconds
                                                // do not water
                  water_time = 0;
              }

              if (water_time) {
                // check if water time is still valid
                // because it may end up being zero after scaling
                q = pd.enqueue();
                if (q) {
                  q->st = 0;
                  q->dur = water_time;
                  q->sid = sid;
                  q->pid = pid+1;
                  match_found = true;
                } else {
                  // queue is full
                }
              }// if water_time
            }// if prog.durations[sid]
          }// for sid
        }// if check_match
      }// for pid

      // calculate start and end time
      if (match_found) {
        schedule_all_stations(curr_time);

        // For debugging: print out queued elements
        DEBUG_PRINT("en:");
        for(q=pd.queue;q<pd.queue+pd.nqueue;q++) {
          DEBUG_PRINT("[");
          DEBUG_PRINT(q->sid);
          DEBUG_PRINT(",");
          DEBUG_PRINT(q->dur);
          DEBUG_PRINT(",");
          DEBUG_PRINT(q->st);
          DEBUG_PRINT("]");
        }
        DEBUG_PRINTLN("");
      }
    }//if_check_current_minute
コード例 #11
0
ファイル: main.c プロジェクト: mazzoo/usbflattinyheart
int __attribute__((noreturn)) main(void)
{
    int   led_timer   = 0;
    uchar led_counter = 0;

    wdt_enable(WDTO_1S);
    /* Even if you don't use the watchdog, turn it off here. On newer devices,
     * the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
     */
    /* RESET status: all port bits are inputs without pull-up.
     * That's the way we need D+ and D-. Therefore we don't need any
     * additional hardware initialization.
     */
    odDebugInit();
    DBG1(0x00, 0, 0);       /* debug output: main starts */
    usbInit();
#if 0
    usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */
    i = 0;
    while(--i){             /* fake USB disconnect for > 250 ms */
        wdt_reset();
        _delay_ms(1);
    }
    usbDeviceConnect();
#endif
    sei();

    /* usbflattiny code */
    DDRB |= (1<<PORTB5) | (1<<PORTB4) | (1<<PORTB3) | (1<<PORTB1);

    PORTB |= (1<<PORTB5);
    PORTB |= (1<<PORTB3);
    PORTB &= ~(1<<PORTB4);
    PORTB &= ~(1<<PORTB1);
    /* /usbflattiny code */

    DBG1(0x01, 0, 0);       /* debug output: main loop starts */
    for(;;){                /* main event loop */
        DBG1(0x02, 0, 0);   /* debug output: main loop iterates */
        wdt_reset();
        usbPoll();
        if(usbInterruptIsReady()){
            /* called after every poll of the interrupt endpoint */
            advance_mouse();
            DBG1(0x03, 0, 0);   /* debug output: interrupt report prepared */
            usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
        }
        /* usbflattiny code */
        led_timer++;
        if (led_timer == 23*1000)
        {
            led_counter++;
            if (led_counter == 0x10) led_counter = 0;
            if (led_counter & 0x1) PORTB |= (1<<PORTB4); else PORTB &= ~(1<<PORTB4);
            if (led_counter & 0x2) PORTB |= (1<<PORTB3); else PORTB &= ~(1<<PORTB3);
            if (led_counter & 0x4) PORTB |= (1<<PORTB5); else PORTB &= ~(1<<PORTB5);
            if (led_counter & 0x8) PORTB |= (1<<PORTB1); else PORTB &= ~(1<<PORTB1);
            led_timer = 0;
        }
        /* /usbflattiny code */
    }
}
コード例 #12
0
void WDT_reset(void){
	wdt_reset(); 
}
コード例 #13
0
ファイル: clock.c プロジェクト: Talustus/culfw
void
Minute_Task(void)
{
  static uint8_t last_tick;
  if((uint8_t)ticks == last_tick)
    return;
  last_tick = (uint8_t)ticks;
  wdt_reset();

  // 125Hz
#ifdef XLED
  if ((ticks % 12) == 0) {
    if ( xled_pattern & _BV(xled_pos++) ) {
      LED_ON();
    } else {
      LED_OFF();
    }
  }
  xled_pos &= 15;
#endif
#ifdef HAS_FHT_TF
  // iterate over all TFs
  for(uint8_t i = 0; i < FHT_TF_NUM; i++) {
    // if timed out -> call fht_tf_timer to send out data
    if(fht_tf_timeout_Array[3 * i] == 0) {
      fht_tf_timer(i);
    }
  }
#endif
#ifdef HAS_FHT_8v
  if(fht8v_timeout == 0)
    fht8v_timer();
#endif
#ifdef HAS_FHT_80b
  if(fht80b_timeout == 0)
    fht80b_timer();
#endif
#ifdef HAS_RF_ROUTER
  if(rf_router_sendtime && --rf_router_sendtime == 0)
    rf_router_flush();
#endif

#ifdef HAS_ONEWIRE
  // Check if a running conversion is done
  // if HMS Emulation is on, and the Minute timer has expired
  onewire_HsecTask ();
#endif

  if(clock_hsec<125)
    return;
  clock_hsec = 0;       // once per second from here on.

#ifndef XLED
  if(led_mode & 2)
    LED_TOGGLE();
#endif

  if (credit_10ms < MAX_CREDIT) // 10ms/1s == 1% -> allowed talk-time without CD
    credit_10ms += 1;

#ifdef HAS_ONEWIRE
  // if HMS Emulation is on, check the HMS timer
  onewire_SecTask ();
#endif
#ifdef HAS_VZ
  vz_sectask();
#endif

#if defined(HAS_SLEEP) && defined(JOY_PIN1)
  if(joy_inactive < 255)
    joy_inactive++;

  if(sleep_time && joy_inactive == sleep_time) {
    if(USB_IsConnected)
      lcd_switch(0);
    else
      dosleep();
  }
#endif

#ifdef HAS_NTP
  if((ntp_sec & NTP_INTERVAL_MASK) == 0)
    ntp_sendpacket();
#endif

  static uint8_t clock_sec;
  clock_sec++;
if(clock_sec != 60)       // once per minute from here on
    return;
  clock_sec = 0;

#ifdef HAS_FHT_80b
  fht80b_minute++;
  if(fht80b_minute >= 60)
    fht80b_minute = 0;
#endif

#if defined(HAS_LCD) && defined(BAT_PIN)
  bat_drawstate();
#endif
}
コード例 #14
0
void CheckPins(uint8_t HighPin, uint8_t LowPin, uint8_t TristatePin) {	// Do the tests on the Probe pins, get device characteristics
									// HighPin   - Starts at H, logic 1.
									// LowPin    - Starts at L, logic 0.
									// TriState  - Starts Hi-Z, is put both H and L during the tests.
unsigned int adcv[6];
uint8_t tmpval, tmpval2;
									// HighPin is Vcc, LowPin is Gnd, TriState is HiZ
  wdt_reset();
									// Pin set
  tmpval = (LowPin * 2);						// necessarily because of the arrangement of the resistances
  R_DDR = (1<<tmpval);							// Low pin on exit and over R_L to ground
  R_PORT = 0;
  ADC_DDR = (1<<HighPin);					// High pin on exit
  ADC_PORT = (1<<HighPin);					// High pin to Vcc
  _delay_ms(5);
									// With some MOSFETs the gate (TriState act pin) must be unloaded first
									// N-channel:
  DischargePin(TristatePin,0);						
  adcv[0] = ReadADC(LowPin);						// Read the Voltage at the Low pin
  
  if(adcv[0] < 200) 
    goto next;								// Does the Device close now?
									
  DischargePin(TristatePin,1);						// otherwise: Unloaded for p-channel (gate on pluses)
  adcv[0] = ReadADC(LowPin);						// Read the Voltage at the Low pin

  next:

  if(adcv[0] > 19) {							// Device leads something without control current
									// Test on N-JFET or leading N-MOSFET
    R_DDR |= (2<<(TristatePin*2));					// Tristate pin (assumed gate) over R_H to ground
    _delay_ms(20);
    adcv[1] = ReadADC(LowPin);						// Voltage at the assumed SOURCE measure
    R_PORT |= (2<<(TristatePin*2));					// Tristate pin (assumed gate) over R_H on pluses
    _delay_ms(20);
    adcv[2] = ReadADC(LowPin);						// Voltage at the assumed SOURCE measure again
									// If it concerns a leading MOSFET or JFET, would have adcv [1] > adcv [0] its
    if(adcv[2]>(adcv[1]+100)) {						// Voltage at the gate measure, to the distinction between MOSFET and JFET
      ADC_PORT = 0x00;
      ADC_DDR = (1<<LowPin);					// Low pin to ground
      tmpval = (HighPin * 2);						// necessarily because of the arrangement of the resistances
      R_DDR |= (1<<tmpval);						// High pin on exit
      R_PORT |= (1<<tmpval);						// High pin over R_L on Vcc
      _delay_ms(20);
      adcv[2] = ReadADC(TristatePin);					// Voltage at the assumed gate measure

      if(adcv[2]>800) {							// MOSFET
	PartFound = PART_FET;						// N-channel-MOSFET
	PartMode = PART_MODE_N_D_MOS;					// Depletion MOSFET
      } else {								// JFET (pn transition between G and S leads)
	PartFound = PART_FET;						// N-channel-JFET
	PartMode = PART_MODE_N_JFET;
      }
      
      b = TristatePin;
      c = HighPin;
      e = LowPin;
    }
    
    ADC_PORT = 0x00;

									// Test on P-JFET or leading P-MOSFET
    ADC_DDR = (1<<LowPin);					// Low pin (assumed drain) to ground, Tristate pin (assumed gate) still is over R_H on pluses
    tmpval = (HighPin * 2);						// necessarily because of the arrangement of the resistances
									
    R_DDR |= (1<<tmpval);						// High pin on exit
    R_PORT |= (1<<tmpval);						// High pin over R_L on Vcc
    _delay_ms(20);
    adcv[1] = ReadADC(HighPin);						// Voltage at the assumed SOURCE measure
									
    R_PORT = (1<<tmpval);						// Tristate pin (assumed gate) over R_H to ground
    _delay_ms(20);
    adcv[2] = ReadADC(HighPin);						// Voltage at the assumed SOURCE measure again
									// - If it concerns a leading P-MOSFET or P-JFET, would have adcv [0] > adcv [1] its
    if(adcv[1]>(adcv[2]+100)) {
									// - Voltage at the gate measure, for distinction between MOSFET and JFET
      ADC_PORT = (1<<HighPin);				// High pin firmly on pluses
      ADC_DDR = (1<<HighPin);				// High pin on exit
      _delay_ms(20);
      adcv[2] = ReadADC(TristatePin);					// Voltage at the assumed gate measure
      
      if(adcv[2]<200) {							// MOSFET
	PartFound = PART_FET;						// P-channel-MOSFET 
	PartMode = PART_MODE_P_D_MOS;					// Depletion MOSFET
      } else {								// JFET (pn transition between G and S leads)
	PartFound = PART_FET;						// P-channel-JFET
	PartMode = PART_MODE_P_JFET;
      }

      b = TristatePin;
      c = LowPin;
      e = HighPin;
    }
  }
									// Pins erneut setzen - Pin set again
  tmpval = (LowPin * 2);						// necessarily because of the arrangement of the resistances
  R_DDR = (1<<tmpval);							// Low pin on exit and over R_L to ground
  R_PORT = 0;
  ADC_DDR = (1<<HighPin);					// High pin on exit
  ADC_PORT = (1<<HighPin);					// High pin to Vcc
  _delay_ms(5);	

  if(adcv[0] < 200) {							// If the Device does not have a passage between HighPin and LowPin
									// Test auf pnp
    tmpval2 = (TristatePin * 2);					// necessarily because of the arrangement of the resistances
    R_DDR |= (1<<tmpval2);						// Tristate pin over R_L to ground, to the test on pnp
    _delay_ms(2);
    adcv[1] = ReadADC(LowPin);						// Voltage measure
    
    if(adcv[1] > 700) {
									// Device leads => Pnp transistor or the like.
									// Amplification factor in both directions measure
      R_DDR = (1<<tmpval);						// Tristate pin (basis) high impedance
      tmpval2++;
      R_DDR |= (1<<tmpval2);						// Tristate pin (basis) over R_H to ground

      _delay_ms(10);
      adcv[1] = ReadADC(LowPin);					// Voltage at the Low pin (assumed collector) measure
      adcv[2] = ReadADC(TristatePin);					// Base voltage measure
									// Examine whether test already times run
      if((PartFound == PART_TRANSISTOR) || (PartFound == PART_FET)) 
	PartReady = 1;

      hfe[PartReady] = adcv[1];
	uBE[PartReady] = adcv[2];

      if(PartFound != PART_THYRISTOR) {
	if(adcv[2] > 200) {
	  PartFound = PART_TRANSISTOR;					// PNP transistor found (basis is " " upward; pulled)
	  PartMode = PART_MODE_PNP;
	} else {
	    if(adcv[0] < 20) {						// - Durchlassspannung in the closed condition small enough? (otherwise D-mode-FETs are falsely recognized as E-mode)
	      PartFound = PART_FET;					// P-channel-MOSFET found (basis/gate is not " " upward; pulled)
	      PartMode = PART_MODE_P_E_MOS;
									// Measurement of the gate threshold voltage
	      tmpval = (1<<LowPin);
	      tmpval2 = R_DDR;
	      ADMUX = TristatePin | (1<<REFS0);
	      gthvoltage = 0;

	      for(b=0;b<13;b++) {
		wdt_reset();
		DischargePin(TristatePin,1);

		while (!(ADC_PIN&tmpval));				// Control rooms, until the MOSFET scolded and on high goes to drain

		R_DDR = 0;
		ADCSRA |= (1<<ADSC);

		while (ADCSRA&(1<<ADSC));
		
		gthvoltage += (MAX_ADC - ADCW);
		R_DDR = tmpval2;
	      }

	      gthvoltage *= 3;						// Conversion in mV, together with the division by 8 (with the LCD announcement)
	    }
	  }
	  b = TristatePin;
	  c = LowPin;
	  e = HighPin;
	}
      }

									// Tristate (basis assumed) on pluses, to the test on npn
      ADC_PORT = 0x00;						// Low pin to ground
      tmpval = (TristatePin * 2);					// necessarily because of the arrangement of the resistances
      tmpval2 = (HighPin * 2);						// necessarily because of the arrangement of the resistances
      R_DDR = (1<<tmpval) | (1<<tmpval2);				// High pin and Tristate pin on exit
      R_PORT = (1<<tmpval) | (1<<tmpval2);				// High pin and Tristate pin over R_L on Vcc
      ADC_DDR = (1<<LowPin);					// Low pin on exit
      _delay_ms(10);
      adcv[1] = ReadADC(HighPin);					// Voltage at the High pin measure
      
      if(adcv[1] < 500) {
	if(PartReady == 1) goto testend;
									// Device leads => NPN transistor or the like.
									// Test on thyristor:
									// Gate unload
	R_PORT = (1<<tmpval2);						// Tristate pin (gate) over R_L to ground
	_delay_ms(10);
	R_DDR = (1<<tmpval2);						// Tristate pin (gate) high impedance
									
	_delay_ms(5);
	adcv[3] = ReadADC(HighPin);					// Again Voltage at the High pin (anode assumed) measure

	R_PORT = 0;							// High pin (anode assumed) to ground
	_delay_ms(5);
	R_PORT = (1<<tmpval2);						// High pin (anode assumed) pluses
	_delay_ms(5);
	adcv[2] = ReadADC(HighPin);					// Again Voltage at the High pin (anode assumed) measure

	if((adcv[3] < 500) && (adcv[2] > 900)) {			// After switching the holding current off the thyristor must close
									// was switched before disconnection of triggering Rome and is still switched although gate out => Thyristor
	  PartFound = PART_THYRISTOR;
									//  Test on Triac
	  R_DDR = 0;
	  R_PORT = 0;
	  ADC_PORT = (1<<LowPin);				// Low-Pin fest auf Plus - Low pin firmly on pluses
	  _delay_ms(5);
	  R_DDR = (1<<tmpval2);						// HighPin over R_L to ground
	  _delay_ms(5);

	  if(ReadADC(HighPin) > 50) 
	    goto savenresult;						// - Voltage at the High pin (more assumed a2) measure; if too highly: Device leads now => no triac

	  R_DDR |= (1<<tmpval);						// Gate also over R_L to ground => Triac would have to ignite
	  _delay_ms(5);

	  if(ReadADC(TristatePin) < 200) 
	    goto savenresult;						// - Voltage at the Tristate pin (assumed gate) measure; Abort if Voltage too small

	  if(ReadADC(HighPin) < 150) 
	    goto savenresult;						// Device does not lead now => no triac => Abort

	  R_DDR = (1<<tmpval2);						// TriState act pin (gate) again high impedance
	  _delay_ms(5);

	  if(ReadADC(HighPin) < 150) 
	    goto savenresult;    					// - Device does not lead after switching the gate stream off any longer => no triac => Abort

	  R_PORT = (1<<tmpval2);					// HighPin over R_L on pluses => Holding current out
	  _delay_ms(5);
	  R_PORT = 0;							// HighPin again over R_L to ground; Triac would have to now close
	  _delay_ms(5);

	  if(ReadADC(HighPin) > 50) 
	    goto savenresult;						// - Voltage at the High pin (more assumed a2) measure; if too highly: Device leads now => no triac

	  PartFound = PART_TRIAC;
	  PartReady = 1;
	  goto savenresult;
	}
									// Test on transistor or MOSFET
	tmpval++;
	R_DDR |= (1<<tmpval);						// Tristate pin (basis) on exit
	R_PORT |= (1<<tmpval);						// Tristate pin (basis) over R_H on pluses
	_delay_ms(50);
	adcv[1] = ReadADC(HighPin);					// Voltage at the High pin (assumed collector) measure
	adcv[2] = ReadADC(TristatePin);					// Base voltage measure
  
	if((PartFound == PART_TRANSISTOR) || (PartFound == PART_FET)) 
	  PartReady = 1;						// examine whether test already times run

	hfe[PartReady] = MAX_ADC - adcv[1];
	uBE[PartReady] = MAX_ADC - adcv[2];

	if(adcv[2] < 500) {
	  PartFound = PART_TRANSISTOR;					// NPN transistor found (basis is " " downward; pulled)
	  PartMode = PART_MODE_NPN;
	} else {
	    if(adcv[0] < 20) {						// - Durchlassspannung in the closed condition small enough? (otherwise D-mode-FETs are falsely recognized as E-mode)
	      PartFound = PART_FET;					// N-channel-MOSFET found (basis/gate is not " " downward; pulled)
	      PartMode = PART_MODE_N_E_MOS;
	      tmpval2 = R_DDR;						// Gate threshold voltage measure
	      tmpval=(1<<HighPin);
	      ADMUX = TristatePin | (1<<REFS0);
	      gthvoltage = 0;

	      for(b=0;b<13;b++) {
		wdt_reset();
		DischargePin(TristatePin,0);

		while ((ADC_PIN&tmpval));	 			// Control rooms, until the MOSFET scolded and on low goes to drain 

		R_DDR = 0;
		R_PORT = 0;
		ADCSRA |= (1<<ADSC);

		while (ADCSRA&(1<<ADSC));

		gthvoltage += ADCW;

		R_DDR = tmpval2;
		R_PORT = tmpval2;
	      }

	      gthvoltage *= 3;						// Conversion in mV, together with the division by 8 (with the LCD announcement)
	    }
	  }

	  savenresult:
	  b = TristatePin;
	  c = HighPin;
	  e = LowPin;
	}

	ADC_DDR = 0x00;
	ADC_PORT = 0x00;
									// Finished
	} else {							// Passage
									// Test auf Diode
	    tmpval2 = (2<<(2*HighPin));					// R_H
	    tmpval = (1<<(2*HighPin));					// R_L
	    ADC_PORT = 0x00;
	    ADC_DDR = (1<<LowPin);				// Low pin to ground, High pin still is over R_L on Vcc
	    DischargePin(TristatePin,1);				// Unloaded for P-channel-MOSFET
	    _delay_ms(5);
	    adcv[0] = ReadADC(HighPin) - ReadADC(LowPin);
	    R_DDR = tmpval2;						// High pin over R_H on pluses
	    R_PORT = tmpval2;
	    _delay_ms(5);
	    adcv[2] = ReadADC(HighPin) - ReadADC(LowPin);
	    R_DDR = tmpval;						// High pin over R_L on pluses
	    R_PORT = tmpval;
	    DischargePin(TristatePin,0);				// Unloaded for N-channel-MOSFET
	    _delay_ms(5);
	    adcv[1] = ReadADC(HighPin) - ReadADC(LowPin);
	    R_DDR = tmpval2;						// High pin over R_H on pluses
	    R_PORT = tmpval2;
	    _delay_ms(5);
	    adcv[3] = ReadADC(HighPin) - ReadADC(LowPin);
		/*      Without unloading it can come to wrong identifications, since the gate of a MOSFETs can be still loaded. 
		        The additional measurement with " großen" R_H resisted is accomplished, around antiparallel diodes of 
		        Resistances differentiate to be able.
		        A diode has a Durchlassspg relatively independent of the passage stream. 
		        With a resistance the voltage drop changes strongly (linear) with the river. 
		*/
	    if(adcv[0] > adcv[1]) {
	      adcv[1] = adcv[0];					// the higher value wins
	      adcv[3] = adcv[2];
	    }

	    if((adcv[1] > 30) && (adcv[1] < 950)) {			// Voltage is over 0,15V and under 4,64V => Ok one 
	      if((PartFound == PART_NONE) || (PartFound == PART_RESISTOR)) 
		PartFound = PART_DIODE;					// Diode by default.
									// Otherwise there would be problems with transistors with protection diode 
	      diodes[NumOfDiodes].Anode = HighPin;
	      diodes[NumOfDiodes].Cathode = LowPin;
	      diodes[NumOfDiodes].Voltage = (adcv[1]*54/11);		// - Multiply by approx 4,9, in order to receive from the ADC the Voltage in millivolts
	      NumOfDiodes++;

	      for(uint8_t i=0;i<NumOfDiodes;i++) {
		if((diodes[i].Anode == LowPin) && (diodes[i].Cathode == HighPin)) {	// two antiparallel diodes: Defectively or duo LED 
		  if((adcv[3]*64) < (adcv[1] / 5)) {			// Durchlassspannung falls with smaller test stream strongly off => Defectively
		    if(i<NumOfDiodes) {
		      for(uint8_t j=i;j<(NumOfDiodes-1);j++) {diodes[j].Anode = diodes[j+1].Anode;\
			                                      diodes[j].Cathode = diodes[j+1].Cathode;\
			                                      diodes[j].Voltage = diodes[j+1].Voltage;
		      }
		    }

		    NumOfDiodes -= 2;
	          }
	        }
	      }
	    }
	}

									// Test on resistance
	tmpval2 = (2<<(2*HighPin));					// R_H
	tmpval = (1<<(2*HighPin));					// R_L
	ADC_PORT = 0x00;
	ADC_DDR = (1<<LowPin);				// Low pin to ground
	R_DDR = tmpval;							// High pin over R_L on pluses
	R_PORT = tmpval;
	adcv[2] = ReadADC(LowPin);
	adcv[0] = ReadADC(HighPin) - adcv[2];
	R_DDR = tmpval2;						// High pin over R_H on pluses
	R_PORT = tmpval2;
	adcv[3] = ReadADC(LowPin);
	adcv[1] = ReadADC(HighPin) - adcv[3];

									// Measurement of the voltage difference between the positive terminal of R_L and R_H and Vcc
	tmpval2 = (2<<(2*LowPin));					// R_H
	tmpval = (1<<(2*LowPin));					// R_L
	ADC_DDR = (1<<HighPin);				// High pin on exit
	ADC_PORT = (1<<HighPin);				// High pin firmly on pluses
	R_PORT = 0;
	R_DDR = tmpval;							// Low pin over R_L to ground
	adcv[2] += (MAX_ADC - ReadADC(HighPin));
	R_DDR = tmpval2;						// Low pin over R_H to ground
	adcv[3] += (MAX_ADC - ReadADC(HighPin));

	if(((adcv[0] - adcv[2]) < 900) && ((adcv[1] - adcv[3]) > 20)) goto testend; 	// Voltage drops with small test stream not far enough

	if(((adcv[1] * 32) / 31) < adcv[0]) {				// - Sloping Voltage does not drop with smaller test stream strongly and it exists " Almost Kurzschluss" => Resistance
	  if((PartFound == PART_DIODE) || (PartFound == PART_NONE) || (PartFound == PART_RESISTOR)) {
	    if((tmpPartFound == PART_RESISTOR) && (ra == LowPin) && (rb == HighPin)) {
					/* The Device was tested already once with reverse polarity. Now compare both results with one another.
					If they are quite similar, it concerns (in all probability) a resistance. 
					*/
	      if(!((((adcv[0] + 100) * 6) >= ((rv[0] + 100) * 5)) &&  \
		   (((rv[0] + 100) * 6) >= ((adcv[0] + 100) * 5)) &&  \
		   (((adcv[1] + 100) * 6) >= ((rv[1] + 100) * 5)) &&  \
		   (((rv[1] + 100) * 6) >= ((adcv[1] + 100) * 5)))) {	// min. 20% deviation => no resistance
		tmpPartFound = PART_NONE;
		goto testend;
	      }

	      PartFound = PART_RESISTOR;
	    }

	    rv[0] = adcv[0];
	    rv[1] = adcv[1];

	    radcmax[0] = MAX_ADC - adcv[2];				// - V at the Low pin is not completely zero, but approximately 0,1V (however one measures).
	    radcmax[1] = MAX_ADC - adcv[3];
	    ra = HighPin;
	    rb = LowPin;
	    tmpPartFound = PART_RESISTOR;
	  }
	}

	testend:
	ADC_DDR = 0x00;
	ADC_PORT = 0x00;
	R_DDR = 0;
	R_PORT = 0;
}									// End of CheckPins()
コード例 #15
0
ファイル: CDC.cpp プロジェクト: akkera102/07_tiny_basic
bool CDC_Setup(USBSetup& setup)
{
	u8 r = setup.bRequest;
	u8 requestType = setup.bmRequestType;

	if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
	{
		if (CDC_GET_LINE_CODING == r)
		{
			USB_SendControl(0,(void*)&_usbLineInfo,7);
			return true;
		}
	}

	if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
	{
		if (CDC_SEND_BREAK == r)
		{
			breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
		}

		if (CDC_SET_LINE_CODING == r)
		{
			USB_RecvControl((void*)&_usbLineInfo,7);
		}

		if (CDC_SET_CONTROL_LINE_STATE == r)
		{
			_usbLineInfo.lineState = setup.wValueL;
		}

		if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r)
		{
			// auto-reset into the bootloader is triggered when the port, already 
			// open at 1200 bps, is closed.  this is the signal to start the watchdog
			// with a relatively long period so it can finish housekeeping tasks
			// like servicing endpoints before the sketch ends

			uint16_t magic_key_pos = MAGIC_KEY_POS;

// If we don't use the new RAMEND directly, check manually if we have a newer bootloader.
// This is used to keep compatible with the old leonardo bootloaders.
// You are still able to set the magic key position manually to RAMEND-1 to save a few bytes for this check.
#if MAGIC_KEY_POS != (RAMEND-1)
			// For future boards save the key in the inproblematic RAMEND
			// Which is reserved for the main() return value (which will never return)
			if (_updatedLUFAbootloader) {
				// horray, we got a new bootloader!
				magic_key_pos = (RAMEND-1);
			}
#endif

			// We check DTR state to determine if host port is open (bit 0 of lineState).
			if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
			{
#if MAGIC_KEY_POS != (RAMEND-1)
				// Backup ram value if its not a newer bootloader.
				// This should avoid memory corruption at least a bit, not fully
				if (magic_key_pos != (RAMEND-1)) {
					*(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos;
				}
#endif
				// Store boot key
				*(uint16_t *)magic_key_pos = MAGIC_KEY;
				wdt_enable(WDTO_120MS);
			}
			else
			{
				// Most OSs do some intermediate steps when configuring ports and DTR can
				// twiggle more than once before stabilizing.
				// To avoid spurious resets we set the watchdog to 250ms and eventually
				// cancel if DTR goes back high.

				wdt_disable();
				wdt_reset();
#if MAGIC_KEY_POS != (RAMEND-1)
				// Restore backed up (old bootloader) magic key data
				if (magic_key_pos != (RAMEND-1)) {
					*(uint16_t *)magic_key_pos = *(uint16_t *)(RAMEND-1);
				} else
#endif
				{
				// Clean up RAMEND key
					*(uint16_t *)magic_key_pos = 0x0000;
				}
			}
		}
		return true;
	}
	return false;
}
コード例 #16
0
ファイル: cap.c プロジェクト: gojimmypi/ComponentTester
uint8_t SmallCap(Capacitor_Type *Cap)
{
  uint8_t           Flag = 3;      /* return value */
  uint8_t           TempByte;      /* temp. value */
  int8_t            Scale;         /* capacitance scale */
  uint16_t          Ticks;         /* timer counter */
  uint16_t          Ticks2;        /* timer overflow counter */
  uint16_t          U_c;           /* voltage of capacitor */
  uint32_t          Raw;           /* raw capacitance value */
  uint32_t          Value;         /* corrected capacitance value */


  /*
   *  Measurement method used for small caps < 50uF:
   *  We need a much better resolution for the time measurement. Therefore we
   *  use the MCUs internal 16-bit counter and analog comparator. The counter
   *  inceases until the comparator detects that the voltage of the DUT is as
   *  high as the internal bandgap reference. To support the higher time
   *  resolution we use the Rh probe resistor for charging.
   *
   *  Remark:
   *  The analog comparator has an Input Leakage Current of -50nA up to 50nA 
   *  at Vcc/2. The Input Offset is <10mV at Vcc/2.
   */

  Ticks2 = 0;                           /* reset timer overflow counter */

  /*
   *  init hardware
   */

  /* prepare probes */
  DischargeProbes();                    /* try to discharge probes */
  if (Check.Found == COMP_ERROR) return 0;     /* skip on error */

  /* set probes: Gnd -- all probes / Gnd -- Rh -- probe-1 */
  R_PORT = 0;                           /* set resistor port to low */
  /* set ADC probe pins to output mode */
  ADC_DDR = (1 << TP1) | (1 << TP2) | (1 << TP3);
  ADC_PORT = 0;                         /* set ADC port to low */
  R_DDR = Probes.Rh_1;                  /* pull-down probe-1 via Rh */

  /* setup analog comparator */
  ADCSRB = (1 << ACME);                 /* use ADC multiplexer as negative input */
  ACSR =  (1 << ACBG) | (1 << ACIC);    /* use bandgap as positive input, trigger timer1 */
  ADMUX = (1 << REFS0) | Probes.Pin_1;  /* switch ADC multiplexer to probe 1 */
                                        /* and set AREF to Vcc */
  ADCSRA = ADC_CLOCK_DIV;               /* disable ADC, but keep clock dividers */
  wait200us();

  /* setup timer */
  TCCR1A = 0;                           /* set default mode */
  TCCR1B = 0;                           /* set more timer modes */
  /* timer stopped, falling edge detection, noise canceler disabled */
  TCNT1 = 0;                            /* set Counter1 to 0 */
  /* clear all flags (input capture, compare A & B, overflow */
  TIFR1 = (1 << ICF1) | (1 << OCF1B) | (1 << OCF1A) | (1 << TOV1);
  R_PORT = Probes.Rh_1;                 /* pull-up probe-1 via Rh */  
                                        
  /* enable timer */
  if (Check.Found == COMP_FET)
  {
    /* keep all probe pins pulled down but probe-1 */
    TempByte = (((1 << TP1) | (1 << TP2) | (1 << TP3)) & ~(1 << Probes.Pin_1));    
  }
  else
  {
    TempByte = Probes.ADC_2;            /* keep just probe-1 pulled down */
  }

  /* start timer by setting clock prescaler (1/1 clock divider) */
  TCCR1B = (1 << CS10);
  ADC_DDR = TempByte;                   /* start charging DUT */


  /*
   *  timer loop
   *  - run until voltage is reached
   *  - detect timer overflows
   */

   while (1)
   {
     TempByte = TIFR1;                  /* get timer1 flags */

     /* end loop if input capture flag is set (= same voltage) */
     if (TempByte & (1 << ICF1)) break;

     /* detect timer overflow by checking the overflow flag */
     if (TempByte & (1 << TOV1))
     {
       /* happens at 65.536ms for 1MHz or 8.192ms for 8MHz */
       TIFR1 = (1 << TOV1);             /* reset flag */
       wdt_reset();                     /* reset watchdog */
       Ticks2++;                        /* increase overflow counter */

       /* end loop if charging takes too long (13.1s) */
       if (Ticks2 == (CPU_FREQ / 5000)) break;
     }
   }

  /* stop counter */
  TCCR1B = 0;                           /* stop timer */
  TIFR1 = (1 << ICF1);                  /* reset Input Capture flag */

  Ticks = ICR1;                         /* get counter value */

  /* disable charging */
  R_DDR = 0;                  /* set resistor port to HiZ mode */

  /* catch missed timer overflow */
  if ((TCNT1 > Ticks) && (TempByte & (1 << TOV1)))
  {
    TIFR1 = (1 << TOV1);                /* reset overflow flag */
    Ticks2++;                           /* increase overflow counter */
  }

  /* enable ADC again */
  ADCSRA = (1 << ADEN) | (1 << ADIF) | ADC_CLOCK_DIV;

  /* get voltage of DUT */
  U_c = ReadU(Probes.Pin_1);       /* get voltage of cap */

  /* start discharging DUT */
  R_PORT = 0;                      /* pull down probe-2 via Rh */
  R_DDR = Probes.Rh_1;             /* enable Rh for probe-1 again */

  /* skip measurement if charging took too long */
  if (Ticks2 >= (CPU_FREQ / 5000)) Flag = 1;


  /*
   *  calculate capacitance (<50uF)
   *  - use factor from pre-calculated SmallCap_table
   */

  if (Flag == 3)
  {
    /*  combine both counter values */
    Raw = (uint32_t)Ticks;                /* set lower 16 bits */
    Raw |= (uint32_t)Ticks2 << 16;        /* set upper 16 bits */
    if (Raw > 2) Raw -= 2;                /* subtract processing time overhead */

    Scale = -12;                          /* default factor is for pF scale */
    if (Raw > (UINT32_MAX / 1000))        /* prevent overflow (4.3*10^6) */
    {
      Raw /= 1000;                        /* scale down by 10^3 */
      Scale += 3;                         /* add 3 to the exponent (nF) */
    }

    /* multiply with factor from table */
    Raw *= GetFactor(Config.Bandgap + NV.CompOffset, TABLE_SMALL_CAP);

    /* divide by CPU frequency to get the time and multiply with table scale */
    Raw /= (CPU_FREQ / 10000);
    Value = Raw;                          /* take raw value */

    /* take care about zero offset if feasable */
    if (Scale == -12)                     /* pF scale */
    {
      if (Value >= NV.CapZero)            /* if value is larger than offset */
      {
        Value -= NV.CapZero;              /* substract offset */
      }
      else                                /* if value is smaller than offset */
      {
        /* we have to prevent a negative value */
        Value = 0;                        /* set value to 0 */
      }
    }

    /* copy data */
    Cap->A = Probes.Pin_2;    /* pull-down probe pin */
    Cap->B = Probes.Pin_1;    /* pull-up probe pin */
    Cap->Scale = Scale;       /* -12 or -9 */
    Cap->Raw = Raw;
    Cap->Value = Value;       /* max. 5.1*10^6pF or 125*10^3nF */


    /*
     *  Self-adjust the voltage offset of the analog comparator and internal
     *  bandgap reference if C is 100nF up to 20µF. The minimum of 100nF
     *  should keep the voltage stable long enough for the measurements. 
     *  Changed offsets will be used in next test run.
     */

    if (((Scale == -12) && (Value >= 100000)) ||
        ((Scale == -9) && (Value <= 20000)))
    {
      int16_t         Offset;
      int32_t         TempLong;

      /*
       *  We can self-adjust the offset of the internal bandgap reference
       *  by measuring a voltage lower than the bandgap reference, one time
       *  with the bandgap as reference and a second time with Vcc as
       *  reference. The common voltage source is the cap we just measured.
       */

       while (ReadU(Probes.Pin_1) > 980)
       {
         /* keep discharging */
       }

       R_DDR = 0;                       /* stop discharging */

       Config.AutoScale = 0;            /* disable auto scaling */
       Ticks = ReadU(Probes.Pin_1);     /* U_c with Vcc reference */
       Config.AutoScale = 1;            /* enable auto scaling again */
       Ticks2 = ReadU(Probes.Pin_1);    /* U_c with bandgap reference */

       R_DDR = Probes.Rh_1;             /* resume discharging */

       Offset = Ticks - Ticks2;
       /* allow some offset caused by the different voltage resolutions
          (4.88 vs. 1.07) */
       if ((Offset < -4) || (Offset > 4))    /* offset too large */
       {
         /*
          *  Calculate total offset:
          *  - first get offset per mV: Offset / U_c
          *  - total offset for U_ref: (Offset / U_c) * U_ref
          */

         TempLong = Offset;
         TempLong *= Config.Bandgap;         /* * U_ref */
         TempLong /= Ticks2;                 /* / U_c */

         NV.RefOffset = (int8_t)TempLong;
       }


      /*
       *  In the cap measurement above the analog comparator compared
       *  the voltages of the cap and the bandgap reference. Since the MCU
       *  has an internal voltage drop for the bandgap reference the
       *  MCU used actually U_bandgap - U_offset. We get that offset by
       *  comparing the bandgap reference with the voltage of the cap:
       *  U_c = U_bandgap - U_offset -> U_offset = U_c - U_bandgap
       */

      Offset = U_c - Config.Bandgap;

      /* limit offset to a valid range of -50mV - 50mV */
      if ((Offset > -50) && (Offset < 50)) NV.CompOffset = Offset;
    }
  }

  return Flag;
}
コード例 #17
0
uint8_t BT::read(void)
{
	if(!present)
		return 1;


	uint16_t bytes = 0;

	dataId = 0;
	dataSize = 0;

	BT_SET_CTS;

	uint16_t timeout;

	for(;;)
	{
		timeout = 0;

		while(!Serial_IsCharReceived())
		{
			wdt_reset();
			_delay_us(10);
			if(++timeout > (bytes > 0 ? 50000 : 5000))
				break;
		}

		if(timeout > 50000)
		{
			debug(STR("TIMED OUT!"));
			debug(STR("\r\n   BYTES: "));
			debug(bytes);
			debug(STR("\r\n      ID: "));
			debug((uint8_t)buf[1]);
			debug(STR("\r\n    SIZE: "));
			debug(dataSize);
			debug(STR("\r\n  DATA[0]: "));
			debug(buf[0]);
			debug(STR("\r\n  DATA[1]: "));
			debug((uint8_t)buf[1]);
			debug(STR("\r\n  DATA[2]: "));
			debug((uint8_t)buf[2]);
			debug(STR("\r\n  DATA[3]: "));
			debug((uint8_t)buf[3]);
			debug(STR("\r\n  DATA[4]: "));
			debug(buf[4]);
			debug(STR("\r\n  DATA[5]: "));
			debug(buf[5]);
		    debug(STR("\r\n"));
			break;
		}
		else if(timeout > 5000 && bytes == 0)
		{
			break;
		}

		buf[bytes] = (char)Serial_ReceiveByte();

		if(!(bytes == 0 && (buf[0] == '\n' || buf[0] == '\r'))) bytes++; // skip leading CR/LF
		if(mode == BT_MODE_CMD)
		{
			if(bytes > 0 && buf[bytes - 1] == '\n') // just get one line at a time
				break;
		}
		else
		{
			if(buf[0] != '$' && bytes > 1 && buf[bytes - 1] == '$')
			{
				buf[0] = '$';
				bytes = 1;
			}
			if(dataSize > 0)
			{
				if(bytes > dataSize + 5) break;
			}
			else
			{
				if(bytes > 5 && buf[0] == '$' && buf[5] == ':')
				{
					dataId = buf[1];
					dataType = buf[2];

					*(&dataSize) = buf[3];
					*(&dataSize + 1) = buf[4];

					data = (buf + 6);

					if(dataSize == 0) break;
				}
				else if(buf[0] != '$' && buf[bytes - 1] == '\n') // just get one line at a time
				{
					break;
				}
			}
		}

		if(bytes >= BT_BUF_SIZE)
			break;
	}

	BT_CLR_CTS;

	buf[bytes] = 0;

	return bytes;
}
コード例 #18
0
ファイル: main.c プロジェクト: hylics/IRFS105
int main(void)
{
    //STATIC_ASSERT(sizeof(uint16_t) == 2);
    InitGPIO();
    InitSPI_soft();
    InitI2C_soft();
    InitADC();
    InitSystemTimer();
    InitTimers();
    InitMessages();
    InitCC2500(preferredSettings); //(const uint8_t **)conf(+6bytes of code), preferredSettings
    uart0_init( UART_BAUD_SELECT(RS485_BAUDRATE, F_CPU) );
    //_delay_ms(5000);
    //InitEXTI();
    //MCUCR |= (_BV(ISC11) | _BV(ISC01));

    /*check Watchdog reset flag*/
    if(bit_is_set(MCUCSR, WDRF)) {
      //increase wathcdog reset counter and save in eeprom
    }

    set_sleep_mode(SLEEP_MODE_IDLE); //варианты SLEEP_MODE_PWR_SAVE SLEEP_MODE_IDLE SLEEP_MODE_ADC
    //wdt_enable(WDTO_2S);
    sei(); //enable interrupts

    for (uint8_t i = 0; i<0x05; i++) {
          //_spi_start();
          //spi_TxRx(0x9D);
          //_spi_stop();
          _delay_ms(100);
          PORTC |= _BV(PC2); //blink for test
          _delay_ms(100);
          PORTC &= ~_BV(PC2);
          _delay_ms(100);

          RS485_DE_HIGH;
          uart0_putc(0xba);
          _delay_ms(2);
          RS485_DE_LOW;
        }
        RS485_DE_LOW;

    while(1) {
      cc_table_state[CC_state]();


      ProcessTimers(&sys_timer);
      ProcessMessages();
      wdt_reset();

      /*enter in sleep mode until interrupts occured*/
//      cli(); //disable interrupts
//      if (some_condition)
//      {
//        sleep_enable();
//        sei();
//        sleep_cpu();
//        sleep_disable();
//      }
//      sei();
    }

    return 0;
}
コード例 #19
0
/**
 * \par Function
 *   deviceCalibration
 * \par Description
 *   Calibration function for the MeCompass. 
 * \param[in]
 *   None
 * \par Output
 *   None
 * \return
 *   None.
 * \par Others
 *   Pressing the button to run the calibration function with the led flickering,
 *   rotate the MeCompass over 360 degress in a stable plane that you specified to calibrate,
 *   and press the button again to finish the calibration.
 */
void MeCompass::deviceCalibration(void)
{
#ifdef ME_PORT_DEFINED
  if(dRead1(INPUT_PULLUP) == 0)   //check the KEY
#else  // ME_PORT_DEFINED
  pinMode(_keyPin, INPUT_PULLUP);
  if(digitalRead(_keyPin) == 0)
#endif
  {
  	delay(10);
#ifdef ME_PORT_DEFINED
  	if(dRead1(INPUT_PULLUP) == 0)
#else  // ME_PORT_DEFINED
    pinMode(_keyPin, INPUT_PULLUP);
    if(digitalRead(_keyPin) == 0)
#endif
  	{
      if(testConnection()==false)
      {
#ifdef COMPASS_SERIAL_DEBUG
        Serial.println("It is not Me Compass!!!!!");
#endif
        return;
      }  
      long time_num,cal_time;
      bool LED_state = 0;
      int16_t X_num,Y_num,Z_num;
      int16_t X_max = -32768;
      int16_t X_min = 32767;
      int16_t Y_max = -32768;
      int16_t Y_min = 32767;
      int16_t Z_max = -32768;
      int16_t Z_min = 32767;
      int16_t X_abs,Y_abs,Z_abs;  
#ifdef COMPASS_SERIAL_DEBUG
      Serial.println("Compass calibration !!!");
#endif  
      time_num = millis();
#ifdef ME_PORT_DEFINED
      while(dRead1(INPUT_PULLUP) == 0)
#else  // ME_PORT_DEFINED
      pinMode(_keyPin, INPUT_PULLUP);
      while(digitalRead(_keyPin) == 0)
#endif
      {
        if( millis() - time_num > 200 )   //control the LED
        {
          wdt_reset();
          time_num = millis();
          LED_state = !LED_state;
#ifdef ME_PORT_DEFINED
          dWrite2(LED_state); 
#else  // ME_PORT_DEFINED
          pinMode(_ledPin, OUTPUT);
          digitalWrite(_ledPin, LED_state);
#endif
#ifdef COMPASS_SERIAL_DEBUG
          Serial.println("You can free the KEY now ");
#endif
        }
      }  
#ifdef COMPASS_SERIAL_DEBUG
      Serial.println("collecting value.....");
#endif  
      delay(100);  
      cal_time = millis();
#ifndef ME_PORT_DEFINED 
      pinMode(_keyPin, INPUT_PULLUP);
#endif
      do
      {
        if(millis() - time_num > 200)   //control the LED
        {
          wdt_reset();
          time_num = millis();
          LED_state = !LED_state;
#ifdef ME_PORT_DEFINED
          dWrite2(LED_state); 
#else  // ME_PORT_DEFINED
          pinMode(_ledPin, OUTPUT);
          digitalWrite(_ledPin, LED_state);
#endif
        }
        if(millis() - cal_time > 10)
        {
          wdt_reset();
          getHeading(&X_num,&Y_num,&Z_num);  
          if(X_num < X_min)
          {
            X_min = X_num;
          }
          else if(X_num > X_max)
          {
            X_max = X_num;
          }  
          if(Y_num < Y_min)
          {
            Y_min = Y_num;
          }
          else if(Y_num > Y_max)
          {
            Y_max = Y_num;
          }  
          if(Z_num < Z_min)
          {
            Z_min = Z_num;
          }
          else if(Z_num > Z_max)
          {
            Z_max = Z_num;
          }
        }
      }
#ifdef ME_PORT_DEFINED
      while(dRead1(INPUT_PULLUP)==1);
      dWrite2(LOW);  //turn off the LED
#else  // ME_PORT_DEFINED
      while(digitalRead(_keyPin) == 1);
      pinMode(_ledPin, OUTPUT);
      digitalWrite(_ledPin, LOW);
#endif

      Cal_parameter.X_excursion = -( (float)X_max + (float)X_min ) / 2;
      Cal_parameter.Y_excursion = -( (float)Y_max + (float)Y_min ) / 2;
      Cal_parameter.Z_excursion = -( (float)Z_max + (float)Z_min ) / 2;
      Cal_parameter.X_gain = 1;
      Cal_parameter.Y_gain = ( (float)Y_max - (float)Y_min ) / ( (float)X_max - (float)X_min );
      Cal_parameter.Z_gain = ( (float)Z_max - (float)Z_min ) / ( (float)X_max - (float)X_min );  
      X_abs = abs(X_max-X_min);
      Y_abs = abs(Y_max-Y_min);
      Z_abs = abs(Z_max-Z_min);  
      if(X_abs<=Y_abs && X_abs<=Z_abs)
      {
        Cal_parameter.Rotation_Axis=1;  //X_Axis
      }
      else if(Y_abs<=X_abs && Y_abs<=Z_abs)
      {
        Cal_parameter.Rotation_Axis=2;  //Y_Axis
      }
      else
      {
        Cal_parameter.Rotation_Axis=3;  //Z_Axis
      }  
#ifdef COMPASS_SERIAL_DEBUG
      Serial.println("Print Calibration Parameter:");
      Serial.print("X_excursion: "); Serial.print(Cal_parameter.X_excursion,1); Serial.println(" ");
      Serial.print("Y_excursion: "); Serial.print(Cal_parameter.Y_excursion,1); Serial.println(" ");
      Serial.print("Z_excursion: "); Serial.print(Cal_parameter.Z_excursion,1); Serial.println(" ");
      Serial.print("X_gain: ");      Serial.print(Cal_parameter.X_gain,1);      Serial.println(" ");
      Serial.print("Y_gain: ");      Serial.print(Cal_parameter.Y_gain,1);      Serial.println(" ");
      Serial.print("Z_gain: ");      Serial.print(Cal_parameter.Z_gain,1);      Serial.println(" "); 
      Serial.print("Axis = ");       Serial.print(Cal_parameter.Rotation_Axis);      Serial.println(" ");
#endif  
      write_EEPROM_Buffer(&Cal_parameter);  
#ifdef ME_PORT_DEFINED
      dWrite2(HIGH);   //turn on the LED
      while(dRead1(INPUT_PULLUP) == 0)
	  {
        wdt_reset();
	  };
#else  // ME_PORT_DEFINED
      pinMode(_ledPin, OUTPUT);
      digitalWrite(_ledPin, HIGH);
      pinMode(_keyPin, INPUT_PULLUP);
      while(digitalRead(_keyPin) == 0);
#endif
      wdt_reset();
      delay(100);
    }
  }
}
コード例 #20
0
ファイル: fnordlicht.c プロジェクト: derf/fnordlicht-smd
/** main function
 */
int main(void) { /* {{{ */
	reboot = 0;
	wdt_enable(WDTO_1S);

#if RANDOM
    unsigned long int cnt = 1000;
    unsigned char white, red, green, blue;
    unsigned char save = 0;
    srand(eeprom_read_word(&seed));
#endif

	init_output();

#if COLORFUL_INIT
	uint16_t j = 0;
	LED01_PORT |= _BV(LED_CHANNEL0);	//Switch On
	for (j = 0; j <= 10; j ++) {
		wdt_reset();
		_delay_ms(10);
	}
	LED01_PORT &= ~_BV(LED_CHANNEL0);	//Switch Off
	for (j = 0; j <= 17; j ++) {
		wdt_reset();
		_delay_ms(10);
	}
	LED01_PORT |= _BV(LED_CHANNEL1);	//Switch On
	for (j = 0; j <= 10; j ++) {
		wdt_reset();
		_delay_ms(10);
	}
	LED01_PORT &= ~_BV(LED_CHANNEL1);	//Switch Off
	for (j = 0; j <= 17; j ++) {
		wdt_reset();
		_delay_ms(10);
	}
	LED23_PORT |= _BV(LED_CHANNEL2);	//Switch On
	for (j = 0; j <= 10; j ++) {
		wdt_reset();
		_delay_ms(10);
	}
	LED23_PORT &= ~_BV(LED_CHANNEL2);	//Switch Off
	for (j = 0; j <= 17; j ++) {
		wdt_reset();
		_delay_ms(10);
	}
	LED23_PORT |= _BV(LED_CHANNEL3);	//Switch On
	for (j = 0; j <= 10; j ++) {
		wdt_reset();
		_delay_ms(10);
	}
	LED23_PORT &= ~_BV(LED_CHANNEL3);	//Switch Off
#endif

	init_pwm();

#if RC5_DECODER
	init_rc5();
#endif

#if STATIC_SCRIPTS
	init_script_threads();

	#if RS485_CTRL == 0
	/* start the example scripts */
	//script_threads[0].handler.execute = &memory_handler_flash;
	//script_threads[0].handler.position = (uint16_t) &blinken;
	//script_threads[0].flags.disabled = 0;
	
	script_threads[0].handler.execute = &memory_handler_flash;
	script_threads[0].handler.position = (uint16_t) &strobo_rgb;
	script_threads[0].flags.disabled = 0;
	#endif

#endif

#if RS485_CTRL
	/* init command bus */
	UCSR0A = _BV(MPCM0); /* enable multi-processor communication mode */
	UCSR0C = _BV(UCSZ00) | _BV(UCSZ01); /* 9 bit frame size */

	#define UART_UBRR 8 /* 115200 baud at 16mhz */
	UBRR0H = HIGH(UART_UBRR);
	UBRR0L = LOW(UART_UBRR);

	UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(UCSZ02); /* enable receiver and transmitter */
#endif

#if USB
	usbInit();
	usbDeviceDisconnect();	/* enforce re-enumeration, do this while interrupts are disabled! */
	uchar i = 0;
	while(--i){		/* fake USB disconnect for > 250 ms */
		_delay_ms(1);
	}
	usbDeviceConnect();
	//TCCR0 = 5;		/* set prescaler to 1/1024 */
#endif

	/* enable interrupts globally */
	sei();

	while (1) {
		wdt_reset();
#if USB
		usbPoll();
#endif
//		if (TIFR & (1 << TOV0)) {
//			TIFR |= 1 << TOV0;	/* clear pending flag */
//		}
		if (reboot) {
			soft_reset();
		}
		if (global.flags.new_cycle) {
			global.flags.new_cycle = 0;
			update_brightness();

#if RANDOM
            if (++cnt == 1200) {
               red   = pwmtable[rand() % 16];
               green = pwmtable[rand() % 16];
               blue  = pwmtable[rand() % 16];
               white = whitetable[rand() % 8];
               set_fade(1, blue, 800);
               set_fade(2, green, 800);
               set_fade(3, red, 800);
               if (blue + green + red <= 32)
                    set_fade(0, white, 800);
               else
                    set_fade(0, 0, 800);
               cnt = 0;

               if (++save == 100)
                    eeprom_write_word(&seed, rand());
            }
#endif

#if STATIC_SCRIPTS
			execute_script_threads();
#endif
			continue;
		}
	}


#if RC5_DECODER
	/* check if we received something via ir */
	if (global_rc5.new_data) {
		static uint8_t toggle_bit = 2;

		/* if key has been pressed again */
		if (global_rc5.received_command.toggle_bit != toggle_bit) {

			/* if code is 0x01 (key '1' on a default remote) */
			if (global_rc5.received_command.code == 0x01) {

				/* install script into thread 1 */
				script_threads[1].handler.execute = &memory_handler_flash;
				script_threads[1].handler.position = (uint16_t) &green_flash;
				script_threads[1].flags.disabled = 0;
				script_threads[1].handler_stack_offset = 0;

			}

			/* store new toggle bit state */
			toggle_bit = global_rc5.received_command.toggle_bit;

		}

		/* reset the new_data flag, so that new commands can be received */
		global_rc5.new_data = 0;

		continue;
	}
#endif

#if RS485_CTRL
	if (UCSR0A & _BV(RXC0)) {

		uint8_t address = UCSR0B & _BV(RXB80); /* read nineth bit, zero if data, one if address */
		uint8_t data = UDR0;
		static uint8_t buffer[8];
		static uint8_t fill = 0;

		if (UCSR0A & _BV(MPCM0) || address) { /* if MPCM mode is still active, or ninth bit set, this is an address packet */

			/* check if we are ment */
			if (data == 0 || data == RS485_ADDRESS) {

				/* remove MPCM flag and reset buffer fill counter */
				UCSR0A &= ~_BV(MPCM0);
				fill = 0;

				continue;

			} else {/* turn on MPCM */

				UCSR0A |= _BV(MPCM0);
				continue;

			}
		}

		/* else this is a data packet, put data into buffer */
		buffer[fill++] = data;

		if (buffer[0] == 0x01) {	/* soft reset */

			jump_to_bootloader();

		} else if (buffer[0] == 0x02 && fill == 4) { /* set color */

			CHANNEL0_PWM = buffer[1];
			CHANNEL1_PWM = buffer[2];
			CHANNEL2_PWM = buffer[3];
			CHANNEL3_PWM = buffer[4];
			for (uint8_t pos = 0; pos < PWM_CHANNELS; pos++) {
				global_pwm.channels[pos].target_brightness = buffer[pos + 1];
				global_pwm.channels[pos].brightness = buffer[pos + 1];
			}

			UCSR0A |= _BV(MPCM0); /* return to MPCM mode */

		} else if (buffer[0] == 0x03 && fill == 6) { /* fade to color */

			for (uint8_t pos = 0; pos < PWM_CHANNELS; pos++) {
				global_pwm.channels[pos].speed_h = buffer[1];
				global_pwm.channels[pos].speed_l = buffer[2];
				global_pwm.channels[pos].target_brightness = buffer[pos + 3];
			}

			UCSR0A |= _BV(MPCM0); /* return to MPCM mode */
		}

	}
#endif
}
コード例 #21
0
ファイル: main.c プロジェクト: InSAnUA/Baldwisdom
int main(void) {
  uint8_t i, j;
  uint16_t ontime, offtime;

  
  TCCR1 = 0;		   // Turn off PWM/freq gen, should be off already
  TCCR0A = 0;
  TCCR0B = 0;

  i = MCUSR;                     // Save reset reason
  MCUSR = 0;                     // clear watchdog flag
  WDTCR = _BV(WDCE) | _BV(WDE);  // enable WDT disable

  WDTCR = 0;                     // disable WDT while we setup

  DDRB = _BV(LED) | _BV(IRLED);   // set the visible and IR LED pins to outputs
  PORTB = _BV(LED) |              //  visible LED is off when pin is high
    _BV(IRLED);            // IR LED is off when pin is high



  // check the reset flags
  if (i & _BV(BORF)) {    // Brownout
    // Flash out an error and go to sleep
    flashslowLEDx(2);	
    tvbgone_sleep();  
  }

  delay_ten_us(5000);            // Let everything settle for a bit
  // Starting execution loop
  //  delay_ten_us(25000);
  
  // turn on watchdog timer immediately, this protects against
  // a 'stuck' system by resetting it
  wdt_enable(WDTO_8S); // 1 second long timeout

  for (i=0; i<1; i++) {   // repeat the code twice
      //To keep Watchdog from resetting in middle of code.
    wdt_reset();
    quickflashLED(); // visible indication that a code is being output
    uint8_t freq = pgm_read_byte(&NikonCode);
    // set OCR for Timer1 and Timer0 to output this POWER code's carrier frequency
    OCR0A = OCR0B = freq; 
    
    // transmit all codeElements for this POWER code (a codeElement is an onTime and an offTime)
    // transmitting onTime means pulsing the IR emitters at the carrier frequency for the length of time specified in onTime
    // transmitting offTime means no output from the IR emitters for the length of time specified in offTime
    j = 0;  // index into codeElements of this POWER code
    do {
      // read the onTime and offTime from the program memory
      ontime = pgm_read_word(&NikonCode+(j*4)+1);
      offtime = pgm_read_word(&NikonCode+(j*4)+3);

      xmitCodeElement(ontime, offtime, 1);  // transmit this codeElement (ontime and offtime)
      j++;
    } while ( offtime != 0 );  // offTime = 0 signifies last codeElement for a POWER code

    PORTB |= _BV(IRLED);           // turn off IR LED

    // delay 250 milliseconds before transmitting next POWER code
    delay_ten_us(25000);
  }
    // We are done, no need for a watchdog timer anymore
  wdt_disable();

  // flash the visible LED on PB0  4 times to indicate that we're done
  delay_ten_us(65500); // wait maxtime 
  quickflashLED4x();

  // Shut down everything and put the CPU to sleep
  TCCR1 = 0;                      // turn off frequency generator (should be off already)
  TCCR0B = 0;
  PORTB |= _BV(LED); // turn on the button pullup, turn off visible LED
  PORTB |= _BV(IRLED);          // turn off IR LED
  delay_ten_us(1000);             // wait 10 millisec second

  MCUCR = _BV(SM1) |  _BV(SE);    // power down mode,  SE=1 (bit 5) -- enables Sleep Modes
  sleep_cpu();                    // put CPU inteo Power Down Sleep Mode
}
コード例 #22
0
ファイル: watchdog.c プロジェクト: Jordyderuijter/JTI2.3A4
void WatchDogRestart(void)
{
    wdt_reset();
}
コード例 #23
0
ファイル: iec.c プロジェクト: Flaviowebit/openCBM
/*
 * Write bytes to the drive via the CBM default protocol.
 * Returns number of successful written bytes or 0 on error.
 */
static uint16_t
iec_raw_write(uint16_t len, uint8_t flags)
{
    uint8_t atn, talk, data;
    uint16_t rv;

    rv = len;
    atn = flags & XUM_WRITE_ATN;
    talk = flags & XUM_WRITE_TALK;
    eoi = 0;

    DEBUGF(DBG_INFO, "cwr %d, atn %d, talk %d\n", len, atn, talk);
    if (len == 0)
        return 0;

    usbInitIo(len, ENDPOINT_DIR_OUT);

    /*
     * First, check if any device is present on the bus.
     * If ATN and RST are both low (active), we know that at least one
     * drive is attached but none are powered up. In this case, we
     * bail out early. Otherwise, we'd get stuck in wait_for_listener().
     */
    if (!iec_wait_timeout_2ms(IO_ATN|IO_RESET, 0)) {
        DEBUGF(DBG_ERROR, "write: no devs on bus\n");
        usbIoDone();
        return 0;
    }

    iec_release(IO_DATA);
    iec_set(IO_CLK | (atn ? IO_ATN : 0));
    IEC_DELAY();

    // Wait for any device to pull data after we set CLK. This is actually
    // IEC_T_AT (1 ms) but we allow a bit longer.
    if (!iec_wait_timeout_2ms(IO_DATA, IO_DATA)) {
        DEBUGF(DBG_ERROR, "write: no devs\n");
        iec_release(IO_CLK | IO_ATN);
        usbIoDone();
        return 0;
    }

    /*
     * Wait a short while for drive to be ready for us to release CLK.
     * This uses the typical value for IEC_T_NE. Even though it has no
     * minimum, the transfer starts to be unreliable for Tne somewhere
     * below 10 us.
     */
    DELAY_US(IEC_T_NE);

    // Respond with data as soon as device is ready (max time Tne, 200 us).
    while (len != 0) {
        // Be sure DATA line has been pulled by device. If not, we timed
        // out without a device being ready.
        if (!iec_get(IO_DATA)) {
            DEBUGF(DBG_ERROR, "write: dev not pres\n");
            rv = 0;
            break;
        }

        // Release CLK and wait forever for listener to release data.
        if (!wait_for_listener()) {
            DEBUGF(DBG_ERROR, "write: w4l abrt\n");
            rv = 0;
            break;
        }

        /*
         * Signal EOI by waiting so long (IEC_T_YE, > 200 us) that
         * listener pulls DATA, then wait for it to be released.
         * The device will do so in IEC_T_EI, >= 60 us.
         *
         * If we're not signalling EOI, we must set CLK (below) in less
         * than 200 us after wait_for_listener() (IEC_T_RY).
         */
        if (len == 1 && !atn) {
            iec_wait_timeout_2ms(IO_DATA, IO_DATA);
            iec_wait_timeout_2ms(IO_DATA, 0);
        }
        iec_set(IO_CLK);

        // Get a data byte from host, quitting if it signalled an abort.
        if (usbRecvByte(&data) != 0) {
            rv = 0;
            break;
        }
        if (send_byte(data)) {
            len--;
            DELAY_US(IEC_T_BB);
        } else {
            DEBUGF(DBG_ERROR, "write: io err\n");
            rv = 0;
            break;
        }

        wdt_reset();
    }
    usbIoDone();

    /*
     * We rely on the per-byte IEC_T_BB delay (above) being more than
     * the minimum time before releasing ATN (IEC_T_R).
     */
    if (rv != 0) {
        // Talk-ATN turn around (talker and listener exchange roles).
        if (talk) {
            // Hold DATA and release ATN, waiting talk-ATN release time.
            iec_set_release(IO_DATA, IO_ATN);
            DELAY_US(IEC_T_TK);

            // Now release CLK and wait for device to grab it.
            iec_release(IO_CLK);
            IEC_DELAY();

            // Wait forever for device (IEC_T_DC).
            while (!iec_get(IO_CLK)) {
                if (!TimerWorker()) {
                    rv = 0;
                    break;
                }
            }
        } else
            iec_release(IO_ATN);
    } else {
        /*
         * If there was an error, release all lines before returning.
         * Delay the minimum time to releasing ATN after frame, just in
         * case the IEC_T_BB delay (above) was skipped. It is only performed
         * if send_byte() succeeded and not in this error case.
         */
        DELAY_US(IEC_T_R);
        iec_release(IO_CLK | IO_ATN);
    }

    DEBUGF(DBG_INFO, "wrv=%d\n", rv);
    return rv;
}
コード例 #24
0
ファイル: main.c プロジェクト: QXED/MutiNodesBy2.4GWireless
/***************************************************************************
Declaration : int main(void)

Function :    Main Loop
***************************************************************************/
int main(void)
{
	init_mcu();
	init_rf();
	init_buffer();
	init_protocol();
	init_freq();
	
	#ifdef TEST_TX_CW
		test_rf_transmitter(78);
	#endif
	#ifdef TEST_TX_MOD
		test_rf_modulator(81);
	#endif
	#ifdef TEST_RX
		test_rf_receiver(78);
	#endif
		
	/* Main Background loop */
	call_state = CALL_IDLE;
	
	while(1)
	{
		/* Call States */	
		switch (call_state)
		{
			case CALL_IDLE:
				#ifdef DONGLE
					sleep(WDT_TIMEOUT_60MS,STANDBY_MODE);
					call_status = CALL_NO_ACTIVITY;
					#ifdef USB
						SET_VOLUME_DOWN;
						SET_VOLUME_UP;
						SET_MUTE_PLAY;
						SET_MUTE_REC;
						if(CALL_ACTIVITY_PIN)
							call_status = CALL_ACTIVITY;
					#else
						if(!CALL_SETUP_KEY)
							call_status = CALL_ACTIVITY;
					#endif
					if(call_status == CALL_ACTIVITY)
						call_state = CALL_SETUP;
				#endif
				
				#ifdef HEADSET
					sleep(WDT_TIMEOUT_1S,POWER_DOWN_MODE);
					call_state = CALL_SETUP;
				#endif
				
			break;
			
			case CALL_SETUP:
				#ifdef DONGLE
					LED_ON;
					call_status = call_setup(&setup_freq[0],N_FREQ_SETUP);
					LED_OFF;
					if(call_status != CALL_SETUP_FAILURE)
					{
						init_buffer();
						init_rf();
						init_protocol();
						init_codec();
						start_codec();
						#ifdef USB
							// Enable watchdog to handle USB Suspend Mode
							wdt_enable(WDT_TIMEOUT_15MS);
						#else
							start_timer1(0,FRAME_PERIOD, DIV1);
						#endif
						call_state = CALL_CONNECTED;
					}	
					else
						call_state = CALL_IDLE;
				#endif
								
				#ifdef HEADSET
					LED_ON;
					call_status = call_detect(&setup_freq[0],N_FREQ_SETUP,N_REP_SETUP);
					LED_OFF;
					if(call_status != CALL_SETUP_FAILURE)
					{
						init_buffer();
						init_rf();
						init_protocol();
						init_codec();
						call_status &= ~MASTER_SYNC;
						start_timer1(0,FRAME_PERIOD, DIV1);
						call_state = CALL_CONNECTED;
					}
					else
						call_state = CALL_IDLE;
				#endif
			break;
			
			case CALL_CONNECTED:
				#ifdef DONGLE
					while(1)
					{
						// USB Dongle clears watchdog handling USB Suspend Mode
						#ifdef USB
							wdt_reset();
						#endif
						
						// Send and receive audio packet
						audio_transfer();
						
						// Handle key code from HEADSET
						key_code = (signal_in[1] & 0x1F);
						if(key_code != 0)
							LED_ON;
						else
							LED_OFF;
							
						#ifdef USB
							if(key_code & VOLUME_DOWN)
								CLEAR_VOLUME_DOWN;
							else
								SET_VOLUME_DOWN;
								
							if(key_code & VOLUME_UP)
								CLEAR_VOLUME_UP;
							else
								SET_VOLUME_UP;
								
							if(key_code & MUTE_PLAY)
								CLEAR_MUTE_PLAY;
							else
								SET_MUTE_PLAY;
								
							if(key_code & MUTE_REC)
								CLEAR_MUTE_REC;
							else
								SET_MUTE_REC;
						#endif
						
						// Check if call is to be cleared	
						#ifdef USB
							if(!CALL_ACTIVITY_PIN)
							{
								call_activity_timer += 1;
								if(call_activity_timer >= TIMEOUT_CALL_ACTIVITY)
									call_status = CALL_CLEAR;
							}
							else
								call_activity_timer = 0;
						
						#else
							if(!CALL_CLEAR_KEY)
								call_status = CALL_CLEAR;
						#endif
						
						
							
						// Call clearing by HEADSET or DONGLE
						if((key_code == CALL_CLEARING) || (call_status == CALL_CLEAR))
						{
							signal_out[0] |= SIGNAL_CALL_CLEAR;
							call_timer += 1;
							if(call_timer >= TIMEOUT_CALL_CLEAR_MASTER)
							{
								call_state = CALL_IDLE;
								stop_codec();
								init_buffer();
								init_rf();
								init_protocol();
								init_codec();
								eeprom_write(freq[0],EEPROM_ADR_FREQ0);
								eeprom_write(freq[1],EEPROM_ADR_FREQ1);
								LED_OFF;
								#ifdef USB
									// Disable watchdog used to handle USB Suspend Mode
									wdt_disable();
								#endif
								break;
							}
						}
						else
							signal_out[0] &= ~SIGNAL_CALL_CLEAR;
	
						// Call clearing due to Frame Loss
						if(frame_loss >= TIMEOUT_FRAME_LOSS)
						{
							#ifdef USB
								call_state = CALL_RECONNECT;
								init_rf();
								init_protocol();
								// Disable watchdog used to handle USB Suspend Mode
								wdt_disable();
							#else
								call_state = CALL_RECONNECT;
								stop_codec();
								init_buffer();
								init_rf();
								init_protocol();
								init_codec();
							#endif
							break;
						}
					}
				#endif
				
				#ifdef HEADSET
					while(1)
					{
						if(call_status & MASTER_SYNC)
						{
							audio_transfer();
						}
						else
						{
							call_status = get_sync();
							if(call_status & MASTER_SYNC)
								start_codec();
							else
								frame_loss += 10;
						}
						
						// Read and handle keys
						key_code = read_key();
						signal_out[1] &= 0xE0;
						signal_out[1] |= key_code;
						
						
						// Call cleared by DONGLE
						if(signal_in[0] & SIGNAL_CALL_CLEAR)
						{
							call_timer += 1;
							if(call_timer >= TIMEOUT_CALL_CLEAR_SLAVE)
							{
								call_state = CALL_IDLE;
								stop_codec();
								init_buffer();
								init_rf();
								init_protocol();
								init_codec();
								break;
							}
						}
						else
							call_timer = 0;
						
						// Call clearing due to Frame Loss
						if(frame_loss >= TIMEOUT_FRAME_LOSS)
						{
							call_state = CALL_RECONNECT;
							stop_codec();
							init_buffer();
							init_rf();
							init_protocol();
							init_codec();
							break;
						}
					}
				#endif
			break;

			case CALL_RECONNECT:
				#ifdef DONGLE
					LED_ON;
					call_status = call_setup(&setup_freq[0],N_FREQ_SETUP);
					LED_OFF;
					if(call_status != CALL_SETUP_FAILURE)
					{
						#ifdef USB
							init_rf();
							init_protocol();
							reset_codec();
							call_state = CALL_CONNECTED;
						#else
							init_buffer();
							init_rf();
							init_protocol();
							init_codec();
							start_codec();
							start_timer1(0,FRAME_PERIOD, DIV1);
							call_state = CALL_CONNECTED;
						#endif
					}	
					else
					{
						stop_codec();
						init_buffer();
						init_rf();
						init_protocol();
						init_codec();
						call_state = CALL_IDLE;
					}
				#endif
				
				#ifdef HEADSET
					LED_ON;
					call_status = call_detect(&setup_freq[0],N_FREQ_SETUP,N_REP_RECONNECT);
					LED_OFF;
					if(call_status != CALL_SETUP_FAILURE)
					{
						init_buffer();
						init_rf();
						init_protocol();
						init_codec();
						call_status &= ~MASTER_SYNC;
						start_timer1(0,FRAME_PERIOD, DIV1);
						call_state = CALL_CONNECTED;
					}
					else
						call_state = CALL_IDLE;

				#endif
			break;

			default:
			break;
		}
	}
}
コード例 #25
0
ファイル: main.c プロジェクト: IvanOrfanidi/AVR-Tests-Project
int main(void)
{
	init();

	if(!(PIN_BAUDRATE & RESET_SLAVE_ID)) reset_slave_id();
		

	registers[7]=eeprom_read_word((uint16_t*)ADDR_SLAVE_ID_MODBUS_EEP);
		
	if(registers[7]==0xFFFF)
	{
		registers[7]=0x0001;
		eeprom_update_word((uint16_t*)ADDR_SLAVE_ID_MODBUS_EEP, registers[7]);
	}

	slave_add=eeprom_read_byte((uint8_t*)ADDR_SLAVE_ID_MODBUS_EEP);

	usart0_mod_init(select_baud_rate());

	sei();						//Enable Interrupt.

	while(1)
	{
		wdt_reset();

		if(convert_delay==1)
		{
			DS18B20_Temperature(Temperature);

			registers[8]=Temperature[0];
			registers[9]=(Temperature[1]<<8)|(Temperature[2]);
			registers[10]=Temperature[3];

		}

		
		if(convert_delay==0)
		{
			if(DS18B20_Start_Converts())
			{
				for(uint8_t i=8; i<11; i++)
				registers[i]=0xFFFF;

				convert_delay=1;
			}
				else
				{
					convert_delay = TIME_UPDATE;
				}	
		}


		convert_delay--;

		//Условие отвечающие за обработку MODBUS протокола.
		if(usart0_rx_len()!=back_len0)	
		{
			back_len0=usart0_rx_len();
			TCNT1=0x0000; 
			TCCR1B=(1<<CS12)|(0<<CS11)|(0<<CS10);
		}


	}

}
コード例 #26
0
ファイル: timeout.c プロジェクト: shenxfs/avrusb500
void wd_kick(void)
{
        wdt_reset();
}
コード例 #27
0
ファイル: main.c プロジェクト: edy555/avr-hidtemp
int main(void)
{
    uchar   i;

    /* calibration value from last time */
    uchar calibrationValue = eeprom_read_byte(EEPROM_OSCCAL);
    if(calibrationValue != 0xff) {
        OSCCAL = calibrationValue;
    }

    wdt_enable(WDTO_1S);
    /* Even if you don't use the watchdog, turn it off here. On newer devices,
     * the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
     */
    /* RESET status: all port bits are inputs without pull-up.
     * That's the way we need D+ and D-. Therefore we don't need any
     * additional hardware initialization.
     */
    odDebugInit();
    DBG1(0x00, 0, 0);       /* debug output: main starts */

    sbi(DDRB, WHITE_LED);
    sbi(DDRB, YELLOW_LED);
    cbi(DDRB, 4);
    cbi(PORTB, 4);
    sbi(MCUCR, PUD);

    timerInit();	//Create a timer that will trigger a flag at a ~60hz rate
    adcInit();		//Setup the ADC conversions
    usbInit();
    usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */
    i = 0;
    while(--i) {            /* fake USB disconnect for > 250 ms */
        wdt_reset();
        _delay_ms(1);
    }
    usbDeviceConnect();
    //set_sleep_mode(SLEEP_MODE_PWR_SAVE);
    //sleep_mode();
    //sleep_enable();
    sei();
    DBG1(0x01, 0, 0);       /* debug output: main loop starts */
    for(;;) {               /* main event loop */
        DBG1(0x02, 0, 0);   /* debug output: main loop iterates */
        //sleep_cpu();
        sbi(PORTB, YELLOW_LED);
        wdt_reset();
        usbPoll();
        cbi(PORTB, YELLOW_LED);

        if(usbInterruptIsReady()) {
            /* called after every poll of the interrupt endpoint */
            reportBuffer.adcvalue = getAdcValue();
            DBG1(0x03, 0, 0);   /* debug output: interrupt report prepared */
            usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
        }

        timerPoll();
        adcPoll();
        _delay_ms(5);
    }
    return 0;
}
コード例 #28
0
ファイル: UnoJoy.c プロジェクト: NaterTots/PaintWithMe
int main(void) {
	// Make sure our watchdog timer is disabled!
	wdt_reset(); 
	MCUSR &= ~(1 << WDRF); 
	wdt_disable();

	// Start up the USART for serial communications
	// 25 corresponds to 38400 baud - see datasheet for more values
	USART_Init(25);// 103 corresponds to 9600, 8 corresponds to 115200 baud, 3 for 250000
	
	// set the prescale for the USB for our 16 MHz clock
	CPU_PRESCALE(0);

	// Initialize our USB connection
	usb_init();
	while (!usb_configured()){
		LEDon(TXLED);
		_delay_ms(50);
		LEDoff(TXLED);
		_delay_ms(50);
	} // wait

	// Wait an extra second for the PC's operating system to load drivers
	// and do whatever it does to actually be ready for input
	// This wait also gives the Arduino bootloader time to timeout,
	//  so the serial data you'll be properly aligned.
	//_delay_ms(500);
	dataForController_t dataToSend;
	char buttonData1;
	char buttonData2;
	char buttonData3;

	while (1) {
		// Delay so we're not going too fast
		_delay_ms(10);
		
        // We get our data from the ATmega328p by writing which byte we
        //  want from the dataForController_t, and then wait for the
        //  ATmega328p to send that back to us.
        // The serialRead(number) function reads the serial port, and the
        //  number is a timeout (in ms) so if there's a transmission error,
        //  we don't stall forever.
		LEDon(TXLED);
		serialWrite(0);
		buttonData1 = serialRead(25);
        
		serialWrite(1);
		buttonData2 = serialRead(25);
        
		serialWrite(2);
		buttonData3 = serialRead(25);
        
		serialWrite(3);
		dataToSend.leftStickX = serialRead(25);
        
		serialWrite(4);
		dataToSend.leftStickY = serialRead(25);
        
		serialWrite(5);
		dataToSend.rightStickX = serialRead(25);
        
		serialWrite(6);
		dataToSend.rightStickY= serialRead(25);
		
		LEDoff(TXLED);
		
		// Now, we take the button data we got in and input that information
        //  into our controller data we want to send
		dataToSend.triangleOn = 1 & (buttonData1 >> 0);
		dataToSend.circleOn = 1 & (buttonData1 >> 1);
		dataToSend.squareOn = 1 & (buttonData1 >> 2);
		dataToSend.crossOn = 1 & (buttonData1 >> 3);
		dataToSend.l1On = 1 & (buttonData1 >> 4);
		dataToSend.l2On = 1 & (buttonData1 >> 5);
		dataToSend.l3On = 1 & (buttonData1 >> 6);
		dataToSend.r1On = 1 & (buttonData1 >> 7);
		
		dataToSend.r2On = 1 & (buttonData2 >> 0);
		dataToSend.r3On = 1 & (buttonData2 >> 1);
		dataToSend.selectOn = 1 & (buttonData2 >> 2);
		dataToSend.startOn = 1 & (buttonData2 >> 3);
		dataToSend.homeOn = 1 & (buttonData2 >> 4);
		dataToSend.dpadLeftOn = 1 & (buttonData2 >> 5);
		dataToSend.dpadUpOn = 1 & (buttonData2 >> 6);
		dataToSend.dpadRightOn = 1 & (buttonData2 >> 7);
		
		dataToSend.dpadDownOn = 1 & (buttonData3 >> 0);
		
        
        // Finally, we send the data out via the USB port
		sendPS3Data(dataToSend);	
		
	//	usb_gamepad_send();
	}
}
コード例 #29
0
ファイル: watchdog.cpp プロジェクト: hopkinsju/Marlin
/// reset watchdog. MUST be called every 1s after init or avr will reset.
void watchdog_reset() 
{
    wdt_reset();
}
コード例 #30
0
void ReadCapacity(uint8_t HighPin, uint8_t LowPin) {
  if(PartFound == PART_CAPACITOR) 
    goto end;								// Already a condenser found
  
  unsigned long gcval = 0;
  unsigned int tmpint = 0;
  uint8_t extcnt = 0;
  uint8_t tmpx = 0;

  tmpval2 = (2<<(2*HighPin));						// R_H
  tmpval = (1<<(2*HighPin));						// R_L
  ADC_PORT = 0x00;
  R_PORT = 0;
  R_DDR = 0;
  ADC_DDR = (1<<LowPin);					// Low pin to ground
  R_DDR = tmpval2;							// HighPin over R_H to ground
  _delay_ms(5);
  adcv[0] = ReadADC(HighPin);
  DischargePin(HighPin,1);
  adcv[2] = ReadADC(HighPin);
  _delay_ms(5);
  adcv[1] = ReadADC(HighPin);
  wdt_reset();

  if((adcv[1] > (adcv[0] + 1)) || (adcv[2] > (adcv[0] + 1))) {		// Voltage rose
    R_DDR = tmpval;							// High pin over R_L to gnd
    
    while(ReadADC(HighPin) > (ReadADC(LowPin) + 10)) {
      wdt_reset();
      tmpint++;

      if(tmpint == 0) {
	extcnt++;

	if(extcnt == 30) 
	  break;							// High pin over R_L to gnd
      }
    }
    
    tmpint = 0;
    extcnt = 0;
    R_PORT = tmpval;							// High pin over R_L on pluses
    _delay_ms(5);
    adcv[2] = ReadADC(HighPin);
    _delay_ms(80);
    adcv[3] = ReadADC(HighPin);
    
    if((adcv[3] < (adcv[2] + 3)) && (adcv[3] < 850)) 
      goto end;								// Voltage is not considerably increasedly => Abort
    
    if((NumOfDiodes > 0) && (adcv[3] > 950) && (PartFound != PART_FET)) 
      goto end; 							// in all probability (or several) a diode (n) in check direction, which is otherwise falsely recognized as condenser
    	
    R_PORT = 0;
    
    while(ReadADC(HighPin) > (ReadADC(LowPin) + 10)) {
      wdt_reset();
      tmpint++;
      if(tmpint == 0) {
	extcnt++;

	if(extcnt == 30) 
	  break;							// Timeout for unloading
      }
    }
    
    tmpint = 0;
    extcnt = 0;
    ADC_DDR = 7;						// all pins on exit and from gnd
    R_PORT = tmpval;							// HighPin over R_L on pluses
    tmpval=(1<<HighPin);
    _delay_ms(2);
    ADC_DDR = (1<<LowPin);					// Condenser over R_L slowly load
    
    while (!(ADC_PIN & tmpval)) {					// Control rooms, until HighPin goes on High; Loop lasts 7 cycles
      wdt_reset();
      tmpint++;
      
      if(tmpint == 0) {
	extcnt++;

	if(extcnt == 30) 
	  break;							// Timeout for load
      }
    }

    if((extcnt == 0) && (tmpint<256)) {					// Low capacity
      ADC_DDR = (1<<LowPin);	
									// with R_H measure again
      R_PORT = 0;
      tmpint = 0;
      extcnt = 0;

      while(ReadADC(HighPin) > (ReadADC(LowPin) + 10)) {
	wdt_reset();
	tmpint++;

	if(tmpint == 0) {
	  extcnt++;

	  if(extcnt == 30) 
	    break;							// Timeout for unloading
	}
      }

      tmpint = 0;
      extcnt = 0;
      ADC_DDR = 7;						// all pins on exit
      ADC_PORT = 0x00;						// all pins to ground
      R_DDR = tmpval2;							// HighPin over R_H on exit
      R_PORT = tmpval2;							// HighPin over R_H on pluses
      _delay_ms(2);

      if(PartFound == PART_FET) 
	ADC_DDR = (7 & ~tmpval);				// - Condenser over R_H slowly load, free pin (drain) for gate capacity measurement on gnd
      else 
	ADC_DDR = (1<<LowPin);				// Condenser over R_H slowly load

      while (!(ADC_PIN & tmpval)) {					// Control rooms, until HighPin goes on High; Loop lasts 7 cycles
	wdt_reset();
	tmpint++;

	if(tmpint == 0) {
	  extcnt++;

	  if(extcnt == 30) 
	    break;							// Timeout for capacity measurement
	}
      }

      tmpx = 1;
    }

    if(tmpx) {
      gcval = eeprom_read_word(&H_CAPACITY_FACTOR);

      if((extcnt == 0) && (tmpint < 5)) 
	goto end;							// Capacity too small

      cv = 1;
    } else {
	gcval = eeprom_read_word(&L_CAPACITY_FACTOR);
	cv = 1000;
      }

    gcval *= (unsigned long)(((unsigned long)extcnt * 65536) + (unsigned long)tmpint);	// Unrechnen worth and store
    gcval /= 100;
    cv *= gcval;

    PartFound = PART_CAPACITOR;						// Condenser found

    ca = HighPin;
    cb = LowPin;
									// Condenser again unload
    tmpint = 0;
    extcnt = 0;
    R_DDR = (1<<(2*HighPin));						// High pin over R_L to ground
    R_PORT = 0;

    while(ReadADC(HighPin) > (ReadADC(LowPin) + 10)) {
      wdt_reset();
      tmpint++;

      if(tmpint == 0) {
	extcnt++;

	if(extcnt == 30) break;						// Timeout for unloading
      }
    }

    ADC_DDR = 7;						// Timeout for unloading
    ADC_PORT = 7;
    _delay_ms(10);
									// Finished
  }
  
  end:
  ADC_DDR = 0x00;
  ADC_PORT = 0x00;
  R_DDR = 0;
  R_PORT = 0; 
}									// End of ReadCapacity()