You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
190 lines
6.8 KiB
190 lines
6.8 KiB
5 years ago
|
module matrix_kbd (input CLK, input RESET, input FREEZE, inout [3:0] ROWS, input [3:0] COLUMNS, output [63:0] kbd_report, output INT);
|
||
|
|
||
|
// * - ESC (29), 7 - F1 (3A), 4 - F2 (3B), 1 - NUM_LOCK (53)
|
||
|
// 0 - CAPS LOCK (39), 8 - R (15), 5 - BACKSPACE (2A), 2 - ENTER (58)
|
||
|
// # - LSHIFT (E1), 9 - C (06), 6 - V (19), 3 - DELETE (4C)
|
||
|
// D - LCTRL (E0), C - LALT (E2), B - SPACE (2C), A - RGUI (E7)
|
||
|
|
||
|
parameter ONE_ROW_TIME = 12000;
|
||
|
|
||
|
reg [15:0] row_time = 0;
|
||
|
reg [1:0] row_counter;
|
||
|
|
||
|
reg [15:0] last_data;
|
||
|
reg [7:0] i;
|
||
|
|
||
|
reg [63:0] report;
|
||
|
reg [5:0] report_free_place;
|
||
|
reg isr;
|
||
|
|
||
|
reg [3:0] ROWS_EN = 0;
|
||
|
reg [3:0] ROWS_OUT = 0;
|
||
|
wire [3:0] ROWS_IN;
|
||
|
reg [3:0] COLS_SHADOW;
|
||
|
|
||
|
reg [7:0] kbd_code;
|
||
|
reg is_pressed;
|
||
|
|
||
|
always @ (negedge CLK) begin
|
||
|
COLS_SHADOW <= COLUMNS;
|
||
|
end
|
||
|
|
||
|
always @ (posedge CLK) begin
|
||
|
if (RESET == 0) begin
|
||
|
last_data <= 16'hFFFF;
|
||
|
report_free_place <= 6'h3F;
|
||
|
report <= 63'h_00_00_00_00_00_00_00_00;
|
||
|
end
|
||
|
else begin
|
||
|
if (FREEZE == 0) begin
|
||
|
if (row_time == ONE_ROW_TIME) begin
|
||
|
row_time <= 0;
|
||
|
row_counter = row_counter + 1;
|
||
|
ROWS_EN = 1 << row_counter;
|
||
|
end
|
||
|
else
|
||
|
row_time <= row_time + 1;
|
||
|
// ROW 0 - D, 1 - A, 2 - C, 3 - B
|
||
|
if (row_time == (ONE_ROW_TIME/2 + 0)) begin
|
||
|
if (COLS_SHADOW[0] != last_data[row_counter*4 + 0]) begin
|
||
|
case (row_counter) 0: kbd_code = 8'h29; 1: kbd_code = 8'h53; 2: kbd_code = 8'h3A; 3: kbd_code = 8'h3B; // ESC, F1-F2, NUM LOCK
|
||
|
default: kbd_code = 1;
|
||
|
endcase
|
||
|
if ((COLS_SHADOW[0] == 0) && (last_data[row_counter*4 + 0] == 1)) is_pressed = 1;
|
||
|
else is_pressed = 0;
|
||
|
end
|
||
|
else kbd_code = 0;
|
||
|
last_data[row_counter*4 + 0] <= COLS_SHADOW[0];
|
||
|
end
|
||
|
|
||
|
else if (row_time == (ONE_ROW_TIME/2 + 4)) begin
|
||
|
if (COLS_SHADOW[2] != last_data[row_counter*4 + 2]) begin
|
||
|
case (row_counter) 0: kbd_code = 8'h39; 1: kbd_code = 8'h58; 2: kbd_code = 8'h15; 3: kbd_code = 8'h2A; // CAPS LOCK, R, BACKSPACE, ENTER
|
||
|
default: kbd_code = 1;
|
||
|
endcase
|
||
|
if ((COLS_SHADOW[2] == 0) && (last_data[row_counter*4 + 2] == 1)) is_pressed = 1;
|
||
|
else is_pressed = 0;
|
||
|
end
|
||
|
else kbd_code = 0;
|
||
|
last_data[row_counter*4 + 2] <= COLS_SHADOW[2];
|
||
|
end
|
||
|
|
||
|
else if (row_time == (ONE_ROW_TIME/2 + 2)) begin
|
||
|
if (COLS_SHADOW[1] != last_data[row_counter*4 + 1]) begin
|
||
|
case (row_counter) 0: kbd_code = 8'hE1; 1: kbd_code = 8'h4C; 2: kbd_code = 8'h06; 3: kbd_code = 8'h19; // LEFT SHIFT, C, V, DELETE
|
||
|
default: kbd_code = 1;
|
||
|
endcase
|
||
|
if ((COLS_SHADOW[1] == 0) && (last_data[row_counter*4 + 1] == 1)) is_pressed = 1;
|
||
|
else is_pressed = 0;
|
||
|
end
|
||
|
else kbd_code = 0;
|
||
|
last_data[row_counter*4 + 1] <= COLS_SHADOW[1];
|
||
|
end
|
||
|
|
||
|
else if (row_time == (ONE_ROW_TIME/2 + 6)) begin
|
||
|
if (COLS_SHADOW[3] != last_data[row_counter*4 + 3]) begin
|
||
|
case (row_counter) 0: kbd_code = 8'hE0; 1: kbd_code = 8'hE7; 2: kbd_code = 8'hE2; 3: kbd_code = 8'h2C; // LCTRL, LALT, SPACE, RGUI
|
||
|
default: kbd_code = 1;
|
||
|
endcase
|
||
|
if ((COLS_SHADOW[3] == 0) && (last_data[row_counter*4 + 3] == 1)) is_pressed = 1;
|
||
|
else is_pressed = 0;
|
||
|
end
|
||
|
else kbd_code = 0;
|
||
|
last_data[row_counter*4 + 3] <= COLS_SHADOW[3];
|
||
|
end
|
||
|
|
||
|
else
|
||
|
kbd_code = 0;
|
||
|
|
||
|
// START PACK I2C_HID REPORT
|
||
|
if (kbd_code != 0) begin
|
||
|
isr = 1;
|
||
|
report[15:8] <= 0;
|
||
|
//report[63:56] <= 0;
|
||
|
if ((kbd_code > 8'hDF) && (kbd_code < 8'hE8)) begin
|
||
|
kbd_code = kbd_code & 8'h07;
|
||
|
if (is_pressed)
|
||
|
report [7:0] <= report [7:0] | (1<<kbd_code);
|
||
|
else
|
||
|
report [7:0] <= report [7:0] & (~(1<<kbd_code));
|
||
|
end
|
||
|
else begin
|
||
|
if (is_pressed) begin
|
||
|
/*for (i = 0; i < 4; i = i + 1) begin
|
||
|
if (report_free_place[i] == 1) begin
|
||
|
report [ ((i + 2) * 8 + 7) : ((i + 2) * 8 + 0)] <= kbd_code;
|
||
|
report_free_place[i] = 0;
|
||
|
is_pressed = 0; // NO ERROR DETECTED
|
||
|
end
|
||
|
end
|
||
|
if (report_free_place[0] == 1) begin
|
||
|
report [ ((0 + 2) * 8 + 7) : ((0 + 2) * 8 + 0)] <= kbd_code;
|
||
|
report_free_place[0] = 0;
|
||
|
end*/
|
||
|
if (report [ 23 : 16 ] == 0)
|
||
|
report [ 23 : 16 ] <= kbd_code;
|
||
|
else if (report [ 31 : 24 ] == 0)
|
||
|
report [ 31 : 24 ] <= kbd_code;
|
||
|
else if (report [ 39 : 32 ] == 0)
|
||
|
report [ 39 : 32 ] <= kbd_code;
|
||
|
else if (report [ 47 : 40 ] == 0)
|
||
|
report [ 47 : 40 ] <= kbd_code;
|
||
|
else if (report [ 55 : 48 ] == 0)
|
||
|
report [ 55 : 48 ] <= kbd_code;
|
||
|
else if (report [ 63 : 56 ] == 0)
|
||
|
report [ 63 : 56 ] <= kbd_code;
|
||
|
end
|
||
|
|
||
|
else begin
|
||
|
for (i = 0; i < 6; i = i + 1) begin
|
||
|
if (report [ ((i + 2) * 8 + 7) : ((i + 2) * 8 + 0)] == kbd_code) begin
|
||
|
report [ ((i + 2) * 8 + 7) : ((i + 2) * 8 + 0)] <= 0;
|
||
|
//report_free_place[i] = 1;
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
//if (kbd_code == 8'h2C) begin
|
||
|
//if (is_pressed)
|
||
|
// report [15:8] <= kbd_code;
|
||
|
//else
|
||
|
// report [15:8] <= 0;
|
||
|
//end
|
||
|
//else if (kbd_code == 1) begin
|
||
|
// if (is_pressed)
|
||
|
// report [23:16] <= kbd_code;
|
||
|
// else
|
||
|
// report [23:16] <= 0;
|
||
|
//end
|
||
|
end
|
||
|
end // END OF KBD CODE SEND ALG
|
||
|
else
|
||
|
isr <= 0;
|
||
|
|
||
|
/*if (kbd_code != 0) begin
|
||
|
if (is_pressed)
|
||
|
report [7:0] <= kbd_code;
|
||
|
else
|
||
|
report [7:0] <= 0;
|
||
|
end*/
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
assign kbd_report = report;
|
||
|
assign INT = isr;
|
||
|
//assign ROWS_EN = (1 << row_counter);
|
||
|
|
||
|
|
||
|
|
||
|
SB_IO #(
|
||
|
.PIN_TYPE(6'b 1010_01),
|
||
|
.PULLUP(1'b 0)
|
||
|
) rows_io [3:0] (
|
||
|
.PACKAGE_PIN(ROWS),
|
||
|
.OUTPUT_ENABLE(ROWS_EN),
|
||
|
.D_OUT_0(ROWS_OUT),
|
||
|
.D_IN_0(ROWS_IN)
|
||
|
);
|
||
|
|
||
|
endmodule
|