void serialboot() { struct sfl_frame frame; int failed; unsigned int cmdline_adr, initrdstart_adr, initrdend_adr; static const char str[SFL_MAGIC_LEN] = SFL_MAGIC_REQ; const char *c; printf("I: Attempting serial firmware loading\n"); usb_debug_enable(0); c = str; while(*c) { uart_write(*c); c++; } if(!check_ack()) { printf("E: Timeout\n"); usb_debug_enable(1); return; } failed = 0; cmdline_adr = initrdstart_adr = initrdend_adr = 0; while(1) { int i; int actualcrc; int goodcrc; /* Grab one frame */ frame.length = uart_read(); frame.crc[0] = uart_read(); frame.crc[1] = uart_read(); frame.cmd = uart_read(); for(i=0;i<frame.length;i++) frame.payload[i] = uart_read(); /* Check CRC */ actualcrc = ((int)frame.crc[0] << 8)|(int)frame.crc[1]; goodcrc = crc16(&frame.cmd, frame.length+1); if(actualcrc != goodcrc) { failed++; if(failed == MAX_FAILED) { printf("E: Too many consecutive errors, aborting"); usb_debug_enable(1); return; } uart_write(SFL_ACK_CRCERROR); continue; } /* CRC OK */ switch(frame.cmd) { case SFL_CMD_ABORT: failed = 0; uart_write(SFL_ACK_SUCCESS); usb_debug_enable(1); return; case SFL_CMD_LOAD: { char *writepointer; failed = 0; writepointer = (char *)( ((unsigned int)frame.payload[0] << 24) |((unsigned int)frame.payload[1] << 16) |((unsigned int)frame.payload[2] << 8) |((unsigned int)frame.payload[3] << 0)); for(i=4;i<frame.length;i++) *(writepointer++) = frame.payload[i]; uart_write(SFL_ACK_SUCCESS); break; } case SFL_CMD_JUMP: { unsigned int addr; failed = 0; addr = ((unsigned int)frame.payload[0] << 24) |((unsigned int)frame.payload[1] << 16) |((unsigned int)frame.payload[2] << 8) |((unsigned int)frame.payload[3] << 0); uart_write(SFL_ACK_SUCCESS); boot(cmdline_adr, initrdstart_adr, initrdend_adr, rescue, addr); break; } case SFL_CMD_CMDLINE: failed = 0; cmdline_adr = ((unsigned int)frame.payload[0] << 24) |((unsigned int)frame.payload[1] << 16) |((unsigned int)frame.payload[2] << 8) |((unsigned int)frame.payload[3] << 0); uart_write(SFL_ACK_SUCCESS); break; case SFL_CMD_INITRDSTART: failed = 0; initrdstart_adr = ((unsigned int)frame.payload[0] << 24) |((unsigned int)frame.payload[1] << 16) |((unsigned int)frame.payload[2] << 8) |((unsigned int)frame.payload[3] << 0); uart_write(SFL_ACK_SUCCESS); break; case SFL_CMD_INITRDEND: failed = 0; initrdend_adr = ((unsigned int)frame.payload[0] << 24) |((unsigned int)frame.payload[1] << 16) |((unsigned int)frame.payload[2] << 8) |((unsigned int)frame.payload[3] << 0); uart_write(SFL_ACK_SUCCESS); break; default: failed++; if(failed == MAX_FAILED) { printf("E: Too many consecutive errors, aborting"); usb_debug_enable(1); return; } uart_write(SFL_ACK_UNKNOWN); break; } } }
BOOL handle_vendorcommand(BYTE cmd) { if(cmd == 0x90) { // Reset reset(); // Nothing to reply EP0BCH = 0; EP0BCL = 0; EP0CS |= bmHSNAK; return TRUE; } else if(cmd == 0x91) { // Enable/Disable debug short val = SETUP_VALUE(); if(val != 0) { usb_debug_enable(); USB_DEBUG_PRINTF(6, "Debug enabled"); } else { usb_debug_disable(); } EP0BCH = 0; EP0BCL = 0; EP0CS |= bmHSNAK; return TRUE; } else if(cmd == 0x92) { // Start stream USB_DEBUG_PRINTF(6, "Start"); IOA &= ~SIG_EN; // Low // Nothing to reply EP0BCH = 0; EP0BCL = 0; EP0CS |= bmHSNAK; #ifdef SIMULATION fx2_setup_timer0(29); #else IFCONFIG |= bmIFFIFO; #endif return TRUE; } else if(cmd == 0x93) { // Stop stream USB_DEBUG_PRINTF(6, "Stop"); IOA |= SIG_EN; // High // Reset EP2 FIFORESET = bmNAKALL; SYNCDELAY(); FIFORESET = bmNAKALL | 2; SYNCDELAY(); FIFORESET = 0x00; SYNCDELAY(); // Nothing to reply EP0BCH = 0; EP0BCL = 0; EP0CS |= bmHSNAK; #ifdef SIMULATION fx2_setup_timer0(0); #else IFCONFIG &= ~bmIFFIFO; #endif return TRUE; } else if(cmd == 0x94) { // Get version USB_PRINTF(0, "AdslSniffer V0.0.1"); EP0CS |= bmHSNAK; return TRUE; } else if(cmd == 0x95) { // Get bitrate WORD size = sizeof(DWORD); DWORD *rate = (DWORD*)EP0BUF; *rate = 8832000; EP0BCH = MSB(size); EP0BCL = LSB(size); EP0CS |= bmHSNAK; return TRUE; } else if(cmd == 0x99) { // Test debug EP USB_DEBUG_PRINTF(6, "Test"); EP0BCH = 0; EP0BCL = 0; EP0CS |= bmHSNAK; return TRUE; } return FALSE; }