/* -*- c++ -*- */\r
-\r
/*-----------------------------------------------------------------------------\r
-\r
* I2C read/write functions for FX2\r
-\r
*-----------------------------------------------------------------------------\r
-\r
* Code taken from USRP2 firmware (GNU Radio Project), version 3.0.2,\r
-\r
* Copyright 2003 Free Software Foundation, Inc.\r
-\r
*-----------------------------------------------------------------------------\r
-\r
* This code is part of usbjtag. usbjtag is free software; you can redistribute\r
-\r
* it and/or modify it under the terms of the GNU General Public License as\r
-\r
* published by the Free Software Foundation; either version 2 of the License,\r
-\r
* or (at your option) any later version. usbjtag is distributed in the hope\r
-\r
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied\r
-\r
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-\r
* GNU General Public License for more details. You should have received a\r
-\r
* copy of the GNU General Public License along with this program in the file\r
-\r
* COPYING; if not, write to the Free Software Foundation, Inc., 51 Franklin\r
-\r
* St, Fifth Floor, Boston, MA 02110-1301 USA\r
-\r
*-----------------------------------------------------------------------------\r
-\r
*/\r
\r
-\r
-\r
#include "i2c.h"\r
-\r
#include "fx2regs.h"\r
-\r
#include <string.h>\r
\r
\r
-\r
-\r
-\r
// issue a stop bus cycle and wait for completion\r
\r
\r
-\r
-\r
-\r
// returns non-zero if successful, else 0\r
-\r
unsigned char\r
-\r
i2c_read (unsigned char addr, xdata unsigned char *buf, unsigned char len)\r
-\r
{\r
-\r
volatile unsigned char junk;\r
-\r
\r
-\r
if (len == 0) // reading zero bytes always works\r
-\r
return 1;\r
-\r
\r
-\r
while (I2CS & bmSTOP) // wait for stop to clear\r
-\r
;\r
\r
-\r
-\r
I2CS = bmSTART;\r
-\r
I2DAT = (addr << 1) | 1; // write address and direction (1's the read bit)\r
\r
-\r
-\r
while ((I2CS & bmDONE) == 0)\r
-\r
;\r
\r
-\r
-\r
if ((I2CS & bmBERR) || (I2CS & bmACK) == 0) // no device answered...\r
-\r
goto fail;\r
\r
-\r
-\r
if (len == 1)\r
-\r
I2CS |= bmLASTRD; \r
\r
-\r
-\r
junk = I2DAT; // trigger the first read cycle\r
\r
-\r
-\r
while (--len != 0){\r
-\r
while ((I2CS & bmDONE) == 0)\r
-\r
;\r
\r
-\r
-\r
if (I2CS & bmBERR)\r
-\r
goto fail;\r
\r
-\r
-\r
if (len == 1)\r
-\r
I2CS |= bmLASTRD;\r
-\r
\r
-\r
*buf++ = I2DAT; // get data, trigger another read\r
-\r
}\r
\r
-\r
-\r
// wait for final byte\r
-\r
\r
-\r
while ((I2CS & bmDONE) == 0)\r
-\r
;\r
-\r
\r
-\r
if (I2CS & bmBERR)\r
-\r
goto fail;\r
\r
-\r
-\r
I2CS |= bmSTOP;\r
-\r
*buf = I2DAT;\r
\r
-\r
-\r
return 1;\r
\r
-\r
-\r
fail:\r
-\r
I2CS |= bmSTOP;\r
-\r
return 0;\r
-\r
}\r
\r
\r
\r
-\r
-\r
-\r
-\r
// returns non-zero if successful, else 0\r
-\r
unsigned char\r
-\r
i2c_write (unsigned char addr, xdata const unsigned char *buf, unsigned char len)\r
-\r
{\r
-\r
while (I2CS & bmSTOP) // wait for stop to clear\r
-\r
;\r
\r
-\r
-\r
I2CS = bmSTART;\r
-\r
I2DAT = (addr << 1) | 0; // write address and direction (0's the write bit)\r
\r
-\r
-\r
while ((I2CS & bmDONE) == 0)\r
-\r
;\r
\r
-\r
-\r
if ((I2CS & bmBERR) || (I2CS & bmACK) == 0) // no device answered...\r
-\r
goto fail;\r
\r
-\r
-\r
while (len > 0){\r
-\r
I2DAT = *buf++;\r
-\r
len--;\r
\r
-\r
-\r
while ((I2CS & bmDONE) == 0)\r
-\r
;\r
\r
-\r
-\r
if ((I2CS & bmBERR) || (I2CS & bmACK) == 0) // no device answered...\r
-\r
goto fail;\r
-\r
}\r
\r
-\r
-\r
I2CS |= bmSTOP;\r
-\r
return 1;\r
\r
-\r
-\r
fail:\r
-\r
I2CS |= bmSTOP;\r
-\r
return 0;\r
-\r
}\r
-\r