基于线性序列机思想设计读写该芯片的SPI协议,线性序列机简单来说就是用一个计数器对时钟计数,对于每一个计数值,按照时序要求对信号做出相应操作。简单写了一下 Read Manufacturer / Device ID (90h) 指令,需要先发送0x90(一字节),接着发送地址0x000000(三字节),再接收Manufacturer ID 和Device ID 两字节,接收正确的话分别是0xEF和0x14。芯片手册的指令说明及时序图如下。
按照时序图一步一步写即可,程序如下,已经验证。
module spi_dri(
input wire sys_clk,
input wire rst_n,
input wire start,
input wire [7:0] instruct,
input wire [23:0] addr,
output reg spi_clk,
output reg spi_cs_n,
output reg spi_mosi,
input wire spi_miso,
output reg work_done,
output reg [7:0] manu_id,
output reg [7:0] device_id
);
reg [7:0] r_manu_id;
reg [7:0] r_device_id;
reg work_ing;
reg [9:0] cnt_sysclk;
always@(posedge sys_clk or negedge rst_n)
if(!rst_n)
work_ing <= 1'b0;
else if(start)
work_ing <= 1'b1;
else if(work_done)
work_ing <= 1'b0;
else
work_ing <= work_ing;
always@(posedge sys_clk or negedge rst_n)
if(!rst_n)
cnt_sysclk <= 10'b0;
else if(work_ing)
cnt_sysclk <= cnt_sysclk + 1'b1;
else if(cnt_sysclk == 10'd97)
cnt_sysclk <= 10'b0;
else
cnt_sysclk <= cnt_sysclk;
always@(posedge sys_clk or negedge rst_n)
if(!rst_n)begin
spi_cs_n <= 1'b1;
spi_clk <= 1'b0;
spi_mosi <= 1'b1;
r_device_id <= 8'd0;
r_manu_id <= 8'd0;
device_id <= 8'd0;
manu_id <= 8'd0;
work_done <= 1'b0;
end
else begin
case(cnt_sysclk)
0:begin spi_cs_n <= 1'b0; spi_clk <= 1'b0; spi_mosi <= instruct[7]; end
1:begin spi_clk <= 1'b1; end
2:begin spi_clk <= 1'b0; spi_mosi <= instruct[6]; end
3:begin spi_clk <= 1'b1; end
4:begin spi_clk <= 1'b0; spi_mosi <= instruct[5]; end
5:begin spi_clk <= 1'b1; end
6:begin spi_clk <= 1'b0; spi_mosi <= instruct[4];end
7:begin spi_clk <= 1'b1; end
8:begin spi_clk <= 1'b0; spi_mosi <= instruct[3];end
9:begin spi_clk <= 1'b1; end
10:begin spi_clk <= 1'b0; spi_mosi <= instruct[2];end
11:begin spi_clk <= 1'b1; end
12:begin spi_clk <= 1'b0; spi_mosi <= instruct[1];end
13:begin spi_clk <= 1'b1; end
14:begin spi_clk <= 1'b0; spi_mosi <= instruct[0];end
15:begin spi_clk <= 1'b1; end
16:begin spi_clk <= 1'b0; spi_mosi <= addr[23]; end
17:begin spi_clk <= 1'b1; end
18:begin spi_clk <= 1'b0; spi_mosi <= addr[22]; end
19:begin spi_clk <= 1'b1; end
20:begin spi_clk <= 1'b0; spi_mosi <= addr[21]; end
21:begin spi_clk <= 1'b1; end
22:begin spi_clk <= 1'b0; spi_mosi <= addr[20];end
23:begin spi_clk <= 1'b1; end
24:begin spi_clk <= 1'b0; spi_mosi <= addr[19];end
25:begin spi_clk <= 1'b1; end
26:begin spi_clk <= 1'b0; spi_mosi <= addr[18];end
27:begin spi_clk <= 1'b1; end
28:begin spi_clk <= 1'b0; spi_mosi <= addr[17];end
29:begin spi_clk <= 1'b1; end
30:begin spi_clk <= 1'b0; spi_mosi <= addr[16]; end
31:begin spi_clk <= 1'b1; end
32:begin spi_clk <= 1'b0; spi_mosi <= addr[15]; end
33:begin spi_clk <= 1'b1; end
34:begin spi_clk <= 1'b0; spi_mosi <= addr[14]; end
35:begin spi_clk <= 1'b1; end
36:begin spi_clk <= 1'b0; spi_mosi <= addr[13];end
37:begin spi_clk <= 1'b1; end
38:begin spi_clk <= 1'b0; spi_mosi <= addr[12];end
39:begin spi_clk <= 1'b1; end
40:begin spi_clk <= 1'b0; spi_mosi <= addr[11];end
41:begin spi_clk <= 1'b1; end
42:begin spi_clk <= 1'b0; spi_mosi <= addr[10];end
43:begin spi_clk <= 1'b1; end
44:begin spi_clk <= 1'b0; spi_mosi <= addr[9]; end
45:begin spi_clk <= 1'b1; end
46:begin spi_clk <= 1'b0; spi_mosi <= addr[8]; end
47:begin spi_clk <= 1'b1; end
48:begin spi_clk <= 1'b0; spi_mosi <= addr[7]; end
49:begin spi_clk <= 1'b1; end
50:begin spi_clk <= 1'b0; spi_mosi <= addr[6];end
51:begin spi_clk <= 1'b1; end
52:begin spi_clk <= 1'b0; spi_mosi <= addr[5];end
53:begin spi_clk <= 1'b1; end
54:begin spi_clk <= 1'b0; spi_mosi <= addr[4];end
55:begin spi_clk <= 1'b1; end
56:begin spi_clk <= 1'b0; spi_mosi <= addr[3];end
57:begin spi_clk <= 1'b1; end
58:begin spi_clk <= 1'b0; spi_mosi <= addr[2]; end
59:begin spi_clk <= 1'b1; end
60:begin spi_clk <= 1'b0; spi_mosi <= addr[1]; end
61:begin spi_clk <= 1'b1; end
62:begin spi_clk <= 1'b0; spi_mosi <= addr[0]; end
63:begin spi_clk <= 1'b1; end
64:begin spi_clk <= 1'b0; end
65:begin spi_clk <= 1'b1; r_manu_id[7] <= spi_miso; end
66:begin spi_clk <= 1'b0; end
67:begin spi_clk <= 1'b1; r_manu_id[6] <= spi_miso; end
68:begin spi_clk <= 1'b0; end
69:begin spi_clk <= 1'b1; r_manu_id[5] <= spi_miso; end
70:begin spi_clk <= 1'b0; end
71:begin spi_clk <= 1'b1; r_manu_id[4] <= spi_miso; end
72:begin spi_clk <= 1'b0; end
73:begin spi_clk <= 1'b1; r_manu_id[3] <= spi_miso; end
74:begin spi_clk <= 1'b0; end
75:begin spi_clk <= 1'b1; r_manu_id[2] <= spi_miso; end
76:begin spi_clk <= 1'b0; end
77:begin spi_clk <= 1'b1; r_manu_id[1] <= spi_miso; end
78:begin spi_clk <= 1'b0; end
79:begin spi_clk <= 1'b1; r_manu_id[0] <= spi_miso; manu_id <= r_manu_id; end
80:begin spi_clk <= 1'b0; end
81:begin spi_clk <= 1'b1; r_device_id[7] <= spi_miso;end
82:begin spi_clk <= 1'b0; end
83:begin spi_clk <= 1'b1; r_device_id[6] <= spi_miso;end
84:begin spi_clk <= 1'b0; end
85:begin spi_clk <= 1'b1; r_device_id[5] <= spi_miso; end
86:begin spi_clk <= 1'b0; end
87:begin spi_clk <= 1'b1; r_device_id[4] <= spi_miso; end
88:begin spi_clk <= 1'b0; end
89:begin spi_clk <= 1'b1; r_device_id[3] <= spi_miso; end
90:begin spi_clk <= 1'b0;end
91:begin spi_clk <= 1'b1; r_device_id[2] <= spi_miso; end
92:begin spi_clk <= 1'b0; end
93:begin spi_clk <= 1'b1;r_device_id[1] <= spi_miso; end
94:begin spi_clk <= 1'b0; end
95:begin spi_clk <= 1'b1; r_device_id[0] <= spi_miso;device_id <= r_device_id;end
96:begin spi_cs_n <= 1'b1; work_done <= 1'b1; end
default:;
endcase
end
endmodule
没有回复内容