Index: avrftdi_private.h =================================================================== --- avrftdi_private.h (Revision 1183) +++ avrftdi_private.h (Arbeitskopie) @@ -80,6 +80,7 @@ int rx_buffer_size; /* pin checklist. */ struct pin_checklist_t pin_checklist[N_PINS]; +bool use_bitbanging; } avrftdi_t; void avrftdi_log(int level, const char * func, int line, const char * fmt, ...); Index: avrftdi.c =================================================================== --- avrftdi.c (Revision 1183) +++ avrftdi.c (Arbeitskopie) @@ -295,6 +295,131 @@ set_pin(pgm, PPI_AVR_VCC, OFF); } + +static inline int set_data(PROGRAMMER * pgm, avrftdi_t* pdata, unsigned char *buf, unsigned char data, bool read_data) { + int j; + int buf_pos = 0; + unsigned char bit = 0x80; + + for (j=0; j<8; j++) { + pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_MOSI,data & bit); + // could be optimized if we know if sck is in same byte as mosi + // in case if not if we would sent the byte containing the mosi data first + buf[buf_pos++] = SET_BITS_LOW; + buf[buf_pos++] = (pdata->pin_value) & 0xff; + buf[buf_pos++] = (pdata->pin_direction) & 0xff; + buf[buf_pos++] = SET_BITS_HIGH; + buf[buf_pos++] = ((pdata->pin_value) >> 8) & 0xff; + buf[buf_pos++] = ((pdata->pin_direction) >> 8) & 0xff; + + pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_SCK,1); + buf[buf_pos++] = SET_BITS_LOW; + buf[buf_pos++] = (pdata->pin_value) & 0xff; + buf[buf_pos++] = (pdata->pin_direction) & 0xff; + buf[buf_pos++] = SET_BITS_HIGH; + buf[buf_pos++] = ((pdata->pin_value) >> 8) & 0xff; + buf[buf_pos++] = ((pdata->pin_direction) >> 8) & 0xff; + + if (read_data) { + buf[buf_pos++] = GET_BITS_LOW; + buf[buf_pos++] = GET_BITS_HIGH; + } + + pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_SCK,0); + buf[buf_pos++] = SET_BITS_LOW; + buf[buf_pos++] = (pdata->pin_value) & 0xff; + buf[buf_pos++] = (pdata->pin_direction) & 0xff; + buf[buf_pos++] = SET_BITS_HIGH; + buf[buf_pos++] = ((pdata->pin_value) >> 8) & 0xff; + buf[buf_pos++] = ((pdata->pin_direction) >> 8) & 0xff; + + bit >>= 1; + } + return buf_pos; +} + +static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, int offset) { + int j; + unsigned char bit = 0x80; + unsigned char r = 0; + uint16_t in; + + buf += offset * 16; // 2 bytes per bit, 8 bits + for (j=0; j<8; j++) { + in = buf[0] | (buf[1] << 8); + if (GET_BITS_0(in,pgm,PIN_AVR_MISO)) { + r |= bit; + } + buf += 2; // 2 bytes per input + bit >>= 1; + } + return r; +} + + +static int avrftdi_transmit_bb(PROGRAMMER * pgm, avrftdi_t* pdata, unsigned char mode, unsigned char *buf, + unsigned char *data, int buf_size) +{ + size_t blocksize; + size_t remaining = buf_size; + size_t written = 0; + + //if we are not reading back, we can just write the data out + //if(!(mode & MPSSE_DO_READ)) + // blocksize = buf_size; + //else + blocksize = 16;//pdata->rx_buffer_size/2; // we are reading 2 bytes per data byte + + while(remaining) + { + + size_t transfer_size = (remaining > blocksize) ? blocksize : remaining; + + // (8*3) outputs per data byte, 6 transmit bytes per output (SET_BITS_LOW/HIGH), + // (8*1) inputs per data byte, 2 transmit bytes per input (GET_BITS_LOW/HIGH), + // 1x SEND_IMMEDIATE + unsigned char send_buffer[(8*3*6)*transfer_size+(8*1*2)*transfer_size+1]; + int len = 0,len2; + int i; + + for(i = 0 ; i< transfer_size; i++) { + len += set_data(pgm,pdata,send_buffer + len, buf[written+i], (mode & MPSSE_DO_READ) != 0); + } + send_buffer[len++] = SEND_IMMEDIATE; + +// fprintf(stderr,"ftdi_write_data: [%d]\n",len); +//int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len); +// hexdump_buf(stderr,0,&buf[written],transfer_size); +// hexdump_buf(stderr,0,send_buffer,len); + + E(ftdi_write_data(pdata->ftdic, send_buffer, len) != len, pdata->ftdic); + if (mode & MPSSE_DO_READ) { + unsigned char recv_buffer[2*16*transfer_size]; + int n; + int k = 0; + do { + n = ftdi_read_data(pdata->ftdic, &recv_buffer[k], 2*16*transfer_size - k); + E(n < 0, pdata->ftdic); + k += n; + } while (k < transfer_size); + +// fprintf(stderr,"ftdi_read_data: [%d]\n",k); +//int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len); +// hexdump_buf(stderr,0,recv_buffer,k); + for(i = 0 ; i< transfer_size; i++) { + data[written + i] = extract_data(pgm, recv_buffer, i); + } +// hexdump_buf(stderr,0,&data[written],transfer_size); + } + + written += transfer_size; + remaining -= transfer_size; + } + + return written; + +} + /* Send 'buf_size' bytes from 'cmd' to device and return data from device in * buffer 'data'. * Write is only performed when mode contains MPSSE_DO_WRITE. @@ -527,9 +652,11 @@ for(pin = PIN_LED_ERR; pin < N_PINS; ++pin) { pdata->led_mask |= pgm->pin[pin].mask[0]; } + pdata->use_bitbanging = 1; + /* assumes all checklists above have same number of entries */ - if (pins_check(pgm, pdata->pin_checklist,N_PINS)) { + if (0 && pins_check(pgm, pdata->pin_checklist,N_PINS)) { log_err("Pin configuration for FTDI MPSSE must be:\n"); log_err("%s: 0, %s: 1, %s: 2 (is: %s, %s, %s)\n", avr_pin_name(PIN_AVR_SCK), avr_pin_name(PIN_AVR_MOSI), avr_pin_name(PIN_AVR_MISO), @@ -754,7 +881,10 @@ { /* Do not use 'sizeof(cmd)'. => message from cppcheck: Using sizeof for array given as function argument returns the size of pointer. */ - return avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, res, 4); + if (to_pdata(pgm)->use_bitbanging) + return avrftdi_transmit_bb(pgm, to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, res, 4); + else + return avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, res, 4); } @@ -849,7 +979,7 @@ { avr_set_addr(m->op[AVR_OP_WRITE], &cmd[3], add); avr_set_input(m->op[AVR_OP_WRITE], &cmd[3], *data++); - +// TODO //avrftdi_transmit(to_pdata(pgm), MPSSE_DO_WRITE, cmd, cmd, 4); E(ftdi_write_data(to_pdata(pgm)->ftdic, cmd, sizeof(cmd)) != sizeof(cmd), to_pdata(pgm)->ftdic); @@ -873,7 +1003,10 @@ avr_set_bits(m->op[AVR_OP_READ], cmd); avr_set_addr(m->op[AVR_OP_READ], cmd, add); - avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, cmd, 4); + if (to_pdata(pgm)->use_bitbanging) + avrftdi_transmit_bb(pgm, to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, cmd, 4); + else + avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, cmd, 4); avr_get_output(m->op[AVR_OP_READ], cmd, bufptr++); } @@ -963,7 +1096,10 @@ buf_dump(buf, buf_size, "command buffer", 0, 16*2); log_info("Transmitting buffer of size: %d\n", buf_size); - avrftdi_transmit(to_pdata(pgm), MPSSE_DO_WRITE, buf, buf, buf_size); + if (to_pdata(pgm)->use_bitbanging) + return avrftdi_transmit_bb(pgm, to_pdata(pgm), MPSSE_DO_WRITE, buf, buf, buf_size); + else + return avrftdi_transmit(to_pdata(pgm), MPSSE_DO_WRITE, buf, buf, buf_size); bufptr = buf; /* find a poll byte. we cannot poll a value of 0xff, so look @@ -1053,7 +1189,10 @@ buf_dump(o_buf, sizeof(o_buf), "o_buf", 0, 32); } - avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len * 4); + if (to_pdata(pgm)->use_bitbanging) + return avrftdi_transmit_bb(pgm, to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len * 4); + else + return avrftdi_transmit(to_pdata(pgm), MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len * 4); if(verbose > TRACE) { buf_dump(i_buf, sizeof(i_buf), "i_buf", 0, 32);