From 735ea2fd1f746bed999e488eee129ff5b3af059a Mon Sep 17 00:00:00 2001 From: Marcin Bukat Date: Tue, 1 Mar 2011 09:13:48 +0000 Subject: Move drivers/i2c.c into target tree as it contains SH specific bits. Leave associated header file intact as it is used in many places for historical reasons. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29480 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 2 +- firmware/drivers/i2c.c | 252 --------------------------------- firmware/target/sh/archos/i2c-archos.c | 252 +++++++++++++++++++++++++++++++++ 3 files changed, 253 insertions(+), 253 deletions(-) delete mode 100644 firmware/drivers/i2c.c create mode 100644 firmware/target/sh/archos/i2c-archos.c diff --git a/firmware/SOURCES b/firmware/SOURCES index b1378ff28a..2952ad71d2 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -401,7 +401,6 @@ drivers/audio/tsc2100.c #if defined(CPU_SH) #ifndef SIMULATOR -drivers/i2c.c target/sh/adc-sh.c target/sh/bitswap.S target/sh/crt0.S @@ -412,6 +411,7 @@ target/sh/memset-sh.S target/sh/strlen-sh.S target/sh/system-sh.c target/sh/archos/descramble.S +target/sh/archos/i2c-archos.c target/sh/debug-sh.c #endif /* SIMULATOR */ diff --git a/firmware/drivers/i2c.c b/firmware/drivers/i2c.c deleted file mode 100644 index b3a53240b4..0000000000 --- a/firmware/drivers/i2c.c +++ /dev/null @@ -1,252 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2002 by Linus Nielsen Feltzing - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "lcd.h" -#include "cpu.h" -#include "kernel.h" -#include "thread.h" -#include "debug.h" -#include "system.h" -#include "i2c.h" - -/* cute little functions, atomic read-modify-write */ - -/* SDA is PB7 */ -#define SDA_LO and_b(~0x80, &PBDRL) -#define SDA_HI or_b(0x80, &PBDRL) -#define SDA_INPUT and_b(~0x80, &PBIORL) -#define SDA_OUTPUT or_b(0x80, &PBIORL) -#define SDA (PBDRL & 0x80) - -#if CONFIG_I2C == I2C_ONDIO -/* Ondio pinout, SCL moved to PB6 */ -#define SCL_INPUT and_b(~0x40, &PBIORL) -#define SCL_OUTPUT or_b(0x40, &PBIORL) -#define SCL_LO and_b(~0x40, &PBDRL) -#define SCL_HI or_b(0x40, &PBDRL) -#define SCL (PBDRL & 0x40) -#else -/* "classic" pinout, SCL is PB13 */ -#define SCL_INPUT and_b(~0x20, &PBIORH) -#define SCL_OUTPUT or_b(0x20, &PBIORH) -#define SCL_LO and_b(~0x20, &PBDRH) -#define SCL_HI or_b(0x20, &PBDRH) -#define SCL (PBDRH & 0x20) -#endif - -/* arbitrary delay loop */ -#define DELAY do { int _x; for(_x=0;_x<20;_x++);} while (0) - -static struct mutex i2c_mtx SHAREDBSS_ATTR; - -void i2c_begin(void) -{ - mutex_lock(&i2c_mtx); -} - -void i2c_end(void) -{ - mutex_unlock(&i2c_mtx); -} - -void i2c_start(void) -{ - SDA_OUTPUT; - SDA_HI; - SCL_HI; - SDA_LO; - DELAY; - SCL_LO; -} - -void i2c_stop(void) -{ - SDA_LO; - SCL_HI; - DELAY; - SDA_HI; -} - -void i2c_init(void) -{ - int i; - - mutex_init(&i2c_mtx); - -#if CONFIG_I2C == I2C_ONDIO - /* make PB6 & PB7 general I/O */ - PBCR2 &= ~0xf000; -#else /* not Ondio */ - /* make PB7 & PB13 general I/O */ - PBCR1 &= ~0x0c00; /* PB13 */ - PBCR2 &= ~0xc000; /* PB7 */ -#endif - - SCL_OUTPUT; - SDA_OUTPUT; - SDA_HI; - SCL_LO; - for (i=0;i<3;i++) - i2c_stop(); -} - -void i2c_ack(int bit) -{ - /* Here's the deal. The MAS is slow, and sometimes needs to wait - before it can receive the acknowledge. Therefore it forces the clock - low until it is ready. We need to poll the clock line until it goes - high before we release the ack. */ - - SCL_LO; /* Set the clock low */ - if ( bit ) - { - SDA_HI; - } - else - { - SDA_LO; - } - - SCL_INPUT; /* Set the clock to input */ - while(!SCL) /* and wait for the MAS to release it */ - sleep(0); - - DELAY; - SCL_OUTPUT; - SCL_LO; -} - -int i2c_getack(void) -{ - int ret = 1; - - /* Here's the deal. The MAS is slow, and sometimes needs to wait - before it can send the acknowledge. Therefore it forces the clock - low until it is ready. We need to poll the clock line until it goes - high before we read the ack. */ - -#ifdef HAVE_I2C_LOW_FIRST - SDA_LO; /* First, discharge the data line */ -#endif - SDA_INPUT; /* And set to input */ - SCL_INPUT; /* Set the clock to input */ - while(!SCL) /* and wait for the MAS to release it */ - sleep(0); - - if (SDA) - /* ack failed */ - ret = 0; - - SCL_OUTPUT; - SCL_LO; - SDA_HI; - SDA_OUTPUT; - return ret; -} - -void i2c_outb(unsigned char byte) -{ - int i; - - /* clock out each bit, MSB first */ - for ( i=0x80; i; i>>=1 ) { - if ( i & byte ) - { - SDA_HI; - } - else - { - SDA_LO; - } - SCL_HI; - SCL_LO; - } - - SDA_HI; -} - -unsigned char i2c_inb(int ack) -{ - int i; - unsigned char byte = 0; - - /* clock in each bit, MSB first */ - for ( i=0x80; i; i>>=1 ) { -#ifdef HAVE_I2C_LOW_FIRST - /* Tricky business. Here we discharge the data line by driving it low - and then set it to input to see if it stays low or goes high */ - SDA_LO; /* First, discharge the data line */ -#endif - SDA_INPUT; /* And set to input */ - SCL_HI; - if ( SDA ) - byte |= i; - SCL_LO; - SDA_OUTPUT; - } - - i2c_ack(ack); - - return byte; -} - -int i2c_write(int address, const unsigned char* buf, int count ) -{ - int i,x=0; - - i2c_start(); - i2c_outb(address & 0xfe); - if (i2c_getack()) - { - for (i=0; i ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Linus Nielsen Feltzing + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "lcd.h" +#include "cpu.h" +#include "kernel.h" +#include "thread.h" +#include "debug.h" +#include "system.h" +#include "i2c.h" + +/* cute little functions, atomic read-modify-write */ + +/* SDA is PB7 */ +#define SDA_LO and_b(~0x80, &PBDRL) +#define SDA_HI or_b(0x80, &PBDRL) +#define SDA_INPUT and_b(~0x80, &PBIORL) +#define SDA_OUTPUT or_b(0x80, &PBIORL) +#define SDA (PBDRL & 0x80) + +#if CONFIG_I2C == I2C_ONDIO +/* Ondio pinout, SCL moved to PB6 */ +#define SCL_INPUT and_b(~0x40, &PBIORL) +#define SCL_OUTPUT or_b(0x40, &PBIORL) +#define SCL_LO and_b(~0x40, &PBDRL) +#define SCL_HI or_b(0x40, &PBDRL) +#define SCL (PBDRL & 0x40) +#else +/* "classic" pinout, SCL is PB13 */ +#define SCL_INPUT and_b(~0x20, &PBIORH) +#define SCL_OUTPUT or_b(0x20, &PBIORH) +#define SCL_LO and_b(~0x20, &PBDRH) +#define SCL_HI or_b(0x20, &PBDRH) +#define SCL (PBDRH & 0x20) +#endif + +/* arbitrary delay loop */ +#define DELAY do { int _x; for(_x=0;_x<20;_x++);} while (0) + +static struct mutex i2c_mtx SHAREDBSS_ATTR; + +void i2c_begin(void) +{ + mutex_lock(&i2c_mtx); +} + +void i2c_end(void) +{ + mutex_unlock(&i2c_mtx); +} + +void i2c_start(void) +{ + SDA_OUTPUT; + SDA_HI; + SCL_HI; + SDA_LO; + DELAY; + SCL_LO; +} + +void i2c_stop(void) +{ + SDA_LO; + SCL_HI; + DELAY; + SDA_HI; +} + +void i2c_init(void) +{ + int i; + + mutex_init(&i2c_mtx); + +#if CONFIG_I2C == I2C_ONDIO + /* make PB6 & PB7 general I/O */ + PBCR2 &= ~0xf000; +#else /* not Ondio */ + /* make PB7 & PB13 general I/O */ + PBCR1 &= ~0x0c00; /* PB13 */ + PBCR2 &= ~0xc000; /* PB7 */ +#endif + + SCL_OUTPUT; + SDA_OUTPUT; + SDA_HI; + SCL_LO; + for (i=0;i<3;i++) + i2c_stop(); +} + +void i2c_ack(int bit) +{ + /* Here's the deal. The MAS is slow, and sometimes needs to wait + before it can receive the acknowledge. Therefore it forces the clock + low until it is ready. We need to poll the clock line until it goes + high before we release the ack. */ + + SCL_LO; /* Set the clock low */ + if ( bit ) + { + SDA_HI; + } + else + { + SDA_LO; + } + + SCL_INPUT; /* Set the clock to input */ + while(!SCL) /* and wait for the MAS to release it */ + sleep(0); + + DELAY; + SCL_OUTPUT; + SCL_LO; +} + +int i2c_getack(void) +{ + int ret = 1; + + /* Here's the deal. The MAS is slow, and sometimes needs to wait + before it can send the acknowledge. Therefore it forces the clock + low until it is ready. We need to poll the clock line until it goes + high before we read the ack. */ + +#ifdef HAVE_I2C_LOW_FIRST + SDA_LO; /* First, discharge the data line */ +#endif + SDA_INPUT; /* And set to input */ + SCL_INPUT; /* Set the clock to input */ + while(!SCL) /* and wait for the MAS to release it */ + sleep(0); + + if (SDA) + /* ack failed */ + ret = 0; + + SCL_OUTPUT; + SCL_LO; + SDA_HI; + SDA_OUTPUT; + return ret; +} + +void i2c_outb(unsigned char byte) +{ + int i; + + /* clock out each bit, MSB first */ + for ( i=0x80; i; i>>=1 ) { + if ( i & byte ) + { + SDA_HI; + } + else + { + SDA_LO; + } + SCL_HI; + SCL_LO; + } + + SDA_HI; +} + +unsigned char i2c_inb(int ack) +{ + int i; + unsigned char byte = 0; + + /* clock in each bit, MSB first */ + for ( i=0x80; i; i>>=1 ) { +#ifdef HAVE_I2C_LOW_FIRST + /* Tricky business. Here we discharge the data line by driving it low + and then set it to input to see if it stays low or goes high */ + SDA_LO; /* First, discharge the data line */ +#endif + SDA_INPUT; /* And set to input */ + SCL_HI; + if ( SDA ) + byte |= i; + SCL_LO; + SDA_OUTPUT; + } + + i2c_ack(ack); + + return byte; +} + +int i2c_write(int address, const unsigned char* buf, int count ) +{ + int i,x=0; + + i2c_start(); + i2c_outb(address & 0xfe); + if (i2c_getack()) + { + for (i=0; i