summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-03-11 13:59:31 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-03-11 13:59:31 +0000
commit89a38d4273a9ef6f7e2d46876ddfe5ce8cee10da (patch)
treec3707e992cf53ddf71410e75eab4a35ed97defcc /firmware/target/coldfire
parent04ea446edc56d0891f458ffa8f2b0e2616e443df (diff)
downloadrockbox-89a38d4273a9ef6f7e2d46876ddfe5ce8cee10da.tar.gz
rockbox-89a38d4273a9ef6f7e2d46876ddfe5ce8cee10da.zip
iAudio X5: Enable reading of DS2411 serial number. See it under System|Debug|View HW info.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12723 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/coldfire')
-rw-r--r--firmware/target/coldfire/iaudio/x5/ds2411-x5.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/firmware/target/coldfire/iaudio/x5/ds2411-x5.c b/firmware/target/coldfire/iaudio/x5/ds2411-x5.c
new file mode 100644
index 0000000000..a8b2ae705c
--- /dev/null
+++ b/firmware/target/coldfire/iaudio/x5/ds2411-x5.c
@@ -0,0 +1,206 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Michael Sevakis
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "config.h"
21#include "system.h"
22#include "cpu.h"
23#include "ds2411.h"
24#include "logf.h"
25
26/* Delay factor that depends on CPU frequency */
27static unsigned int ds2411_delay_factor = 0;
28
29#define DS2411_BIT (1 << 22)
30
31/* Delay the specified number of microseconds - plus a tiny bit */
32#define DELAY(uS) \
33 asm volatile( \
34 "move.l %[x], %%d0 \n" \
35 "mulu.l %[factor], %%d0 \n" \
36 "1: \n" \
37 "subq.l #1, %%d0 \n" \
38 "bhi.s 1b \n" \
39 : : [factor]"d"(ds2411_delay_factor), [x]"d"(uS) : "d0");
40
41/* Calculate the CRC of a byte */
42static unsigned char ds2411_calc_crc(unsigned char byte)
43{
44 /* POLYNOMIAL = X^8 + X^5 + X^4 + 1 */
45 static const unsigned char eor[8] =
46 {
47 0x5e, /* 01011110 */
48 0xbc, /* 10111100 */
49 0x61, /* 01100001 */
50 0xc2, /* 11000010 */
51 0x9d, /* 10011101 */
52 0x23, /* 00100011 */
53 0x46, /* 01000110 */
54 0x8c, /* 10001100 */
55 };
56
57 unsigned char crc = 0;
58 int i = 0;
59
60 do
61 {
62 if (byte & (1 << i))
63 crc ^= eor[i];
64 }
65 while (++i < 8);
66
67 return crc;
68} /* ds2411_calc_crc */
69
70/* Write a byte to the DS2411 - LSb first */
71static void ds2411_write_byte(unsigned char data)
72{
73 int i = 0;
74
75 do
76 {
77 if (data & 0x01)
78 {
79 /* Write a "1": Hold line low, then leave line pulled up and wait
80 out the remainder of Tslot */
81 or_l(DS2411_BIT, &GPIO_ENABLE);
82 DELAY(6);
83 and_l(~DS2411_BIT, &GPIO_ENABLE);
84 DELAY(60);
85 }
86 else
87 {
88 /* Write a "0": Hold line low, then leave line pulled up and wait
89 out the remainder of Tslot which is just Trec */
90 or_l(DS2411_BIT, &GPIO_ENABLE);
91 DELAY(60);
92 and_l(~DS2411_BIT, &GPIO_ENABLE);
93 DELAY(6);
94 }
95
96 data >>= 1;
97 }
98 while (++i < 8);
99} /* ds2411_write_byte */
100
101/* Read a byte from the DS2411 - LSb first */
102static unsigned char ds2411_read_byte(void)
103{
104 int i = 0;
105 unsigned data = 0;
106
107 do
108 {
109 /* Hold line low to begin bit read: Tf + Trl */
110 or_l(DS2411_BIT, &GPIO_ENABLE);
111 DELAY(6);
112
113 /* Set line high and delay before sampling within the master
114 sampling window: Tmsr - max 15us from Trl start */
115 and_l(~DS2411_BIT, &GPIO_ENABLE);
116 DELAY(9);
117
118 /* Sample data line */
119 if ((GPIO_READ & DS2411_BIT) != 0)
120 data |= 1 << i;
121
122 /* Wait out the remainder of Tslot */
123 DELAY(60);
124 }
125 while (++i < 8);
126
127 return data;
128} /* ds2411_read_byte */
129
130/*
131 * Byte 0: 8-bit family code (01h)
132 * Bytes 1-6: 48-bit serial number
133 * Byte 7: 8-bit CRC code
134 */
135int ds2411_read_id(struct ds2411_id *id)
136{
137 int i;
138 unsigned char crc;
139
140 /* Initialize delay factor based on loop time: 3*(uS-1) + 3 */
141 ds2411_delay_factor = MIN(cpu_frequency / (1000000*3), 1);
142
143 /* Init GPIO 1 wire bus for bit banging with a pullup resistor where
144 * it is set low as output and switched between input and output mode.
145 * Required for bidirectional communication on a single wire.
146 */
147 or_l(DS2411_BIT, &GPIO_FUNCTION); /* Set pin as GPIO */
148 and_l(~DS2411_BIT, &GPIO_ENABLE); /* Set as input */
149 and_l(~DS2411_BIT, &GPIO_OUT); /* Set low when set as output */
150
151 /* Delay 100us to stabilize */
152 DELAY(100);
153
154 /* Issue reset pulse - 480uS or more to ensure standard (not overdrive)
155 mode - we don't have the timing accuracy for that. */
156 or_l(DS2411_BIT, &GPIO_ENABLE);
157 /* Delay 560us: (Trstlmin + Trstlmax) / 2*/
158 DELAY(560);
159 and_l(~DS2411_BIT, &GPIO_ENABLE);
160 /* Delay 66us: Tpdhmax + 6 */
161 DELAY(66);
162
163 /* Read presence pulse - line should be pulled low at proper time by the
164 slave device */
165 if (GPIO_READ & DS2411_BIT)
166 {
167 logf("ds2411: no presence pulse");
168 return DS2411_NO_PRESENCE;
169 }
170
171 /* Trsth + 1 - 66 = Tpdhmax + Tpdlmax + Trecmin + 1 - 66 */
172 DELAY(240);
173
174 /* ds2411 should be ready for data transfer */
175
176 /* Send Read ROM command */
177 ds2411_write_byte(0x33);
178
179 /* Read ROM serial number and CRC */
180 i = 0, crc = 0;
181
182 do
183 {
184 unsigned char byte = ds2411_read_byte();
185 ((unsigned char *)id)[i] = byte;
186 crc = ds2411_calc_crc(crc ^ byte);
187 }
188 while (++i < 8);
189
190 /* Check that family code is ok */
191 if (id->family_code != 0x01)
192 {
193 logf("ds2411: invalid family code=%02X", (unsigned)id->family_code);
194 return DS2411_INVALID_FAMILY_CODE;
195 }
196
197 /* Check that CRC was ok */
198 if (crc != 0) /* Because last loop eors the CRC with the resulting CRC */
199 {
200 logf("ds2411: invalid CRC=%02X", (unsigned)id->crc);
201 return DS2411_INVALID_CRC;
202 }
203
204 /* Good ID read */
205 return DS2411_OK;
206} /* ds2411_read_id */