diff options
author | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2008-04-09 15:25:20 +0000 |
---|---|---|
committer | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2008-04-09 15:25:20 +0000 |
commit | c02b1835460ebf615f497a477bc46c3f7eea659e (patch) | |
tree | 8ea76ea516e801ad534edfdc50c64bc388da6a47 | |
parent | 6848961aa5f93a290917071ff3496e1d5026621b (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-x | firmware/target/arm/tms320dm320/i2c-dm320.c | 128 | ||||
-rwxr-xr-x | firmware/target/arm/tms320dm320/i2c-dm320.h | 30 |
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); |