Date: Tue, 30 Aug 2005 10:51:12 -0700 (PDT) From: User Tomdean <tomdean@speakeasy.org> To: ticso@cicely.de Cc: freebsd-usb@freebsd.org Subject: Re: Ucom/Uftdi Thru-put Message-ID: <200508301751.j7UHpCt8000858@asus.tddhome> In-Reply-To: <20050826112422.GY37930@cicely12.cicely.de> (message from Bernd Walter on Fri, 26 Aug 2005 13:24:23 %2B0200) References: <200508202157.j7KLv1GF005017@asus.tddhome> <20050826093914.GV37930@cicely12.cicely.de> <20050826112422.GY37930@cicely12.cicely.de>
next in thread | previous in thread | raw e-mail | index | archive | help
Sorry this is long, I have attached the code at the bottom. ucom_read.c is the FreeBSD code. UMP2_send.c is the AVR code. # kldload ucom # kldload uftdi power up UMP2 and AVR In dmesg, I see ucom0: FTDI USB HS Serial Converter, rev 1.10/2.00, addr 2 With a scope, on the USB_DATA+ line, I see groups of 3 uSec activity, every 1 mSec. Within the groups, I see 100 nSec pulses, or a 10 mBit rate. # ./ucom_read With a scope, on the USB_DATA+ line, I see activity every 1 mSec. But, the AVR has groups of activity every 2 mSEC! Just before the 52 uSec of activity caused by the AVR, I see a 3 uSec group of activity. So, the USB bus has its normal 3 uSec activity every 1 mSec overlayed by 52 uSec of AVR activity every 2 mSec. So, ucom_read only gets the USB bus every 2 msec. The AVR send loop takes 0.9 to 1.1 uSec. These happen in bursts of 74 uSec every 2 mSec. The AVR waits for the UMP2 TX ready signal most of the time. >From looking at the USB_DATA+ line and the UMP2 *TXE signal, the *TXE signal is not true until the buffer is empty. The doc states 'If this signal is log.1, the buffer is full'. 10 mSec --+---------+---------+---------+--------- USB --1---------123-------1---------123------ *TXE ---------------4-------------------4----- 1 - 3 uSec USB activity from FreeBSD 2 - 10 uSec gap 3 - 52 uSec USB activity from the UMP2 4 - 72 uSec activity on the *TXE line, high otherwise. The nominal return from the FreeBSD read is 62 bytes. The UMP2 has a FT8U245BM chip, which has a 384 byte transmit buffer. The output from ucom_read, Read 1000060 bytes in 32.242824 seconds in chuncks of 62 bytes This is a thruput of 31017 bytes/second. Does FreeBSD only request 64 bytes from the UMP2???? tomdean === ucom_read ========================================================= /* * asus-read.c - read ucom0, doing time measurements * * $Id$ */ #include <stdio.h> #include <termios.h> /* termios settings */ #include <fcntl.h> /* open */ #include <sys/types.h> /* read */ #include <sys/uio.h> /* read */ #include <unistd.h> /* read */ #include <sys/time.h> /* time */ #define USB_BUF_SIZE 20000 #define BYTES_TO_READ 1000000 /* * Set up ucom's state */ void ucomsetup (int fd) { struct termios termios; tcgetattr (fd, &termios); /* input modes */ termios.c_iflag = (IGNBRK); /* local modes */ termios.c_lflag = 0; /* common modes */ termios.c_cflag = (CLOCAL|HUPCL|CREAD|CS8); /* no parity */ /* since the UMP2 is a USB to parallel device, speed is meaningless */ if (0) termios.c_ispeed = termios.c_ospeed = B9600; if (0) termios.c_ispeed = termios.c_ospeed = B38400; if (0) termios.c_ispeed = termios.c_ospeed = B115200; if (0) termios.c_ispeed = termios.c_ospeed = B230400; if (0) termios.c_ispeed = termios.c_ospeed = B921600; tcsetattr (fd, TCSANOW, &termios); return; } /* * main */ int main(int argc, char **argv) { int fd; /* file descriptor */ int numRead; size_t bytes; uint8_t *buf[USB_BUF_SIZE]; struct timeval start, stop; struct timezone tz; long sec, usec; double elapsed, mb_sec, nsec; if ((fd = open("/dev/ucom0", O_RDONLY)) < 0) { perror("Open /dev/ucom0"); return -1; } /* need to do this */ ucomsetup(fd); numRead = 0; /* * get the start time */ gettimeofday(&start, &tz); /* * read a large number of bytes and keep track of time */ while (numRead < BYTES_TO_READ) { bytes = read(fd, buf, USB_BUF_SIZE); if (0) printf("Read %d bytes\n", bytes); numRead += bytes; } /* * get the end time */ gettimeofday(&stop, &tz); /* * calculate the time, etc. */ sec = stop.tv_sec - start.tv_sec; if (sec < 0) sec++; usec = stop.tv_usec - start.tv_usec; if (usec < 0) { sec--; usec += 1000000L; } elapsed = (double)sec + ((double) usec)/1000000.0; printf("Read %d bytes in %f seconds in chuncks of %d bytes\n", numRead, elapsed, bytes); close(fd); return 0; } == UMP2_send ======================================================== /* * UMP2-send.c - provide loopback for the UMP2 module * * Connections * PORTA * <7> UMP2 RD# =0 to read data * <6> UMP2 WR =1 to write data * <5> UMP2 TXE# =0 TX is available to accept data * <4> UMP2 RXF# =0 RX has data available * <3> UMP2 PWE# =0 if device is configured via USB * <2> * <1> * <0> * PORTB LEDs * <7> Init OK * <6> * <5> * <4> * <3> Wait Tx ready * <2> Wait Rx data * <1> Writing data to UMP2 * <0> Reading data from UMP2 * PORTC * <7:0> UMP2 data * * $Id$ */ #include <avr/io.h> /* io definitions like PORTB, etc */ #include <libasus.h> /* prototypes */ #include <avr/interrupt.h> /* cli */ #include <stdint.h> /* uint8_t, etc */ /* led 0 is the first led, or bit 0 */ /* PORTB is at 0x18 */ #define LED_PORT 0x18 #define LED_ON(n) asm("cbi %0,%1"::"i"(LED_PORT),"i"(n)) #define LED_OFF(n) asm("sbi %0,%1"::"i"(LED_PORT),"i"(n)); /* * UMP2 bit definitions */ #define UMP2_CTL PORTA #define UMP2_CTL_PIN PINA #define UMP2_RD 7 #define UMP2_WR 6 #define UMP2_TXE 5 #define UMP2_RXF 4 #define UMP2_PWE 3 #define UMP2_DATA PORTC #define SET_READ DDRC=0x00 #define SET_WRITE DDRC=0xff int main() { uint8_t c; uint8_t r; asm("cli"); DDRA = (1<<UMP2_RD) | (1<<UMP2_WR); DDRB=0xff; /* all output */ DDRC=0x00; /* all input */ PORTC=0x00; /* make sure no pullups */ /* ser UMP2_RD high */ PORTA |= (1<<UMP2_RD); /* pull up the low signals */ PORTA |= (1<<UMP2_TXE) |(1<<UMP2_RXF) |(1<<UMP2_PWE); PORTB = 0xff; /* all led's off */ serial_init(); /* * set the UART baud rate */ UBRRL = 8; /* 115.2k at 16.0000Mhz */ PORTB = 0; /* all led's on */ if (0) r = serial_recv(); /* get in sync */ PORTB = 0xff; /* all led's off */ LED_ON(7); LED_OFF(7); c = 'a'; /* set the data port direction to out */ SET_WRITE; while(1) { /* visual output and scope trigger */ LED_ON(0); /* Write data to UMP2 */ while (UMP2_CTL_PIN & (1<<UMP2_TXE)) ; /* WR up */ UMP2_CTL |= (1<<UMP2_WR); /* present data */ UMP2_DATA = c; /* WR down */ UMP2_CTL &= ~(1<<UMP2_WR); /* the loop is done */ LED_OFF(0); } return 0; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508301751.j7UHpCt8000858>