diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/SOURCES | 1 | ||||
-rw-r--r-- | firmware/export/ds2411.h | 48 | ||||
-rw-r--r-- | firmware/target/coldfire/iaudio/x5/ds2411-x5.c | 206 |
3 files changed, 255 insertions, 0 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 2d2296a439..945f400243 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -364,6 +364,7 @@ target/coldfire/iaudio/system-iaudio.c | |||
364 | target/coldfire/iaudio/usb-iaudio.c | 364 | target/coldfire/iaudio/usb-iaudio.c |
365 | target/coldfire/iaudio/x5/backlight-x5.c | 365 | target/coldfire/iaudio/x5/backlight-x5.c |
366 | target/coldfire/iaudio/x5/button-x5.c | 366 | target/coldfire/iaudio/x5/button-x5.c |
367 | target/coldfire/iaudio/x5/ds2411-x5.c | ||
367 | target/coldfire/iaudio/x5/lcd-as-x5.S | 368 | target/coldfire/iaudio/x5/lcd-as-x5.S |
368 | target/coldfire/iaudio/x5/lcd-x5.c | 369 | target/coldfire/iaudio/x5/lcd-x5.c |
369 | target/coldfire/iaudio/x5/m5636-x5.c | 370 | target/coldfire/iaudio/x5/m5636-x5.c |
diff --git a/firmware/export/ds2411.h b/firmware/export/ds2411.h new file mode 100644 index 0000000000..c55579cba5 --- /dev/null +++ b/firmware/export/ds2411.h | |||
@@ -0,0 +1,48 @@ | |||
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 | #ifndef _DS2411_H_ | ||
21 | #define _DS2411_H_ | ||
22 | |||
23 | #include <stdbool.h> | ||
24 | |||
25 | /* | ||
26 | * Byte 0: 8-bit family code (always 01h) | ||
27 | * Bytes 1-6: 48-bit serial number | ||
28 | * Byte 7: 8-bit CRC code | ||
29 | */ | ||
30 | struct ds2411_id | ||
31 | { | ||
32 | unsigned char family_code; | ||
33 | unsigned char uid[6]; | ||
34 | unsigned char crc; | ||
35 | } __attribute__((packed)); | ||
36 | |||
37 | extern int ds2411_read_id(struct ds2411_id *id); | ||
38 | |||
39 | /* return values */ | ||
40 | enum ds2411_id_return_codes | ||
41 | { | ||
42 | DS2411_NO_PRESENCE = -3, | ||
43 | DS2411_INVALID_FAMILY_CODE, | ||
44 | DS2411_INVALID_CRC, | ||
45 | DS2411_OK = 0, | ||
46 | }; | ||
47 | |||
48 | #endif /* _DS2411_H_ */ | ||
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 */ | ||
27 | static 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 */ | ||
42 | static 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 */ | ||
71 | static 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 */ | ||
102 | static 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 | */ | ||
135 | int 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 */ | ||