上一节说了bpi flash的第一个操作:读芯片ID,这一节说说读ID的代码怎么写,(打工仔)没什么时间去慢慢分析代码了,直接把代码贴上来,有问题可以评论区联系。
工程放在百度网盘了:
链接:https://pan.baidu.com/s/1M_hxX0AV7qQMEf_-4hzdhQ
提取码:xiag
代码只是读芯片ID部分的代码,主要代码如下:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/02/17 10:08:13
// Design Name:
// Module Name: bpi_wr_rd
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module bpi_wr_rd(
input clk50m,
input rst,//1: reset
input[31:0]CNT,//分频系数
input [2:0]mode_sel, //读,写,擦除等
input byte_sel,//0 :x16 1:x8
//input [15:0]in_data,
output reg [15:0] Manufacture_ID,
output reg [15:0]Device_id_1,Device_id_2,Device_id_3,
output reg [15:0]out_en,
output reg [4:0]cnt_state,
//io
input [15:0]IO_bpi_in,
output reg [15:0]IO_bpi_out,
output reg [25:0]bpi_addr,
output bpi_ce,//使能
output bpi_oe,//bpi读使能
output bpi_we//bpi写使能
);
reg ce,oe,we;
wire byte;
assign bpi_ce=~ce;
assign bpi_oe=~oe;
assign bpi_we=~we;
reg flash_clk;
reg[31:0]cnt_0;
always@(posedge clk50m or posedge rst)
begin
if(rst)
begin
cnt_0<=32'd0;
flash_clk<=0;
end
else
if(cnt_0==CNT/2-1)
begin
cnt_0<=32'd0;
flash_clk<=~flash_clk;
end
else
cnt_0<=cnt_0+1;
end
parameter cmd_idle =4'd0;
parameter cmd_wr_data =4'd1;
parameter cmd_rd_id =4'd2;
parameter cmd_erase =4'd3;
parameter cmd_rd_finish =4'd4;
parameter add_dat1 = 26'h555; //特殊地址1
parameter add_dat2 = 26'haaa; //特殊地址2
parameter add_dat3 = 26'h2aa; //特殊地址3
parameter delay_times = 4'd10;
reg [3:0]state;
// reg [4:0]cnt_state;
reg[3:0] delay_cnt;
always@(posedge flash_clk or posedge rst)
begin
if(rst)
begin
state<=cmd_idle;
cnt_state<=0;
ce<=0;
oe<=0;
we<=0;
IO_bpi_out<=0;
out_en<=0;
bpi_addr<=0;
Manufacture_ID<=0;
Device_id_1<= 0;
Device_id_2<=0;
Device_id_3<=0;
end
else
begin
case(state)
cmd_idle:begin
cnt_state<=0;
ce<=0;
oe<=0;
we<=0;
IO_bpi_out<=0;
out_en<=0;
delay_cnt<=0;
case(mode_sel)
3'b000:state<=cmd_rd_id;
default:state<=cmd_idle;
endcase
end
cmd_rd_id:begin
case(cnt_state)
5'd0:begin
ce<=1;
IO_bpi_out<=16'h00aa;
out_en<=16'hffff;
cnt_state<=cnt_state+1;
if(byte_sel==1'b0)
bpi_addr<=add_dat1;//x16
else
bpi_addr<=add_dat2;//x8
end
5'd1,5'd4,5'd7:begin
we<=1;
cnt_state<=cnt_state+1;
end
5'd2,5'd5,5'd8:begin
we<=0;
cnt_state<=cnt_state+1;
end
5'd3:begin
IO_bpi_out<=16'h0055;
cnt_state<=cnt_state+1;
if(byte_sel==1'b0)
bpi_addr<=add_dat3; //x16
else
bpi_addr<=add_dat1;//x8
end
5'd6:begin
IO_bpi_out<=16'h0090;
cnt_state<=cnt_state+1;
if(byte_sel==1'b0)
bpi_addr<=add_dat1; //x16
else
bpi_addr<=add_dat2;//x8
end
5'd9:begin
bpi_addr<={10'd0,16'h0000}; //x16 x8制造商ID读取
cnt_state<=cnt_state+1;
end
5'd10:begin
oe<=1;
out_en<=16'h0000;
if(delay_cnt==delay_times)begin
delay_cnt <=4'd0;
cnt_state <=cnt_state+1;
end
else begin
delay_cnt <=delay_cnt+1'b1;
end
end
5'd11:begin
cnt_state <=cnt_state+1;
Manufacture_ID <=IO_bpi_in;//------制造商ID读取
if(byte_sel==1'b0)
bpi_addr <={10'd0,16'h0001};//x16
else
bpi_addr <={10'd0,16'h0002};//x8
end
5'd12,5'd14,5'd16:begin
if(delay_cnt==delay_times)begin
delay_cnt <=4'd0;
cnt_state <=cnt_state+1;
end
else begin
delay_cnt <=delay_cnt+1'b1;
end
end
5'd13:begin
cnt_state <=cnt_state+1;
Device_id_1 <=IO_bpi_in; //------设备ID读取
if(byte_sel==1'b0)
bpi_addr <={10'd0,16'h000e};//x16
else
bpi_addr <={10'd0,16'h001c};//x8
end
5'd15:begin
cnt_state <=cnt_state+1;
Device_id_2 <=IO_bpi_in; //------设备ID读取
if(byte_sel==1'b0)
bpi_addr <={10'd0,16'h000f};//x16
else
bpi_addr <={10'd0,16'h001e};//x8
end
5'd17:begin
cnt_state <=cnt_state+1;
Device_id_3 <=IO_bpi_in; //------设备ID读取
end
5'd18:begin
oe <=1'b0;
we <=1'b0;
cnt_state <=cnt_state+1;
out_en<=16'hffff;//全部输出
end
5'd19:begin
IO_bpi_out =16'h00f0;//复位
cnt_state<=cnt_state+1;
end
5'd20:begin
we<=1'b1;
if(delay_cnt==delay_times)begin
delay_cnt <=4'd0;
cnt_state <=cnt_state+1;
end
else begin
delay_cnt <=delay_cnt+1'b1;
end
end
5'd21:begin
oe<=1'b0;
we<=1'b0;
state <=cmd_rd_finish;
end
default:begin
state<=cmd_rd_finish;
end
endcase
end
cmd_rd_finish:begin
ce<=0;
state<=cmd_idle;
end
default:begin
state<=cmd_idle;
end
endcase
end
end
endmodule