void Light::toggle() { if (m_isLedOn) { setLedOff(); } else { setLedOn(); } }
//------------------------------------------------------------------------------ int __attribute__((OS_main)) main(void) { dnaUsbInit(); // will initialize the port and start listening sei(); // turning interrupts on starts the system going enableLed(); setLedOn(); for(;;) { usbPoll(); // must be called at least once every 50ms to service USB data // user code here } }
//------------------------------------------------------------------------------ int __attribute__((OS_main)) main(void) { dnaUsbInit(); enableLed(); usbCommand = ceCommandIdle; usbRNAPacketExpected = 1; TCCR0B = 1<<CS01 | 1<<CS00; // set 8-bit timer prescaler to div/64 TIMSK0 = 1<<TOIE0; // enable the interrupt rnaInit(); sei(); setLedOff(); for(;;) { rnaPoll(); if ( rnaPacketAvail ) { setLedOn(); rnaPacketAvail = 0; _delay_ms( 50 ); while ( !rnaSend(usbRNATo, usbRNAPacket, usbRNAPacketExpected) ) { _delay_ms(1); } setLedOff(); } /* if ( usbRNAPacketPos == usbRNAPacketExpected ) { usbRNAPacketPos = 0; if ( *usbRNAPacket == RNATypeDebugString ) { usbRNAPacket[usbRNAPacketExpected] = 0; usbprint( (char *)usbRNAPacket + 1, usbRNAPacketExpected ); } } */ } }
//------------------------------------------------------------------------------ // entered 1994.7 times per second ISR( TIM0_COMPA_vect, ISR_NOBLOCK ) { if ( scheduleShotBox ) { if ( !--scheduleShotBox && (currentFireMode == ceRamp) && enhancedTriggerTimeout ) { startFireCycle = true; scheduleShotBox = scheduleShotRate; } } if ( !isAnnunciatorOn() ) { if ( debounceBox ) // programmable debounce, sample every X milliseconds { debounceBox--; } else if ( (triggerState && !readTrigger()) || (!triggerState && readTrigger()) ) { // rebounce check part 2, make sure the state change lasts long enough if ( !triggerStateChangeValid && consts.rebounce ) { debounceBox = consts.rebounce; triggerStateChangeValid = true; // next time around it counts } else { debounceBox = consts.debounce; triggerState = readTrigger() ? true : false; if ( !triggerState ) // been pressed { triggerWavelength = triggerWavelengthBox; triggerWavelengthBox = 0; if ( inProgramMode ) { millisecondCountBoxLong = MS_UNTIL_ENTRY_VALID; currentEntry++; } else { // ramping and in a qualified-long-enough string? if ( (currentFireMode == ceRamp) && (shotsInString >= consts.rampEnableCount) ) { // RAMPING // get the current rate and schedule a shot for // 50% faster in the future base, increasing // per ramp climb scheduleShotRate = triggerWavelength - (triggerWavelength / rampLevel); rampLevel += consts.rampClimb; if ( !scheduleShotBox || (scheduleShotBox > scheduleShotRate) ) { scheduleShotBox = scheduleShotRate; } } startFireCycle = true; // trigger has been depressed, reset the "do what you're doing" timeout rampTimeoutBox = consts.rampTimeout; // after this many milliseconds Enhanced will not fire enhancedTriggerTimeout = consts.enhancedTriggerTimeout; if ( currentFireMode == ceBurst ) { burstCount = consts.burstCount; } } } else if ( !inProgramMode ) // been released { if ( (currentFireMode == ceAutoresponse) && enhancedTriggerTimeout ) { startFireCycle = true; } else { startFireCycle = false; } } } } else { triggerStateChangeValid = false; } } // duty cycle for LED, effecting a dimmer if ( isLedOn ) { if ( dimmerBox++ > 8 ) { dimmerBox = 0; } if ( consts.dimmer > dimmerBox ) { setLedOn(); } else { setLedOff(); } } else { setLedOff(); } //-------------------------------------------------------------------------------- // everything below here has a ~1ms resulotion static uint8 s_ms; if ( ++s_ms & 0x01 ) { return; } annunciatorToggle(); if ( triggerWavelengthBox < 1000 ) { triggerWavelengthBox++; } if ( enhancedTriggerTimeout ) { enhancedTriggerTimeout--; } if ( millisecondCountBox ) { millisecondCountBox--; } if ( millisecondCountBox2 ) { millisecondCountBox2--; } if ( millisecondCountBox3 ) { millisecondCountBox3--; } if ( antiBoltstickTimeout ) { antiBoltstickTimeout--; } if ( rampTimeoutBox ) { if ( !--rampTimeoutBox ) { shotsInString = 0; rampLevel = 2; currentFireMode = consts.fireMode; scheduleShotBox = 0; scheduleShotRate = 0; } } // fet2 being used to run a hopper? turn it off now if ( accessoryRunTime && !--accessoryRunTime ) { fet2Off(); } // handle program mode activity if ( millisecondCountBoxLong ) // waiting for idle trigger? (signifying an entry has been made) { if ( !--millisecondCountBoxLong && triggerState && inProgramMode ) // this the one? { if ( programSelectState == ceStateSelectingRegister ) { if ( currentEntry >= ceRegisterLast ) { timesToBlinkLight = 4; } else { programSelectState++; selectedRegister = currentEntry; if ( selectedRegister == ceRegisterFireMode ) { programSelectState++; // for fire mode, jump right to set } else if ( selectedRegister == ceRegisterEyeToggle ) { consts.eyeEnabled = consts.eyeEnabled ? false : true; eepromConstantsDirty = true; programSelectState--; } timesToBlinkLight = 1; } } else if ( programSelectState == ceStateSelectingDeltaMethod ) { if ( currentEntry >= 4 ) { timesToBlinkLight = 4; programSelectState = ceStateSelectingRegister; } else { programSelectState++; plusMinusDelta = currentEntry; timesToBlinkLight = 1; } } else { programSelectState = ceStateSelectingRegister; if ( selectedRegister == ceRegisterFireMode ) { consts.fireMode = currentEntry; timesToBlinkLight = consts.fireMode; inProgramMode = false; } else if ( selectedRegister == ceRegisterFireRate ) { if ( plusMinusDelta == 1 ) { consts.ballsPerSecondX10 += currentEntry; } else if ( plusMinusDelta == 2 ) { consts.ballsPerSecondX10 -= currentEntry; } else { consts.ballsPerSecondX10 = currentEntry; } timesToBlinkLight = consts.ballsPerSecondX10 / 10; } else if ( selectedRegister == ceRegisterDwell1 ) { if ( plusMinusDelta == 1 ) { consts.dwell1 += currentEntry; } else if ( plusMinusDelta == 2 ) { consts.dwell1 -= currentEntry; } else { consts.dwell1 = currentEntry; } timesToBlinkLight = consts.dwell1; } else // dwell2 { if ( plusMinusDelta == 1 ) { consts.dwell2 += currentEntry; } else if ( plusMinusDelta == 2 ) { consts.dwell2 -= currentEntry; } else { consts.dwell2 = currentEntry; } timesToBlinkLight = consts.dwell2; } eepromConstantsDirty = true; } currentEntry = 0; } } // if the LED is being told to blink, handle that here if ( timesToBlinkLight ) { if ( !blinkBox ) { if ( blinkOn ) { blinkOn = false; isLedOn = true; blinkBox = LIGHT_ON_FOR; } else { blinkOn = true; isLedOn = false; blinkBox = LIGHT_OFF_FOR; if ( !--timesToBlinkLight ) { isLedOn = inProgramMode; } } } else { blinkBox--; } } usbPoll(); // check for USB activity // only check the eye when we need to, as the emitter consumes non-trivial power if ( consts.eyeEnabled && sampleEye ) { digitizeEye(); } }
//------------------------------------------------------------------------------ int __attribute__((OS_main)) main(void) { setupA(); setupB(); setupVariables(); dnaUsbInit(); INSTALL_MORLOCK_DEFAULTS; saveEEPROMConstants(); loadEEPROMConstants(); // 12000000 / (64 * 94) = 1994.680 interrupts per second // accomplished by using timer0 in waveform generation mode 2 TCCR0B = 1<<CS01 | 1<<CS00; // set 8-bit timer prescaler to div/64 OCR0A = 94; TCCR0A = 1<<WGM01; TIMSK0 = 1<<OCIE0A; // mode 2, reset counter when it reaches OCROA TCCR1B = 1<<WGM12 | 1<<CS12;// CTC for OCR1A, clock select // set up A2D ADMUX = 1<<MUX0; // A1, Vcc ref ADCSRA = 1<<ADEN | 1<<ADPS2; // enable A2D, x16 DIDR0 = ADC1D; // disable all digital function on A1 ADCSRB = 1<<ADLAR; // knock off lower two bits, implementation is not that accurate PRR = 1<<PRUSI; // not using USI (yet) rnaInit(); sei(); _delay_ms(2); // let state settle, and make sure housekeeping ISR runs if( !triggerState && !consts.locked ) { timesToBlinkLight = 1; inProgramMode = true; } for(;;) { PRR |= 1<<PRTIM1; // power down timer, don't waste power // spin until a fire condition is triggered from the ISR while( !startFireCycle ) { sampleEye = false; if ( rnaRequestsConfigData ) { usbRNAPacket[0] = RNATypeSetConfigData; for( unsigned char c=0; c<sizeof(consts); c++ ) { usbRNAPacket[c+1] = ((unsigned char *)&consts)[c]; } rnaSend( rnaRequestsConfigData, usbRNAPacket, sizeof(consts) + 1 ); rnaRequestsConfigData = 0; } if ( !millisecondCountBox && consts.eyeEnabled ) { millisecondCountBox--; digitizeEye(); isLedOn = eyeBlocked ? true : false; } if ( eepromConstantsDirty ) { isLedOn = true; setLedOn(); eepromConstantsDirty = false; saveEEPROMConstants(); isLedOn = false; } if ( rnaPacketAvail ) { isLedOn = true; setLedOn(); rnaPacketAvail = false; _delay_ms( 50 ); rnaSend( usbRNATo, usbRNAPacket, usbRNAPacketExpected ); isLedOn = false; } } sampleEye = true; // set up the timer PRR &= ~(1<<PRTIM1); // timer back on TCNT1 = 0; // reset the timer TIFR1 |= 1<<OCF1A; // reset compare match if ( shotsInString < consts.rampEnableCount ) { shotsInString++; } // setup complete, cycle the marker if ( consts.singleSolenoid ) { cycleSingleSolenoid(); } else { cycleDoubleSolenoid(); } // bursting? if so count it down if ( burstCount && --burstCount ) { startFireCycle = true; } else if ( currentFireMode != ceFullAuto ) { startFireCycle = false; } isLedOn = false; // make sure at least this much time elapses at the end of a fire cycle millisecondCountBox = consts.shortCyclePreventionInterval; while( millisecondCountBox ); while( !(TIFR1 & 1<<OCF1A) ); // wait for end of fire cycle if ( currentFireMode == ceRamp && startFireCycle && (consts.rampTopMode != ceSemi) ) // officially hit top rate, blow guts out { // a shot was scheduled at the maximum rate it could be, go // ahead and shift up to whatever top mode the user wanted currentFireMode = consts.rampTopMode; scheduleShotBox = 0; scheduleShotRate = 0; } } }
uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) { uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)]; uint8_t rcode; UsbDevice *p = NULL; EpInfo *oldep_ptr = NULL; uint16_t PID; uint16_t VID; // get memory address of USB device address pool AddressPool &addrPool = pUsb->GetAddressPool(); #ifdef EXTRADEBUG Notify(PSTR("\r\nPS3USB Init")); #endif // check if address has already been assigned to an instance if (bAddress) { #ifdef DEBUG Notify(PSTR("\r\nAddress in use")); #endif return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; } // Get pointer to pseudo device with address 0 assigned p = addrPool.GetUsbDevicePtr(0); if (!p) { #ifdef DEBUG Notify(PSTR("\r\nAddress not found")); #endif return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; } if (!p->epinfo) { #ifdef DEBUG Notify(PSTR("\r\nepinfo is null")); #endif return USB_ERROR_EPINFO_IS_NULL; } // Save old pointer to EP_RECORD of address 0 oldep_ptr = p->epinfo; // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence p->epinfo = epInfo; p->lowspeed = lowspeed; // Get device descriptor rcode = pUsb->getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);// Get device descriptor - addr, ep, nbytes, data // Restore p->epinfo p->epinfo = oldep_ptr; if(rcode) goto FailGetDevDescr; VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor; PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct; if(VID != PS3_VID || (PID != PS3_PID && PID != PS3NAVIGATION_PID && PID != PS3MOVE_PID)) goto FailUnknownDevice; // Allocate new address according to device class bAddress = addrPool.AllocAddress(parent, false, port); if (!bAddress) return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; // Extract Max Packet Size from device descriptor epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; // Assign new address to the device rcode = pUsb->setAddr( 0, 0, bAddress ); if (rcode) { p->lowspeed = false; addrPool.FreeAddress(bAddress); bAddress = 0; #ifdef DEBUG Notify(PSTR("\r\nsetAddr: ")); #endif PrintHex<uint8_t>(rcode); return rcode; } #ifdef EXTRADEBUG Notify(PSTR("\r\nAddr: ")); PrintHex<uint8_t>(bAddress); #endif p->lowspeed = false; //get pointer to assigned address record p = addrPool.GetUsbDevicePtr(bAddress); if (!p) return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; p->lowspeed = lowspeed; // Assign epInfo to epinfo pointer - only EP0 is known rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); if (rcode) goto FailSetDevTblEntry; /* The application will work in reduced host mode, so we can save program and data memory space. After verifying the PID and VID we will use known values for the configuration values for device, interface, endpoints and HID for the PS3 Controllers */ /* Initialize data structures for endpoints of device */ epInfo[ PS3_OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint epInfo[ PS3_OUTPUT_PIPE ].epAttribs = EP_INTERRUPT; epInfo[ PS3_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints epInfo[ PS3_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE; epInfo[ PS3_OUTPUT_PIPE ].bmSndToggle = bmSNDTOG0; epInfo[ PS3_OUTPUT_PIPE ].bmRcvToggle = bmRCVTOG0; epInfo[ PS3_INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint epInfo[ PS3_INPUT_PIPE ].epAttribs = EP_INTERRUPT; epInfo[ PS3_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints epInfo[ PS3_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE; epInfo[ PS3_INPUT_PIPE ].bmSndToggle = bmSNDTOG0; epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = bmRCVTOG0; rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo); if( rcode ) goto FailSetDevTblEntry; delay(200);//Give time for address change rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1); if( rcode ) goto FailSetConf; if(PID == PS3_PID || PID == PS3NAVIGATION_PID) { if(PID == PS3_PID) { #ifdef DEBUG Notify(PSTR("\r\nDualshock 3 Controller Connected")); #endif PS3Connected = true; } else { // must be a navigation controller #ifdef DEBUG Notify(PSTR("\r\nNavigation Controller Connected")); #endif PS3NavigationConnected = true; } /* Set internal bluetooth address and request for data */ setBdaddr(my_bdaddr); enable_sixaxis(); setLedOn(LED1); // Needed for PS3 Dualshock and Navigation commands to work for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); for (uint8_t i = 6; i < 10; i++) readBuf[i] = 0x7F; // Set the analog joystick values to center position } else { // must be a Motion controller #ifdef DEBUG Notify(PSTR("\r\nMotion Controller Connected")); #endif PS3MoveConnected = true; setMoveBdaddr(my_bdaddr); // Set internal bluetooth address moveSetBulb(Red); // Needed for Move commands to work for (uint8_t i = 0; i < MOVE_REPORT_BUFFER_SIZE; i++) writeBuf[i] = pgm_read_byte(&MOVE_REPORT_BUFFER[i]); } bPollEnable = true; Notify(PSTR("\r\n")); timer = millis(); return 0; // successful configuration /* diagnostic messages */ FailGetDevDescr: #ifdef DEBUG Notify(PSTR("\r\ngetDevDescr:")); #endif goto Fail; FailSetDevTblEntry: #ifdef DEBUG Notify(PSTR("\r\nsetDevTblEn:")); #endif goto Fail; FailSetConf: #ifdef DEBUG Notify(PSTR("\r\nsetConf:")); #endif goto Fail; FailUnknownDevice: #ifdef DEBUG Notify(PSTR("\r\nUnknown Device Connected - VID: ")); PrintHex<uint16_t>(VID); Notify(PSTR(" PID: ")); PrintHex<uint16_t>(PID); #endif rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; goto Fail; Fail: #ifdef DEBUG Notify(PSTR("\r\nPS3 Init Failed, error code: ")); Serial.print(rcode,HEX); #endif Release(); return rcode; }
THREAD(SoundRecord, arg) { printf("SoundAnalyzer started\n"); fflush(stdout); VsTest(); NutSleep(200); SoundStruct* ss = arg; int i; int recording = -1; ResetDevice(); unsigned int samplecount = 0; short sample; short * recordBuffer = malloc( RECORD_BUFFER_SIZE * sizeof(short) ); for(i = 0; i < RECORD_BUFFER_SIZE; i++) recordBuffer[i] = 0; i = 0; int absolute = 0; //sum of the absolute values of samples short absoluteCount = 0; //number of recorded samples up to ABSOLUTE_COUNT bool readyToBegin = false; bool lastWindow = false; RecordDeviceInit(8000, 1, 0, 20); for(;;) { NutSleep(3); samplecount = VsRegRead(VS_HDAT1_REG); // spec page 54: if sci_hdat1 >= 896 may be better not // to read and wait for overflow while ( (samplecount > 0 && samplecount < 896 )) { samplecount--; sample = VsRegRead(VS_HDAT0_REG); recordBuffer[i] = sample; absolute += abs(sample); if( absoluteCount < ABSOLUTE_COUNT) absoluteCount++; else //the oldest sample must be deducted from the sum variable (absolute) { if ( i - ABSOLUTE_COUNT < 0) absolute -= abs(recordBuffer[RECORD_BUFFER_SIZE+i-ABSOLUTE_COUNT]); else absolute -= abs(recordBuffer[i-ABSOLUTE_COUNT]); } i++; if ( i == RECORD_BUFFER_SIZE ) { i=0; readyToBegin = true; //printf("%d, ", absolute/ABSOLUTE_COUNT); //DEBUG } if( absoluteCount < ABSOLUTE_COUNT) continue; //recording does not begin until the averaging window has been fully covered //start recording, if the treshold is exceeded //if (readyToBegin && (absolute/ABSOLUTE_COUNT > RECORD_START) && recording == -1) if(readyToBegin && sample > RECORD_START && recording == -1) { setLedOn(_BV(_LED_1)); recording = 0; /* if ( i < BACKTRACE ) { memcpy(ss->buffer, recordBuffer+i-BACKTRACE, BACKTRACE-i); memcpy(ss->buffer+(BACKTRACE-i), recordBuffer, i); } else memcpy(ss->buffer, recordBuffer+i, BACKTRACE); */ } //if we are recording, save sample if ( recording != -1) { ss->buffer[BACKTRACE+recording] = sample; recording++; } if (recording >= 0 && ( (BACKTRACE+recording == WIN_SIZE* CEPS_COUNT) || (absolute/ABSOLUTE_COUNT < RECORD_STOP) ) ) lastWindow = true; //-2 means that recording should be stopped whenever the last window is filled if( lastWindow && ((BACKTRACE + recording) % WIN_SIZE == 0) ) //dynamic length { //if ( ABSOLUTE_COUNT+recording == WIN_SIZE* CEPS_COUNT && recording != -1) { //fixed length ss->ceps_count = (BACKTRACE + recording) / WIN_SIZE; lastWindow = false; if(ss->ceps_count < 5) continue; setLedOff(_BV(_LED_1)); recording = -1; if(ss->ceps_count < MIN_CEPS_COUNT) continue; if(ss->ceps_count != CEPS_COUNT && ss->ceps_count > 3) ss->ceps_count -= 3; //WAWISETTI // printf("\n\n"); // int j; // for(j = 0; j < 44; j++) // printf("%02x ", wavheader[j]); // // printf("\n\n\n"); // for(j = 0; j < ss->ceps_count*WIN_SIZE; j++) // printf("%02x ", recordBuffer[j]); // // printf("\n\n\n"); // for(;;) // NutThreadYield(); NutEventPost( &recordBufferReadyRead ); //for(;;) // NutThreadYield(); //break; //mihi tätä breakkii tarvitaan?? } } } }
void Light::on() { m_pulseScheduler.stop(); setLedOn(); }