2ad040aba705ab8991a890420e441ea880cde7a4
[fw/altos] / target / ee / ee.c
1 /*
2  * Copyright © 2008 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include <stdint.h>
20
21 sfr at 0x80 P0;
22 sfr at 0x90 P1;
23 sfr at 0xA0 P2;
24 sfr at 0xC6 CLKCON;
25
26 sfr at 0xF1 PERCFG;
27 sfr at 0xF2 ADCCFG;
28 sfr at 0xF3 P0SEL;
29 sfr at 0xF4 P1SEL;
30 sfr at 0xF5 P2SEL;
31
32 sfr at 0xFD P0DIR;
33 sfr at 0xFE P1DIR;
34 sfr at 0xFF P2DIR;
35 sfr at 0x8F P0INP;
36 sfr at 0xF6 P1INP;
37 sfr at 0xF7 P2INP;
38
39 sfr at 0x89 P0IFG;
40 sfr at 0x8A P1IFG;
41 sfr at 0x8B P2IFG;
42
43 sbit at 0x90 P1_0;
44 sbit at 0x91 P1_1;
45 sbit at 0x92 P1_2;
46 sbit at 0x93 P1_3;
47 sbit at 0x94 P1_4;
48 sbit at 0x95 P1_5;
49 sbit at 0x96 P1_6;
50 sbit at 0x97 P1_7;
51
52 #define MOSI    P1_5
53 #define MISO    P1_4
54 #define SCK     P1_3
55 #define CS      P1_2
56
57 #define DEBUG   P1_1
58
59 #define nop()   _asm nop _endasm;
60
61 void
62 delay (unsigned char n)
63 {
64         unsigned char i = 0;
65         unsigned char j = 0;
66
67         while (--n != 0)
68                 while (--i != 0)
69                         while (--j != 0)
70                                 nop();
71 }
72
73 void
74 cs(uint8_t b)
75 {
76         SCK = 0;
77         CS = b;
78         delay(1);
79 }
80
81 void
82 out_bit(uint8_t b)
83 {
84         MOSI = b;
85         delay(1);
86         SCK = 1;
87         delay(1);
88         SCK = 0;
89 }
90
91 void
92 out_byte(uint8_t byte)
93 {
94         uint8_t s;
95
96         for (s = 0; s < 8; s++) {
97                 uint8_t b = (byte & 0x80) ? 1 : 0;
98                 out_bit(b);
99                 byte <<= 1;
100         }
101 }
102
103 uint8_t
104 in_bit(void)
105 {
106         uint8_t b;
107         
108         delay(1);
109         SCK = 1;
110         delay(1);
111         b = MISO;
112         SCK = 0;
113         return b;
114 }
115
116 uint8_t
117 in_byte(void)
118 {
119         uint8_t byte = 0;
120         uint8_t s;
121         uint8_t b;
122
123         for (s = 0; s < 8; s++) {
124                 b = in_bit();
125                 byte = byte << 1;
126                 byte |= b;
127         }
128         return byte;
129 }
130
131 uint8_t
132 rdsr(void)
133 {
134         uint8_t status;
135         cs(0);
136         out_byte(0x05);
137         status = in_byte();
138         cs(1);
139         return status;
140 }
141
142 void
143 wrsr(uint8_t status)
144 {
145         cs(0);
146         out_byte(0x01);
147         out_byte(status);
148         cs(1);
149 }
150         
151 void
152 wren(void)
153 {
154         cs(0);
155         out_byte(0x06);
156         cs(1);
157 }
158
159 void
160 write(uint32_t addr, uint8_t *bytes, uint16_t len)
161 {
162         wren();
163         cs(0);
164         out_byte(0x02);
165         out_byte(addr >> 16);
166         out_byte(addr >> 8);
167         out_byte(addr);
168         while (len-- > 0)
169                 out_byte(*bytes++);
170         cs(1);
171         for (;;) {
172                 uint8_t status = rdsr();
173                 if ((status & (1 << 0)) == 0)
174                         break;
175         }
176 }
177
178 void
179 read(uint32_t addr, uint8_t *bytes, uint16_t len)
180 {
181         cs(0);
182         out_byte(0x03);
183         out_byte(addr >> 16);
184         out_byte(addr >> 8);
185         out_byte(addr);
186         while (len-- > 0)
187                 *bytes++ = in_byte();
188         cs(1);
189 }
190
191 void
192 debug_byte(uint8_t byte)
193 {
194         uint8_t s;
195
196         for (s = 0; s < 8; s++) {
197                 DEBUG = byte & 1;
198                 delay(2);
199                 byte >>= 1;
200         }
201 }
202
203 #define STRING  "\360\252"
204 #define LENGTH  2
205
206 main ()
207 {
208         uint8_t status;
209         uint8_t buf[LENGTH];
210         int i;
211
212         CLKCON = 0;
213         
214         CS = 1;
215         SCK = 0;
216         P1DIR = ((1 << 5) |
217                  (0 << 4) |
218                  (1 << 3) |
219                  (1 << 2) |
220                  (1 << 1));
221         status = rdsr();
222         /*
223          * Turn off both block-protect bits
224          */
225         status &= ~((1 << 3) | (1 << 2));
226         /*
227          * Turn off write protect enable
228          */
229         status &= ~(1 << 7);
230         wrsr(status);
231         write(0x0, STRING, LENGTH);
232         for (;;) {
233                 read(0x0, buf, LENGTH);
234                 for (i = 0; i < LENGTH; i++)
235                         debug_byte(buf[i]);
236         }
237 }