|
|
|
|
|
|
|
module top (input CLK, output LED1, LED2, LED3, LED4, LED5,
|
|
|
|
input SCL, inout SDA, /*output ACK,*/ output INTERRUPT,
|
|
|
|
input COM_RX, output COM_TX, COM_DCD, COM_DSR, COM_RTS,
|
|
|
|
input [7:0] KBD_COLUMNS, inout [15:0] KBD_ROWS);
|
|
|
|
|
|
|
|
|
|
|
|
wire RESET;
|
|
|
|
reg [3:0] rststate = 0;
|
|
|
|
assign RESET = &rststate;
|
|
|
|
|
|
|
|
//reg [7:0] I2C_TX; // TRANSMITTED TO MASTER
|
|
|
|
wire [7:0] I2C_TX;
|
|
|
|
reg [7:0] I2C_TX_DESC;
|
|
|
|
reg [7:0] I2C_TX_REPORT;
|
|
|
|
assign I2C_TX = (I2C_TX_DESC & I2C_OUT_DESC_MASK) | (I2C_TX_REPORT & (~I2C_OUT_DESC_MASK));
|
|
|
|
wire [7:0] I2C_RX; // RECEIVED FROM MASTER
|
|
|
|
wire I2C_TRANS, I2C_READ, I2C_ACK, I2C_ACK_MSTR_CTRL, I2C_WR;
|
|
|
|
wire [7:0] I2C_COUNTER;
|
|
|
|
i2c_slave I2C (CLK, RESET, SCL, SDA, I2C_TRANS, I2C_READ, I2C_ACK, I2C_WR, //I2C_ACK_MSTR_CTRL,
|
|
|
|
I2C_RX, I2C_TX, I2C_COUNTER);
|
|
|
|
|
|
|
|
reg UART_WR, UART_DTR, UART_RTS, UART_DCD;
|
|
|
|
reg [7:0] UART_TX_DATA;
|
|
|
|
wire UART_ACTIVE, UART_TX_LINE;
|
|
|
|
initial begin
|
|
|
|
UART_WR = 0; UART_RTS = 1; UART_DTR = 0; UART_DCD = 0;
|
|
|
|
end
|
|
|
|
uart UART (CLK, RESET, UART_WR, UART_TX_DATA, UART_ACTIVE, UART_TX_LINE);
|
|
|
|
|
|
|
|
//wire [63:0] kbd_report;
|
|
|
|
wire [7:0] kbd_report [6:0];
|
|
|
|
wire ISR;
|
|
|
|
reg INT = 1; // INTERRUPT LINE TO HOST
|
|
|
|
reg KBD_FREEZE = 1; // LOGIC REG FOR BLOCK KBD ACTIVITY WHEN I2C IS WORKING
|
|
|
|
//reg IS_EMPTY_REPORT = 0; // REGISTER FOR CORRECT START (HOST MUST REQUEST EMPTY REGISTER AFTER INTERRUPT. THEN INTERRRUPT SET TO 1)
|
|
|
|
matrix_kbd KEYBOARD (CLK, RESET, 0 /*KBD_FREEZE*/, KBD_ROWS, KBD_COLUMNS, kbd_report[0], kbd_report[1], kbd_report[2], kbd_report[3], kbd_report[4], kbd_report[5], kbd_report[6], ISR);
|
|
|
|
|
|
|
|
descriptors I2C_HID_DESC (CLK, RESET, I2C_WR, I2C_OUTPUT_TYPE[1:0], I2C_COUNTER, I2C_TX_DESC/*, kbd_report*/);
|
|
|
|
|
|
|
|
parameter MAX_INPUT_LEN = 10;
|
|
|
|
reg [7:0] I2C_INPUT_DATA [MAX_INPUT_LEN:0];
|
|
|
|
reg [7:0] temp_output_report;
|
|
|
|
reg [3:0] i2c_input_data_type; // 0 - UNKNOWN, 1 - I2C_HID_DESC_REQUEST, 2 - HID_REPORT_DESC_REQUEST, 3 - INPUT_REPORT_REQUEST, 4 - OUTPUT_REPORT_SET
|
|
|
|
// 5 - RESET, 6 - GET_INPUT_REPORT, 7 - SET_OUTPUT_REPORT
|
|
|
|
reg [7:0] I2C_INPUT_LEN = 0;
|
|
|
|
reg [2:0] I2C_OUTPUT_TYPE = 0; // 0 - ALL ZERO DATA, 1 - I2C HID DESCR, 2 - OUTPUT REPORT, 3 - HID REPORT DESCR
|
|
|
|
reg [7:0] I2C_OUT_DESC_MASK = 0;
|
|
|
|
reg [7:0] KBD_LED_STATUS = 0;
|
|
|
|
|
|
|
|
reg [7:0] ring_report [(8*8-1):0];
|
|
|
|
reg [2:0] ring_wr, ring_rd;
|
|
|
|
reg [2:0] wr_cnt;
|
|
|
|
|
|
|
|
reg last_wr = 0, last_trans = 0, last_uart_active = 0, last_isr = 0, uart_double_ff = 0;
|
|
|
|
|
|
|
|
always @(posedge CLK) begin
|
|
|
|
|
|
|
|
// RESET LOGIC
|
|
|
|
rststate <= rststate + !RESET;
|
|
|
|
if (RESET == 0) begin
|
|
|
|
I2C_OUTPUT_TYPE = 0;
|
|
|
|
I2C_OUT_DESC_MASK = 0;
|
|
|
|
KBD_LED_STATUS = 7; // BIT 0 - NUM LOCK, BIT 1 - CAPS LOCK, BIT 2 - SCROOL LOCK
|
|
|
|
I2C_INPUT_LEN = 0;
|
|
|
|
INT = 0;
|
|
|
|
UART_WR = 0;
|
|
|
|
//KBD_FREEZE = 1;
|
|
|
|
//IS_EMPTY_REPORT = 0;
|
|
|
|
ring_wr = 0;
|
|
|
|
ring_rd = 0;
|
|
|
|
wr_cnt = 0;
|
|
|
|
end
|
|
|
|
|
|
|
|
// NOT RESET MODE LOGIC
|
|
|
|
else begin
|
|
|
|
if ((last_wr == 0) && (I2C_WR == 1)) begin // I2C NEW BYTE TX/RX
|
|
|
|
I2C_INPUT_LEN = I2C_COUNTER - 1;
|
|
|
|
if (I2C_READ == 0) begin
|
|
|
|
/*if (I2C_COUNTER < (MAX_INPUT_LEN + 2))
|
|
|
|
I2C_INPUT_DATA[I2C_COUNTER - 2] <= I2C_RX;*/
|
|
|
|
|
|
|
|
if (I2C_COUNTER == 2) begin
|
|
|
|
if ((I2C_RX > 5) || (I2C_RX < 1))
|
|
|
|
i2c_input_data_type = 0;
|
|
|
|
else
|
|
|
|
i2c_input_data_type = I2C_RX;
|
|
|
|
end
|
|
|
|
else if (I2C_COUNTER == 3) begin
|
|
|
|
if (I2C_RX != 0)
|
|
|
|
i2c_input_data_type = 0;
|
|
|
|
end
|
|
|
|
else if (I2C_COUNTER == 4) begin
|
|
|
|
if (i2c_input_data_type == 5) begin
|
|
|
|
case (I2C_RX) 0: i2c_input_data_type = 5; 16: i2c_input_data_type = 6;
|
|
|
|
32: i2c_input_data_type = 7; default: i2c_input_data_type = 0; endcase
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else if (I2C_COUNTER == 5) begin
|
|
|
|
if (((i2c_input_data_type == 5) && (I2C_RX != 1)) || ((i2c_input_data_type == 6) && (I2C_RX != 2)) || ((i2c_input_data_type == 7) && (I2C_RX != 3)))
|
|
|
|
i2c_input_data_type = 0;
|
|
|
|
end
|
|
|
|
else if (I2C_COUNTER == 6) begin
|
|
|
|
if (i2c_input_data_type == 4)
|
|
|
|
temp_output_report = I2C_RX;
|
|
|
|
else if (((i2c_input_data_type == 6) || (i2c_input_data_type == 7)) && (I2C_RX != 6))
|
|
|
|
i2c_input_data_type = 0;
|
|
|
|
end
|
|
|
|
else if (I2C_COUNTER == 7) begin
|
|
|
|
if (((i2c_input_data_type == 6) || (i2c_input_data_type == 7)) && (I2C_RX != 0))
|
|
|
|
i2c_input_data_type = 0;
|
|
|
|
end
|
|
|
|
else if (I2C_COUNTER == 10) begin
|
|
|
|
if (i2c_input_data_type == 7)
|
|
|
|
temp_output_report = I2C_RX;
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
if (I2C_OUTPUT_TYPE == 3) begin
|
|
|
|
if ((I2C_COUNTER < 2) || (I2C_COUNTER > (2 + 10 - 1)))
|
|
|
|
I2C_TX_REPORT <= 0;
|
|
|
|
else if (I2C_COUNTER == 2)
|
|
|
|
I2C_TX_REPORT <= 10;
|
|
|
|
else if ((I2C_COUNTER == 3) || (I2C_COUNTER == 5))
|
|
|
|
I2C_TX_REPORT <= 0;
|
|
|
|
else if (I2C_COUNTER == 4)
|
|
|
|
I2C_TX_REPORT <= kbd_report[0];
|
|
|
|
else
|
|
|
|
I2C_TX_REPORT <= kbd_report[I2C_COUNTER - 5];
|
|
|
|
//I2C_TX_REPORT <= kbd_report[ (8 * (I2C_COUNTER - 4) + 7) : (8 * (I2C_COUNTER - 4) + 0) ];
|
|
|
|
end
|
|
|
|
else
|
|
|
|
I2C_TX_REPORT <= 0;
|
|
|
|
end
|
|
|
|
end // I2C NEW BYTE TX/RX - END
|
|
|
|
|
|
|
|
else if ((last_wr == 1) && (I2C_WR == 0)) begin // I2C_NEW_BYTE_NEGEDGE_FOR_UART
|
|
|
|
UART_WR <= 1;
|
|
|
|
if (I2C_READ == 0)
|
|
|
|
UART_TX_DATA <= I2C_RX;
|
|
|
|
else
|
|
|
|
UART_TX_DATA <= I2C_TX;
|
|
|
|
end // I2C_NEW_BYTE_NEGEDGE_FOR_UART - END
|
|
|
|
|
|
|
|
else if ((last_trans == 0) && (I2C_TRANS == 1)) begin // I2C_START_CONDITION OR REPEAT START (UART FF)
|
|
|
|
i2c_input_data_type = 0; // UNKNOWN DATA IN
|
|
|
|
UART_TX_DATA = 8'hFF;
|
|
|
|
UART_WR = 1;
|
|
|
|
uart_double_ff = 1;
|
|
|
|
KBD_FREEZE = 0;
|
|
|
|
end // I2C_START_CONDITION (UART FF) - END
|
|
|
|
|
|
|
|
else if ((last_trans == 1) && (I2C_TRANS == 0)) begin // I2C_STOP CONDITION (OR REPEAT START DETECTED)
|
|
|
|
KBD_FREEZE <= 0;
|
|
|
|
if (I2C_READ == 0) begin // DECODING PACKET RECEIVED FROM HOST
|
|
|
|
if (((i2c_input_data_type < 4) && (I2C_INPUT_LEN != 2)) || ((i2c_input_data_type == 4) && (I2C_INPUT_LEN != 5)) || ((i2c_input_data_type == 5) && (I2C_INPUT_LEN != 4)) || ((i2c_input_data_type == 6) && (I2C_INPUT_LEN != 6)) || ((i2c_input_data_type == 7) && (I2C_INPUT_LEN != 9)))
|
|
|
|
i2c_input_data_type = 0;
|
|
|
|
if ((i2c_input_data_type == 1) || (i2c_input_data_type == 2) || (i2c_input_data_type == 3))
|
|
|
|
I2C_OUTPUT_TYPE = i2c_input_data_type;
|
|
|
|
else if ((i2c_input_data_type == 4) || (i2c_input_data_type == 7))
|
|
|
|
KBD_LED_STATUS = temp_output_report;
|
|
|
|
else if (i2c_input_data_type == 6)
|
|
|
|
I2C_OUTPUT_TYPE = 3;
|
|
|
|
else if (i2c_input_data_type == 5)
|
|
|
|
rststate <= 4'h0; // RESET COMMAND
|
|
|
|
/*if (I2C_INPUT_LEN == 0)
|
|
|
|
KBD_FREEZE <= 0;
|
|
|
|
else if (I2C_INPUT_LEN == 2) begin
|
|
|
|
if ((I2C_INPUT_DATA[0] == 1) && (I2C_INPUT_DATA[1] == 0)) // I2C_HID_DESC_REQUEST
|
|
|
|
I2C_OUTPUT_TYPE = 1;
|
|
|
|
else if ((I2C_INPUT_DATA[0] == 2) && (I2C_INPUT_DATA[1] == 0)) // HID REPORT DESC REQUEST
|
|
|
|
I2C_OUTPUT_TYPE = 2;
|
|
|
|
else if ((I2C_INPUT_DATA[0] == 3) && (I2C_INPUT_DATA[1] == 0)) // INPUT REPORT REQUEST (ADR)
|
|
|
|
I2C_OUTPUT_TYPE = 3;
|
|
|
|
//else
|
|
|
|
// I2C_OUTPUT_TYPE = 0; //
|
|
|
|
end
|
|
|
|
else if (I2C_INPUT_LEN == 5) begin // OUTPUT REPORT SET (LEDS) - WRITE TO OUT ADR
|
|
|
|
if ((I2C_INPUT_DATA[0] == 4) && (I2C_INPUT_DATA[1] == 0) && (I2C_INPUT_DATA[2] == 1) && (I2C_INPUT_DATA[3] == 0)) begin
|
|
|
|
KBD_LED_STATUS <= I2C_INPUT_DATA[4];
|
|
|
|
KBD_FREEZE <= 0;
|
|
|
|
end
|
|
|
|
//else
|
|
|
|
// I2C_OUTPUT_TYPE = 0; //
|
|
|
|
end
|
|
|
|
else if (I2C_INPUT_LEN == 6) begin // INPUT REPORT REQUEST (KBD PRESS INFO)
|
|
|
|
if ((I2C_INPUT_DATA[0] == 5) && (I2C_INPUT_DATA[1] == 0) && (I2C_INPUT_DATA[2] == 16) && (I2C_INPUT_DATA[3] == 2) && (I2C_INPUT_DATA[4] == 6) && (I2C_INPUT_DATA[5] == 0))
|
|
|
|
I2C_OUTPUT_TYPE = 3;
|
|
|
|
//else
|
|
|
|
// I2C_OUTPUT_TYPE = 0; //
|
|
|
|
end
|
|
|
|
else if (I2C_INPUT_LEN == 9) begin // OUTPUT REPORT SET (LEDS) - WRITE BY CMD
|
|
|
|
if ((I2C_INPUT_DATA[0] == 5) && (I2C_INPUT_DATA[1] == 0) && (I2C_INPUT_DATA[2] == 32) && (I2C_INPUT_DATA[3] == 3) && (I2C_INPUT_DATA[4] == 6) && (I2C_INPUT_DATA[5] == 0) /*&& (I2C_INPUT_DATA[6] == 1) && (I2C_INPUT_DATA[7] == 0)*//*) begin
|
|
|
|
KBD_LED_STATUS <= I2C_INPUT_DATA[8];
|
|
|
|
KBD_FREEZE <= 0;
|
|
|
|
end
|
|
|
|
//else
|
|
|
|
// I2C_OUTPUT_TYPE = 0; //
|
|
|
|
end
|
|
|
|
else if (I2C_INPUT_LEN == 4) begin
|
|
|
|
if ((I2C_INPUT_DATA[0] == 5) && (I2C_INPUT_DATA[1] == 0) && (I2C_INPUT_DATA[2] == 0) && (I2C_INPUT_DATA[3] == 1))
|
|
|
|
rststate <= 4'h0; // RESET COMMAND
|
|
|
|
end */
|
|
|
|
//else
|
|
|
|
// I2C_OUTPUT_TYPE = 0; //
|
|
|
|
if ((I2C_OUTPUT_TYPE == 1) || (I2C_OUTPUT_TYPE == 2))
|
|
|
|
I2C_OUT_DESC_MASK = 8'hFF;
|
|
|
|
else
|
|
|
|
I2C_OUT_DESC_MASK = 8'h00;
|
|
|
|
end // END OF I2C_READ == 0
|
|
|
|
else begin
|
|
|
|
//KBD_FREEZE <= 0; // UNFREEZING KBD AFTER ANYONE I2C RECEIVING
|
|
|
|
//if (((I2C_OUTPUT_TYPE == 3) && (I2C_INPUT_LEN == 10)) || ((I2C_OUTPUT_TYPE == 0) && (I2C_INPUT_LEN > 1))) begin // HARD
|
|
|
|
if (((I2C_OUTPUT_TYPE == 3) || (I2C_OUTPUT_TYPE == 0)) && (I2C_INPUT_LEN > 1)) begin // SOFT
|
|
|
|
// DEACTIVATING INTERRRUPT IF HOST READ INPUT REPORT (LEN 10) AFTER INTERRUPT OR EMPTY DATA (>=2 BYTES) AFTER RESET
|
|
|
|
// AND UNFREEZING KEYBOARD
|
|
|
|
INT <= 1;
|
|
|
|
//KBD_FREEZE <= 0;
|
|
|
|
//IS_EMPTY_REPORT = 1;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end // I2C_STOP CONDITION (OR REPEAT START DETECTED) - END
|
|
|
|
|
|
|
|
else if ((last_uart_active == 1) && (UART_ACTIVE == 0) && (uart_double_ff == 1)) begin
|
|
|
|
UART_WR = 1;
|
|
|
|
UART_TX_DATA = 8'hFF;
|
|
|
|
uart_double_ff = 0;
|
|
|
|
I2C_INPUT_LEN = 0;
|
|
|
|
end
|
|
|
|
|
|
|
|
else if (UART_WR == 1)
|
|
|
|
UART_WR <= 0;
|
|
|
|
|
|
|
|
else if ((last_isr == 0) && (ISR == 1) && (INT == 1)) begin // INTERRUPT FROM KEYBOARD
|
|
|
|
/*if ((ring_wr + 1) != ring_rd)
|
|
|
|
ring_wr = ring_wr + 1;
|
|
|
|
ring_report[ring_wr * 8 + 0] <= kbd_report[ (8 * 0 + 7) : (8 * 0 + 0) ];
|
|
|
|
wr_cnt = 1;*/
|
|
|
|
INT = 0;
|
|
|
|
I2C_OUTPUT_TYPE = 3;
|
|
|
|
I2C_OUT_DESC_MASK = 8'h00;
|
|
|
|
end
|
|
|
|
/*else if (wr_cnt != 0) begin
|
|
|
|
ring_report[ring_wr * 8 + wr_cnt] <= kbd_report[ (8 * wr_cnt + 7) : (8 * wr_cnt + 0) ];
|
|
|
|
wr_cnt = wr_cnt + 1;
|
|
|
|
// if (wr_cnt == 0) // START ISR
|
|
|
|
end*/
|
|
|
|
|
|
|
|
last_wr <= I2C_WR;
|
|
|
|
last_trans <= I2C_TRANS;
|
|
|
|
last_uart_active <= UART_ACTIVE;
|
|
|
|
last_isr <= ISR;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
assign LED5 = I2C_TRANS;
|
|
|
|
//assign LED5 = COM_RX;
|
|
|
|
assign LED1 = INT ^ 1;//KBD_COLUMNS[0];//I2C_OUTPUT_TYPE[0];//I2C_RX[0];
|
|
|
|
//assign LED2 = I2C_OUTPUT_TYPE[0];
|
|
|
|
//assign LED3 = I2C_OUTPUT_TYPE[1];
|
|
|
|
assign LED2 = KBD_LED_STATUS[0];
|
|
|
|
assign LED3 = KBD_LED_STATUS[1];
|
|
|
|
assign LED4 = KBD_LED_STATUS[2];//KBD_FREEZE;//UART_ACTIVE;
|
|
|
|
//assign ACK = I2C_READ;//I2C_WR; //I2C_ACK;
|
|
|
|
|
|
|
|
assign COM_TX = UART_TX_LINE;//COM_RX;
|
|
|
|
assign INTERRUPT = INT;
|
|
|
|
assign COM_RTS = I2C_READ;//UART_RTS;
|
|
|
|
assign COM_DSR = KBD_FREEZE;//UART_DTR;
|
|
|
|
assign COM_DCD = INT;
|
|
|
|
|
|
|
|
endmodule //top
|