diff options
author | Michael Sparmann <theseven@rockbox.org> | 2009-10-10 17:22:06 +0000 |
---|---|---|
committer | Michael Sparmann <theseven@rockbox.org> | 2009-10-10 17:22:06 +0000 |
commit | 31464f7930cd8857ef8d00ed75534087057058e2 (patch) | |
tree | 7ccbbd402ab9b9e0b07f0cc4537a611808ad1c04 | |
parent | e2aeef7501d0a0ef1c33432692cdaeff225d5d8b (diff) | |
download | rockbox-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.c | 66 |
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) | |||
67 | int i2c_write(unsigned char slave, int address, int len, const unsigned char *data) | 67 | int 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 | |||
100 | int i2c_read(unsigned char slave, int address, int len, unsigned char *data) | 122 | int 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; |