Camera controller, Sample Generator Frame detector

master
gaurav 2022-07-11 20:16:37 +02:00
parent e23c09b515
commit 3946012ca1
3 changed files with 226 additions and 0 deletions

View File

@ -0,0 +1,89 @@
//this module handles basic camera functions, such enabling regulators on the camera board, setting camera reset
module camera_controller(sclk_i, //a basic low freqency slow clock, should not be comming from MIPI block/Camera
reset_i, //global reset
cam_ctrl_in, //control camera control input from host
cam_pwr_en_o, //enable camera power
cam_reset_o, //camera reset to camera
cam_xmaster_o //camera master or slave
);
input sclk_i;
input reset_i;
input cam_ctrl_in;
output reg cam_pwr_en_o;
output reg cam_reset_o;
output reg cam_xmaster_o;
reg [1:0]camera_state;
parameter state_reset = 2'h0;
parameter state_power_on = 2'h1;
parameter state_active = 2'h2;
parameter state_idle = 2'h3;
parameter delay_bewteen_state = 16'd1280; //around 10ms //on Crosslink nx slow internal oscillator is around 128Khz
reg [15:0]state_time_counter;
always @(posedge sclk_i or posedge reset_i)
begin
if (reset_i || !cam_ctrl_in)
begin
state_time_counter <= delay_bewteen_state;
camera_state <= state_reset;
cam_pwr_en_o <= 1'b0;
cam_reset_o <= 1'b1;
cam_xmaster_o <= 1'b0;
end
else
begin
state_time_counter <= state_time_counter - 1'b1;
if (state_time_counter == 0)
begin
camera_state <= camera_state + (camera_state != state_idle); //go to next state if state is not equal to state_active
case(camera_state)
state_reset:
begin
cam_pwr_en_o <= 1'b0;
cam_reset_o <= 1'b1;
cam_xmaster_o <= 1'b0;
state_time_counter <= delay_bewteen_state;
end
state_power_on:
begin
cam_pwr_en_o <= 1'b1;
cam_reset_o <= 1'b1;
cam_xmaster_o <= 1'b0;
state_time_counter <= delay_bewteen_state;
end
state_active:
begin
cam_pwr_en_o <= 1'b1;
cam_reset_o <= 1'b0;
cam_xmaster_o <= 1'b0;
state_time_counter <= delay_bewteen_state;
end
state_idle:
begin
cam_pwr_en_o <= 1'b1;
cam_reset_o <= 1'b0;
cam_xmaster_o <= 1'b0;
end
default:
begin
cam_pwr_en_o <= 1'b0;
cam_reset_o <= 1'b1;
cam_xmaster_o <= 1'b0;
end
endcase
end
end
end
endmodule

View File

@ -0,0 +1,62 @@
module frame_detector #(parameter MIPI_GEAR=8)( reset_i,
clk_i,
data_valid_i,
data_lane0_i,
detected_frame_sync_o
);
localparam [7:0]SYNC_BYTE = 8'hB8;
localparam [7:0]MIPI_CSI_START = 8'h00;
localparam [7:0]MIPI_CSI_STOP = 8'h01;
input reset_i;
input clk_i;
input data_valid_i;
input [(MIPI_GEAR - 1'h1):0]data_lane0_i;
output reg detected_frame_sync_o;
reg [(MIPI_GEAR - 1'h1):0]last_data_lane0_i;
reg [1:0]packed_processed;
wire [((MIPI_GEAR*2) - 1'h1):0]pipe;
assign pipe = {data_lane0_i,last_data_lane0_i};
//packet format <SYNC_BYTE> <DataID> <WCount 8bit> <WCount8bit> <ECC8bit>
always @(posedge clk_i)
begin
if (reset_i)
begin
last_data_lane0_i <= 0;
detected_frame_sync_o <=0;
packed_processed <= 0;
end
else
begin
last_data_lane0_i <= data_lane0_i;
if (data_valid_i)
begin
packed_processed[0] <= 1'b1; //only check first two bytes/words having two bits variable allow bascially a counter till 2
packed_processed[1] <= packed_processed[0];
if ( !packed_processed[1])
begin
if (pipe[7:0] == SYNC_BYTE && pipe[15:8] == MIPI_CSI_START)
begin
detected_frame_sync_o <= 1'b0; //active low
end
else if (pipe[7:0] == SYNC_BYTE && pipe[15:8] == MIPI_CSI_STOP)
begin
detected_frame_sync_o <= 1'b1;
end
end
end
else
begin
packed_processed <= 2'b0;
end
end
end
endmodule

View File

@ -0,0 +1,75 @@
module sample_generator(clk_i,
reset_i,
framesync_i,
byte_o,
byte_valid_o);
input reset_i;
input clk_i;
input framesync_i;
output [15:0]byte_o;
output reg byte_valid_o;
reg [11:0]sample_counter;
wire [15:0]output_first;
wire [15:0]output_second;
rom_sec romsec_ins(.rd_clk_i(clk_i),
.rst_i(reset_i),
.rd_en_i(1'b1),
.rd_clk_en_i(1'b1),
.rd_addr_i(sample_counter),
.rd_data_o(output_second)) ;
debug_rom debug_rom_ins(.rd_clk_i(clk_i),
.rst_i(reset_i),
.rd_en_i(1'b1),
.rd_clk_en_i(1'b1),
.rd_addr_i(sample_counter),
.rd_data_o(output_first)) ;
reg [9:0]line_counter;
assign byte_o = line_counter[0]?output_second:output_first;
always @(posedge framesync_i or negedge reset_i)
begin
if (framesync_i)
begin
line_counter <= 0;
end
else
begin
line_counter <= line_counter + 1'h1;
end
end
always @(negedge clk_i)
begin
if (reset_i)
begin
sample_counter <= 16'h0;
end
else
begin
sample_counter <= sample_counter + 1'h1;
end
end
always @(*)
begin
if (reset_i)
begin
byte_valid_o = 1'b0;
end
else
begin
if ((line_counter > 10'h3) && (line_counter < 10'd994) && byte_o[7:0] == 8'hB8)
begin
byte_valid_o = 1'b1;
end
end
end
endmodule