Hello :-) Sorry for my ignorance but Andreas could you please tell in one or two words what is the main reason of creating "new" ft2232 driver and what is new about that driver - the MPSSE is still the same instruction set..?
Could you please tell what is the difference between new driver and ft2232_bitbang and ft2232_transfer that I use for SWD as part of LibSWD - maybe I could improve its speed too? :-) http://repo.or.cz/w/openocd/libswd.git/blob/HEAD:/src/jtag/drivers/ft2232.c 615 /** Generic IO BITBANG Port Manipulation Routine. 616 * It can read and write port state using signal names. Each interface have its 617 * own specific signal names and fields. This function works on those fields 618 * and based on their values talks to the FT*232 chip on the interface device. 619 * ft2232 drivers use {low,high}_{output,direction} global variables to remember 620 * port direction and value, so we need to work on them as well not to change 621 * any other pin with our bit-baning performed only on selected pins. 622 * The function name 'bitbang' reflects ability to change selected pin states. 623 * 624 * @Note: FT2232 has special mechanism called MPSSE for serial communications 625 * that is far more efficient than pure 'bitbang' mode on this device family. 626 * Although our function is named 'bitbang' it does not use bitbang mode. 627 * MPSSE command send value and port bytes on port write, but does not on read. 628 * This happens every time we want to change pin value, so we need to use cache. 629 * On write we want to OR direction mask already set by init() procedure 630 * to mark bit-mask output. On read we want to clear bits given by mask 631 * to mark them input. To read we need to write/update port state first. 632 * Long story short: to read data we first need to set pins to input. 633 * 634 * @Warning: reading and writing will set pin direction input or output, 635 * so it is possible to disable basic data output pins with bad masking, 636 * but also gives chance to create and manage full TCL signal description, 637 * that can be used to take advantage of some additional interface hardware 638 * features installed on some devices (i.e. ADC, power supply, etc). 639 * This gives new way of signal handling that is still backward-compatible. 640 * 641 * \param *device void pointer to pass additional driver information to the routine. 642 * \param signal is the string representation of the signal mask stored in layout structure. 643 * \param GETnSET if zero then perform read operation, write otherwise. 644 * \param *value is the pointer that holds the value. 645 * \return ERROR_OK on success, or ERROR_FAIL on failure. 646 */ 647 int ft2232_bitbang(void *device, char *signal_name, int GETnSET, int *value){ 648 uint8_t buf[3]; 649 int retval, vall=0, valh=0; 650 unsigned int sigmask; 651 uint32_t bytes_written, bytes_read; 652 oocd_interface_signal_t *sig; 653 654 //First get the signal mask, or return error if signal not defined. 655 if (!(sig=oocd_interface_signal_find(signal_name))){ 656 LOG_ERROR("Requested signal not found on this interface!"); 657 return ERROR_FAIL; 658 } 659 // Pin mask is also related with port direction and complicates it!!! 660 sigmask=sig->mask; 661 662 // First check against restricted port pins defined by the interface layout 663 if (sigmask & layout->bitbang_deny){ 664 LOG_ERROR("This interface does not allow to bit-bang selected pins (0x%08X)!", layout->bitbang_deny); 665 return ERROR_FAIL; 666 } 667 668 if (!GETnSET){ 669 // We will SET port pins selected by sigmask. 670 // Modify our pins value, but remember about other pins and their previous value 671 low_output = (low_output & ~sigmask) | ((*value & sigmask) & 0x0ff); 672 high_output = (high_output & ~(sigmask>>8)) | (((*value & sigmask)>>8) & 0x0ff); 673 // Modify our pins direction, but remember about other pins and their previous direction 674 low_direction |= sigmask & 0x0ff; 675 high_direction |= (sigmask>>8) & 0x0ff; 676 // Now send those settings to the interface chip 677 buf[0] = 0x80; //Set Data Bits LowByte 678 buf[1] = low_output; 679 buf[2] = low_direction; 680 if ((retval=ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) return retval; 681 buf[0] = 0x82; //Set Data Bits HighByte 682 buf[1] = high_output; 683 buf[2] = high_direction; 684 if ((retval=ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) return retval; 685 sig->value = ((high_output<<8) | low_output) & sig->mask; 686 } else { 687 // Modify our pins value, but remember about other pins and their previous value 688 // DO WE REALLY NEED TO PULL-UP PINS TO READ THEIR STATE OR SIMPLY LEAVE AS IS? 689 //low_output = (low_output & ~sigmask) | (sigmask & 0x0ff); 690 //high_output = (high_output & ~sigmask) | (sigmask>>8) & 0x0ff); 691 // Modify our pins direction to input, but remember about other pins and their previous direction 692 low_direction &= ~(sigmask); 693 high_direction &= ~(sigmask>>8); 694 // Now send those settings to the interface chip 695 // First change desired pins to input 696 buf[0] = 0x80; //Set Data Bits LowByte 697 buf[1] = low_output; 698 buf[2] = low_direction; 699 if ((retval=ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) return retval; 700 buf[0] = 0x82; //Set Data Bits HighByte 701 buf[1] = high_output; 702 buf[2] = high_direction; 703 if ((retval=ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) return retval; 704 // Then read pins designated by a signal mask 705 buf[0]=0x81; //Read Data Bits LowByte. 706 if ((retval=ft2232_write(buf, 1, &bytes_written)) != ERROR_OK) return retval; 707 if ((retval=ft2232_read((uint8_t *)&vall, 1, &bytes_read)) != ERROR_OK) return retval; 708 buf[0]=0x83; //Read Data Bits HighByte. 709 if ((retval=ft2232_write(buf, 1, &bytes_written)) != ERROR_OK) return retval; 710 if ((retval=ft2232_read((uint8_t *)&valh, 1, &bytes_read)) != ERROR_OK) return retval; 711 sig->value = *value = ((valh<<8)|vall) & sig->mask; //Join result bytes and apply signal bitmask 712 } 713 return ERROR_OK; 714 } 715 716 717 /** Transfer bits in/out stored in char array starting from LSB first or MSB first, 718 * alternatively if you want to make MSB-first shift on LSB-first mode put data 719 * in reverse order into input/output array. 720 * \param *device void pointer to pass driver details to the function. 721 * \param bits is the number of bits (char array elements) to transfer. 722 * \param *mosidata pointer to char array with data to be send. 723 * \param *misodata pointer to char array with data to be received. 724 * \param nLSBfirst if zero shift data LSB-first, otherwise MSB-first. 725 * \return number of bits sent on success, or ERROR_FAIL on failure. 726 */ 727 int ft2232_transfer(void *device, int bits, char *mosidata, char *misodata, int nLSBfirst){ 728 static uint8_t buf[65539], databuf; 729 int i, retval, bit=0, byte=0, bytes=0; 730 uint32_t bytes_written, bytes_read; 731 732 LOG_DEBUG("ft2232_transfer(device=@%p, bits=%d, mosidata=@%p, misodata=@%p, nLSDfirst=%d) ",\ 733 (void*)device, bits, (void*)mosidata, (void*)misodata, nLSBfirst); 734 735 if (bits>65535){ 736 LOG_ERROR("Cannot transfer more than 65536 bits at once!"); 737 return ERROR_FAIL; 738 } 739 740 if (bits>=8){ 741 //Try to pack as many bits into bytes for better performance. 742 bytes = bits/8; 743 bytes--; // MPSSE starts counting bytes from 0. 744 buf[0]=(nLSBfirst)?0x31:0x39; // Clock Bytes In and Out LSb or MSb first. 745 buf[1]=(char)bytes&0x0ff; 746 buf[2]=(char)((bytes>>8)&0x0ff); 747 bytes++; 748 for (byte=0;byte*8<bits;byte++){ 749 databuf=0; 750 for (i=0;i<8;i++) {databuf|=mosidata[byte*8+i]?(1<<i):0;} 751 buf[byte+3]=databuf; 752 } 753 retval=ft2232_write(buf, bytes+3, &bytes_written); 754 if (retval<0){ 755 LOG_ERROR("ft2232_write() returns %d", retval); 756 return ERROR_FAIL; 757 } 758 retval=ft2232_read((uint8_t *)buf, bytes, &bytes_read); 759 if (retval<0){ 760 LOG_ERROR("ft2232_read() returns %d", retval); 761 return ERROR_FAIL; 762 } 763 // Explode read bytes into bit array. 764 //for (bit=0;bit<bytes*8;bit++) {misodata[bit]=(buf[bit/8]&(1<<bit))?1:0;} 765 for(byte=0;byte*8<bits;byte++) for(bit=0;bit<8;bit++) misodata[byte*8+bit]=buf[byte]&(1<<bit)?1:0; 766 } 767 768 // Now send remaining bits that cannot be packed as bytes. 769 // Because "Clock Data Bits In and Out LSB/MSB" of FTDI is a mess, pack single 770 // bit read/writes into buffer and then flush it using single USB transfer. 771 for (bit=bytes*8;bit<bits;bit++){ 772 buf[3*bit+0]=(nLSBfirst)?0x33:0x3b; // Clock Bits In and Out LSb or MSb first. 773 buf[3*bit+1]=0; // One bit per element. 774 buf[3*bit+2]=mosidata[bit]?0xff:0; // Take data from supplied array. 775 } 776 retval=ft2232_write(buf, 3*(bits-(bytes*8)), &bytes_written); 777 if (retval<0){ 778 LOG_ERROR("ft2232_write() returns %d", retval); 779 return ERROR_FAIL; 780 } 781 retval=ft2232_read((uint8_t *)misodata, bits-(bytes*8), &bytes_read); 782 if (retval<0){ 783 LOG_ERROR("ft2232_read() returns %d", retval); 784 return ERROR_FAIL; 785 } 786 // FTDI MPSSE returns shift register value, our bit is MSb 787 for (bit=bytes*8;bit<bits;bit++) misodata[bit]=(misodata[bit]&(nLSBfirst?0x01:0x80))?1:0; 788 //USE THIS FOR WIRE-LEVEL DEBUG 789 //LOG_DEBUG("read 0x%02X written 0x%02X", misodata[bit], mosidata[bit]); 790 791 return bit; 792 } Best regards! :-) Tomek -- CeDeROM, SQ7MHZ, http://www.tomek.cedro.info ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
