コード例 #1
0
void main(void)
{
  char pinStatus = 0, TXon = 0, boxOpen = 0;
  long int runTime = 0;             //
  
   /* device setup */
  set32MHzXOSC();
  timerSetup(TICKS_FREQ025, T1_PRE);     
  timer4Setup(T4_PRE); 
//  CSPT = 0xFF;
//  PICTL |= BIT7;
  
  P0DIR |= 0x8C;                        //P0 BIT2,3,7 are output, BIT1,4,5,6 are input
  if (P0 & BOX) P0 = RED_LED;
  else P0 = GREEN_LED;

  /* interrupt setup */
   setT1int();             //TIMER1 interrupts
   setT4int();             //TIMER4 interrupts
  //void setP0int();       //Port 0 interrupts
  
  while(P0 & BOX);              //wait for box to close before reading setup parameters
  T1_ovf_cnt = 0;               //restart transmitting period after closing the box
  pinStatus = readPin();
  setupTX(pinStatus);
  
  IEN0 |= BIT7;                                 //enable global interrupts.
  T1CTL |= BIT0;                                //start timer1 in free running mode
  
  if (pinStatus == 0x02) runTime = 322;         //total run time is approx. 3 hours
  else runTime = 18;                            //total run time is approx. 10 minutes
  
  while(T1_ovf_cnt < runTime)       //stop program after XXX hours
  {
    while(!(P0 & BOX) && T1_ovf_cnt < runTime)     //Box is closed 
    {
      if (!TXon)
      {
        if (pinStatus == 0x22) freqSweep(FREQ2395, FREQ2507, 4);
        else startTX();
        TXon = 1;
      }
    }
    stopTX();
    TXon = 0;
//    if (P0 & BOX) boxOpen = 1;
//    else 
//    {
//      while(P0 & BOX);              //wait for box to close before reading setup parameters
//    }
    while (P0 & BOX) boxOpen = 1;
    if (boxOpen == 1) T1_ovf_cnt = 0;               //restart transmitting period after closing the box
    pinStatus = readPin();
    setupTX(pinStatus);
    if (pinStatus == 0x02) runTime = 645;         //total run time is approx. 6 hours
    else runTime = 18;                            //total run time is approx. 10 minutes
    boxOpen = 0;
  }
  stopTX();
}
コード例 #2
0
/*
* Updates the local state if warranted, but always returns local state.
*/
ChargeState PMU::getChargeState() {
  uint8_t idx = 0;
  bool s1 = readPin(_stat1_pin);
  bool s2 = readPin(_stat2_pin);
  _er_set_flag(DIGITAB_PMU_FLAG_STAT1, s1);
  _er_set_flag(DIGITAB_PMU_FLAG_STAT2, s2);
  idx += s1 ? 1 : 0;
  idx += s2 ? 2 : 0;
  switch (idx) {
    case 0:
      _charge_state = ChargeState::TEST;
      break;
    case 1:
      _charge_state = ChargeState::FULL;
      break;
    case 2:
      _charge_state = ChargeState::CHARGING;
      break;
    case 3:
      // Both pins high. No inference possible.
    default:
      break;
  }
  return _charge_state;
}
コード例 #3
0
void PMU::gpioSetup() {
  /* These Port B pins are inputs:
  *
  * #  Default   Purpose
  * -----------------------------------------------
  * 0     0      CHG_STAT_1
  * 1     0      CHG_STAT_2
  */
  // This will cause interrupts to be enabled for these pins.
  setPinFxn(_stat1_pin, CHANGE_PULL_UP, mcp73833_stat1_isr);
  setPinFxn(_stat2_pin, CHANGE_PULL_UP, mcp73833_stat2_isr);
  _er_set_flag(DIGITAB_PMU_FLAG_STAT1, readPin(_stat1_pin));
  _er_set_flag(DIGITAB_PMU_FLAG_STAT2, readPin(_stat2_pin));
}
コード例 #4
0
ファイル: matrix.c プロジェクト: 0xdec/qmk_firmware
static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
{
    // Store last value of row prior to reading
    matrix_row_t last_row_value = current_matrix[current_row];

    // Clear data in matrix row
    current_matrix[current_row] = 0;

    // Select row and wait for row selecton to stabilize
    select_row(current_row);
    wait_us(30);

    // For each col...
    for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {

        // Select the col pin to read (active low)
        uint8_t pin_state = readPin(col_pins[col_index]);

        // Populate the matrix row with the state of the col pin
        current_matrix[current_row] |=  pin_state ? 0 : (ROW_SHIFTER << col_index);
    }

    // Unselect row
    unselect_row(current_row);

    return (last_row_value != current_matrix[current_row]);
}
コード例 #5
0
ファイル: matrix.c プロジェクト: UnderSampled/qmk_firmware
static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
  bool matrix_changed = false;

  // Select col and wait for col selecton to stabilize
  select_col(current_col);
  wait_us(30);

  // For each row...
  for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) {
    // Store last value of row prior to reading
    matrix_row_t last_row_value = current_matrix[row_index];

    // Check row pin state
    if (readPin(row_pins[row_index])) {
      // Pin HI, clear col bit
      current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
    } else {
      // Pin LO, set col bit
      current_matrix[row_index] |= (ROW_SHIFTER << current_col);
    }

    // Determine if the matrix changed state
    if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) {
      matrix_changed = true;
    }
  }

  // Unselect col
  unselect_col(current_col);

  return matrix_changed;
}
コード例 #6
0
ファイル: Switches.cpp プロジェクト: tomorrow56/Arduino
bool Switches::read()
{
  if (millis() - prev < interval)
    return val;

  readPin();
  return val;
}
コード例 #7
0
ファイル: IOFilter.cpp プロジェクト: HenryLoenwind/SCoop
void InputFilter::check_time(int16_t temp)
{ if (readPin() != value)
     if (value) { // falling edge
        if ((temp - time) > timeOff) { value=0; } }
     else { // rising edge
        if ((temp - time) > timeOn)  { counter++; value=1; } } 
  else { time=temp; }
}
コード例 #8
0
int main(void)
{	
  //write enable port 0, 1, 2
  DDRB = (1<<PB0) | (1<<PB1) | (1<<PB2);
  
  //read enable port 3 
  DDRB |= (0<<PB3);
  
  //enable port 3 pullup
  PORTB |= (1<<PB3);

  //configure the PWM and timer interrupts
  setupTimer();

	//set the initial state
	state=ANIMATE;
	msAnimateStart = millis;
	channel=A;
	
	//if the button is held down, reset the color
	if (readPin(BUTTON_PIN)==false) {
		hue[A]=0.001;
		hue[B]=0.501;
		saveABColors(hue[A], hue[B]);
		
		//wait until the button is released
		do {
			delay(MSEC_BUTTON_DEBOUNCE);
		} while (readPin(BUTTON_PIN)==false);
	}
	//otherwise load the saved color
	else {
		loadABColors(&hue[A], &hue[B]);
	}

	//set the initial color
	//updateColor(hue[A]);	

	//input handling loop
	while(true) {
		loop();
	}
	
	return 0;
}
コード例 #9
0
ファイル: DS18B20.c プロジェクト: GitYun/ZigBee-Network
/*
** return		0 - if the salve presence, or 1
*/
unsigned char oneWireCheck()
{
	unsigned char isSlave;
	ds_delay_us(30);
	isSlave = (unsigned char)readPin();
	outputHigh();		// releases the bus.
	ds_delay_us(100);
	return isSlave;
}
コード例 #10
0
ファイル: MGC3130.cpp プロジェクト: jspark311/ManuvrOS
/**
* Called prior to the given bus operation beginning.
* Returning 0 will allow the operation to continue.
* Returning anything else will fail the operation with IO_RECALL.
*   Operations failed this way will have their callbacks invoked as normal.
*
* @param  _op  The bus operation that was completed.
* @return 0 to run the op, or non-zero to cancel it.
*/
int8_t MGC3130::io_op_callahead(BusOp* _op) {
  if (!readPin(_ts_pin)) {   // Only initiate a read if there is something there.
    unsetPinIRQ(_ts_pin);
    gpioDefine(_ts_pin, GPIOMode::OUTPUT);
    are_we_holding_ts(true);
    return 0;
  }
  return -1;
}
コード例 #11
0
ファイル: ButtonGroup.cpp プロジェクト: dillstead/ButtonGroup
void ButtonGroup::readAllPins()
{
    for (int currentPin = 0; currentPin < MAX_PINS; currentPin++)
    {
        if (bitRead(activePins, currentPin))
        {
            readPin(currentPin);
        }
    }
}
コード例 #12
0
int main(void)
{
//=============================================================
//  Enable A-Pins & Port
//=============================================================
	volatile uint32_t ui32Loop;
    // Enable the GPIO port that is used for the on-board LED.
    SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOA;	//SYSCTL_RCGC2_GPIOF; // This is the same as: SYSCTL_RCGC2_R |= 0x00000021;

    // Do a dummy read to insert a few cycles after enabling the peripheral.
    ui32Loop = SYSCTL_RCGC2_R;

    //--- Pin setup
    // Enable the GPIO pin for the LED (PF).  Set the direction as output, and
    // enable the GPIO pin for digital function.

    GPIO_PORTA_DIR_R = Pin2+Pin3;// This is the same as: 0x02+0x04+0x08;

    GPIO_PORTA_PDR_R = Pin2+Pin3+Pin6;
    GPIO_PORTA_AFSEL_R &= ~Pin2+Pin3+Pin6;      // 6) disable alt funct on PA7
    GPIO_PORTA_DEN_R = Pin2+Pin3+Pin6;

	enablePortF_Out(BLUE_LED+RED_LED+GREEN_LED); // Experimental EnableOut function

//=============================================================

	GPIO_PORTF_DATA_R |= RED_LED;

    // Loop forever.
    while(1)
    {

    	toggle(PortF,RED_LED);
    	variableTest = readPin(PortA,Pin6);
    	delay(delayTime);
    	toggle(PortF,RED_LED);
    	variableTest = readPin(PortA,Pin6);
    	delay(delayTime);

     }
}
コード例 #13
0
ファイル: matrix.c プロジェクト: UnderSampled/qmk_firmware
static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
  matrix_row_t last_row_value = current_matrix[current_row];
  current_matrix[current_row] = 0;

  for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
    pin_t pin = direct_pins[current_row][col_index];
    if (pin != NO_PIN) {
      current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index);
    }
  }

  return (last_row_value != current_matrix[current_row]);
}
コード例 #14
0
GPIOPinInput::GPIOPinInput(QDeclarativeItem *parent) :
    QDeclarativeItem(parent)
{
    gpio_config_pin(I2C_GPIO_ADDR, m_pin, 1);
    setState(gpio_rd_reg_bit(I2C_GPIO_ADDR, REG_INPUT, m_pin));

    if (m_pollPin)
    {
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(readPin()));
        timer->start(10);
    }
}
コード例 #15
0
ファイル: split_util.c プロジェクト: Depariel/qmk_firmware
bool is_keyboard_left(void) {
  #ifdef SPLIT_HAND_PIN
    // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand
    setPinInput(SPLIT_HAND_PIN);
    return readPin(SPLIT_HAND_PIN);
  #else
    #ifdef EE_HANDS
      return eeprom_read_byte(EECONFIG_HANDEDNESS);
    #else
      #ifdef MASTER_RIGHT
        return !is_keyboard_master();
      #else
        return is_keyboard_master();
      #endif
    #endif
  #endif
}
コード例 #16
0
ファイル: xilskey_jscmd.c プロジェクト: caiogustavo/TCC
void jtagShiftTDI (unsigned char tdiData, unsigned char* tdoData, int clkCount, int exitState)
{
   int count = clkCount;
   unsigned char mask = 0x01;

   while (count)
   {
	   if (tdoData) // read tdo bit
	   {
		   if (readPin (MIO_TDO))
		   {
			   *(unsigned char*)tdoData |= mask;
		   }
		   else
		   {
			   *(unsigned char*)tdoData &= ~mask;
		   }
	   }
	   if (tdiData & mask)
	   {
		   setPin (MIO_TDI, 1);
	   }
	   else
       {
		   setPin (MIO_TDI, 0);
       }
       if (exitState == 1)
       {
           if (count == 1)
           {
               setPin (MIO_TMS, 1);
           }
       }

       // pulse tck pin
       setPin (MIO_TCK, 1);
       setPin (MIO_TCK, 0);

       mask <<= 1;
       count--;
   }
}
コード例 #17
0
ファイル: DS18B20.c プロジェクト: GitYun/ZigBee-Network
unsigned char oneWireRead()
{
	int count;
	unsigned char data = 0;
	
	for (count = 0; count < 8; count++)
	{		
		outputLow();
		ds_delay_us(2);			// pull the 1-wire bus low to initiate read time-slot.
		outputHigh();			// now let the 1-wire bus high for sample data of the Slave.
		ds_delay_us(8);			// let device state stabilise.
		data >>= 1;				// LSB first.
		if ( readPin() == 1 )
			data |= 0x80;
		ds_delay_us(60);			// wait until end of read slot.
		//data >>= 1;			// error		
	}
	
	return data;
}
コード例 #18
0
ファイル: CRaspiGPIO.cpp プロジェクト: CRLG/LABOTBOX
// _____________________________________________________________________
void CRaspiGPIO::setPinModeInput(unsigned int gpio_num, unsigned int pullup_down)
{
    pinMode(gpio_num, INPUT);
    pullUpDnControl(gpio_num, pullup_down);
    QString txt;
    QString tooltip;
    if (pullup_down == PUD_UP) {
        txt+="Iu";
        tooltip = "Input with pull UP";
    }
    else if (pullup_down == PUD_DOWN) {
        txt+="Id";
        tooltip = "Input with pull DOWN";
    }
    else {
        txt+="I";
        tooltip = "Digital Input";
    }
    QLabel *lbl = m_ihm.findChild<QLabel*>(PREFIX_MODE_GPIO + QString::number(gpio_num));
    if (lbl) {
        lbl->setText(txt);
        lbl->setToolTip(tooltip);
        lbl->setEnabled(true);
    }
    QLabel *lbl_name = m_ihm.findChild<QLabel*>(PREFIX_GPIO_NAME + QString::number(gpio_num));
    if (lbl_name) {
        lbl_name->setEnabled(true);
    }

    // On ne peut pas forcer l'état sur une entrée
    QCheckBox *checkbox = m_ihm.findChild<QCheckBox*>(PREFIX_CHECKBOX_WRITE + QString::number(gpio_num));
    if (checkbox) {
        checkbox->setEnabled(false);
    }

    m_raspi_pins_config[gpio_num] = tRaspiPinConfig { INPUT, pullup_down, 0};
    readPin(gpio_num);
}
コード例 #19
0
void loop()
{
	//read the button value (false: pressed)
	boolean button=readPin(BUTTON_PIN);
	
	//calculate the state transitions
	//hold or animate become select when the button is pressed
	if ((state==HOLD || state==ANIMATE) && button==false) {
		state=SELECT;
		updateColor(hue[channel]);
		delay(MSEC_BUTTON_DEBOUNCE);
		return;
	}
	//select becomes hold for the next channel
	else if (state==SELECT && button==true) {
		//save the current channel positions
		saveABColors(hue[A], hue[B]);
		state=HOLD;
		
		msHoldStart = millis;
		
		//choose the next channel
		switch (channel) {
			case A:
				channel=B;
				break;
			case B:
				channel=A;
				break;
		}
		
		delay(MSEC_BUTTON_DEBOUNCE);
	}

	//handle the select mode
	else if (state==SELECT && button==false) {
		//increment the hue
		hue[channel]+=HUE_STEP;
		//mod the hue by 1
		if (hue[channel]>1)
			hue[channel]-=floor(hue[channel]);
	
		updateColor(hue[channel]);
	}
	
	//hold becomes animate after a delay, or when first starting
	else if (state==START || (state==HOLD && (millis-msHoldStart > MSEC_HOLD_DELAY))) {
		
		//flash the colors to indicate animate start
		updateBlack();
		delay(500);
		updateColor(hue[A]);
		delay(500);
		updateBlack();
		delay(500);
		updateColor(hue[B]);
		delay(500);
		updateBlack();
		delay(500);
		
		
		state = ANIMATE;
		msAnimateStart = millis;
	}
	
	//handle animation
	else if (state==ANIMATE) {				
		doABAnimate();
	}
		
	
	delay(STEP_DELAY);
}
コード例 #20
0
ファイル: Communication.c プロジェクト: yenng/mockTest
uint32_t readBit(int pinNo){
  setPinHigh(CLK_PIN);
  setPinLow(CLK_PIN);
  return readPin(pinNo);
}
コード例 #21
0
uint16_t NoteDetector::detect( uint16_t frequency, uint32_t timeout )
{
    //
    // This implementation of Goertzel algorithm
    // is taken from Wikipedia (http://en.wikipedia.org/wiki/Goertzel_algorithm).
    //
    double curr     = 0;
    double prev     = 0;
    double prevPrev = 0;
    double result   = 0;

    double sampleRate = SAMPLE_RATE;
    double targetFrequeny = (double)frequency;

    double normalizedFrequency = targetFrequeny / sampleRate;
    double coeff               = 2*cos(2*PI*normalizedFrequency);

    m_debugInterface->debug("Target frequency: ", targetFrequeny );
    m_debugInterface->debug("Normalized frequency: ", normalizedFrequency );

    uint32_t timoutAt   = millis() + timeout;
    uint16_t sampleNo = 0;
    int16_t  reading  = 0;

    // Wait until there is a loud sound

    while ( millis() < timoutAt )
    {
        while ( readPin() < m_volumeThreshold && millis() < timoutAt );

        sampleNo = 0;
        prev     = 0;
        prevPrev = 0;

        while ( sampleNo < SAMPLE_COUNT )
        {
            reading = readPin();

            curr     = reading + coeff*prev - prevPrev;

            prevPrev = prev;
            prev     = curr;

            sampleNo += 1;
        }

        result = prevPrev*prevPrev + prev*prev - coeff*prev*prevPrev;

        // If our frequency is prominent enough return it
        if ( result/10000000 > 200.0  )


        {
            m_debugInterface->debug("Detected ", frequency );
            m_debugInterface->debug("Result ", result/10000000 );

            return frequency;
        }
    }

    m_debugInterface->debug("Nothing detected" );
    // Timed out, nothing detected
    return 0;
}
コード例 #22
0
ファイル: button.c プロジェクト: antongulenko/TankOS
BOOL buttonStatus(Button button) {
    if (!buttonValid(button)) return FALSE;
	BOOL val = readPin(BUTTON->pin);
	if (BUTTON->flags & ButtonInverted) val = !val;
	return val;
}
コード例 #23
0
ファイル: Switches.cpp プロジェクト: tomorrow56/Arduino
void Switches::setPin(int p, int mode)
{
  pin = p;
  mode_ = mode;
  readPin();
}
コード例 #24
0
int main() 
{
    systemReset(); // peripherals but not PC
    setupCLK();
    setupLED();
    setupUSB();
    setupBUTTON();
    setupFLASH();

    strobePin(LED_BANK, LED, STARTUP_BLINKS, BLINK_FAST);

	/* wait for host to upload program or halt bootloader */
	bool no_user_jump = (!checkUserCode(USER_CODE_RAM) && !checkUserCode(USER_CODE_FLASH0X8005000) && !checkUserCode(USER_CODE_FLASH0X8002000)) || readPin(BUTTON_BANK,BUTTON);
	int delay_count = 0;

    while ((delay_count++ < BOOTLOADER_WAIT) || no_user_jump)
	{

        strobePin(LED_BANK, LED, 1, BLINK_SLOW);

        if (dfuUploadStarted()) 
		{
            dfuFinishUpload(); // systemHardReset from DFU once done
        }
    }

	if (checkUserCode(USER_CODE_RAM)) 
	{
		jumpToUser(USER_CODE_RAM);
	} 
	
	else if (checkUserCodeRam(USER_CODE_FLASH0X8002000+4))
	{
		int ptr;
		/*
		u32 *flashAdr = (u32 *)USER_CODE_FLASH0X8002000;
		u32 *ramAdr = (u32 *)USER_CODE_RAM;
		for (ptr = 0; ptr < ((RAM_END-USER_CODE_RAM)-1024)/4; ptr ++) {
			ramAdr[ptr] = flashAdr[ptr];
        }
		*/
		u32 const *flashAdr = (u32 const *)USER_CODE_FLASH0X8002000;
		u32 *ramAdr = (u32 *)USER_CODE_RAM;
		ptr = ((RAM_END-USER_CODE_RAM)-1024)>>2;
		while (ptr--)
		{
			*ramAdr++ = *flashAdr++;
		}
		jumpToUser(USER_CODE_RAM);
	}
コード例 #25
0
ファイル: Joystick.cpp プロジェクト: rockwood/arduino-cam
void Joystick::readInto(uint8_t arr[3]) {
  arr[0] = readPin(_xPin);
  arr[1] = readPin(_yPin);
  arr[2] = readPin(_zPin);
}
コード例 #26
0
ファイル: CRaspiGPIO.cpp プロジェクト: CRLG/LABOTBOX
// _____________________________________________________________________
void CRaspiGPIO::readAllInputs()
{
    for (tListPins::const_iterator it=m_raspi_pins_config.constBegin(); it!=m_raspi_pins_config.constEnd() ; it++) {
        readPin(it.key());
    }
}
コード例 #27
0
ファイル: main.c プロジェクト: 1stsetup/AeroQuad
int main() {
  systemReset(); // peripherals but not PC
  setupCLK();
  setupLED();
  setupBUTTON();

#ifdef STM32F2
	setupDisconnectPin();
	disconnectUSB();
#else
  setupUSB();
  setupFLASH();
#endif


  strobePin(LED_BANK,LED,STARTUP_BLINKS,BLINK_FAST);

#ifdef STM32F2
  // enter built in boot load if magic number found in RAM
	if(*START_BOOT_LOADER_MAGIC_ADDR == START_BOOT_LOADER_MAGIC) {
 	  connectUSB();
		*START_BOOT_LOADER_MAGIC_ADDR = 0;
    jumpToUser(BUILT_IN_BOOT_LOADER);
	}
#endif



#ifdef FASTSTART
  // for an unknown reason the loader process hangs if the button port is not read
	bool pinState = readPin(BUTTON_BANK, BUTTON);
#else

	bool buttonStatusHigh = TRUE;
	bool buttonStatusLow  = FALSE;
	for(int i=0; i<10; i++) {
		bool pinState = readPin(BUTTON_BANK, BUTTON);
		buttonStatusHigh = buttonStatusHigh && pinState;
		buttonStatusLow  = buttonStatusLow || pinState;
	}

  /* wait for host to upload program or halt bootloader */
  bool no_user_jump = (!checkUserCode(USER_CODE_FLASH) && !checkUserCode(USER_CODE_RAM))
        								|| buttonStatusHigh;
  int delay_count = 0;


  while ((delay_count++ < BOOTLOADER_WAIT) || no_user_jump) {
    strobePin(LED_BANK,LED,1,BLINK_SLOW);

  #ifndef STM32F2
    if (dfuUploadStarted()) {
      dfuFinishUpload(); // systemHardReset from DFU once done
    }
  #endif
  }
#endif

	if (checkUserCode(USER_CODE_RAM)) {
    jumpToUser(USER_CODE_RAM);
  } else if (checkUserCode(USER_CODE_FLASH)) {
    jumpToUser(USER_CODE_FLASH);
  } else {
    // some sort of fault occurred, hard reset
    strobePin(LED_BANK,LED,5,BLINK_FAST);
    systemHardReset();
  }

  return 0;               /* can't happen, but placate the compiler */
}
コード例 #28
0
byte SX1509::digitalRead(byte pin)
{
	return readPin(pin);
}
コード例 #29
0
ファイル: main.c プロジェクト: OpenUAS/maple-bootloader
int main() {
  systemReset(); // peripherals but not PC
  setupCLK();
  setupLED();
  setupUSB();
  setupBUTTON();
  setupFLASH();

  strobePin(LED_BANK,LED,STARTUP_BLINKS,BLINK_FAST);

  /* wait for host to upload program or halt bootloader */
  bool no_user_jump = !checkUserCode(USER_CODE_FLASH) && !checkUserCode(USER_CODE_RAM) || readPin(BUTTON_BANK,BUTTON);
  int delay_count = 0;

  while ((delay_count++ < BOOTLOADER_WAIT) 
	 || no_user_jump) {

    strobePin(LED_BANK,LED,1,BLINK_SLOW);

    if (dfuUploadStarted()) {
      dfuFinishUpload(); // systemHardReset from DFU once done
    }
  }
  
  if (checkUserCode(USER_CODE_RAM)) {
    jumpToUser(USER_CODE_RAM);
  } else if (checkUserCode(USER_CODE_FLASH)) {
    jumpToUser(USER_CODE_FLASH);
  } else {
    // some sort of fault occurred, hard reset
    strobePin(LED_BANK,LED,5,BLINK_FAST);
    systemHardReset();
  }
  
}