diff options
| author | Thomas Tsou <ttsou@vt.edu> | 2010-08-12 16:22:04 -0700 | 
|---|---|---|
| committer | Thomas Tsou <ttsou@vt.edu> | 2010-08-13 17:54:01 -0700 | 
| commit | b3a092055abacb99b3e9d71edd26c2dd2059dd7f (patch) | |
| tree | 6c3466c342525e21de69008ebb6b2d9e2eb87ffd | |
| parent | 70eae1d242a9530cab4efa927bd1331b099fdd00 (diff) | |
| download | uhd-b3a092055abacb99b3e9d71edd26c2dd2059dd7f.tar.gz uhd-b3a092055abacb99b3e9d71edd26c2dd2059dd7f.tar.bz2 uhd-b3a092055abacb99b3e9d71edd26c2dd2059dd7f.zip | |
usrp1: Add SPI transaction command to FX2 firmware
The existing SPI read command is set for half-duplex 8-bit
or 16-bit writes followed by an equivalent sized read.
This patch adds a new command, VRQ_SPI_TRANSACT, which
performs a full-duplex transaction up to 4-bytes. Since the
data buffer of the USB control transfer is not available
for outbound data on IN requests, the 4 bytes of write data
are sent through the request parameters. Enables are sent
in the previsouly unused high byte of the length parameter.
The USB field mappings are shown below. Only rising edge
and MSB operation is supported.
Field (8-bit)           Description
=====                   =====
bmRequestType           0x80 (USB Device IN request)
bRequest                0x83 (VRQ_SPI_TRANSACT)
wValueH                 OUT data(0)
wValueL                 OUT data(1)
wIndexH                 OUT data(2)
wIndexL                 OUT data(3)
wLengthH                SPI enables
wLengthL                Number of bytes to transfer (1-4)
EP0BUF                  IN data
| -rw-r--r-- | firmware/fx2/include/usrp_commands.h | 7 | ||||
| -rw-r--r-- | firmware/fx2/src/usrp1/spi.c | 95 | ||||
| -rw-r--r-- | firmware/fx2/src/usrp1/spi.h | 7 | ||||
| -rw-r--r-- | firmware/fx2/src/usrp1/usrp_main.c | 10 | 
4 files changed, 116 insertions, 3 deletions
| diff --git a/firmware/fx2/include/usrp_commands.h b/firmware/fx2/include/usrp_commands.h index 20c28e264..02778c7e3 100644 --- a/firmware/fx2/include/usrp_commands.h +++ b/firmware/fx2/include/usrp_commands.h @@ -54,6 +54,13 @@  							// wIndexL:	format  							// len: how much to read +#define	VRQ_SPI_TRANSACT		0x83		// wValueH:  OUT byte 0 +							// wValueL:  OUT byte 1 +							// wIndexH:  OUT byte 2 +							// wIndexL:  OUT byte 3  +							// wLengthH: enables  +							// wLengthL: transaction length +  // OUT commands  #define	VRQ_SET_LED			0x01		// wValueL off/on {0,1}; wIndexL: which {0,1} diff --git a/firmware/fx2/src/usrp1/spi.c b/firmware/fx2/src/usrp1/spi.c index f5803c55b..0aaffea5d 100644 --- a/firmware/fx2/src/usrp1/spi.c +++ b/firmware/fx2/src/usrp1/spi.c @@ -97,13 +97,18 @@ count_bits8 (unsigned char v)  static void  write_byte_msb (unsigned char v); +unsigned char +transact_byte_msb (unsigned char v); +  static void  write_bytes_msb (const xdata unsigned char *buf, unsigned char len);  static void  read_bytes_msb (xdata unsigned char *buf, unsigned char len); -   +static void +transact_bytes_msb (xdata unsigned char *buf, unsigned char len); +  // returns non-zero if successful, else 0  unsigned char  spi_read (unsigned char header_hi, unsigned char header_lo, @@ -214,7 +219,93 @@ spi_write (unsigned char header_hi, unsigned char header_lo,    return 1;		// success  } -// ---------------------------------------------------------------- +unsigned char +spi_transact (unsigned char data0, unsigned char data1, +              unsigned char data2, unsigned char data3, +              unsigned char enables, xdata unsigned char *buf, +              unsigned char len) +{ +  if (count_bits8 (enables) > 1) +    return 0;		// error, too many enables set + +  if (len > 4) +    return 0; + +  setup_enables (enables); + +  buf[0] = data0; +  buf[1] = data1; +  buf[2] = data2;  +  buf[3] = data3;  + +  if (len != 0) +    transact_bytes_msb(buf, len); + +  disable_all (); +  return 1;		// success +} + +static unsigned char  +transact_byte_msb (unsigned char v) +{ +  v = (v << 1) | (v >> 7);	// rotate left (MSB into bottom bit) +  bitS_OUT = v & 0x1; +  bitS_CLK = 1; +  v |= bitS_IN;                 // read into bottom bit +  bitS_CLK = 0; + +  v = (v << 1) | (v >> 7); +  bitS_OUT = v & 0x1; +  bitS_CLK = 1; +  v |= bitS_IN; +  bitS_CLK = 0; + +  v = (v << 1) | (v >> 7); +  bitS_OUT = v & 0x1; +  bitS_CLK = 1; +  v |= bitS_IN; +  bitS_CLK = 0; + +  v = (v << 1) | (v >> 7); +  bitS_OUT = v & 0x1; +  bitS_CLK = 1; +  v |= bitS_IN; +  bitS_CLK = 0; + +  v = (v << 1) | (v >> 7); +  bitS_OUT = v & 0x1; +  bitS_CLK = 1; +  v |= bitS_IN; +  bitS_CLK = 0; + +  v = (v << 1) | (v >> 7); +  bitS_OUT = v & 0x1; +  bitS_CLK = 1; +  v |= bitS_IN; +  bitS_CLK = 0; + +  v = (v << 1) | (v >> 7); +  bitS_OUT = v & 0x1; +  bitS_CLK = 1; +  v |= bitS_IN; +  bitS_CLK = 0; + +  v = (v << 1) | (v >> 7); +  bitS_OUT = v & 0x1; +  bitS_CLK = 1; +  v |= bitS_IN; +  bitS_CLK = 0; + +  return v; +} + +static void +transact_bytes_msb (xdata unsigned char *buf, unsigned char len) +{ +  while (len-- != 0){ +    *buf++ = transact_byte_msb (*buf); +  } +}  static void  write_byte_msb (unsigned char v) diff --git a/firmware/fx2/src/usrp1/spi.h b/firmware/fx2/src/usrp1/spi.h index 12bc5e544..5342b82b8 100644 --- a/firmware/fx2/src/usrp1/spi.h +++ b/firmware/fx2/src/usrp1/spi.h @@ -39,5 +39,12 @@ spi_write (unsigned char header_hi, unsigned char header_lo,  	   unsigned char enables, unsigned char format,  	   const xdata unsigned char *buf, unsigned char len); +// returns non-zero if successful, else 0 +unsigned char +spi_transact (unsigned char data0, unsigned char data1, +              unsigned char data2, unsigned char data3, +	      unsigned char enables, xdata unsigned char *buf, +              unsigned char len); +  #endif /* INCLUDED_SPI_H */ diff --git a/firmware/fx2/src/usrp1/usrp_main.c b/firmware/fx2/src/usrp1/usrp_main.c index c7c09f8c5..b8c2e98ec 100644 --- a/firmware/fx2/src/usrp1/usrp_main.c +++ b/firmware/fx2/src/usrp1/usrp_main.c @@ -117,7 +117,7 @@ app_vendor_cmd (void)        EP0BCH = 0;        EP0BCL = wLengthL;        break; -       +      case VRQ_SPI_READ:        if (!spi_read (wValueH, wValueL, wIndexH, wIndexL, EP0BUF, wLengthL))  	return 0; @@ -126,6 +126,14 @@ app_vendor_cmd (void)        EP0BCL = wLengthL;        break; +    case VRQ_SPI_TRANSACT: +      if (!spi_transact (wValueH, wValueL, wIndexH, wIndexL, wLengthH, EP0BUF, wLengthL)) +	return 0; + +      EP0BCH = 0; +      EP0BCL = wLengthL; +      break; +      default:        return 0;      } | 
