§ Команды
Активируется команда путем записи в sd_cmd значения:00 Инициализация устройства в режим SPI (80 единиц) 01 Прием и передача данных из sd_din, в sd_out 02 Включить чип (CS=0) 03 Выключить чип (CS=1)Активируется позитивным фронтом сигнала
sd_signal
, но при этом sd_busy должен быть равен 0!При sd_timeout=1 необходимо снова выслать
sd_cmd=00
(init).Для чтения данных используется sd_din=FFh, sd_cmd=1, и позитивный фронт sd_signal.
Максимальная скорость передачи данных 12,5 мегабит (~1.5 мегабайт в сек).
§ Top-уровень
Этот код предназначен для DE0-CV.1assign SD_DATA[0] = 1'bZ; 2 3wire [1:0] sd_cmd; 4wire [7:0] sd_din; 5wire [7:0] sd_out; 6wire sd_signal; 7wire sd_busy; 8wire sd_timeout; 9 10sd UnitSD 11( 12 // 50 Mhz 13 .clock50 (CLOCK_50), 14 15 // Физический интерфейс 16 .SPI_CS (SD_DATA[3]), // Выбор чипа 17 .SPI_SCLK (SD_CLK), // Тактовая частота 18 .SPI_MISO (SD_DATA[0]), // Входящие данные 19 .SPI_MOSI (SD_CMD), // Исходящие 20 21 // Интерфейс 22 .sd_signal (sd_signal), // In =1 Сообщение отослано на spi 23 .sd_cmd (sd_cmd), // In Команда 24 .sd_din (sd_din), // Out Принятое сообщение от карты 25 .sd_out (sd_out), // In Сообщение на отправку к карте 26 .sd_busy (sd_busy), // Out =1 Занято 27 .sd_timeout (sd_timeout) // Out =1 Таймаут 28); 29
§ Код модуля
1module sd 2( 3 // 50 Mhz 4 input wire clock50, 5 6 // SPI 7 output reg SPI_CS, 8 output reg SPI_SCLK, 9 input wire SPI_MISO, 10 output reg SPI_MOSI, 11 12 // Интерфейс 13 input wire sd_signal, // 0->1 Команда на позитивном фронте 14 input wire [ 1:0] sd_cmd, // ID команды 15 output reg [ 7:0] sd_din, // Исходящие данные в процессор 16 input wire [ 7:0] sd_out, // Входящие данные из процессора 17 output reg sd_busy, // =1 Устройство занято 18 output wire sd_timeout // =1 Вышел таймаут 19); 20 21`define SPI_TIMEOUT_CNT 5000000 // 0.1 s 22 23initial begin 24 25 SPI_CS = 1'b1; 26 SPI_SCLK = 1'b0; 27 SPI_MOSI = 1'b0; 28 sd_din = 8'h00; 29 sd_busy = 1'b0; 30 31end 32 33// --------------------------------------------------------------------- 34// SPI SdCard 35// --------------------------------------------------------------------- 36 37// Сигналы нейтрализации (сброс активации команды) 38reg [1:0] spi_latch = 2'b00; 39 40// Сигнал о том, занято ли устройство 41assign sd_timeout = (sd_timeout_cnt == `SPI_TIMEOUT_CNT); 42 43reg [2:0] spi_process = 0; 44reg [3:0] spi_cycle = 0; 45reg [7:0] spi_data_w = 0; 46 47// INIT SPI MODE 48reg [7:0] spi_counter = 0; 49reg [7:0] spi_slow_tick = 0; 50reg [24:0] sd_timeout_cnt = `SPI_TIMEOUT_CNT; 51 52always @(posedge clock50) begin 53 54 // Счетчик таймаута. Дойдя для 55 if (sd_timeout_cnt < `SPI_TIMEOUT_CNT && spi_process == 0) 56 sd_timeout_cnt <= sd_timeout_cnt + 1; 57 58 case (spi_process) 59 60 // Инициировать процессинг 61 0: if (spi_latch == 2'b01) begin 62 63 spi_process <= 1 + sd_cmd; 64 spi_counter <= 0; 65 spi_cycle <= 0; 66 spi_data_w <= sd_out; 67 sd_busy <= 1; 68 sd_timeout_cnt <= 0; 69 70 end 71 72 // Command-1: 80 тактов в slow-режиме 73 1: begin 74 75 SPI_CS <= 1; 76 SPI_MOSI <= 1; 77 78 // 250*100`000 79 if (spi_slow_tick == (250 - 1)) begin 80 81 SPI_SCLK <= ~SPI_SCLK; 82 spi_slow_tick <= 0; 83 spi_counter <= spi_counter + 1; 84 85 // 80 ticks 86 if (spi_counter == (2*80 - 1)) begin 87 88 SPI_SCLK <= 0; 89 spi_process <= 0; 90 sd_busy <= 0; 91 92 end 93 94 end 95 // Оттикивание таймера 96 else begin spi_slow_tick <= spi_slow_tick + 1; end 97 98 end 99 100 // Command 1: Read/Write SPI 101 2: case (spi_cycle) 102 103 // CLK-DN 104 0: begin spi_cycle <= 1; SPI_SCLK <= 0; SPI_MOSI <= 0; end 105 1: begin spi_cycle <= 2; SPI_MOSI <= spi_data_w[7]; end 106 // CLK-UP 107 2: begin spi_cycle <= 3; SPI_SCLK <= 1; spi_counter <= spi_counter + 1; end 108 3: begin 109 110 spi_cycle <= 0; 111 sd_din <= {sd_din[6:0], SPI_MISO}; 112 spi_data_w <= {spi_data_w[6:0], 1'b0}; 113 114 if (spi_counter == 8) begin 115 116 SPI_SCLK <= 0; 117 sd_busy <= 0; 118 spi_counter <= 0; 119 spi_process <= 0; 120 SPI_MOSI <= 0; 121 122 end 123 end 124 125 endcase 126 127 // Переключиться за 2 такта, чтобы среагировал CPU 128 3: case (spi_cycle) 129 130 0: spi_cycle <= 1; 131 1: spi_cycle <= 2; 132 2: begin SPI_CS <= 1'b0; spi_process <= 0; sd_busy <= 0; end 133 134 endcase 135 136 4: case (spi_cycle) 137 138 0: spi_cycle <= 1; 139 1: spi_cycle <= 2; 140 2: begin SPI_CS <= 1'b1; spi_process <= 0; sd_busy <= 0; end 141 142 endcase 143 144 endcase 145 146 // Активизация работы устройства 147 spi_latch <= {spi_latch[0], sd_signal}; 148 149end 150 151endmodule