OSDN Git Service

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