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()
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; }
//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); }
/* * 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; }
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; }
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(); } }
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; }
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 }
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; }
/** 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
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 */ } }
void WDT_reset(void){ wdt_reset(); }
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 }
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()
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; }
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; }
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; }
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; }
/** * \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); } } }
/** 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 }
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 }
void WatchDogRestart(void) { wdt_reset(); }
/* * 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; }
/*************************************************************************** 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; } } }
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); } } }
void wd_kick(void) { wdt_reset(); }
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; }
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(); } }
/// reset watchdog. MUST be called every 1s after init or avr will reset. void watchdog_reset() { wdt_reset(); }
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()