OSDN Git Service

Changed system task structure.
[kozos-expbrd/kozos_expbrd.git] / firm / sample / sample1 / os / vs1011e.c
1
2 #include "vs1011e.h"
3 #include "portconf.h"
4 #include "spi.h"
5
6 #define VS1011E_OPCODE_READ     0x03
7 #define VS1011E_OPCODE_WRITE    0x02
8
9 #define REGADDR_MODE            0x00
10 #define REGADDR_STATUS          0x01
11 #define REGADDR_BASS            0x02
12 #define REGADDR_CLOCKF          0x03
13 #define REGADDR_DECODE_TIME     0x04
14 #define REGADDR_AUDATA          0x05
15 #define REGADDR_WRAM            0x06
16 #define REGADDR_WRAMADDR        0x07
17 #define REGADDR_HDAT0           0x08
18 #define REGADDR_HDAT1           0x09
19 #define REGADDR_AIADDR          0x0A
20 #define REGADDR_VOL             0x0B
21 #define REGADDR_AICTRL0         0x0C
22 #define REGADDR_AICTRL1         0x0D
23 #define REGADDR_AICTRL2         0x0E
24 #define REGADDR_AICTRL3         0x0F
25
26 #define SM_DIFF         (1 <<  0)
27 #define SM_LAYER12      (1 <<  1)
28 #define SM_RESET        (1 <<  2)
29 #define SM_OUTOFWAV     (1 <<  3)
30 #define SM_SETTOZERO1   (1 <<  4)
31 #define SM_TESTS        (1 <<  5)
32 #define SM_STREAM       (1 <<  6)
33 #define SM_SETTOZERO2   (1 <<  7)
34 #define SM_DACT         (1 <<  8)
35 #define SM_SDIORD       (1 <<  9)
36 #define SM_SDISHARE     (1 << 10)
37 #define SM_SDINEW       (1 << 11)
38 #define SM_SETTOZERO3   (1 << 12)
39 #define SM_SETTOZERO4   (1 << 13)
40
41 #define SCI_BASS_BITBASS_ST_AMP         12
42 #define SCI_BASS_BITBASS_ST_FREQ        8
43 #define SCI_BASS_BITBASS_SB_AMP         4
44 #define SCI_BASS_BITBASS_SB_FREQ        0
45
46 #define VS1011E_RESET1()    do { *PORTCONF_P4DR |=  PORTCONF_P4BIT_VSRST; } while (0)
47 #define VS1011E_RESET0()    do { *PORTCONF_P4DR &= ~PORTCONF_P4BIT_VSRST; } while (0)
48
49 #define VS1011E_CHK_DREQ()  (((*PORTCONF_P4DR) & PORTCONF_P4BIT_VSDREQ) ? 0 : 1)
50
51 static void _delay_ms(int ms)
52 {
53     int i;
54     for (i = 0; i < ms * 10000; i++) {
55     }
56 }
57
58 static void _delay_us(int us)
59 {
60     int i;
61     for (i = 0; i < us * 10; i++) {
62     }
63 }
64
65 static void vs1011e_read(uint8 addr, uint16 * stat);
66 static void vs1011e_write(uint8 addr, uint16 stat);
67
68 void vs1011e_init()
69 {
70     vs1011e_reset_by_hardware();
71     vs1011e_reset_by_software();
72 }
73
74 void vs1011e_reset_by_hardware()
75 {
76     // Assert vs1011 reset
77     VS1011E_RESET0();
78     // Delay 30ms
79     _delay_ms(30);
80     // Deassert CS
81     spi_deselect();
82     // Release vs1011 reset
83     VS1011E_RESET1();
84     // Delay 10ms (2.5ms accordig to datasheet)
85     _delay_ms(10);
86     // Set volume to minimum
87     vs1011e_write(REGADDR_VOL, 0xFFFF);
88     // Set CLOCKF
89     vs1011e_write(REGADDR_CLOCKF, 0x9800);
90     // Delay 1ms
91     _delay_ms(1);
92     // Set slow sample rate for slow analog part startup
93     vs1011e_write(REGADDR_AUDATA, 10);
94     // Delay 100ms
95     _delay_ms(100);
96     // Switch on the analog parts
97     vs1011e_write(REGADDR_VOL, 0xFEFE);
98     vs1011e_write(REGADDR_AUDATA, 44101);
99     vs1011e_write(REGADDR_VOL, 0x0202);
100 }
101
102 void vs1011e_reset_by_software()
103 {
104     uint16 i;
105
106     // Delay 200ms
107     _delay_ms(200);
108     // Set SW reset bit, set VS1011 native mode on SPI
109     vs1011e_write(REGADDR_MODE,
110             SM_LAYER12 | SM_RESET | SM_SDINEW | SM_TESTS);
111     // Delay 2us
112     _delay_us(2);
113     // Rewrite SCI_CLOCKF after soft reset
114     vs1011e_write(REGADDR_CLOCKF, 0x9800);
115     // Assert DCS
116     spi_select(SpiTarget_VS1011E_DATA);
117     // Check the DREQ.
118     while (VS1011E_CHK_DREQ()) {
119     }
120     // Send 0x53 to SPI
121     spi_tx(0x53);
122     // Send 1024 nulls
123     for (i = 0; i < 1024; i++) {
124         // Check the DREQ.
125         while (VS1011E_CHK_DREQ()) {
126         }
127         spi_tx(0x00);
128     }
129     // Deassert DCS
130     spi_deselect();
131 }
132
133 void vs1011e_cancel_data()
134 {
135     uint16 i;
136     while (VS1011E_CHK_DREQ()) {
137     }
138
139     spi_select(SpiTarget_VS1011E_DATA);
140     for (i = 0; i < 2048; i++) {
141         while (VS1011E_CHK_DREQ()) {
142         }
143         spi_tx(0x00);
144     }
145     spi_deselect();
146 }
147
148 void vs1011e_set_enhancer(uint8 st_amp, uint8 st_freq, uint8 sb_amp,
149         uint8 sb_freq)
150 {
151     uint16 val =
152         (st_amp << SCI_BASS_BITBASS_ST_AMP) |
153         (st_freq << SCI_BASS_BITBASS_ST_FREQ) |
154         (sb_amp << SCI_BASS_BITBASS_SB_AMP) |
155         (sb_freq << SCI_BASS_BITBASS_SB_FREQ);
156     vs1011e_write(REGADDR_BASS, val);
157 }
158
159 void vs1011e_get_enhancer(uint8 * st_amp, uint8 * st_freq,
160         uint8 * sb_amp, uint8 * sb_freq)
161 {
162     uint16 val;
163     vs1011e_read(REGADDR_BASS, &val);
164     *st_amp = (val >> SCI_BASS_BITBASS_ST_AMP) & 0x0F;
165     *st_freq = (val >> SCI_BASS_BITBASS_ST_FREQ) & 0x0F;
166     *sb_amp = (val >> SCI_BASS_BITBASS_SB_AMP) & 0x0F;
167     *sb_freq = (val >> SCI_BASS_BITBASS_SB_FREQ) & 0x0F;
168 }
169
170 void vs1011e_volume_read(uint8 * left, uint8 * right)
171 {
172     uint16 val;
173     vs1011e_read(REGADDR_VOL, &val);
174     *left = val >> 8;
175     *right = val >> 0;
176 }
177
178 void vs1011e_volume_write(const uint8 left, const uint8 right)
179 {
180     uint16 val =
181         (((uint16) left << 8) & 0xFF00) | (((uint16) right << 0) &
182             0x00FF);
183     vs1011e_write(REGADDR_VOL, val);
184 }
185
186 void vs1011e_play(
187         void *buf, int siz,
188         int (*waitfunc)(void),
189         int (*readfunc)(void * buf, const int len))
190 {
191     int i;
192     while (1) {
193         /*
194          * Read the song data.
195          */
196         int n = readfunc(buf, siz);
197         if (n <= 0) {
198             return;
199         }
200         /*
201          * Send the data.
202          */
203         spi_select(SpiTarget_VS1011E_DATA);
204         for (i = 0; i < n; i++) {
205             while (VS1011E_CHK_DREQ()) {
206                 if (waitfunc() <= 0) {
207                     return;
208                 }
209             }
210             spi_tx(*((char *)buf + i));
211         }
212         spi_deselect();
213     }
214 }
215
216 void vs1011e_play_with_data(void *buf, int siz)
217 {
218     int i;
219     /*
220      * Send the data.
221      */
222     spi_select(SpiTarget_VS1011E_DATA);
223     for (i = 0; i < siz; i++) {
224         while (VS1011E_CHK_DREQ()) {
225         }
226         spi_tx(*((char *)buf + i));
227     }
228     spi_deselect();
229 }
230
231 void vs1011e_decodetime_read(uint16 * sec)
232 {
233     vs1011e_read(REGADDR_DECODE_TIME, sec);
234 }
235
236 void vs1011e_decodetime_write(const uint16 sec)
237 {
238     vs1011e_write(REGADDR_DECODE_TIME, sec);
239 }
240
241 void vs1011e_sinetest_init()
242 {
243     while (VS1011E_CHK_DREQ()) {
244     }
245
246     spi_select(SpiTarget_VS1011E_DATA);
247     spi_tx(0x53);
248     spi_tx(0xEF);
249     spi_tx(0x6E);
250     spi_tx(0xF0);
251     spi_tx(0x00);
252     spi_tx(0x00);
253     spi_tx(0x00);
254     spi_tx(0x00);
255     spi_deselect();
256 }
257
258 void vs1011e_sinetest_fini()
259 {
260     while (VS1011E_CHK_DREQ()) {
261     }
262
263     spi_select(SpiTarget_VS1011E_DATA);
264     spi_tx(0x45);
265     spi_tx(0x78);
266     spi_tx(0x69);
267     spi_tx(0x74);
268     spi_tx(0x00);
269     spi_tx(0x00);
270     spi_tx(0x00);
271     spi_tx(0x00);
272     spi_deselect();
273
274     vs1011e_cancel_data();
275 }
276
277 void vs1011e_register_print()
278 {
279 #if 0
280     uint8 i;
281     uint16 val;
282     xprintf(PSTR("===================\r\n"));
283     for (i = 0; i <= 0x0F; i++) {
284         vs1011e_read(i, &val);
285         xprintf(PSTR("0x%02X: 0x%04X\r\n"), i, val);
286     }
287     xprintf(PSTR("===================\r\n"));
288 #endif
289 }
290
291 static void vs1011e_read(uint8 addr, uint16 * stat)
292 {
293     while (VS1011E_CHK_DREQ()) {
294     }
295
296     spi_select(SpiTarget_VS1011E_CTRL);
297
298     spi_tx(VS1011E_OPCODE_READ);
299     spi_tx(addr);
300
301     *stat = 0;
302     *stat |= spi_rx() << 8;
303     *stat |= spi_rx();
304
305     spi_deselect();
306 }
307
308 static void vs1011e_write(uint8 addr, uint16 stat)
309 {
310     while (VS1011E_CHK_DREQ()) {
311     }
312
313     spi_select(SpiTarget_VS1011E_CTRL);
314
315     spi_tx(VS1011E_OPCODE_WRITE);
316     spi_tx(addr);
317
318     spi_tx(stat >> 8);
319     spi_tx(stat >> 0);
320
321     spi_deselect();
322 }