static void packetbuf_out_next_packet(void){ if (USB_ep_out_received(2) && packetbuf_out_can_write()){ cli(); USB_ep_out_start(2, out_buf[out_end_index]); out_end_index = (out_end_index+1)%PACKETS_BUFFER; out_count++; sei(); } }
void packetbuf_reset(void){ in_start_index = in_end_index = in_count = 0; out_start_index = out_count = 0; USB_ep_in_reset(1); USB_ep_out_reset(2); out_end_index = 1; USB_ep_out_start(2, out_buf[0]); }
/// 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; }
void pollEndpoint(void){ if (USB_ep_out_received(1)){ pageOffs += EP1_SIZE; if (pageOffs == APP_SECTION_PAGE_SIZE){ // Write a page to flash SP_LoadFlashPage(pageBuf); NVM.CMD = NVM_CMD_NO_OPERATION_gc; SP_WriteApplicationPage(page*APP_SECTION_PAGE_SIZE); SP_WaitForSPM(); NVM.CMD = NVM_CMD_NO_OPERATION_gc; page++; pageOffs = 0; } if (page * APP_SECTION_PAGE_SIZE < APP_SECTION_END){ // If there's remaining room in flash, configure the endpoint to accept more data USB_ep_out_start(1, &pageBuf[pageOffs]); } } }