summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sparmann <theseven@rockbox.org>2009-10-10 17:22:06 +0000
committerMichael Sparmann <theseven@rockbox.org>2009-10-10 17:22:06 +0000
commit31464f7930cd8857ef8d00ed75534087057058e2 (patch)
tree7ccbbd402ab9b9e0b07f0cc4537a611808ad1c04
parente2aeef7501d0a0ef1c33432692cdaeff225d5d8b (diff)
downloadrockbox-31464f7930cd8857ef8d00ed75534087057058e2.tar.gz
rockbox-31464f7930cd8857ef8d00ed75534087057058e2.zip
Add a timeout for I2C transfers (S5L870x)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23077 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/s5l8700/i2c-s5l8700.c66
1 files changed, 57 insertions, 9 deletions
diff --git a/firmware/target/arm/s5l8700/i2c-s5l8700.c b/firmware/target/arm/s5l8700/i2c-s5l8700.c
index fed10578c2..a5661c5848 100644
--- a/firmware/target/arm/s5l8700/i2c-s5l8700.c
+++ b/firmware/target/arm/s5l8700/i2c-s5l8700.c
@@ -67,31 +67,53 @@ void i2c_init(void)
67int i2c_write(unsigned char slave, int address, int len, const unsigned char *data) 67int i2c_write(unsigned char slave, int address, int len, const unsigned char *data)
68{ 68{
69 mutex_lock(&i2c_mtx); 69 mutex_lock(&i2c_mtx);
70 long timeout = current_tick + HZ / 50;
70 71
71 /* START */ 72 /* START */
72 IICDS = slave & ~1; 73 IICDS = slave & ~1;
73 IICSTAT = 0xF0; 74 IICSTAT = 0xF0;
74 IICCON = 0xB7; 75 IICCON = 0xB7;
75 while ((IICCON & 0x10) == 0); 76 while ((IICCON & 0x10) == 0)
77 if (TIME_AFTER(current_tick, timeout))
78 {
79 mutex_unlock(&i2c_mtx);
80 return 1;
81 }
82
76 83
77 if (address >= 0) { 84 if (address >= 0) {
78 /* write address */ 85 /* write address */
79 IICDS = address; 86 IICDS = address;
80 IICCON = 0xB7; 87 IICCON = 0xB7;
81 while ((IICCON & 0x10) == 0); 88 while ((IICCON & 0x10) == 0)
89 if (TIME_AFTER(current_tick, timeout))
90 {
91 mutex_unlock(&i2c_mtx);
92 return 2;
93 }
82 } 94 }
83 95
84 /* write data */ 96 /* write data */
85 while (len--) { 97 while (len--) {
86 IICDS = *data++; 98 IICDS = *data++;
87 IICCON = 0xB7; 99 IICCON = 0xB7;
88 while ((IICCON & 0x10) == 0); 100 while ((IICCON & 0x10) == 0)
101 if (TIME_AFTER(current_tick, timeout))
102 {
103 mutex_unlock(&i2c_mtx);
104 return 4;
105 }
89 } 106 }
90 107
91 /* STOP */ 108 /* STOP */
92 IICSTAT = 0xD0; 109 IICSTAT = 0xD0;
93 IICCON = 0xB7; 110 IICCON = 0xB7;
94 while ((IICSTAT & (1 << 5)) != 0); 111 while ((IICSTAT & (1 << 5)) != 0)
112 if (TIME_AFTER(current_tick, timeout))
113 {
114 mutex_unlock(&i2c_mtx);
115 return 5;
116 }
95 117
96 mutex_unlock(&i2c_mtx); 118 mutex_unlock(&i2c_mtx);
97 return 0; 119 return 0;
@@ -100,36 +122,62 @@ int i2c_write(unsigned char slave, int address, int len, const unsigned char *da
100int i2c_read(unsigned char slave, int address, int len, unsigned char *data) 122int i2c_read(unsigned char slave, int address, int len, unsigned char *data)
101{ 123{
102 mutex_lock(&i2c_mtx); 124 mutex_lock(&i2c_mtx);
125 long timeout = current_tick + HZ / 50;
103 126
104 if (address >= 0) { 127 if (address >= 0) {
105 /* START */ 128 /* START */
106 IICDS = slave & ~1; 129 IICDS = slave & ~1;
107 IICSTAT = 0xF0; 130 IICSTAT = 0xF0;
108 IICCON = 0xB7; 131 IICCON = 0xB7;
109 while ((IICCON & 0x10) == 0); 132 while ((IICCON & 0x10) == 0)
133 if (TIME_AFTER(current_tick, timeout))
134 {
135 mutex_unlock(&i2c_mtx);
136 return 1;
137 }
110 138
111 /* write address */ 139 /* write address */
112 IICDS = address; 140 IICDS = address;
113 IICCON = 0xB7; 141 IICCON = 0xB7;
114 while ((IICCON & 0x10) == 0); 142 while ((IICCON & 0x10) == 0)
143 if (TIME_AFTER(current_tick, timeout))
144 {
145 mutex_unlock(&i2c_mtx);
146 return 2;
147 }
115 } 148 }
116 149
117 /* (repeated) START */ 150 /* (repeated) START */
118 IICDS = slave | 1; 151 IICDS = slave | 1;
119 IICSTAT = 0xB0; 152 IICSTAT = 0xB0;
120 IICCON = 0xB7; 153 IICCON = 0xB7;
121 while ((IICCON & 0x10) == 0); 154 while ((IICCON & 0x10) == 0)
155 if (TIME_AFTER(current_tick, timeout))
156 {
157 mutex_unlock(&i2c_mtx);
158 return 3;
159 }
122 160
123 while (len--) { 161 while (len--) {
124 IICCON = (len == 0) ? 0x37 : 0xB7; /* NACK or ACK */ 162 IICCON = (len == 0) ? 0x37 : 0xB7; /* NACK or ACK */
125 while ((IICCON & 0x10) == 0); 163 while ((IICCON & 0x10) == 0)
164 if (TIME_AFTER(current_tick, timeout))
165 {
166 mutex_unlock(&i2c_mtx);
167 return 4;
168 }
126 *data++ = IICDS; 169 *data++ = IICDS;
127 } 170 }
128 171
129 /* STOP */ 172 /* STOP */
130 IICSTAT = 0x90; 173 IICSTAT = 0x90;
131 IICCON = 0xB7; 174 IICCON = 0xB7;
132 while ((IICSTAT & (1 << 5)) != 0); 175 while ((IICSTAT & (1 << 5)) != 0)
176 if (TIME_AFTER(current_tick, timeout))
177 {
178 mutex_unlock(&i2c_mtx);
179 return 5;
180 }
133 181
134 mutex_unlock(&i2c_mtx); 182 mutex_unlock(&i2c_mtx);
135 return 0; 183 return 0;