summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2008-04-09 15:25:20 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2008-04-09 15:25:20 +0000
commitc02b1835460ebf615f497a477bc46c3f7eea659e (patch)
tree8ea76ea516e801ad534edfdc50c64bc388da6a47
parent6848961aa5f93a290917071ff3496e1d5026621b (diff)
Add DM320 I²C driver, although not (yet) enabled in the sources.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17050 a1c6a512-1295-4272-9138-f99709370657
-rwxr-xr-xfirmware/target/arm/tms320dm320/i2c-dm320.c128
-rwxr-xr-xfirmware/target/arm/tms320dm320/i2c-dm320.h30
2 files changed, 116 insertions, 42 deletions
diff --git a/firmware/target/arm/tms320dm320/i2c-dm320.c b/firmware/target/arm/tms320dm320/i2c-dm320.c
index 4ca5eb7118..cb6411e412 100755
--- a/firmware/target/arm/tms320dm320/i2c-dm320.c
+++ b/firmware/target/arm/tms320dm320/i2c-dm320.c
@@ -7,7 +7,9 @@
* \/ \/ \/ \/ \/
* $Id$
*
- * Copyright (C) 2007 by Karl Kurbjun
+ * Copyright (C) 2008 by Maurus Cuelenaere
+ *
+ * DM320 I²C driver
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
@@ -17,39 +19,133 @@
*
****************************************************************************/
#include "system.h"
+#include "thread.h"
#include "i2c-dm320.h"
-#if 0
-static int i2c_getack(void)
+#define I2C_SCS_COND_START 0x0001
+#define I2C_SCS_COND_STOP 0x0002
+#define I2C_SCS_XMIT 0x0004
+
+#define I2C_TX_ACK (1 << 20)
+
+static struct mutex i2c_mtx;
+
+static inline void i2c_begin(void)
{
- return 0;
+ mutex_lock(&i2c_mtx);
}
-static int i2c_start(void)
+static inline void i2c_end(void)
{
- return 0;
+ mutex_unlock(&i2c_mtx);
}
-static void i2c_stop(void)
+static inline bool i2c_getack(void)
{
+ return (IO_I2C_RXDATA & 0x100)>>8;
+}
+
+#define WAIT_FOR_I2C if(IO_I2C_SCS & 0x4){ \
+ while(IO_I2C_SCS & 0x4) { \
+ asm volatile("nop"); \
+ } \
+ } \
+static inline void i2c_start(void)
+{
+ IO_I2C_SCS |= I2C_SCS_XMIT;
+ return;
}
-static int i2c_outb(unsigned char byte)
+int i2c_write(unsigned short address, const unsigned char *buf, int count)
{
- (void) byte;
- return 0;
+ int i;
+ int ret=0;
+ i2c_begin();
+ IO_I2C_TXDATA = ( (address << 1) & 0xFF ) | (address>0x7F ? 0 : 1 ) | I2C_TX_ACK;
+ IO_I2C_SCS &= ~0x3; //clear conditions
+ IO_I2C_SCS |= I2C_SCS_COND_START; // write 'start condition'
+ i2c_start();
+ WAIT_FOR_I2C;
+ /* experimental */
+ if(address>0x7F){ // check if it is 10-bit instead of 7-bit
+ IO_I2C_TXDATA = ( (address >> 7) & 0xFF) | I2C_TX_ACK;
+ IO_I2C_SCS &= ~0x3; //normal transfer
+ i2c_start();
+ WAIT_FOR_I2C;
+ IO_I2C_TXDATA = ( (address << 1) & 0xFF) | 1 | I2C_TX_ACK;
+ IO_I2C_SCS &= ~0x3; //clear conditions
+ IO_I2C_SCS |= I2C_SCS_COND_START; //write 'start condition'
+ i2c_start();
+ WAIT_FOR_I2C;
+ }
+
+ for(i=0; i<count; i++){
+ IO_I2C_TXDATA = buf[i] | I2C_TX_ACK;
+ IO_I2C_SCS &= ~0x3; //normal transfer
+ i2c_start();
+ WAIT_FOR_I2C;
+ if(!i2c_getack())
+ ret = -1;
+ }
+ IO_I2C_SCS &= ~0x3; //clear conditions
+ IO_I2C_SCS |= I2C_SCS_COND_STOP; //write 'stop condition'
+ i2c_start();
+ WAIT_FOR_I2C;
+ i2c_end();
+ return ret;
}
-#endif
-void i2c_write(int addr, const unsigned char *buf, int count)
+int i2c_read(unsigned short address, unsigned char* buf, int count)
{
- (void) addr;
- (void) buf;
- (void) count;
+ int i;
+ int ack=0;
+ i2c_begin();
+ IO_I2C_TXDATA = ( (address << 1) & 0xFF ) | (address>0x7F ? 0 : 1 ) | I2C_TX_ACK;
+ IO_I2C_SCS &= ~0x3; //clear conditions
+ IO_I2C_SCS |= I2C_SCS_COND_START; // write 'start condition'
+ i2c_start();
+ WAIT_FOR_I2C;
+ /* experimental */
+ if(address>0x7F){ // check if it is 10-bit instead of 7-bit
+ IO_I2C_TXDATA = ( (address >> 7) & 0xFF ) | I2C_TX_ACK;
+ IO_I2C_SCS &= ~0x3; //normal transfer
+ i2c_start();
+ WAIT_FOR_I2C;
+ IO_I2C_TXDATA = ( (address << 1) & 0xFF ) | 1 | I2C_TX_ACK;
+ IO_I2C_SCS &= ~0x3; //clear conditions
+ IO_I2C_SCS |= I2C_SCS_COND_START; //write 'start condition'
+ i2c_start();
+ WAIT_FOR_I2C;
+ }
+
+ for(i=0; i<count; i++){
+ unsigned short temp;
+ IO_I2C_TXDATA = 0xFF | ( (count-1)==i ? I2C_TX_ACK : 0);
+ IO_I2C_SCS &= ~0x3; //normal transfer
+ i2c_start();
+ WAIT_FOR_I2C;
+ temp = IO_I2C_RXDATA;
+ buf[i] = temp & 0xFF;
+ ack = (temp & 0x100) >> 8;
+ }
+ IO_I2C_SCS &= ~0x3; //clear conditions
+ IO_I2C_SCS |= I2C_SCS_COND_STOP; //write 'stop condition'
+ i2c_start();
+ WAIT_FOR_I2C;
+ i2c_end();
+ return ack;
}
void i2c_init(void)
{
-
+#if 0 //TODO: mimic OF I2C clock settings; currently this is done by the bootloader
+ IO_CLK_MOD2 &= ~CLK_MOD2_I2C; // turn I²C clock off (just to be sure)
+ IO_CLK_LPCTL1 &= ~1; // set Powerdown mode to off
+ IO_CLK_SEL0 &= ~0x800; // set I²C clock to PLLA
+ IO_CLK_DIV4 &= ~0x1F; // I²C clock division = 1
+ IO_CLK_MOD2 |= CLK_MOD2_I2C; // enable I²C clock
+#endif
+ IO_I2C_SCS &= ~0x8; //set clock to 100 kHz
+ IO_INTC_EINT2 &= ~INTR_EINT2_I2C; // disable I²C interrupt
}
diff --git a/firmware/target/arm/tms320dm320/i2c-dm320.h b/firmware/target/arm/tms320dm320/i2c-dm320.h
index aa7ced1119..d73a334eb4 100755
--- a/firmware/target/arm/tms320dm320/i2c-dm320.h
+++ b/firmware/target/arm/tms320dm320/i2c-dm320.h
@@ -5,9 +5,9 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
- * $Id: i2c-meg-fx.h 13720 2007-06-26 02:11:30Z jethead71 $
+ * $Id$
*
- * Copyright (C) 2007 by Michael Sevakis
+ * Copyright (C) 2008 by Maurus Cuelenaere
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
@@ -17,28 +17,6 @@
*
****************************************************************************/
-/* chip-specific i2c functions */
-
-/* IICCON */
-#define I2C_ACKGEN (1 << 7)
-#define I2C_TXCLK_512 (1 << 6)
-#define I2C_TXRX_INTENB (1 << 5)
-#define I2C_TXRX_INTPND (1 << 4)
-
-/* IICSTAT */
-#define I2C_MODE_MASTER (2 << 6)
-#define I2C_MODE_TX (1 << 6)
-#define I2C_BUSY (1 << 5)
-#define I2C_START (1 << 5)
-#define I2C_RXTX_ENB (1 << 4)
-#define I2C_BUS_ARB_FAILED (1 << 3)
-#define I2C_S_ADDR_STAT (1 << 2)
-#define I2C_S_ADDR_MATCH (1 << 1)
-#define I2C_ACK_L (1 << 0)
-
-/* IICLC */
-#define I2C_FLT_ENB (1 << 2)
-
void i2c_init(void);
-void i2c_write(int addr, const unsigned char *data, int count);
-
+int i2c_write(unsigned short address, const unsigned char *data, int count);
+int i2c_read(unsigned short address, unsigned char* buf, int count);