/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start * the loaded application code. */ int main(void) { /* David Cox * In my application is needs internal pullups activated on special pins on these ports as soon as possible. */ PORTB = 0xFF; PORTC = 0xFF; PORTF = 0xFF; /* Setup hardware required for the bootloader */ SetupHardware(); /* Turn on first LED on the board to indicate that the bootloader has started */ LEDs_SetAllLEDs(LEDS_LED1); /* Enable global interrupts so that the USB stack can function */ GlobalInterruptEnable(); while (RunBootloader) { CDC_Task(); USB_USBTask(); } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Unlock the forced application start mode of the bootloader if it is restarted */ MagicBootKey = MAGIC_BOOT_KEY; /* Enable the watchdog and force a timeout to reset the AVR */ wdt_enable(WDTO_250MS); for (;;); }
void Camera_Disable(void) { USB_Detach(); USB_Disable(); Camera_Connected = 0; return; }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); GlobalInterruptEnable(); while (RunBootloader || TicksSinceLastCommand++ < 0xFF) { MS_Device_USBTask(&Disk_MS_Interface); USB_USBTask(); } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Unlock the forced application start mode of the bootloader if it is restarted */ MagicBootKey = MAGIC_BOOT_KEY; /* blink bootloader led couple of times */ for (int i=0; i<2; i++) { PORTE &= 0b10111111; //led low _delay_ms(250); PORTE |= 0b01000000; //led high _delay_ms(250); } PORTE &= 0b10111111; //led low /* Enable the watchdog and force a timeout to reset the AVR */ wdt_enable(WDTO_250MS); for (;;); }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start * the loaded application code. */ int main(void) { /* Setup hardware required for the bootloader */ SetupHardware(); /* Turn on first LED on the board to indicate that the bootloader has started */ LEDs_SetAllLEDs(LEDS_LED1); /* Enable global interrupts so that the USB stack can function */ GlobalInterruptEnable(); while (RunBootloader) { CDC_Task(); USB_USBTask(); } /* Wait a short time to end all USB transactions and then disconnect */ _delay_us(1000); /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Unlock the forced application start mode of the bootloader if it is restarted */ MagicBootKey = MAGIC_BOOT_KEY; /* Enable the watchdog and force a timeout to reset the AVR */ wdt_enable(WDTO_250MS); for (;;); }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start * the loaded application code. */ int main(void) { /* Setup hardware required for the bootloader */ SetupHardware(); /* Turn on first LED on the board to indicate that the bootloader has started */ PORTD ^= (1 << LED_RED); /* Enable global interrupts so that the USB stack can function */ sei(); while (RunBootloader) { CDC_Task(); USB_USBTask(); } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Unlock the forced application start mode of the bootloader if it is restarted */ MagicBootKey = MAGIC_BOOT_KEY; /* Enable the watchdog and force a timeout to reset the AVR */ wdt_enable(WDTO_250MS); for (;;); }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start * the loaded application code. */ int main(void) { /* Setup hardware required for the bootloader */ SetupHardware(); /* Turn on first LED on the board to indicate that the bootloader has started */ LEDs_SetAllLEDs(LEDS_LED1); /* Enable global interrupts so that the USB stack can function */ GlobalInterruptEnable(); while (RunBootloader) { CDC_Task(); USB_USBTask(); /* Time out and start the sketch if one is present */ if (Timeout > TIMEOUT_PERIOD){ RunBootloader = false;} } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Unlock the forced application start mode of the bootloader if it is restarted */ MagicBootKey = MAGIC_BOOT_KEY; /* Enable the watchdog and force a timeout to reset the AVR */ wdt_enable(WDTO_250MS); for (;;); }
void USB_ShutDown(void) { USB_ResetInterface(); USB_Detach(); USB_Controller_Disable(); USB_INT_DisableAllInterrupts(); USB_INT_ClearAllInterrupts(); #if defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) UHWCON &= ~(1 << UIMOD); #endif if (!(USB_Options & USB_OPT_MANUAL_PLL)) USB_PLL_Off(); USB_REG_Off(); #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) USB_OTGPAD_Off(); #endif #if defined(USB_CAN_BE_BOTH) UHWCON &= ~(1 << UIDE); #endif USB_IsInitialized = false; #if defined(USB_CAN_BE_BOTH) USB_CurrentMode = USB_MODE_NONE; #endif }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); GlobalInterruptEnable(); while (RunBootloader || TicksSinceLastCommand++ < 0xFF) { MS_Device_USBTask(&Disk_MS_Interface); USB_USBTask(); } /* Wait a short time to end all USB transactions and then disconnect */ _delay_us(1000); /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Unlock the forced application start mode of the bootloader if it is restarted */ MagicBootKey = MAGIC_BOOT_KEY; /* Enable the watchdog and force a timeout to reset the AVR */ wdt_enable(WDTO_250MS); for (;;); }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until it times out or is instructed to exit. */ int main(void) { /* Save the value of the boot key memory before it is overwritten */ uint16_t bootKeyPtrVal = *bootKeyPtr; *bootKeyPtr = 0; /* Check the reason for the reset so we can act accordingly */ uint8_t mcusr_state = MCUSR; // store the initial state of the Status register MCUSR = 0; // clear all reset flags /* Watchdog may be configured with a 15 ms period so must disable it before going any further */ wdt_disable(); #if DEVICE_PID == 0x606C // Only on the BlinkyTape // Put the user button (B6) in input_pullup mode, so we can read the button state DDRB &= ~(1<<DDB6); PORTB |= (1<<DDB6); #endif if (mcusr_state & (1<<EXTRF)) { // External reset - we should continue to self-programming mode. #if DEVICE_PID == 0x606C // Only on the BlinkyTape } else if (!(PINB & (1<<DDB6))) { // User button held low- Jump into the bootloader, in case the application is borked. #endif } else if ((mcusr_state & (1<<PORF)) && (pgm_read_word(0) != 0xFFFF)) { // After a power-on reset skip the bootloader and jump straight to sketch // if one exists. StartSketch(); } else if ((mcusr_state & (1<<WDRF)) && (bootKeyPtrVal != bootKey) && (pgm_read_word(0) != 0xFFFF)) { // If it looks like an "accidental" watchdog reset then start the sketch. StartSketch(); } /* Setup hardware required for the bootloader */ SetupHardware(); /* Enable global interrupts so that the USB stack can function */ sei(); Timeout = 0; while (RunBootloader) { CDC_Task(); USB_USBTask(); /* Time out and start the sketch if one is present */ if (Timeout > TIMEOUT_PERIOD) RunBootloader = false; LEDPulse(); } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Jump to beginning of application space to run the sketch - do not reset */ StartSketch(); }
CommandStatusIdType CommandExecUpgrade(char* OutMessage) { USB_Detach(); USB_Disable(); SystemEnterBootloader(); return COMMAND_INFO_OK_ID; }
CommandStatusIdType CommandExecReset(char* OutMessage) { USB_Detach(); USB_Disable(); SystemReset(); return COMMAND_INFO_OK_ID; }
void USB_Disable(void) { USB_INT_DisableAllInterrupts(); USB_INT_ClearAllInterrupts(); USB_Detach(); USB_Controller_Disable(); USB_IsInitialized = false; }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until it times out or is instructed to exit. */ int main(void) { /* Save the value of the boot key memory before it is overwritten */ uint16_t bootKeyPtrVal = *bootKeyPtr; *bootKeyPtr = 0; /* Check the reason for the reset so we can act accordingly */ uint8_t mcusr_state = MCUSR; // store the initial state of the Status register MCUSR = 0; // clear all reset flags /* Watchdog may be configured with a 15 ms period so must disable it before going any further */ wdt_disable(); // init HWB pin, wait a ms to allow caps to charge HWB_SETUP(); _delay_ms(1); if ((mcusr_state & (1<<EXTRF)) && HWB_STATUS() && (pgm_read_word(0) != 0xFFFF)) { // External reset - start the sketch if there is one and HWB jumper is not installed (HWB pin is read high) StartSketch(); } else if ((mcusr_state & (1<<PORF)) && (pgm_read_word(0) != 0xFFFF)) { // After a power-on reset skip the bootloader and jump straight to sketch // if one exists. StartSketch(); } else if ((mcusr_state & (1<<WDRF)) && (bootKeyPtrVal != bootKey) && (pgm_read_word(0) != 0xFFFF)) { // If it looks like an "accidental" watchdog reset then start the sketch. StartSketch(); } // so only start programmimg mode when reset came from autoreset = watchdog reset and bootkey matches /* Setup hardware required for the bootloader */ SetupHardware(); /* Enable global interrupts so that the USB stack can function */ sei(); Timeout = 0; while (RunBootloader) { CDC_Task(); USB_USBTask(); /* Time out and start the sketch if one is present */ if (Timeout > TIMEOUT_PERIOD) RunBootloader = false; LEDPulse(); } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Jump to beginning of application space to run the sketch - do not reset */ StartSketch(); }
void PTP_Shutdown(void) { //PTP_Disable(); PTP_CloseSession(); USB_Detach(); configured = 0; PTP_Ready = 0; PTP_Connected = 0; PTP_Bytes_Remaining = 0; PTP_Run_Task = 1; USB_HostState = 0; return; }
void PTP_Disable(void) { PTP_CloseSession(); USB_USBTask(); USB_Detach(); USB_Disable(); #ifdef PTP_DEBUG puts_P(PSTR("Camera Disabled.\r\n")); #endif configured = 0; PTP_Ready = 0; PTP_Connected = 0; PTP_Bytes_Remaining = 0; PTP_Run_Task = 1; USB_HostState = 0; return; }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start * the loaded application code. */ int main(void) { /* Setup hardware required for the bootloader */ SetupHardware(); /* Turn on first LED on the board to indicate that the bootloader has started */ LEDs_SetAllLEDs(LEDS_LED1); /* Fill in the UUID Report */ /* Bootloader ID */ UUIDReport[0] = BOOTLOADER_ID_SIG >> 8; UUIDReport[1] = BOOTLOADER_ID_SIG & 0xFF; /* Bootloader Version */ UUIDReport[2] = BOOTLOADER_VERSION_SIG >> 8; UUIDReport[3] = BOOTLOADER_VERSION_SIG & 0xFF; /* Device ID */ for (size_t i = 4; i < UUID_SIZE; i++) { UUIDReport[i] = eeprom_read_byte((uint8_t*)(intptr_t)(i)); } /* Enable global interrupts so that the USB stack can function */ GlobalInterruptEnable(); while (RunBootloader) { MIDI_Task(); CDC_Task(); MIDI_Device_USBTask(&Keyboard_MIDI_Interface); USB_USBTask(); } /* Wait a short time to end all USB transactions and then disconnect */ _delay_us(1000); /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Unlock the forced application start mode of the bootloader if it is restarted */ MagicBootKey = MAGIC_BOOT_KEY; /* Enable the watchdog and force a timeout to reset the AVR */ wdt_enable(WDTO_250MS); for (;;); }
void USB_Disable(void) { USB_INT_DisableAllInterrupts(); USB_INT_ClearAllInterrupts(); USB_Detach(); USB_Controller_Disable(); USB_OTGPAD_Off(); #if defined(USB_CAN_BE_BOTH) USB_CurrentMode = USB_MODE_None; #endif AVR32_PM.GCCTRL[3].cen = false; USB_IsInitialized = false; }
/// Handle USB control requests bool EVENT_USB_Device_ControlRequest(USB_Request_Header_t* req){ if ((req->bmRequestType & CONTROL_REQTYPE_TYPE) == REQTYPE_VENDOR){ switch (req->bRequest){ case REQ_INFO: fillInfoStruct(); USB_ep0_send(sizeof(BootloaderInfo)); return true; case REQ_ERASE: SP_EraseApplicationSection(); USB_ep0_send(0); return true; case REQ_START_WRITE: page = req->wIndex; pageOffs = 0; USB_ep_out_start(1, pageBuf); USB_ep0_send(0); return true; case REQ_CRC_APP: *(uint32_t*)ep0_buf_in = SP_ApplicationCRC(); USB_ep0_send(sizeof(uint32_t)); return true; case REQ_CRC_BOOT: *(uint32_t*)ep0_buf_in = SP_BootCRC(); USB_ep0_send(sizeof(uint32_t)); return true; case REQ_RESET: USB_ep0_send(0); USB_ep0_wait_for_complete(); _delay_us(10000); USB_Detach(); bootloaderflag = 0; cli(); _delay_us(100000); // 0.1s CCP = CCP_IOREG_gc; RST.CTRL = RST_SWRST_bm; while(1){}; return true; } } return false; }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until it times out or is instructed to exit. */ int main(void) { /* Save the value of the boot key memory before it is overwritten */ uint16_t bootKeyPtrVal = *bootKeyPtr; *bootKeyPtr = 0; /* Check the reason for the reset so we can act accordingly */ uint8_t mcusr_state = MCUSR; // store the initial state of the Status register MCUSR = 0; // clear all reset flags /* Watchdog may be configured with a 15 ms period so must disable it before going any further */ wdt_disable(); /* Jump to bootloader only if correct key is present in eeprom */ if ((eeprom_read_word((uint16_t*)EEP_BOOTKEY_ADDR) != BOOTLOADER_BOOTKEY) && (eeprom_read_word((uint16_t*)EEP_BACKUP_BOOTKEY_ADDR) != BOOTLOADER_BOOTKEY)) { StartSketch(); } /* Setup hardware required for the bootloader */ SetupHardware(); /* Enable global interrupts so that the USB stack can function */ sei(); Timeout = 0; while (RunBootloader) { CDC_Task(); USB_USBTask(); /* Time out and start the sketch if one is present */ if (Timeout > TIMEOUT_PERIOD) RunBootloader = false; LEDPulse(); } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Jump to beginning of application space to run the sketch - do not reset */ StartSketch(); }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until instructed to soft-exit. */ int main(void) { /* Setup hardware required for the bootloader */ SetupHardware(); /* Enable global interrupts so that the USB stack can function */ sei(); while (RunBootloader) USB_USBTask(); /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Enable the watchdog and force a timeout to reset the AVR */ wdt_enable(WDTO_250MS); for (;;); }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); GlobalInterruptEnable(); while (RunBootloader) { uint8_t BytesReceived = PRNT_Device_BytesReceived(&TextOnly_Printer_Interface); if (BytesReceived) { LEDs_SetAllLEDs(LEDMASK_USB_BUSY); while (BytesReceived--) { int16_t ReceivedByte = PRNT_Device_ReceiveByte(&TextOnly_Printer_Interface); /* Feed the next byte of data to the HEX parser */ ParseIntelHEXByte(ReceivedByte); } LEDs_SetAllLEDs(LEDMASK_USB_READY); } PRNT_Device_USBTask(&TextOnly_Printer_Interface); USB_USBTask(); } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Unlock the forced application start mode of the bootloader if it is restarted */ MagicBootKey = MAGIC_BOOT_KEY; /* Enable the watchdog and force a timeout to reset the AVR */ wdt_enable(WDTO_250MS); for (;;); }
void hardware_off(void) { if(battery_status() == 0) { // If USB is used, detach from the bus USB_Detach(); // Disable all interrupts cli(); // Shutdown setHigh(POWER_HOLD_PIN); for(;;); } else // Plugged in { // Charging screen // chargingScreen(); } }
void hardware_off(void) { hardware_flashlight(0); if(battery_status() == 0) { //if(timer.cableIsConnected()) //{ // menu.message(STR("Error: Cable")); //} //else //{ shutter_off(); // Save the current time-lapse settings to nv-mem timer.saveCurrent(); // If USB is used, detach from the bus USB_Detach(); // Shutdown bluetooth bt.disconnect(); bt.sleep(); // Disable all interrupts cli(); // Shutdown setHigh(POWER_HOLD_PIN); FOREVER; //} } else // Plugged in { // Charging screen // clock.sleeping = 1; menu.spawn((void *) batteryStatus); } }
void USB_Disable(void) { USB_INT_DisableAllInterrupts(); USB_INT_ClearAllInterrupts(); USB_Detach(); USB_Controller_Disable(); if (!(USB_Options & USB_OPT_MANUAL_PLL)) USB_PLL_Off(); USB_REG_Off(); #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) USB_OTGPAD_Off(); #endif #if defined(USB_CAN_BE_BOTH) USB_CurrentMode = USB_MODE_None; #endif USB_IsInitialized = false; }
void hardware_bootloader(void) { typedef void (*AppPtr_t)(void) __attribute__ ((noreturn)); AppPtr_t BootStartPtr = (AppPtr_t) 0xF000; // If USB is used, detach from the bus USB_Detach(); USB_Disable(); lcd.off(); clock.disable(); // Disable all interrupts cli(); wdt_disable(); BootStartPtr(); for(;;); }
/** Event handler for the library USB Control Request reception event. */ bool EVENT_USB_Device_ControlRequest(USB_Request_Header_t* req){ usb_cmd = 0; if ((req->bmRequestType & CONTROL_REQTYPE_TYPE) == REQTYPE_VENDOR){ switch(req->bRequest){ case 0x00: // Info if (req->wIndex == 0){ USB_ep0_send_progmem((uint8_t*)hwversion, sizeof(hwversion)); }else if (req->wIndex == 1){ USB_ep0_send_progmem((uint8_t*)fwversion, sizeof(fwversion)); } return true; case 0xA0: // read ADC readADC((IN_sample *) ep0_buf_in); USB_ep0_send(sizeof(IN_sample)); return true; case 0xAA: // write to channel A writeChannel(0, req->wIndex, req->wValue); USB_ep0_send(0); return true; case 0xAB: // write to channel B writeChannel(1, req->wIndex, req->wValue); USB_ep0_send(0); return true; case 0x65: // set gains switch (req->wIndex){ case 0x00: ADCA.CH0.CTRL = ADC_CH_INPUTMODE_DIFFWGAIN_gc | req->wValue; // VS-A break; case 0x01: ADCA.CH1.CTRL = ADC_CH_INPUTMODE_DIFFWGAIN_gc | req->wValue; // ADC-A break; case 0x02: ADCA.CH2.CTRL = ADC_CH_INPUTMODE_DIFFWGAIN_gc | req->wValue; // ADC-B break; case 0x03: ADCA.CH3.CTRL = ADC_CH_INPUTMODE_DIFFWGAIN_gc | req->wValue; // VS-B break; } USB_ep0_send(0); return true; case 0x15: // ISet DACB.CH0DATA = req->wValue; DACB.CH1DATA = req->wIndex; USB_ep0_send(0); return true; case 0x80: // Configure sampling configureSampling(req->wIndex /*mode*/ , req->wValue /*period*/); USB_ep0_send(0); return true; case 0xE0: // Read EEPROM eeprom_read_block(ep0_buf_in, (void*)(req->wIndex*64), 64); USB_ep0_send(64); return true; case 0xE1: // Write EEPROM usb_cmd = req->bRequest; cmd_data = req->wIndex; USB_ep0_send(0); return true; // Wait for OUT data (expecting an OUT transfer) case 0xBB: // disconnect from USB, jump to bootloader cli(); PMIC.CTRL = 0; USB_ep0_send(0); USB_ep0_wait_for_complete(); _delay_us(10000); USB_Detach(); void (*enter_bootloader)(void) = (void *) 0x47fc /*0x8ff8/2*/; enter_bootloader(); return true; } } return false; }
ISR(USB_GEN_vect, ISR_BLOCK) { #if defined(USB_CAN_BE_DEVICE) #if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER) if (USB_INT_HasOccurred(USB_INT_VBUS) && USB_INT_IsEnabled(USB_INT_VBUS)) { USB_INT_Clear(USB_INT_VBUS); RAISE_EVENT(USB_VBUSChange); if (USB_VBUS_GetStatus()) { RAISE_EVENT(USB_VBUSConnect); if (USB_IsConnected) RAISE_EVENT(USB_Disconnect); USB_ResetInterface(); USB_IsConnected = true; RAISE_EVENT(USB_Connect); } else { RAISE_EVENT(USB_Disconnect); USB_Detach(); USB_CLK_Freeze(); USB_PLL_Off(); USB_REG_Off(); USB_IsConnected = false; RAISE_EVENT(USB_VBUSDisconnect); USB_INT_Clear(USB_INT_VBUS); } } #endif if (USB_INT_HasOccurred(USB_INT_SUSPEND) && USB_INT_IsEnabled(USB_INT_SUSPEND)) { USB_INT_Clear(USB_INT_SUSPEND); USB_INT_Disable(USB_INT_SUSPEND); USB_INT_Enable(USB_INT_WAKEUP); USB_CLK_Freeze(); if (!(USB_Options & USB_OPT_MANUAL_PLL)) USB_PLL_Off(); USB_IsSuspended = true; RAISE_EVENT(USB_Suspend); #if defined(USB_LIMITED_CONTROLLER) && !defined(NO_LIMITED_CONTROLLER_CONNECT) if (USB_IsConnected) { USB_IsConnected = false; RAISE_EVENT(USB_Disconnect); } #endif } if (USB_INT_HasOccurred(USB_INT_WAKEUP) && USB_INT_IsEnabled(USB_INT_WAKEUP)) { if (!(USB_Options & USB_OPT_MANUAL_PLL)) { USB_PLL_On(); while (!(USB_PLL_IsReady())); } USB_CLK_Unfreeze(); USB_INT_Clear(USB_INT_WAKEUP); USB_INT_Disable(USB_INT_WAKEUP); USB_INT_Enable(USB_INT_SUSPEND); #if defined(USB_LIMITED_CONTROLLER) && !defined(NO_LIMITED_CONTROLLER_CONNECT) if (!(USB_IsConnected)) { USB_IsConnected = true; RAISE_EVENT(USB_Connect); } #endif USB_IsSuspended = false; RAISE_EVENT(USB_WakeUp); } if (USB_INT_HasOccurred(USB_INT_EORSTI) && USB_INT_IsEnabled(USB_INT_EORSTI)) { USB_INT_Clear(USB_INT_EORSTI); USB_ConfigurationNumber = 0; USB_INT_Clear(USB_INT_SUSPEND); USB_INT_Disable(USB_INT_SUSPEND); USB_INT_Enable(USB_INT_WAKEUP); Endpoint_ClearEndpoints(); Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, ENDPOINT_DIR_OUT, USB_ControlEndpointSize, ENDPOINT_BANK_SINGLE); RAISE_EVENT(USB_Reset); } #endif #if defined(USB_CAN_BE_HOST) if (USB_INT_HasOccurred(USB_INT_DDISCI) && USB_INT_IsEnabled(USB_INT_DDISCI)) { USB_INT_Clear(USB_INT_DDISCI); USB_INT_Clear(USB_INT_DCONNI); USB_INT_Disable(USB_INT_DDISCI); RAISE_EVENT(USB_DeviceUnattached); RAISE_EVENT(USB_Disconnect); USB_ResetInterface(); } if (USB_INT_HasOccurred(USB_INT_VBERRI) && USB_INT_IsEnabled(USB_INT_VBERRI)) { USB_INT_Clear(USB_INT_VBERRI); USB_Host_VBUS_Manual_Off(); USB_Host_VBUS_Auto_Off(); RAISE_EVENT(USB_HostError, HOST_ERROR_VBusVoltageDip); RAISE_EVENT(USB_DeviceUnattached); USB_HostState = HOST_STATE_Unattached; } if (USB_INT_HasOccurred(USB_INT_SRPI) && USB_INT_IsEnabled(USB_INT_SRPI)) { USB_INT_Clear(USB_INT_SRPI); USB_INT_Disable(USB_INT_SRPI); RAISE_EVENT(USB_DeviceAttached); USB_INT_Enable(USB_INT_DDISCI); USB_HostState = HOST_STATE_Attached; } if (USB_INT_HasOccurred(USB_INT_BCERRI) && USB_INT_IsEnabled(USB_INT_BCERRI)) { USB_INT_Clear(USB_INT_BCERRI); RAISE_EVENT(USB_DeviceEnumerationFailed, HOST_ENUMERROR_NoDeviceDetected, 0); RAISE_EVENT(USB_DeviceUnattached); if (USB_IsConnected) RAISE_EVENT(USB_Disconnect); USB_ResetInterface(); } #endif #if defined(USB_CAN_BE_BOTH) if (USB_INT_HasOccurred(USB_INT_IDTI) && USB_INT_IsEnabled(USB_INT_IDTI)) { USB_INT_Clear(USB_INT_IDTI); if (USB_IsConnected) { if (USB_CurrentMode == USB_MODE_HOST) RAISE_EVENT(USB_DeviceUnattached); else RAISE_EVENT(USB_Disconnect); } RAISE_EVENT(USB_UIDChange); USB_ResetInterface(); } #endif }
uint8_t custom_command(struct u2f_hid_msg * msg) { struct atecc_response res; struct u2f_hid_msg * reply = (struct u2f_hid_msg *)appdata.tmp; uint8_t ec; if (msg->cid != U2FHID_BROADCAST) return 0; switch(msg->pkt.init.cmd) { case U2F_CUSTOM_GET_SERIAL_NUMBER: if (atecc_send_recv(ATECC_CMD_READ, ATECC_RW_CONFIG | ATECC_RW_EXT, 0, NULL, 0, reply->pkt.init.payload, sizeof(reply->pkt.init.payload), &res) == 0 ) { if (res.len > 15) res.len = 15; reply->cid = msg->cid; reply->pkt.init.cmd = msg->pkt.init.cmd; U2FHID_SET_LEN(reply, res.len); usb_write((uint8_t*)reply, 64); } else { reply->cid = msg->cid; reply->pkt.init.cmd = msg->pkt.init.cmd; U2FHID_SET_LEN(reply, 0); usb_write((uint8_t*)reply, 64); } break; case U2F_CUSTOM_GET_CONFIG: if (atecc_send_recv(ATECC_CMD_READ, ATECC_RW_CONFIG | ATECC_RW_EXT, (msg->pkt.init.payload[0] << 8) | msg->pkt.init.payload[1], NULL, 0, reply->pkt.init.payload, sizeof(reply->pkt.init.payload), &res) == 0) { if (res.len > 40) res.len = 40; reply->cid = msg->cid; reply->pkt.init.cmd = msg->pkt.init.cmd; U2FHID_SET_LEN(reply, res.len); usb_write((uint8_t*)reply, 64); } else { U2FHID_SET_LEN(msg, 0); usb_write((uint8_t*)msg, 64); } break; case U2F_CUSTOM_INIT_CONFIG: atecc_setup_config(); U2FHID_SET_LEN(msg, 0); usb_write((uint8_t*)msg, 64); break; case U2F_CUSTOM_LOCK_CONFIG: if (is_locked(appdata.tmp)) { msg->pkt.init.payload[0] = 0xff; U2FHID_SET_LEN(msg, 1); usb_write((uint8_t*)msg, 64); } else if (atecc_send_recv(ATECC_CMD_LOCK, ATECC_LOCK_CONFIG, (msg->pkt.init.payload[0] << 8) | msg->pkt.init.payload[1], NULL, 0, appdata.tmp, sizeof(appdata.tmp), NULL)) { msg->pkt.init.payload[0] = 0xfe; U2FHID_SET_LEN(msg, 1); usb_write((uint8_t*)msg, 64); } else { msg->pkt.init.payload[0] = 0x00; U2FHID_SET_LEN(msg, 1); usb_write((uint8_t*)msg, 64); } break; case U2F_CUSTOM_GEN_ATT_KEY: if (atecc_send_recv(ATECC_CMD_GENKEY, ATECC_GENKEY_PRIVATE, U2F_ATTESTATION_KEY_SLOT, NULL, 0, appdata.tmp, sizeof(appdata.tmp), &res) == 0 && res.len <= 64) { U2FHID_SET_LEN(msg, res.len - 1); memmove(msg->pkt.init.payload, res.buf, res.len - 1); usb_write((uint8_t*)msg, 64); } else { U2FHID_SET_LEN(msg, 0); usb_write((uint8_t*)msg, 64); } break; /* case U2F_CUSTOM_GET_RNG: if (atecc_send_recv(ATECC_CMD_RNG,ATECC_RNG_P1,ATECC_RNG_P2, NULL, 0, appdata.tmp, sizeof(appdata.tmp), &res) == 0 ) { memmove(msg->pkt.init.payload, res.buf, 32); U2FHID_SET_LEN(msg, 32); usb_write((uint8_t*)msg, 64); } else { U2FHID_SET_LEN(msg, 0); usb_write((uint8_t*)msg, 64); } break; case U2F_CUSTOM_SEED_RNG: ec = atecc_send_recv(ATECC_CMD_NONCE,ATECC_NONCE_RNG_UPDATE,0, msg->pkt.init.payload, 20, appdata.tmp, sizeof(appdata.tmp), &res); U2FHID_SET_LEN(msg, 1); msg->pkt.init.payload[0] = ec == 0 ? 1 : 0; usb_write((uint8_t*)msg, 64); break; */ case U2F_CUSTOM_WIPE_KEYS: U2FHID_SET_LEN(msg, 1); ec=u2f_wipe_keys(); msg->pkt.init.payload[0] = ec == 0 ? 1 : 0; usb_write((uint8_t*)msg, 64); break; case U2F_CUSTOM_ENTER_BOOTLOADER: USB_Detach(); enterBootloader(); break; case U2F_CUSTOM_INC_COUNT: if (atecc_send_recv(ATECC_CMD_COUNTER, ATECC_COUNTER_INC, ATECC_COUNTER0,NULL,0, appdata.tmp, sizeof(appdata.tmp), &res) == 0) { memmove(msg->pkt.init.payload, res.buf, res.len); U2FHID_SET_LEN(msg, res.len); usb_write((uint8_t*)msg, 64); } else { U2FHID_SET_LEN(msg, 0); usb_write((uint8_t*)msg, 64); } break; default: return 0; } return 1; }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until it times out or is instructed to exit. */ int main(void) { /* Save the value of the boot key memory before it is overwritten */ uint8_t bootKeyPtrVal = *bootKeyPtr; *bootKeyPtr = 0; /* Check the reason for the reset so we can act accordingly */ uint8_t mcusr_state = MCUSR; // store the initial state of the Status register MCUSR = 0; // clear all reset flags /* Watchdog may be configured with a 15 ms period so must disable it before going any further */ // MAH 8/15/12- I removed this because wdt_disable() is the first thing SetupHardware() does- why // do it twice right in a row? //wdt_disable(); /* Setup hardware required for the bootloader */ // MAH 8/15/12- Moved this up to before the bootloader go/no-go decision tree so I could use the // timer in that decision tree. Removed the USBInit() call from it; if I'm not going to stay in // the bootloader, there's no point spending the time initializing the USB. // SetupHardware(); wdt_disable(); // Disable clock division clock_prescale_set(clock_div_1); // Relocate the interrupt vector table to the bootloader section MCUCR = (1 << IVCE); MCUCR = (1 << IVSEL); LED_SETUP(); CPU_PRESCALE(0); L_LED_OFF(); TX_LED_OFF(); RX_LED_OFF(); // Initialize TIMER1 to handle bootloader timeout and LED tasks. // With 16 MHz clock and 1/64 prescaler, timer 1 is clocked at 250 kHz // Our chosen compare match generates an interrupt every 1 ms. // This interrupt is disabled selectively when doing memory reading, erasing, // or writing since SPM has tight timing requirements. OCR1AH = 0; OCR1AL = 250; TIMSK1 = (1 << OCIE1A); // enable timer 1 output compare A match interrupt TCCR1B = ((1 << CS11) | (1 << CS10)); // 1/64 prescaler on timer 1 input // MAH 8/15/12- this replaces bulky pgm_read_word(0) calls later on, to save memory. if (pgm_read_word(0) != 0xFFFF) sketchPresent = true; // MAH 8/15/12- quite a bit changed in this section- let's just pretend nothing has been reserved // and all comments throughout are from me. // First case: external reset, bootKey NOT in memory. We'll put the bootKey in memory, then spin // our wheels for about 750ms, then proceed to the sketch, if there is one. If, during that 750ms, // another external reset occurs, on the next pass through this decision tree, execution will fall // through to the bootloader. if ( (mcusr_state & (1<<EXTRF)) && (bootKeyPtrVal != bootKey) ) { *bootKeyPtr = bootKey; sei(); while (RunBootloader) { if (resetTimeout > EXT_RESET_TIMEOUT_PERIOD) RunBootloader = false; } cli(); *bootKeyPtr = 0; RunBootloader = true; if (sketchPresent) StartSketch(); } // On a power-on reset, we ALWAYS want to go to the sketch. If there is one. else if ( (mcusr_state & (1<<PORF)) && sketchPresent) { StartSketch(); } // On a watchdog reset, if the bootKey isn't set, and there's a sketch, we should just // go straight to the sketch. else if ( (mcusr_state & (1<<WDRF) ) && (bootKeyPtrVal != bootKey) && sketchPresent) { // If it looks like an "accidental" watchdog reset then start the sketch. StartSketch(); } // END ALL COMMENTS ON THIS SECTION FROM MAH. /* Initialize USB Subsystem */ USB_Init(); /* Enable global interrupts so that the USB stack can function */ sei(); Timeout = 0; while (RunBootloader) { CDC_Task(); USB_USBTask(); /* Time out and start the sketch if one is present */ if (Timeout > TIMEOUT_PERIOD) RunBootloader = false; // MAH 8/15/12- This used to be a function call- inlining it saves a few bytes. LLEDPulse++; uint8_t p = LLEDPulse >> 8; if (p > 127) p = 254-p; p += p; if (((uint8_t)LLEDPulse) > p) L_LED_OFF(); else L_LED_ON(); } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Jump to beginning of application space to run the sketch - do not reset */ StartSketch(); }
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until it times out or is instructed to exit. */ int main(void) { /* Save the value of the boot key memory before it is overwritten */ uint16_t bootKeyPtrVal = *bootKeyPtr; *bootKeyPtr = 0; /* Check the reason for the reset so we can act accordingly */ uint8_t mcusr_state = MCUSR; // store the initial state of the Status register MCUSR &= ~((1 << PORF) | (1 << EXTRF) | (1 << WDRF)); // clear reset flags that are used by the bootloader /* Watchdog may be configured with a 15 ms period so must disable it before going any further */ wdt_disable(); if (pgm_read_word(0) != 0xFFFF) { // There is a sketch (otherwise, skip these checks and just run the bootloader). if (mcusr_state & (1 << PORF)) { // After power-on reset, clear BORF so sketch can tell it wasn't a brown-out reset, // then start the sketch. MCUSR &= ~(1 << BORF); StartSketch(); } else if (mcusr_state & (1 << EXTRF)) { // External reset. if (bootKeyPtrVal != bootKey) { // First reset button press. Set boot key for 750 ms so second reset button press // can be detected, then start the sketch if there isn't another reset. *bootKeyPtr = bootKey; _delay_ms(750); *bootKeyPtr = 0; StartSketch(); } else { // Second reset button press; boot key was already set. Fall through to bootloader. } } else if ((mcusr_state & (1 << WDRF)) && (bootKeyPtrVal == bootKey)) { // Watchdog reset triggered by sketch to start bootloader. Fall through. } else { // Reset happened for some other reason; start the sketch. StartSketch(); } } // Clear remaining reset flags so the sketch doesn't see info about an old reset when it runs later. MCUSR = 0; /* Setup hardware required for the bootloader */ SetupHardware(); /* Enable global interrupts so that the USB stack can function */ sei(); Timeout = 0; while (RunBootloader) { CDC_Task(); USB_USBTask(); /* Time out and start the sketch if one is present */ if (Timeout > TIMEOUT_PERIOD) RunBootloader = false; LEDPulse(); } /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); /* Jump to beginning of application space to run the sketch - do not reset */ StartSketch(); }