summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2002-04-20 23:01:30 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2002-04-20 23:01:30 +0000
commitd057c07154b02a067051f8a4711b19e4011a16aa (patch)
treef9c6036c2e45336cff8c59dd5b70f91b7c46a8ab /firmware
parent432ba31511bc1a00803657b4b4c60f27791608ba (diff)
downloadrockbox-d057c07154b02a067051f8a4711b19e4011a16aa.tar.gz
rockbox-d057c07154b02a067051f8a4711b19e4011a16aa.zip
First commit
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@156 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/debug.c181
-rw-r--r--firmware/debug.h25
-rw-r--r--firmware/i2c.c212
-rw-r--r--firmware/i2c.h33
4 files changed, 451 insertions, 0 deletions
diff --git a/firmware/debug.c b/firmware/debug.c
new file mode 100644
index 0000000000..d78fa17528
--- /dev/null
+++ b/firmware/debug.c
@@ -0,0 +1,181 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
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#include "sh7034.h"
20#include <string.h>
21#include <stdio.h>
22#include <stdarg.h>
23
24char debugmembuf[100];
25char debugbuf[200];
26
27static int debug_tx_ready(void)
28{
29 return (SSR1 & SCI_TDRE);
30}
31
32static void debug_tx_char(char ch)
33{
34 while (!debug_tx_ready())
35 {
36 ;
37 }
38
39 /*
40 * Write data into TDR and clear TDRE
41 */
42 TDR1 = ch;
43 SSR1 &= ~SCI_TDRE;
44}
45
46static void debug_handle_error(char ssr)
47{
48 SSR1 &= ~(SCI_ORER | SCI_PER | SCI_FER);
49}
50
51static int debug_rx_ready(void)
52{
53 char ssr;
54
55 ssr = SSR1 & ( SCI_PER | SCI_FER | SCI_ORER );
56 if ( ssr )
57 debug_handle_error ( ssr );
58 return SSR1 & SCI_RDRF;
59}
60
61static char debug_rx_char(void)
62{
63 char ch;
64 char ssr;
65
66 /* Special debug hack. Shut off the IRQ while polling, to prevent the debug
67 stub from catching the IRQ */
68 SCR1 &= ~0x40;
69
70 while (!debug_rx_ready())
71 {
72 ;
73 }
74
75 ch = RDR1;
76 SSR1 &= ~SCI_RDRF;
77
78 ssr = SSR1 & (SCI_PER | SCI_FER | SCI_ORER);
79
80 if (ssr)
81 debug_handle_error (ssr);
82
83 /* Special debug hack. Enable the IRQ again */
84 SCR1 |= 0x40;
85 return ch;
86}
87
88static const char hexchars[] = "0123456789abcdef";
89
90static char highhex(int x)
91{
92 return hexchars[(x >> 4) & 0xf];
93}
94
95static char lowhex(int x)
96{
97 return hexchars[x & 0xf];
98}
99
100static void putpacket (char *buffer)
101{
102 register int checksum;
103
104 char *src = buffer;
105 debug_tx_char ('$');
106 checksum = 0;
107
108 while (*src)
109 {
110 int runlen;
111
112 /* Do run length encoding */
113 for (runlen = 0; runlen < 100; runlen ++)
114 {
115 if (src[0] != src[runlen])
116 {
117 if (runlen > 3)
118 {
119 int encode;
120 /* Got a useful amount */
121 debug_tx_char (*src);
122 checksum += *src;
123 debug_tx_char ('*');
124 checksum += '*';
125 checksum += (encode = runlen + ' ' - 4);
126 debug_tx_char (encode);
127 src += runlen;
128 }
129 else
130 {
131 debug_tx_char (*src);
132 checksum += *src;
133 src++;
134 }
135 break;
136 }
137 }
138 }
139
140
141 debug_tx_char ('#');
142 debug_tx_char (highhex(checksum));
143 debug_tx_char (lowhex(checksum));
144
145 /* Wait for the '+' */
146 debug_rx_char();
147}
148
149/* convert the memory, pointed to by mem into hex, placing result in buf */
150/* return a pointer to the last char put in buf (null) */
151static char *mem2hex (char *mem, char *buf, int count)
152{
153 int i;
154 int ch;
155 for (i = 0; i < count; i++)
156 {
157 ch = *mem++;
158 *buf++ = highhex (ch);
159 *buf++ = lowhex (ch);
160 }
161 *buf = 0;
162 return (buf);
163}
164
165void debug(char *msg)
166{
167 debugbuf[0] = 'O';
168
169 mem2hex(msg, &debugbuf[1], strlen(msg));
170 putpacket(debugbuf);
171}
172
173void debugf(char *fmt, ...)
174{
175 va_list ap;
176
177 va_start(ap, fmt);
178 vsprintf(debugmembuf, fmt, ap);
179 va_end(ap);
180 debug(debugmembuf);
181}
diff --git a/firmware/debug.h b/firmware/debug.h
new file mode 100644
index 0000000000..dc3053cb32
--- /dev/null
+++ b/firmware/debug.h
@@ -0,0 +1,25 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
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#ifndef DEBUG_H
20#define DEBUG_H
21
22void debug(char *msg);
23void debugf(char *fmt, ...);
24
25#endif
diff --git a/firmware/i2c.c b/firmware/i2c.c
new file mode 100644
index 0000000000..3a5603ddd4
--- /dev/null
+++ b/firmware/i2c.c
@@ -0,0 +1,212 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
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#include "lcd.h"
20#include "sh7034.h"
21#include "debug.h"
22
23#define PB13 0x2000
24#define PB7 0x0080
25#define PB5 0x0020
26
27/* cute little functions */
28#define SDA_LO (PBDR &= ~PB7)
29#define SDA_HI (PBDR |= PB7)
30#define SDA_INPUT (PBIOR &= ~PB7)
31#define SDA_OUTPUT (PBIOR |= PB7)
32#define SDA (PBDR & PB7)
33
34#define SCL_INPUT (PBIOR &= ~PB13)
35#define SCL_OUTPUT (PBIOR |= PB13)
36#define SCL_LO (PBDR &= ~PB13)
37#define SCL_HI (PBDR |= PB13)
38#define SCL (PBDR & PB13)
39
40/* arbitrary delay loop */
41#define DELAY do { int _x; for(_x=0;_x<20;_x++);} while (0)
42
43void i2c_start(void)
44{
45 SDA_OUTPUT;
46 SDA_HI;
47 SCL_HI;
48 SDA_LO;
49 DELAY;
50 SCL_LO;
51}
52
53void i2c_stop(void)
54{
55 SDA_LO;
56 SCL_HI;
57 DELAY;
58 SDA_HI;
59}
60
61void i2c_init(void)
62{
63 int i;
64
65 /* make PB5, PB7 & PB13 general I/O */
66 PBCR1 &= ~0x0c00; /* PB13 */
67 PBCR2 &= ~0xcc00; /* PB5 abd PB7 */
68
69 /* PB5 is "MAS enable". make it output and high */
70 PBIOR |= PB5;
71 PBDR |= PB5;
72
73 /* Set the clock line to an output */
74 PBIOR |= PB13;
75
76 SDA_OUTPUT;
77 SDA_HI;
78 SCL_LO;
79 for (i=0;i<3;i++)
80 i2c_stop();
81}
82
83void i2c_ack(int bit)
84{
85 /* Here's the deal. The MAS is slow, and sometimes needs to wait
86 before it can receive the acknowledge. Therefore it forces the clock
87 low until it is ready. We need to poll the clock line until it goes
88 high before we release the ack. */
89
90 SCL_LO; /* Set the clock low */
91 if ( bit )
92 SDA_HI;
93 else
94 SDA_LO;
95
96 SCL_INPUT; /* Set the clock to input */
97 while(!SCL); /* and wait for the MAS to release it */
98
99 DELAY;
100 SCL_OUTPUT;
101 SCL_LO;
102}
103
104int i2c_getack(void)
105{
106 unsigned short x;
107
108 /* Here's the deal. The MAS is slow, and sometimes needs to wait
109 before it can send the acknowledge. Therefore it forces the clock
110 low until it is ready. We need to poll the clock line until it goes
111 high before we read the ack. */
112
113 SDA_LO; /* First, discharge the data line */
114 SDA_INPUT; /* And set to input */
115 SCL_LO; /* Set the clock low */
116 SCL_INPUT; /* Set the clock to input */
117 while(!SCL); /* and wait for the MAS to release it */
118
119 x = SDA;
120 if (x)
121 /* ack failed */
122 return 0;
123 SCL_OUTPUT;
124 SCL_LO;
125 SDA_HI;
126 SDA_OUTPUT;
127 return 1;
128}
129
130void i2c_outb(unsigned char byte)
131{
132 int i;
133
134 /* clock out each bit, MSB first */
135 for ( i=0x80; i; i>>=1 ) {
136 if ( i & byte )
137 SDA_HI;
138 else
139 SDA_LO;
140 SCL_HI;
141 SCL_LO;
142 }
143
144 SDA_HI;
145}
146
147unsigned char i2c_inb(int ack)
148{
149 int i;
150 unsigned char byte = 0;
151
152 /* clock in each bit, MSB first */
153 for ( i=0x80; i; i>>=1 ) {
154 /* Tricky business. Here we discharge the data line by driving it low
155 and then set it to input to see if it stays low or goes high */
156 SDA_LO; /* First, discharge the data line */
157 SDA_INPUT; /* And set to input */
158 SCL_HI;
159 if ( SDA )
160 byte |= i;
161 SCL_LO;
162 SDA_OUTPUT;
163 }
164
165 i2c_ack(ack);
166
167 return byte;
168}
169
170int i2c_write(int address, unsigned char* buf, int count )
171{
172 int i,x=0;
173
174 i2c_start();
175 i2c_outb(address & 0xfe);
176 if (i2c_getack())
177 {
178 for (i=0; i<count; i++)
179 {
180 i2c_outb(buf[i]);
181 if (!i2c_getack())
182 {
183 x=-2;
184 break;
185 }
186 }
187 }
188 else
189 {
190 debugf("i2c_write() - no ack\n");
191 x=-1;
192 }
193 i2c_stop();
194 return x;
195}
196
197int i2c_read(int address, unsigned char* buf, int count )
198{
199 int i,x=0;
200
201 i2c_start();
202 i2c_outb(address | 1);
203 if (i2c_getack()) {
204 for (i=0; i<count; i++) {
205 buf[i] = i2c_inb(0);
206 }
207 }
208 else
209 x=-1;
210 i2c_stop();
211 return x;
212}
diff --git a/firmware/i2c.h b/firmware/i2c.h
new file mode 100644
index 0000000000..a16077428c
--- /dev/null
+++ b/firmware/i2c.h
@@ -0,0 +1,33 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
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#ifndef I2C_H
20#define I2C_H
21
22extern void i2c_init(void);
23extern int i2c_write(int device, unsigned char* buf, int count );
24extern int i2c_read(int device, unsigned char* buf, int count );
25extern int i2c_readmem(int device, int address, unsigned char* buf, int count );
26extern void i2c_outb(unsigned char byte);
27extern unsigned char i2c_inb(int ack);
28extern void i2c_start(void);
29extern void i2c_stop(void);
30extern void i2c_ack(int bit);
31extern int i2c_getack(void);
32
33#endif