1 | /*
|
2 | * Soundmodul_WTV020.c
|
3 | *
|
4 | * Created: 27.05.2014 08:52:39
|
5 | * Author: Admin
|
6 | */
|
7 |
|
8 | // F_CPU = 1000000 Eingetragen unter ATtiny2313 -> AVR/GNU C Compiler -> Toolchain -> Symbols
|
9 |
|
10 | #include <avr/io.h>
|
11 | #include <avr/interrupt.h>
|
12 | #include <util/delay.h>
|
13 | #include <avr/sleep.h>
|
14 |
|
15 | /* * Set I/Os */
|
16 | #define WTV_PORT PORTD
|
17 | #define WTV_DDR DDRD
|
18 | #define WTV_PIN PIND
|
19 | #define WTV_BUSY PD2
|
20 | #define WTV_DO PD3
|
21 | #define WTV_CL PD4
|
22 | #define WTV_RES PD5
|
23 |
|
24 |
|
25 | /* * Defines for Commands
|
26 | * Send with wtv020_sendCommand(COMMAND) to execute */
|
27 | #define PLAY_PAUSE 0xFFFE //play/pause file
|
28 | #define STOP 0xFFFF //stop playing
|
29 | #define VOLUME_MIN 0xFFF0 //mute
|
30 | #define VOLUME_0 0xFFF0 //available volume levels
|
31 | #define VOLUME_1 0xFFF1 //...
|
32 | #define VOLUME_2 0xFFF2
|
33 | #define VOLUME_3 0xFFF3
|
34 | #define VOLUME_4 0xFFF4
|
35 | #define VOLUME_5 0xFFF5
|
36 | #define VOLUME_6 0xFFF6
|
37 | #define VOLUME_7 0xFFF7
|
38 | #define VOLUME_MAX 0xFFF7 //unmute
|
39 |
|
40 |
|
41 | /*
|
42 | * Data Clock Cycle Length in Microseconds
|
43 | * change this if you have problems with sending valid data
|
44 | */
|
45 | //#define CLK 100
|
46 | #define CLK 100
|
47 |
|
48 | ISR (TIMER0_OVF_vect) // every 10ms
|
49 | {
|
50 | static uint8_t ct0, ct1;
|
51 |
|
52 | uint8_t i;
|
53 |
|
54 | TCNT0 = (uint8_t)(int16_t)-(F_CPU / 64 / 2 * 10e-3 + 0.5); // preload for 5ms
|
55 |
|
56 | i = key_state ^ ~KEY_PIN; // key changed ?
|
57 | ct0 = ~( ct0 & i ); // reset or count ct0
|
58 | ct1 = ct0 ^ (ct1 & i); // reset or count ct1
|
59 | i &= ct0 & ct1; // count until roll over ?
|
60 | key_state ^= i; // then toggle debounced state
|
61 | key_press |= key_state & i; // 0->1: key press detect
|
62 | key_release |= ~key_state & i; // 1->0: key release detect
|
63 |
|
64 | if (sleep)
|
65 | sleep--;
|
66 |
|
67 | flag_5ms++;
|
68 | }
|
69 |
|
70 |
|
71 | /* * Send command to WTV020
|
72 | * 0x0000 to 0x01FF (0 to 511 decimal) will play the files 0000.ad4 to 0511.ad4
|
73 | * All other commands are defined in wtv020.h */
|
74 | void wtv020_sendCommand(uint16_t command) {
|
75 |
|
76 | WTV_PORT &= ~(1 << WTV_CL); //Pull CL low for 2ms for start
|
77 | _delay_ms(2);
|
78 |
|
79 | for (int i=15; i>=0; i--){ //for each bit of 16bit data
|
80 | _delay_us(CLK/4);
|
81 |
|
82 | if(((command>>i)&0x0001 )>0) //when bit=1 DO high else low
|
83 | WTV_PORT |= (1 << WTV_DO);
|
84 | else
|
85 | WTV_PORT &= ~(1 << WTV_DO);
|
86 |
|
87 | _delay_us(CLK/4); //CL high pulse
|
88 | WTV_PORT |= (1 << WTV_CL);
|
89 | _delay_us(CLK/2);
|
90 | if(i==0){ //if last bit, stop transmission
|
91 | WTV_PORT |= (1 << WTV_CL);
|
92 | WTV_PORT &= ~(1 << WTV_DO);
|
93 | }
|
94 | else //else begin new clock cycle
|
95 | WTV_PORT &= ~(1 << WTV_CL);
|
96 | }
|
97 | _delay_ms(70); //wait for BUSY-Flag available
|
98 | }
|
99 |
|
100 |
|
101 | /* * Reset the chip */
|
102 | void wtv020_reset(){
|
103 | WTV_PORT |= (1 << WTV_CL); //CL high, DO low
|
104 | WTV_PORT &= ~(1 << WTV_DO);
|
105 | _delay_ms(5);
|
106 |
|
107 | WTV_PORT |= (1 << WTV_RES); //RES pulse
|
108 | _delay_ms(100);
|
109 | WTV_PORT &= ~(1 << WTV_RES);
|
110 | _delay_ms(10);
|
111 | WTV_PORT |= (1 << WTV_RES);
|
112 |
|
113 | _delay_ms(500); //wait until module is ready
|
114 | }
|
115 |
|
116 | /* * Initialize the pins */
|
117 | void wtv020_init(void){
|
118 | WTV_DDR |= (1 << WTV_RES) | (1 << WTV_CL) | (1 << WTV_DO); //RES, CL, DO output
|
119 | WTV_DDR &= ~(1 << WTV_BUSY); //BUSY input
|
120 | WTV_PORT &= ~(1 << WTV_BUSY); //Pull-Up off
|
121 | wtv020_reset(); //Initial Reset
|
122 | }
|
123 |
|
124 | /* * Play file until its end.
|
125 | * BLOCKING FUNCTION!
|
126 | * waits for BUSY-FLAG */
|
127 | void wtv020_playVoice(uint16_t voiceNumber){
|
128 | wtv020_sendCommand(voiceNumber); //Send song number
|
129 | // while(WTV_PIN & (1 << WTV_BUSY)); //Wartet bis File abgespielt wurde
|
130 | }
|
131 |
|
132 |
|
133 | ISR (PCINT_B_vect) {
|
134 |
|
135 | }
|
136 |
|
137 | int main(void)
|
138 | {
|
139 | // Digital IO
|
140 | // Standart DDRx = 0x00 (Eingang)
|
141 | // Standart PORTx = 0x00
|
142 | // DDRx=0x00 Eingang
|
143 | // DDRx=0xFF Ausgang
|
144 |
|
145 | // PORTx=0x00 Ausgang auf 0 Eingang Pull Up deaktivieren
|
146 | // PORTx=0xFF Ausgang auf 1 Eingang Pull Up aktivieren
|
147 |
|
148 | // Unbeschaltete Pins auf Input und Pull Up aktivieren!
|
149 | // Pin 76543210
|
150 | DDRA = 0b00000011; // EEEEEEAA
|
151 | PORTA= 0b11111100; // Aus
|
152 |
|
153 | // Pin 76543210
|
154 | DDRB = 0b00000000; // EEEEEEEE
|
155 | PORTB= 0b11111111; // Pull up ein
|
156 |
|
157 | // Pin 76543210
|
158 | DDRD = 0b11111111; // AAAAAAAA
|
159 | PORTD= 0b00000000; // Aus
|
160 |
|
161 | _delay_ms(2000);
|
162 | wtv020_init();
|
163 | _delay_ms(2000);
|
164 | wtv020_sendCommand(VOLUME_MAX);
|
165 | _delay_ms(1000);
|
166 |
|
167 | wtv020_playVoice(0);
|
168 |
|
169 | TCCR0B = (0<<CS02) | (1<<CS01) | (1<<CS00); // mit Vorteiler 64
|
170 | TIMSK = (1<<TOIE0); // Timer Interrupt 1 ein
|
171 |
|
172 | PCMSK0 = 0xFF; // Alle Pins auswählen
|
173 | GIMSK = (1<<PCIE0); // Pin Change Interrupt aktivieren für PCINT7..0
|
174 |
|
175 | sei();
|
176 |
|
177 | while(1){
|
178 |
|
179 | wtv020_playVoice(1);
|
180 | _delay_ms(20000);
|
181 | wtv020_playVoice(2);
|
182 | _delay_ms(20000);
|
183 |
|
184 | }
|