diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-06-27 00:22:46 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-06-27 00:22:46 +0000 |
commit | 9614612830f05be75c82df1bb226c9375ae8c466 (patch) | |
tree | 0e7f9156bc5ab92181807c078f5dd921a4eee979 | |
parent | 126d81ecf5e65fdf97ab82970e6a61639e0ad43a (diff) |
Bit banged TEA5767 i2c driver was broken by -Os because delay loops were optimized away. Last byte was being acked when reading so fix that too. Calling all developers: seek out any C delay loops and make sure they're volatile.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13723 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/drivers/fmradio_i2c.c | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/firmware/drivers/fmradio_i2c.c b/firmware/drivers/fmradio_i2c.c index 62761b3aa7..b17a979288 100644 --- a/firmware/drivers/fmradio_i2c.c +++ b/firmware/drivers/fmradio_i2c.c @@ -80,8 +80,7 @@ int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) #endif /* delay loop to achieve 400kHz at 120MHz CPU frequency */ -#define DELAY do { int _x; for(_x=0;_x<22;_x++);} while(0) - +#define DELAY do { volatile int _x; for(_x=0;_x<22;_x++);} while (0) static void fmradio_i2c_start(void) { @@ -207,8 +206,6 @@ static unsigned char fmradio_i2c_inb(void) SDA_OUTPUT; } - fmradio_i2c_ack(); - return byte; } @@ -248,9 +245,11 @@ int fmradio_i2c_read(int address, unsigned char* buf, int count) if (fmradio_i2c_getack()) { - for (i=0; i<count; i++) + for (i=count; i>0; i--) { - buf[i] = fmradio_i2c_inb(); + *buf++ = fmradio_i2c_inb(); + if (i != 1) + fmradio_i2c_ack(); } } else @@ -276,8 +275,7 @@ int fmradio_i2c_read(int address, unsigned char* buf, int count) #define SCL (PBDR & 0x0002) /* arbitrary delay loop */ -#define DELAY do { int _x; for(_x=0;_x<20;_x++);} while (0) - +#define DELAY do { volatile int _x; for(_x=0;_x<20;_x++);} while (0) static void fmradio_i2c_start(void) { @@ -370,7 +368,7 @@ static void fmradio_i2c_outb(unsigned char byte) SDA_HI; } -static unsigned char fmradio_i2c_inb(int ack) +static unsigned char fmradio_i2c_inb(void) { int i; unsigned char byte = 0; @@ -385,8 +383,6 @@ static unsigned char fmradio_i2c_inb(int ack) SDA_OUTPUT; } - fmradio_i2c_ack(ack); - return byte; } @@ -424,8 +420,11 @@ int fmradio_i2c_read(int address, unsigned char* buf, int count) fmradio_i2c_start(); fmradio_i2c_outb(address | 1); if (fmradio_i2c_getack()) { - for (i=0; i<count; i++) { - buf[i] = fmradio_i2c_inb(0); + for (i=count; i>0; i--) + { + *buf++ = fmradio_i2c_inb(); + if (i != 1) + fmradio_i2c_ack(ack); } } else |