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

Subversion Repositories mmcfpgaconfig

[/] [mmcfpgaconfig/] [trunk/] [rtl/] [verilog/] [xmsmmc_core.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 openchip
// Copyright 2004-2005 Openchip
2
// http://www.openchip.org
3
 
4
 
5
`include "mmc_boot_defines.v"
6
 
7
module xmsmmc_core(
8
 
9
  // CCLK From FPGA
10
  cclk,
11
  // Done From FPGA, indicates success
12
  done,
13
  // Init From FPGA (start of config and ERROR)
14
  init,
15
 
16
  //
17
  // MMC Card I/O  
18
  // CS is not used tie up, pull up or leave open (not used)
19
  // DAT is directly connected to FPGA DIN(D0)
20
 
21
  // CMD Pin
22
  mmc_cmd,
23
  // CLK Pin
24
  mmc_clk,
25
 
26
  // Output enable control
27
  dis,
28
 
29
  // Error goes high if config error, or no MMC card inserted         
30
  error
31
  );
32
 
33
 
34
// global clock input, is divided to provide 400KHz and 20MHz Clocks    
35
input  cclk;
36
 
37
input  init;      // Pulse to start config
38
input  done;      //
39
 
40
// error/status out, goes high on error
41
output error;
42
 
43
// MMC Card I/O tristate when reset active and after config done/error
44
inout  mmc_cmd;
45
output mmc_clk;
46
 
47
//
48
input dis;
49
 
50
 
51
// command data to MMC card
52
wire cmd_data_out;
53
 
54
// "Transfer Mode" switch MMC clock to direct CCLK!
55
wire mode_transfer;
56
 
57
//
58
 
59
// CMD1 Response Start Bit
60
// if not Low, then no Card detected, error !
61
wire cmd1_resp_start_bit;
62
// CMD1 Response Busy Bit
63
// if Low then busy, loop until goes high
64
wire cmd1_resp_busy_bit;
65
 
66
 
67
 
68
 
69
//
70
// ASYNC reset we do not yet have clock!
71
//
72
 
73
//wire int_reset;
74
//assign int_reset = !init & !done;
75
 
76
wire config_request;
77
assign config_request = !init & !done;
78
 
79
 
80
 
81
/*
82
reg int_reset;
83
 
84
always @(posedge cclk or posedge config_request)
85
  if (config_request)
86
    int_reset <= 1'b1;
87
  else
88
    int_reset <= 1'b0;
89
*/
90
 
91
wire int_reset;
92
assign int_reset = config_request;
93
 
94
 
95
// ---------------------------------------------------------------------------
96
// Clock Prescaler
97
// ---------------------------------------------------------------------------
98
 
99
wire clk_mmc;
100
 
101
mmc_boot_prescaler_16_1 precaler_i (
102
        .rst    (               int_reset       ),
103
        .sys_clk(               cclk            ),
104
        .mmc_clk(               clk_mmc         ),
105
        .mode_transfer(         mode_transfer   )
106
        );
107
 
108
 
109
 
110
// command bit counter
111
reg [7:0] counter_command_bits;
112
 
113
always @(negedge clk_mmc or posedge int_reset)
114
  if (int_reset)
115
    counter_command_bits <= 8'b00000000;
116
  else
117
    counter_command_bits <= counter_command_bits + 8'b00000001;
118
 
119
// ------------------------------------------------------------------
120
//
121
// ------------------------------------------------------------------
122
 
123
// command sequencer state machine
124
reg [3:0] cmd_state;
125
reg [3:0] cmd_state_next;
126
 
127
wire cmd_done;
128
assign cmd_done = counter_command_bits == 8'b11111111;
129
 
130
// CMD1 response Start (must be low if card is responding
131
assign cmd1_resp_start_bit = counter_command_bits[7:0] == 8'b00110101;
132
// CMD1 response Busy bit (must be high if card is ready)
133
assign cmd1_resp_busy_bit = counter_command_bits[7:0] == 8'b00111101;
134
 
135
//
136
// COMMAND State machine
137
//
138
always @(posedge clk_mmc or posedge int_reset)
139
  if (int_reset)
140
    cmd_state <= `CMD_INIT;
141
  else
142
    cmd_state <= cmd_state_next;
143
 
144
// R1 48 bits
145
// 00xx xxxx Sxxx xxxx ... xxx1
146
// R2 136 bits !!
147
// 00xx ... xxx1
148
// R3 48 bit
149
// 00xx ... xxx1
150
 
151
always @(cmd_state, done, cmd_done, init, mmc_cmd, cmd1_resp_start_bit, cmd1_resp_busy_bit)
152
  begin
153
    cmd_state_next = cmd_state;
154
 
155
    case (cmd_state) // synopsys full_case parallel_case
156
 
157
         `CMD_INIT: // send 80+ clocks, then send CMD0
158
           begin
159
             if (cmd_done & init) cmd_state_next = `CMD0;
160
           end
161
 
162
         `CMD0: // No response command, go send CMD1
163
           begin
164
             if (cmd_done) cmd_state_next = `CMD1;
165
           end
166
 
167
         `CMD1: // send CMD1, loop until response bit31 is high
168
           begin
169
             // Response start detected ?
170
                // if not no card and go error
171
             if ( (cmd1_resp_start_bit==1'b1) & (mmc_cmd==1'b1) )
172
                  cmd_state_next = `CMD_CONFIG_ERROR;
173
                // if not busy advance to next
174
                // we can jump to next command as we are in the middle
175
                // of response time, so the next command will not
176
                // start before the last response has been read
177
             if ( (cmd1_resp_busy_bit==1'b1) & (mmc_cmd==1'b1) )
178
                  cmd_state_next = `CMD1_IDLE;
179
           end
180
 
181
         `CMD1_IDLE: // just some clocks spacing
182
           begin
183
             if (cmd_done) cmd_state_next = `CMD2;
184
           end
185
 
186
         `CMD2: // send CMD2    R2
187
           begin
188
             if (cmd_done) cmd_state_next = `CMD3;
189
           end
190
 
191
         `CMD3: // send CMD3    R1
192
           begin
193
             if (cmd_done) cmd_state_next = `CMD7;
194
           end
195
 
196
         `CMD7: // send CMD7    R1
197
           begin
198
             if (cmd_done) cmd_state_next = `CMD11;
199
           end
200
 
201
         `CMD11: // send CMD11 R1
202
           begin
203
             if (cmd_done) cmd_state_next = `CMD_TRANSFER;
204
           end
205
 
206
         //
207
         // Commands are sent, CMD is held high
208
         // MMC Card content is streamed out on DAT pin
209
         //
210
         `CMD_TRANSFER:
211
           begin
212
             if (done)
213
            cmd_state_next = `CMD_CONFIG_DONE;
214
 
215
             if (!init)
216
            cmd_state_next = `CMD_CONFIG_ERROR;
217
           end
218
 
219
         // Config done succesfully!
220
         `CMD_CONFIG_DONE:
221
           begin
222
 
223
           end
224
 
225
         // Some error has occoured
226
         `CMD_CONFIG_ERROR:
227
           begin
228
 
229
           end
230
 
231
    endcase
232
  end
233
 
234
//
235
// transfer mode, select high speed clock
236
//
237
assign mode_transfer = cmd_state == `CMD_TRANSFER;
238
 
239
 
240
// ------------------------------------------------------------------
241
//
242
// Just emulating a memory to select CMD Data output
243
//
244
// ------------------------------------------------------------------
245
 
246
wire cmd_bits;
247
// 
248
mmc_cmd_select mmc_cmd_select_i (
249
        .cmd(           cmd_state               ),
250
        .bit(           counter_command_bits    ),
251
        .cmd_active(    cmd_bits                ),
252
        .data(          cmd_data_out            )
253
    );
254
 
255
 
256
// ------------------------------------------------------------------
257
//
258
// ------------------------------------------------------------------
259
 
260
assign mmc_cmd = (!dis & cmd_bits) ? cmd_data_out : 1'bz;
261
assign mmc_clk = !dis ? (int_reset ? 1'b0 : clk_mmc) : 1'bz;
262
 
263
// signal ERROR (active high)
264
assign error = cmd_state == `CMD_CONFIG_ERROR;
265
 
266
 
267
endmodule
268
 
269
 

powered by: WebSVN 2.1.0

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