static void usbasp_close(PROGRAMMER * pgm) { printf("done."); if (PDATA(pgm)->usbhandle!=NULL) { unsigned char temp[4]; memset(temp, 0, sizeof(temp)); if (PDATA(pgm)->use_tpi) { usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_DISCONNECT, temp, temp, sizeof(temp)); } else { usbasp_transmit(pgm, 1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp)); } #ifdef USE_usb_1_0 usb_close(PDATA(pgm)->usbhandle); #else usb_close(PDATA(pgm)->usbhandle); #endif } #ifdef USE_usb_1_0 usb_exit(ctx); #else /* nothing for usb 0.1 ? */ #endif }
static void usbasp_close(PROGRAMMER * pgm) { if (verbose > 2) fprintf(stderr, "%s: usbasp_close()\n", progname); if (PDATA(pgm)->usbhandle!=NULL) { unsigned char temp[4]; memset(temp, 0, sizeof(temp)); if (PDATA(pgm)->use_tpi) { usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_DISCONNECT, temp, temp, sizeof(temp)); } else { usbasp_transmit(pgm, 1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp)); } #ifdef USE_LIBUSB_1_0 libusb_close(PDATA(pgm)->usbhandle); #else usb_close(PDATA(pgm)->usbhandle); #endif } #ifdef USE_LIBUSB_1_0 libusb_exit(ctx); #else /* nothing for usb 0.1 ? */ #endif }
/* * fck < 12MHz : Low period>2CPU clock cycle High period>2CPU clock cycle * fck >= 12MHz : Low period>3CPU clock cycle High period>3CPU clock cycle * * -d option * USBaspx SCK clock cycle TARGET * 0 : 0 : 3.0MHz fosc/4 0.33us > 12.0MHz * 1 : 1 : 1.5MHz fosc/8 0.67us > 6.0MHz * 2 : 2 : 750.0kHz fosc/16 1.33us > 3.0MHz * * 3 : 3 : 375.0kHz fosc/32 2.67us > 1.5MHz Original High-clock mode * 4 : 4 : 187.5kHz fosc/64 5.33us > 750.0kHz * 5 : 5 : 93.8kHz fosc/128 10.67us > 375.0kHz * ... * 10 : 6 : 50.0kHz (6-5)*10*2 20us > 200.0kHz * 20 : 7 : 25.0kHz (7-5)*10*2 40us > 100.0kHz * 30 : 8 : 16.7kHz (8-5)*10*2 60us > 66.7kHz * 40 : 9 : 12.5kHz (9-5)*10*2 80us > 50.0kHz * 50 : 10 : 10.0kHz (10-5)*10*2 100us > 40.0kHz * * 60 : 11 : 8.3kHz (11-5)*10*2 120us > 33.3kHz Original Low-clock mode * 70 : 12 : 7.1kHz (12-5)*10*2 140us > 28.6kHz * ... * 2500 : 255 : 200Hz (255-5)*10*2 5ms > 800Hz */ int usbasp_connect(int iodly) { unsigned char temp[4]; memset(temp, 0, sizeof(temp)); iodly_value = iodly; if (iodly_value >= 0) { //@@@ by t.k int value; temp[1] = 0xaa; // magic no for Extended function temp[2] = 0x55; // original firm was ignored. if (iodly_value <= 5) { //@@@ hardware sck value = iodly_value; } else { value = (iodly_value+5) / 10; //@@@ per 10us value += 5; // 1.. -> 6.. if (value > 255) value = 255; } temp[3] = (unsigned char)value; //@@@fprintf(stderr, "set usbasp spi delay value %d\n", value); } usbasp_transmit(1, USBASP_FUNC_CONNECT, temp, temp, sizeof(temp)); // usleep(100000); delay_ms(100); // pgm->program_enable(pgm, p); f_connect = true; return 0; }
static void usbasp_close(PROGRAMMER * pgm) { if (PDATA(pgm)->usbhandle!=NULL) { unsigned char temp[4]; memset(temp, 0, sizeof(temp)); if (PDATA(pgm)->use_tpi) { usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_DISCONNECT, temp, temp, sizeof(temp)); } else { usbasp_transmit(pgm, 1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp)); } #ifdef USE_LIBUSB_1_0 libusb_close(PDATA(pgm)->usbhandle); #else usb_close(PDATA(pgm)->usbhandle); #endif } }
/* * USBaspの通信ブロック単位(200bytes)で分割して書き込む */ int usbasp_blockwrite( int function, int address, unsigned char *buffer, int n_bytes, int page_size, unsigned char flags ) { unsigned char cmd[4]; int blocksize, n; int top = address; int wbytes = n_bytes; unsigned char blockflags = USBASP_BLOCKFLAG_FIRST; while (wbytes > 0) { if (function == USBASP_FUNC_WRITEEEPROM) { blocksize = 1; wbytes -= 1; } else if (wbytes > USBASP_WRITEBLOCKSIZE) { blocksize = USBASP_WRITEBLOCKSIZE; wbytes -= USBASP_WRITEBLOCKSIZE; } else { blocksize = wbytes; wbytes = 0; blockflags |= USBASP_BLOCKFLAG_LAST; } cmd[0] = address & 0xFF; cmd[1] = address >> 8; cmd[2] = page_size; cmd[3] = blockflags | flags; blockflags = 0; n = usbasp_transmit(0, function, cmd, buffer, blocksize); if (function == USBASP_FUNC_WRITEEEPROM) { delay_ms(Device->EepromWait); } if (n != blocksize) break; buffer += blocksize; address += blocksize; #if AVRSPX report_update(n); #else //@ report_progress (address, n_bytes, NULL); #endif } return address - top; }
/* Universal functions: for both SPI and TPI */ static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p) { unsigned char temp[4]; unsigned char res[4]; IMPORT_PDATA(pgm); if (verbose > 2) fprintf(stderr, "%s: usbasp_initialize()\n", progname); /* get capabilities */ memset(temp, 0, sizeof(temp)); if(usbasp_transmit(pgm, 1, USBASP_FUNC_GETCAPABILITIES, temp, res, sizeof(res)) == 4) pdata->capabilities = res[0] | ((unsigned int)res[1] << 8) | ((unsigned int)res[2] << 16) | ((unsigned int)res[3] << 24); else pdata->capabilities = 0; pdata->use_tpi = ((pdata->capabilities & USBASP_CAP_TPI) != 0 && (p->flags & AVRPART_HAS_TPI) != 0) ? 1 : 0; if(pdata->use_tpi) { /* calc tpiclk delay */ int dly = 1500000.0 * pgm->bitclock; if(dly < 1) dly = 1; else if(dly > 2047) dly = 2047; temp[0] = dly; temp[1] = dly >> 8; /* connect */ usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_CONNECT, temp, res, sizeof(res)); /* change interface */ pgm->program_enable = usbasp_tpi_program_enable; pgm->chip_erase = usbasp_tpi_chip_erase; pgm->cmd = usbasp_tpi_cmd; pgm->read_byte = usbasp_tpi_read_byte; pgm->write_byte = usbasp_tpi_write_byte; pgm->paged_write = usbasp_tpi_paged_write; pgm->paged_load = usbasp_tpi_paged_load; pgm->set_sck_period = usbasp_tpi_set_sck_period; }
//---------------------------------------------------------------------------- int usbasp_disconnect(void) { int ret = 0; if (f_connect) { unsigned char temp[4]; memset(temp, 0, sizeof(temp)); ret = usbasp_transmit(1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp)); f_connect = false; } return ret; }
int usbasp_cmd(unsigned char cmd[4], unsigned char res[4]) { int nbytes = usbasp_transmit(1, USBASP_FUNC_TRANSMIT, cmd, res, sizeof(res)); if (nbytes != 4) { fprintf(stderr, "%s: error: wrong responds size\n", progname); return -1; } return 0; }
//---------------------------------------------------------------------------- static int usbasp_get_info(unsigned char res[4]) { unsigned char cmd[4]; int nbytes; memset(cmd, 0, sizeof(cmd)); memset(res, 0, sizeof(res)); nbytes = usbasp_transmit(1, USBASPX_FUNC_GETINFO, cmd, res, sizeof(res)); if (nbytes != 4) { // fprintf(stderr, "%s: error: get info\n", progname); return -1; } return 0; }
//---------------------------------------------------------------------------- static int usbasp_set_serial(char *SerialNumber) { unsigned char res[4]; unsigned char cmd[USB_CFG_SERIAL_NUMBER_LEN]; int nbytes; setup_serial((char *)cmd, SerialNumber); memset(res, 0, sizeof(res)); nbytes = usbasp_transmit(1, USBASPX_FUNC_SETSERIAL, cmd, res, sizeof(res)); if (nbytes != 1 || res[0] != 0) { fprintf(stderr, "%s: error: set serial: target doesn't answer. %x \n", progname, res[0]); return -1; } return 0; }
//---------------------------------------------------------------------------- int usbasp_program_enable(void) { unsigned char res[4]; unsigned char cmd[4]; int nbytes; memset(cmd, 0, sizeof(cmd)); memset(res, 0, sizeof(res)); nbytes = usbasp_transmit(1, USBASP_FUNC_ENABLEPROG, cmd, res, sizeof(res)); if ((nbytes < 1) || (res[0] != 0)) { fprintf(stderr, "%s: error: programm enable: target doesn't answer. %x \n", progname, res[0]); return -1; } return 0; }
/* * USBaspの通信ブロック単位(200bytes)で分割して読み込む */ int usbasp_paged_load_sub(int function, int address, unsigned char *buffer, int n_bytes, unsigned char flags) { int n; unsigned char cmd[4]; int wbytes = n_bytes; int blocksize; while (wbytes > 0) { if (wbytes > USBASP_READBLOCKSIZE) { blocksize = USBASP_READBLOCKSIZE; wbytes -= USBASP_READBLOCKSIZE; } else { blocksize = wbytes; wbytes = 0; } cmd[0] = address & 0xFF; cmd[1] = address >> 8; cmd[2] = 0x5A; //@@ magic no by t.k cmd[3] = flags; //@@ n = usbasp_transmit(1, function, cmd, buffer, blocksize); if (n != blocksize) { fprintf(stderr, "%s: error: wrong reading bytes %x\n", progname, n); return -1; } buffer += blocksize; address += blocksize; #if AVRSPX report_update(n); #else //@ report_progress (address, n_bytes, NULL); #endif } return n_bytes; }