OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [soc/] [driver_sound/] [driver_sound.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
module driver_sound(
28
    input           clk_12,
29
    input           rst_n,
30
 
31
    //sound interface slave
32
    input           avs_write,
33
    input   [31:0]  avs_writedata,
34
 
35
    //WM8731 audio codec
36
    output reg      ac_sclk,
37
    inout           ac_sdat,
38
 
39
    output          ac_xclk,
40
    output reg      ac_bclk,
41
    output          ac_dat,
42
    output reg      ac_lr
43
);
44
 
45
//------------------------------------------------------------------------------ audio codec output DSP/PCM mode B
46
 
47
assign ac_dat = sample[15];
48
assign ac_xclk = clk_12;
49
 
50
reg [15:0] sample_next;
51
always @(posedge clk_12 or negedge rst_n) begin
52
    if(rst_n == 1'b0)   sample_next <= 16'd0;
53
    else if(avs_write)  sample_next <= avs_writedata[15:0];
54
end
55
 
56
reg [6:0] sample_cnt;
57
always @(posedge clk_12 or negedge rst_n) begin
58
    if(rst_n == 1'b0)               sample_cnt <= 7'd0;
59
    else if(~(sound_ready))         sample_cnt <= 7'd0;
60
    else if(sample_cnt == 7'd124)   sample_cnt <= 7'd0;
61
    else                            sample_cnt <= sample_cnt + 7'd1;
62
end
63
 
64
always @(posedge clk_12 or negedge rst_n) begin
65
    if(rst_n == 1'b0)                                   ac_lr <= 1'b0;
66
    else if(sample_cnt == 7'd1 || sample_cnt == 7'd2)   ac_lr <= 1'b1;
67
    else                                                ac_lr <= 1'b0;
68
end
69
 
70
always @(posedge clk_12 or negedge rst_n) begin
71
    if(rst_n == 1'b0)                                   ac_bclk <= 1'b0;
72
    else if(sample_cnt >= 7'd2 && sample_cnt <= 7'd64)  ac_bclk <= ~(ac_bclk);
73
    else                                                ac_bclk <= 1'b0;
74
end
75
 
76
reg [15:0] sample;
77
always @(posedge clk_12 or negedge rst_n) begin
78
    if(rst_n == 1'b0)                                                           sample <= 16'd0;
79
    else if(sample_cnt == 7'd1)                                                 sample <= sample_next;
80
    else if(sample_cnt >= 7'd2 && sample_cnt <= 7'd64 && sample_cnt[0] == 1'b1) sample <= { sample[14:0], sample[15] };
81
end
82
 
83
//------------------------------------------------------------------------------
84
 
85
//------------------------------------------------------------------------------
86
 
87
localparam [3:0] CTRL_IDLE     = 4'd0;
88
localparam [3:0] CTRL_RESET    = 4'd1;
89
localparam [3:0] CTRL_POWER    = 4'd2;
90
localparam [3:0] CTRL_OUTPUT   = 4'd3;
91
localparam [3:0] CTRL_SIDE     = 4'd4;
92
localparam [3:0] CTRL_EMPH     = 4'd5;
93
localparam [3:0] CTRL_FORMAT   = 4'd6;
94
localparam [3:0] CTRL_SAMPLING = 4'd7;
95
localparam [3:0] CTRL_ACTIVATE = 4'd8;
96
localparam [3:0] CTRL_READY    = 4'd9;
97
 
98
reg [3:0]  control_state;
99
 
100
reg        control_start;
101
reg [15:0] control_data;
102
 
103
wire sound_ready = control_state == CTRL_READY;
104
 
105
always @(posedge clk_12 or negedge rst_n) begin
106
    if(rst_n == 1'b0) begin
107
        control_start   <= 1'b0;
108
        control_data    <= 16'd0;
109
        control_state   <= CTRL_IDLE;
110
    end
111
    else begin
112
        if(control_state == CTRL_IDLE) begin
113
            control_start   <= 1'b1;
114
            control_data    <= 16'b0001111_000000000; //reset
115
            control_state   <= CTRL_RESET;
116
        end
117
        else if(control_state == CTRL_RESET && i2c_ready == 1'b1) begin
118
            control_start   <= 1'b1;
119
            control_data    <= 16'b0000110_001100111; // power down unused parts
120
            control_state   <= CTRL_POWER;
121
        end
122
        else if(control_state == CTRL_POWER && i2c_ready == 1'b1) begin
123
            control_start   <= 1'b1;
124
            control_data    <= 16'b0000010_101111001; // 0dB headphone output
125
            control_state   <= CTRL_OUTPUT;
126
        end
127
        else if(control_state == CTRL_OUTPUT && i2c_ready == 1'b1) begin
128
            control_start   <= 1'b1;
129
            control_data    <= 16'b0000100_011010010; // DAC select
130
            control_state   <= CTRL_SIDE;
131
        end
132
        else if(control_state == CTRL_SIDE && i2c_ready == 1'b1) begin
133
            control_start   <= 1'b1;
134
            control_data    <= 16'b0000101_000000101; // disable mute, 41.1kHz de-emphasis
135
            control_state   <= CTRL_EMPH;
136
        end
137
        else if(control_state == CTRL_EMPH && i2c_ready == 1'b1) begin
138
            control_start   <= 1'b1;
139
            control_data    <= 16'b0000111_000000011; // DSP mode
140
            control_state   <= CTRL_FORMAT;
141
        end
142
        else if(control_state == CTRL_FORMAT && i2c_ready == 1'b1) begin
143
            control_start   <= 1'b1;
144
            control_data    <= 16'b0001000_000011101; // USB mode, 12MHz, 96 kHz
145
            control_state   <= CTRL_SAMPLING;
146
        end
147
        else if(control_state == CTRL_SAMPLING && i2c_ready == 1'b1) begin
148
            control_start   <= 1'b1;
149
            control_data    <= 16'b0001001_000000001; //activate
150
            control_state   <= CTRL_ACTIVATE;
151
        end
152
        else if(control_state == CTRL_ACTIVATE && i2c_ready == 1'b1) begin
153
            control_state   <= CTRL_READY;
154
        end
155
        else begin
156
            control_start <= 1'b0;
157
        end
158
    end
159
end
160
 
161
//------------------------------------------------------------------------------
162
 
163
wire i2c_ready = (i2c_state == S_IDLE && control_start == 1'b0);
164
assign ac_sdat = (sdat_oe == 1'b0)? 1'bZ : sdat_o;
165
 
166
reg         sdat_oe;
167
reg         sdat_o;
168
reg [7:0]   dat_byte;
169
reg [1:0]   part;
170
reg [2:0]   counter;
171
reg [3:0]   i2c_state;
172
 
173
localparam [3:0] S_IDLE     = 4'd0;
174
localparam [3:0] S_SEND_0   = 4'd1;
175
localparam [3:0] S_SEND_1   = 4'd2;
176
localparam [3:0] S_SEND_2   = 4'd3;
177
localparam [3:0] S_SEND_3   = 4'd4;
178
localparam [3:0] S_SEND_4   = 4'd5;
179
localparam [3:0] S_END_0    = 4'd6;
180
localparam [3:0] S_END_1    = 4'd7;
181
localparam [3:0] S_END_2    = 4'd8;
182
 
183
always @(posedge clk_12 or negedge rst_n) begin
184
    if(rst_n == 1'b0) begin
185
        ac_sclk   <= 1'b1;
186
        sdat_oe   <= 1'b0;
187
        sdat_o    <= 1'b1;
188
        dat_byte  <= 8'd0;
189
        part      <= 2'b0;
190
        counter   <= 3'd0;
191
        i2c_state <= S_IDLE;
192
    end
193
    else if(i2c_state == S_IDLE && control_start == 1'b1) begin
194
        // start
195
        sdat_oe   <= 1'b1;
196
        sdat_o    <= 1'b0;
197
        ac_sclk   <= 1'b1;
198
 
199
        part      <= 2'b0;
200
        dat_byte  <= 8'b0011010_0;
201
        counter   <= 3'd7;
202
        i2c_state <= S_SEND_0;
203
    end
204
    else if(i2c_state == S_SEND_0) begin
205
        sdat_oe   <= 1'b1;
206
        sdat_o    <= dat_byte[7];
207
        ac_sclk   <= 1'b0;
208
        i2c_state <= S_SEND_1;
209
    end
210
    else if(i2c_state == S_SEND_1) begin
211
        ac_sclk <= 1'b1;
212
 
213
        if(counter == 3'd0) i2c_state <= S_SEND_2;
214
        else begin
215
            dat_byte  <= { dat_byte[6:0], 1'b0 };
216
            counter   <= counter - 3'd1;
217
            i2c_state <= S_SEND_0;
218
        end
219
    end
220
    else if(i2c_state == S_SEND_2) begin
221
        sdat_oe   <= 1'b0;
222
        ac_sclk   <= 1'b0;
223
        i2c_state <= S_SEND_3;
224
    end
225
    else if(i2c_state == S_SEND_3) begin
226
        ac_sclk   <= 1'b1;
227
        i2c_state <= S_SEND_4;
228
    end
229
    else if(i2c_state == S_SEND_4 && ac_sdat == 1'b0) begin
230
        ac_sclk   <= 1'b0;
231
        part      <= part + 2'b1;
232
        counter   <= 3'd7;
233
 
234
        if(part == 2'd0)      dat_byte <= control_data[15:8];
235
        else if(part == 2'd1) dat_byte <= control_data[7:0];
236
 
237
        if(part == 2'd0 || part == 2'd1) i2c_state <= S_SEND_0;
238
        else                             i2c_state <= S_END_0;
239
    end
240
    else if(i2c_state == S_END_0) begin
241
        sdat_oe   <= 1'b1;
242
        sdat_o    <= 1'b0;
243
        ac_sclk   <= 1'b0;
244
        i2c_state <= S_END_1;
245
    end
246
    else if(i2c_state == S_END_1) begin
247
        ac_sclk   <= 1'b1;
248
        i2c_state <= S_END_2;
249
    end
250
    else if(i2c_state == S_END_2) begin
251
        // end
252
        sdat_oe   <= 1'b0;
253
        i2c_state <= S_IDLE;
254
    end
255
end
256
 
257
//------------------------------------------------------------------------------
258
 
259
// synthesis translate_off
260
wire _unused_ok = &{ 1'b0, avs_writedata[31:16], 1'b0 };
261
// synthesis translate_on
262
 
263
//------------------------------------------------------------------------------
264
 
265
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.