1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Maurus Cuelenaere 2008-04-09 15:25:20 +00:00
parent 6848961aa5
commit c02b183546
2 changed files with 119 additions and 45 deletions

View file

@ -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;
}
static int i2c_outb(unsigned char byte)
{
(void) byte;
return 0;
}
#endif
#define WAIT_FOR_I2C if(IO_I2C_SCS & 0x4){ \
while(IO_I2C_SCS & 0x4) { \
asm volatile("nop"); \
} \
} \
void i2c_write(int addr, const unsigned char *buf, int count)
static inline void i2c_start(void)
{
(void) addr;
(void) buf;
(void) count;
IO_I2C_SCS |= I2C_SCS_XMIT;
return;
}
int i2c_write(unsigned short address, const unsigned char *buf, int count)
{
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;
}
int i2c_read(unsigned short address, unsigned char* buf, int 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
}

View file

@ -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);