freemyipod r386 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r385‎ | r386 | r387 >
Date:19:42, 26 December 2010
Author:theseven
Status:new
Tags:
Comment:
emBIOS: Fix occasional I2C hangs on S5L8702
Modified paths:
  • /embios/trunk/target/ipodnano3g/i2c.c (modified) (history)
  • /embios/trunk/target/ipodnano3g/s5l8702.h (modified) (history)

Diff [purge]

Index: embios/trunk/target/ipodnano3g/i2c.c
@@ -38,14 +38,19 @@
3939 void i2c_send(uint32_t bus, uint32_t device, uint32_t address, const uint8_t* data, uint32_t length)
4040 {
4141 mutex_lock(&i2cmutex, TIMEOUT_BLOCK);
 42+ while (IIC10(bus));
4243 IICDS(bus) = device & ~1;
 44+ while (IIC10(bus));
4345 IICSTAT(bus) = 0xF0;
 46+ while (IIC10(bus));
4447 IICCON(bus) = 0xB7;
4548 while ((IICCON(bus) & 0x10) == 0) yield();
4649 if (address >= 0)
4750 {
4851 /* write address */
 52+ while (IIC10(bus));
4953 IICDS(bus) = address;
 54+ while (IIC10(bus));
5055 IICCON(bus) = 0xB7;
5156 while ((IICCON(bus) & 0x10) == 0) yield();
5257 }
@@ -52,12 +57,16 @@
5358 /* write data */
5459 while (length--)
5560 {
 61+ while (IIC10(bus));
5662 IICDS(bus) = *data++;
 63+ while (IIC10(bus));
5764 IICCON(bus) = 0xB7;
5865 while ((IICCON(bus) & 0x10) == 0) yield();
5966 }
6067 /* STOP */
 68+ while (IIC10(bus));
6169 IICSTAT(bus) = 0xD0;
 70+ while (IIC10(bus));
6271 IICCON(bus) = 0xB7;
6372 while ((IICSTAT(bus) & (1 << 5)) != 0) yield();
6473 mutex_unlock(&i2cmutex);
@@ -69,28 +78,39 @@
7079 if (address >= 0)
7180 {
7281 /* START */
 82+ while (IIC10(bus));
7383 IICDS(bus) = device & ~1;
 84+ while (IIC10(bus));
7485 IICSTAT(bus) = 0xF0;
 86+ while (IIC10(bus));
7587 IICCON(bus) = 0xB7;
7688 while ((IICCON(bus) & 0x10) == 0) yield();
7789 /* write address */
 90+ while (IIC10(bus));
7891 IICDS(bus) = address;
 92+ while (IIC10(bus));
7993 IICCON(bus) = 0xB7;
8094 while ((IICCON(bus) & 0x10) == 0) yield();
8195 }
8296 /* (repeated) START */
 97+ while (IIC10(bus));
8398 IICDS(bus) = device | 1;
 99+ while (IIC10(bus));
84100 IICSTAT(bus) = 0xB0;
 101+ while (IIC10(bus));
85102 IICCON(bus) = 0xB7;
86103 while ((IICCON(bus) & 0x10) == 0) yield();
87104 while (length--)
88105 {
 106+ while (IIC10(bus));
89107 IICCON(bus) = (length == 0) ? 0x37 : 0xB7; /* NACK or ACK */
90108 while ((IICCON(bus) & 0x10) == 0) yield();
91109 *data++ = IICDS(bus);
92110 }
93111 /* STOP */
 112+ while (IIC10(bus));
94113 IICSTAT(bus) = 0x90;
 114+ while (IIC10(bus));
95115 IICCON(bus) = 0xB7;
96116 while ((IICSTAT(bus) & (1 << 5)) != 0) yield();
97117 mutex_unlock(&i2cmutex);
Index: embios/trunk/target/ipodnano3g/s5l8702.h
@@ -99,6 +99,7 @@
100100 #define IICSTAT(bus) (*((uint32_t volatile*)(0x3C600004 + 0x300000 * (bus))))
101101 #define IICADD(bus) (*((uint32_t volatile*)(0x3C600008 + 0x300000 * (bus))))
102102 #define IICDS(bus) (*((uint32_t volatile*)(0x3C60000C + 0x300000 * (bus))))
 103+#define IIC10(bus) (*((uint32_t volatile*)(0x3C600010 + 0x300000 * (bus))))
103104
104105
105106 /////INTERRUPT CONTROLLERS/////