/// 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; }
/** 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; }