OSDN Git Service

Added KOZOS application.
[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(int8(*func) (uint8 * buf, const uint16 len))
187 {
188 #define UNITBYTE    (128)
189     uint8 i;
190     uint8 buf[UNITBYTE];
191     while (1) {
192         /*
193          * Read the song data.
194          */
195         int8 len = func(buf, UNITBYTE);
196         if (len <= 0) {
197             return;
198         }
199         /*
200          * Send the data.
201          */
202         for (i = 0; i < UNITBYTE; i++) {
203             while (VS1011E_CHK_DREQ()) { }
204             spi_select(SpiTarget_VS1011E_DATA);
205             spi_tx(*(buf + i));
206             spi_deselect();
207         }
208     }
209 }
210
211 void vs1011e_decodetime_read(uint16 * sec)
212 {
213     vs1011e_read(REGADDR_DECODE_TIME, sec);
214 }
215
216 void vs1011e_decodetime_write(const uint16 sec)
217 {
218     vs1011e_write(REGADDR_DECODE_TIME, sec);
219 }
220
221 void vs1011e_sinetest_init()
222 {
223     while (VS1011E_CHK_DREQ()) {
224     }
225
226     spi_select(SpiTarget_VS1011E_DATA);
227     spi_tx(0x53);
228     spi_tx(0xEF);
229     spi_tx(0x6E);
230     spi_tx(0xF0);
231     spi_tx(0x00);
232     spi_tx(0x00);
233     spi_tx(0x00);
234     spi_tx(0x00);
235     spi_deselect();
236 }
237
238 void vs1011e_sinetest_fini()
239 {
240     while (VS1011E_CHK_DREQ()) {
241     }
242
243     spi_select(SpiTarget_VS1011E_DATA);
244     spi_tx(0x45);
245     spi_tx(0x78);
246     spi_tx(0x69);
247     spi_tx(0x74);
248     spi_tx(0x00);
249     spi_tx(0x00);
250     spi_tx(0x00);
251     spi_tx(0x00);
252     spi_deselect();
253
254     vs1011e_cancel_data();
255 }
256
257 void vs1011e_register_print()
258 {
259 #if 0
260     uint8 i;
261     uint16 val;
262     xprintf(PSTR("===================\r\n"));
263     for (i = 0; i <= 0x0F; i++) {
264         vs1011e_read(i, &val);
265         xprintf(PSTR("0x%02X: 0x%04X\r\n"), i, val);
266     }
267     xprintf(PSTR("===================\r\n"));
268 #endif
269 }
270
271 static void vs1011e_read(uint8 addr, uint16 * stat)
272 {
273     while (VS1011E_CHK_DREQ()) {
274     }
275
276     spi_select(SpiTarget_VS1011E_CTRL);
277
278     spi_tx(VS1011E_OPCODE_READ);
279     spi_tx(addr);
280
281     *stat = 0;
282     *stat |= spi_rx() << 8;
283     *stat |= spi_rx();
284
285     spi_deselect();
286 }
287
288 static void vs1011e_write(uint8 addr, uint16 stat)
289 {
290     while (VS1011E_CHK_DREQ()) {
291     }
292
293     spi_select(SpiTarget_VS1011E_CTRL);
294
295     spi_tx(VS1011E_OPCODE_WRITE);
296     spi_tx(addr);
297
298     spi_tx(stat >> 8);
299     spi_tx(stat >> 0);
300
301     spi_deselect();
302 }