From e0d61dc647f6c6baa31133fcb726a71e17e6c0f3 Mon Sep 17 00:00:00 2001 From: Ivan Olenichev Date: Fri, 4 Jan 2019 13:27:11 +0600 Subject: [PATCH] i2c_keyboard update --- i2c_keyboard/.sconsign.dblite | Bin 4307 -> 4303 bytes i2c_keyboard/Makefile | 2 + i2c_keyboard/README | 7 + i2c_keyboard/descriptors.v | 64 +- i2c_keyboard/hardware.asc | 15420 ++++++++++++++------------------ i2c_keyboard/hardware.bin | Bin 32220 -> 32220 bytes i2c_keyboard/hardware.blif | 5386 +++++------ i2c_keyboard/i2c_kbd_alt.bin | Bin 32220 -> 32220 bytes i2c_keyboard/i2c_kbd_alt.blif | 5632 +++++------- i2c_keyboard/i2c_kbd_alt.ex | 14338 +++++++++++++---------------- i2c_keyboard/i2c_slave.v | 76 +- i2c_keyboard/matrix_kbd.v | 147 +- i2c_keyboard/top.v | 396 +- i2c_keyboard/uart.v | 5 +- 14 files changed, 17393 insertions(+), 24080 deletions(-) diff --git a/i2c_keyboard/.sconsign.dblite b/i2c_keyboard/.sconsign.dblite index 62a7239c66822e14e0720ea0f900d1e384f31c34..95aa0572d28ee6e60318c7c7ec8653de556f5c91 100644 GIT binary patch delta 800 zcmZ8fJ8P6d6lLRXqRDO|0V^MD@D(Mh;L&kAKwE{(v z1wo9%lKAv^pjDYn>jU&m^T4^e*4Y!&k%YYqk&cIfBex=JM?M|~XQq1w;J~=dog|Wy zTJH(Bo_fo4mI9jMDDnVnAGf7D+b@&jJwyo#OHE}#3!;SLJl}{1!-zl*3m&IJWA^Yw zI<(^tesQ~0Oqle}P{+Im?2Ez@z{XKgfWw}+B3{V6-Rbn;eD(dczWMZY@ILu|x8wt1 zND>1~=Y#OV8SEJtNu8966CIZ_{}H4sLz?vV#jMblAZDdt#3LbrVTnO0>8)_0h&MCu z=&n?)n~C0pr00SPj+~@Q;=*Tn)`QA#SZF8g^9S`kmC=$Bwi0{SprfVJVavz<;ZIGD zkpr$UbJF5$waGdNFc6?oULKu(56@MOrKypF$&c)_TT2&)LOl<;0$0sOo-f<+RVU9< zX6TC8#9z1LY6mav3te+I@i*=Gwu5i@{BvXy%6vmNz0JZ8?YQ<|qi#y)ci#91vSRB< delta 831 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 XJ#b(@@R1LJ0}eRgfeC-wEaLR9aV}mgS2snV( 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 - DATA TRANSMISSION // RECEIVED BYTES MUST READ WHEN WR POSEDGE, ADRESS NOT READING ###AND BYTE COUNTER >=1 (BYTE COUNTER = 0 - ADRESS) @@ -11,7 +11,7 @@ module i2c_slave (input CLK, input RESET, // LAST BYTE HAS NO WR ####BUT LAST BYTE NOT TRANSMITTED (BECAUSE MASTER STOPS TRANSMIT) parameter I2C_ADRESS = 7'h34; - parameter MAX_I2C_TRANSACTION_EXP2 = 8; // !!! - FOR LIMIT BYTES TO TX/RX (WITH ADRESS) + //parameter MAX_I2C_TRANSACTION_EXP2 = 8; // !!! - FOR LIMIT BYTES TO TX/RX (WITH ADRESS) reg /*SDA_IN,*/ SDA_DIR, SDA_OUT; wire SDA_IN; @@ -33,10 +33,10 @@ module i2c_slave (input CLK, input RESET, reg [3:0] i2c_bit_counter; reg [7:0] received_byte; reg [7:0] byte_to_transmit; - reg [(MAX_I2C_TRANSACTION_EXP2-1):0] byte_counter; - //reg is_for_me; + //reg [(MAX_I2C_TRANSACTION_EXP2-1):0] byte_counter; + reg is_adress; reg is_ack; - reg wr;//reg ack_master_ctrl; + reg wr; // FILTER reg SCLF, SDAF; @@ -45,54 +45,29 @@ module i2c_slave (input CLK, input RESET, simple_filter FLT_SCL (CLK, RESET, SCLF, SCLD); simple_filter FLT_SDA (CLK, RESET, SDAF, SDAD); - always@(negedge CLK) begin - SCLF <= SCL; - SDAF <= SDA_IN; + always@(posedge CLK) begin + SCLF = SCL; + SDAF = SDA_IN; end - always@(posedge CLK or negedge RESET) begin + always@(negedge CLK/* or negedge RESET*/) begin if (RESET == 0) - i2c_state_machine <= 0; + i2c_state_machine = 0; else begin - /* if (scl_cnt != 0) begin - scl_cnt = scl_cnt - 1; - if (scl_cnt == 0) begin - if (SCLD != SCLF) - SCLD = SCLF; - end - end - else begin - if (SCLD != SCLF) - scl_cnt = 3'd7; - end - if (sda_cnt != 0) begin - sda_cnt = sda_cnt - 1; - if (sda_cnt == 0) begin - if (SDAD != SDAF) - SDAD = SDAF; - end - end - else begin - if (SDAD != SDAF) - sda_cnt = 3'd7; - end*/ - // END OF FILTER //SDA_IN = SDA; // FOR IVERILOG if ((SDAD == 0) && (SDA_LAST == 1) && (SCLD == 1)) begin i2c_state_machine = 1; i2c_start_latency = 0; i2c_bit_counter = 4'd8; - byte_counter = 9'd0; - //is_for_me = 1; // RESETS TO ZERO WHEN ADRESS CHECKING + is_adress = 1;//byte_counter = 9'd0; SDA_DIR = 0; is_ack = 0; - //ack_master_ctrl = 1; wr = 0; + is_read = 0; end else if ((i2c_state_machine == 1) && (i2c_start_latency == 0)) begin i2c_start_latency = 1; - is_read = 0; end if ((SDAD == 1) && (SDA_LAST == 0) && (SCLD == 1)) begin i2c_state_machine = 0; @@ -109,24 +84,29 @@ module i2c_slave (input CLK, input RESET, end else begin if ((SCL_LAST == 1) && (SCLD == 0) && (is_ack == 0)) begin - if (byte_counter == 0) begin + if (is_adress == 1) begin if (received_byte[7:1] != I2C_ADRESS) i2c_state_machine = 0; //is_for_me = 0; is_read = received_byte[0]; + //is_adress = 0; end - else begin + //else begin // EMIT SIGNAL OF BYTE RECEIVING - end - if (byte_counter != ((1< 1)) - wr = 1; + else if ((SCL_LAST == 0) && (SCLD == 1) && (is_ack == 1)) begin//(byte_counter > 1)) + if (is_adress == 1) + is_adress = 0; + else + wr = 1; + end else if ((SCL_LAST == 1) && (SCLD == 0) && (is_ack == 1)) begin is_ack = 0; SDA_DIR = 0; @@ -153,8 +133,8 @@ module i2c_slave (input CLK, input RESET, i2c_bit_counter = 8; i2c_state_machine = (SDAD ^ 1) | SDA_DIR; //ack_master_ctrl = SDAD+1; // MAYBE TRANSMIT BYTE REPEAT wr = (SDAD ^ 1) | SDA_DIR; - if (byte_counter != ((1< (ONE_CALC_TIME_POW - 3); ONE_CALC_TIME_POW > 2 (if 2 or smaller, top module overrun may occur) - reg [12:0] row_time = 0; + reg [ONE_ROW_TIME_POW:0] row_time = 0; reg [3:0] row_counter; reg [7:0] temp; reg [7:0] i; - reg [7:0] report [6:0]; // NO BYTE 2 + //reg [7:0] report [6:0]; // NO BYTE 2 + //reg [7:0] report_byte; reg isr; + reg isr_internal; reg [15:0] ROWS_EN = 0; reg [15:0] ROWS_OUT = 0; wire [15:0] ROWS_IN; reg [7:0] COLS_SHADOW; - reg [7:0] kbd_code; + //reg [7:0] kbd_code; + wire [6:0] kbd_code; + assign kbd_code [2:0] = row_time[7:5]; // COLUMN NUM + assign kbd_code [6:3] = row_counter; // ROW NUM wire [7:0] kbd_code_hid; reg is_pressed; @@ -36,33 +43,72 @@ module matrix_kbd (input CLK, input RESET, input FREEZE, inout [15:0] ROWS, inpu reg [8:0] ram_adr; wire [7:0] ram_rd; - reg [3:0] init_delay_cnt; - reg [8:0] init_ram_cnt; + //reg [3:0] init_delay_cnt; + //reg [8:0] init_ram_cnt; + reg IS_RAM_INIT = 0; /*always @ (negedge CLK) begin COLS_SHADOW <= COLUMNS; end*/ + wire [7:0] report_data_rd; + reg [3:0] report_adress_rd; + reg [7:0] report_data_wr; + wire [3:0] report_adress_wr; + assign report_adress_wr = report_adress_rd; + assign REPORT_DATA = report_data_rd; + reg report_wr_en; + ram REPORT (CLK, report_wr_en, report_adress_wr, report_data_wr, report_adress_rd, report_data_rd); ram RAM (CLK, ram_wr, ram_adr, temp, ram_adr, ram_rd);//module ram(input clk, wen, input [8:0] addr, input [7:0] wdata, output [7:0] rdata); - always @ (posedge CLK) begin + always @ (negedge CLK) begin if (RESET == 0) begin - for (i = 0; i < 6; i = i + 1) - report[i] = 0; + //for (i = 0; i < 6; i = i + 1) + // report[i] = 0; isr = 0; - init_delay_cnt = 0; - init_ram_cnt = 0; + isr_internal = 0; + //init_delay_cnt = 0; + //init_ram_cnt = 0; row_time = 0; + IS_RAM_INIT = 1; + ram_adr = 500; + report_adress_rd = 5; + report_wr_en = 0; + //report_byte = 0; end else begin if (FREEZE == 0) begin - if (init_delay_cnt != 15) + /*if (REPORT_ADRESS == 0) + report_byte <= 10; + else if ((REPORT_ADRESS == 1) || (REPORT_ADRESS == 3)) + report_byte <= 0; + else if (REPORT_ADRESS == 2) + report_byte <= report[0]; + else + report_byte <= report[REPORT_ADRESS-3];*/ + /*if (init_delay_cnt != 15) init_delay_cnt = init_delay_cnt + 1; else if (init_ram_cnt < 256) begin ram_wr = 1; ram_adr = init_ram_cnt; temp = 255; init_ram_cnt = init_ram_cnt + 1; + end*/ + if (IS_RAM_INIT) begin + ram_wr = 1; + ram_adr = ram_adr + 1; + temp = 255; + report_adress_rd = report_adress_rd + 1; + if (report_adress_rd == 0) + report_data_wr = 10; + else + report_data_wr = 0;//report_adress_rd & 1; + report_wr_en = 1; + if (ram_adr == 130) begin + //ram_wr = 0; + IS_RAM_INIT = 0; + report_wr_en = 0; + end end /*else if (init_ram_cnt == 256) begin ram_wr = 0; @@ -85,7 +131,8 @@ module matrix_kbd (input CLK, input RESET, input FREEZE, inout [15:0] ROWS, inpu //if (row_time == 8191/*(ROW_STT_PROCESS_TIME + ONE_COLUMN_PROCESS_TIME * 7 + 1)*/) // ram_wr = 1; - if ((row_time[12:8] == 31) && (row_time[4:0] == 0)) begin + //if ((row_time[12:8] == 31) && (row_time[4:0] == 0)) begin + if ((row_time[ONE_ROW_TIME_POW:8] == ((1<<(ONE_ROW_TIME_POW-7))-1)) && (row_time[4:0] == 0)) begin //temp = ram_rd; //COLS_SHADOW = COLUMNS; if (row_time[7:5] == 0) begin @@ -96,8 +143,8 @@ module matrix_kbd (input CLK, input RESET, input FREEZE, inout [15:0] ROWS, inpu if (row_time[7:5] == 7) ram_wr = 1; end - else - kbd_code = 255; + //else + // kbd_code = 255; /*if (row_time == (ROW_STT_PROCESS_TIME + ONE_COLUMN_PROCESS_TIME * 0)) check_column (0); @@ -119,7 +166,55 @@ module matrix_kbd (input CLK, input RESET, input FREEZE, inout [15:0] ROWS, inpu kbd_code = 255;*/ // START PACK I2C_HID REPORT - if (kbd_code_hid != 0) begin + + else if ((isr_internal == 1)/* && (row_time[4:0] > 1)*/) begin + if (report_wr_en == 1) begin + report_wr_en = 0; + isr_internal = 0; + isr = 1; + end + else if (kbd_code_hid == 0) // IF KEY NOT EXIST, DO NOTHING + isr_internal = 0; + else if (kbd_code_hid[7:3] == 5'b11100) begin // BYTE WITH MODIFIERS IS READ AT START OF ALG + if (is_pressed) + report_data_wr = report_data_rd | (1<<(kbd_code_hid & 8'h07)); + else + report_data_wr = report_data_rd & (~(1<<(kbd_code_hid & 8'h07))); + report_wr_en = 1; + end + //else + // isr_internal = 0; + else if (report_adress_rd == 2) // IF BUTTON IS NOT MODIFIER, SET ADRESS TO FIRST BUTTON BYTE + report_adress_rd = 4; + else if (report_adress_rd == 10) // IF TOO MUTCH ADRESSES SEEK, END ALG (BUTTONS ARE IN ADRESSES 4-9) + isr_internal = 0; + else begin + if (is_pressed) begin + if (report_data_rd == kbd_code_hid) // IF BUTTON WITH SAME CODE IS IN REPORT + isr_internal = 0; // CLEAR INTERNAL INTERRUPT, NO EXT INTERRUPT + else if (report_data_rd == 0) begin // IF FREE ADRESS FOUND + report_data_wr = kbd_code_hid; // WRITE CODE TO THIS ADRESS + report_wr_en = 1; + end + else + report_adress_rd = report_adress_rd + 1; // IF NO FREE PLACE, CONTINUE SEEK + end + else begin // BUTTON RELEASED + if (report_data_rd == kbd_code_hid) begin // IF ADRESS WITH THIS CODE FOUND + report_data_wr = 0; // WRITE 0 TO THIS ADRESS (BTN RELEASED) + report_wr_en = 1; + end + else + report_adress_rd = report_adress_rd + 1; // IF THIS CODE NOT FOUND, CONTINUE SEEK + end + end + end + + else begin// if (isr_internal == 0) begin + report_adress_rd = REPORT_ADRESS /*- 1*/; // IF REPORT FILLING PROCESS IS ENDED, SET ADRESS FROM TOP MODULE + isr <= 0; + end + /*if (kbd_code_hid != 0) begin if (kbd_code_hid[7:3] == 5'b11100) begin //if ((kbd_code_hid > 8'hDF) && (kbd_code_hid < 8'hE8)) begin if (is_pressed) @@ -149,7 +244,8 @@ module matrix_kbd (input CLK, input RESET, input FREEZE, inout [15:0] ROWS, inpu else begin for (i = 1; i < 7; i = i + 1) begin - if (report [i] == kbd_code_hid/*kbd_code*/) begin + if (report [i] == kbd_code_hid) begin + //if (report [i] == kbd_code) begin report [i] = 0; isr = 1; end @@ -158,7 +254,7 @@ module matrix_kbd (input CLK, input RESET, input FREEZE, inout [15:0] ROWS, inpu end end // END OF KBD CODE SEND ALG else - isr <= 0; + isr <= 0;*/ end end end @@ -168,22 +264,25 @@ module matrix_kbd (input CLK, input RESET, input FREEZE, inout [15:0] ROWS, inpu input [2:0] column; begin if (COLS_SHADOW[column] != temp[column]) begin - kbd_code = row_counter*8 + column; + //kbd_code = row_counter*8 + column; if ((COLS_SHADOW[column] == 0) && (temp[column] == 1)) is_pressed = 1; else is_pressed = 0; + isr_internal = 1; // INTERNAL ISR AT NEXT TACT + report_adress_rd = 2; // ADRESS TO MODIFIERS end - else kbd_code = 255; + //else kbd_code = 255; temp[column] = COLS_SHADOW[column]; end endtask - assign kbd_r0 = report[0]; + /*assign kbd_r0 = report[0]; assign kbd_r2 = report[1]; assign kbd_r3 = report[2]; assign kbd_r4 = report[3]; assign kbd_r5 = report[4]; assign kbd_r6 = report[5]; - assign kbd_r7 = report[6]; + assign kbd_r7 = report[6];*/ + //assign REPORT_DATA = report_byte; assign INT = isr; SB_RAM40_4K #( diff --git a/i2c_keyboard/top.v b/i2c_keyboard/top.v index 7fa52d9..bc50f18 100644 --- a/i2c_keyboard/top.v +++ b/i2c_keyboard/top.v @@ -4,6 +4,7 @@ module top (input CLK, output LED1, LED2, LED3, LED4, LED5, input COM_RX, output COM_TX, COM_DCD, COM_DSR, COM_RTS, input [7:0] KBD_COLUMNS, inout [15:0] KBD_ROWS); + parameter INTERRUPT_TMR_REFLESH = 14; // 14 - 2^14=16384 tacts or 1.37 ms, 19 - 2^19=524288 tacts or 43.7 ms, 23 - 2^23=8388608 tacts or 0.7 s // 23 - 1119 LCs, 14 - 1081 LCs (in commit 1b6fc60221b595c2a0f69509d29b6e5c3110feb0) @@ -11,276 +12,253 @@ module top (input CLK, output LED1, LED2, LED3, LED4, LED5, 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; + wire [7:0] I2C_TX_DESC; 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; + 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); + I2C_RX, I2C_TX);//, I2C_COUNTER); - reg UART_WR, UART_DTR, UART_RTS, UART_DCD; + reg UART_WR, UART_DTR, UART_RTS, UART_DCD;//, UART_WR2; reg [7:0] UART_TX_DATA; wire UART_ACTIVE, UART_TX_LINE; - initial begin + /*initial begin UART_WR = 0; UART_RTS = 1; UART_DTR = 0; UART_DCD = 0; - end + 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 [7:0] kbd_report [6:0]; + wire [7:0] report_byte; wire ISR; reg INT = 1; // INTERRUPT LINE TO HOST reg [INTERRUPT_TMR_REFLESH:0] int_tmr; 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); + matrix_kbd KEYBOARD (CLK, RESET, IS_RAM_INIT /*KBD_FREEZE*/, KBD_ROWS, KBD_COLUMNS, wr_cnt, report_data_wr, ISR);//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*/); + descriptors I2C_HID_DESC (CLK, /*RESET, I2C_WR,*/ I2C_OUTPUT_TYPE[/*1:*/0], I2C_COUNTER, I2C_TX_DESC/*, kbd_report*/); - //reg [7:0] ring_report [(8*8-1):0]; - reg [7:0] init_ram_cnt; reg [3:0] ring_wr, ring_rd; reg [3:0] wr_cnt; reg report_wr_en; - reg [7:0] report_data_wadr, report_data_radr, report_data_wr; + //reg [7:0] /*report_data_wadr,*/ /*report_data_radr,*/ //report_data_wr; + wire [7:0] report_data_radr, report_data_wadr, report_data_wr; + assign report_data_radr[7:4] = ring_rd; + assign report_data_radr[3:0] = I2C_COUNTER; + assign report_data_wadr[7:4] = ring_wr; + assign report_data_wadr[3:0] = wr_cnt; wire [7:0] report_data_rd; - ram REPORT_DATA (CLK, report_wr_en, report_data_wadr, report_data_wr, report_data_radr, report_data_rd); + ram REPORT_DATA ((1^CLK), report_wr_en, report_data_wadr, report_data_wr, report_data_radr, report_data_rd); assign I2C_TX = (I2C_TX_DESC & I2C_OUT_DESC_MASK) | (/*I2C_TX_REPORT*/report_data_rd & (~I2C_OUT_DESC_MASK)); - //parameter MAX_INPUT_LEN = 10; - //reg [7:0] I2C_INPUT_DATA [MAX_INPUT_LEN:0]; - reg [7:0] temp_output_report; + reg [2: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*/6:0] I2C_COUNTER = 0; + reg [2:0] I2C_OUTPUT_TYPE = 0; // 0 - I2C HID DESCR, 1 - HID REPORT DESC, 2 - INPUT REPORT reg [7:0] I2C_OUT_DESC_MASK = 0; - reg [7:0] KBD_LED_STATUS = 0; + reg [2:0] KBD_LED_STATUS = 0; - - reg last_wr = 0, last_trans = 0, last_uart_active = 0, last_isr = 0, uart_double_ff = 0; + reg last_wr = 0, last_trans = 0, last_isr = 0; + reg IS_RAM_INIT = 0; always @(posedge CLK) begin // RESET LOGIC rststate <= rststate + !RESET; if (RESET == 0) begin - I2C_OUTPUT_TYPE = 3;//0; + I2C_OUTPUT_TYPE = 2;//3;//0; I2C_OUT_DESC_MASK = 0; - KBD_LED_STATUS = 5; // BIT 0 - NUM LOCK, BIT 1 - CAPS LOCK, BIT 2 - SCROOL LOCK - uart_double_ff = 0; last_trans = 0; last_uart_active = 0; last_isr = 0; - I2C_INPUT_LEN = 0; - INT = 1; int_tmr = 0; UART_WR = 0; + KBD_LED_STATUS = 0; // BIT 0 - NUM LOCK, BIT 1 - CAPS LOCK, BIT 2 - SCROOL LOCK + last_trans = 0; last_isr = 0; last_wr = 0; + I2C_COUNTER = 0; + INT = 1; int_tmr = 0; ring_wr = 0; ring_rd = 15; wr_cnt = 0; - init_ram_cnt = 0; + IS_RAM_INIT = 1; + //report_data_wadr = 245; // FIRST 10 TACTS ARE EMPTY + report_wr_en = 0; end // NOT RESET MODE LOGIC else begin - if (init_ram_cnt < 170) begin - report_wr_en = 1; - if (init_ram_cnt < 10) - report_data_wadr = 0; - else - report_data_wadr = init_ram_cnt - 10; - report_data_wr = 0;//report_data_adr + 1; - init_ram_cnt = init_ram_cnt + 1; - end - else if (init_ram_cnt == 170) begin - report_wr_en = 0; - init_ram_cnt = init_ram_cnt + 1; - end - - else if ((last_isr == 0) && (ISR == 1)/* && (INT == 1)*/) begin // INTERRUPT FROM KEYBOARD - if ((ring_wr + 1) != ring_rd) - ring_wr = ring_wr + 1; - report_wr_en = 1; - report_data_wadr = ring_wr * 10; - report_data_wr = 10;//kbd_report [0]; - wr_cnt = 1; - INT = 0; - I2C_OUTPUT_TYPE = 3; - I2C_OUT_DESC_MASK = 8'h00; - last_isr = ISR; - end - else if ((last_isr == 1) && (ISR == 0)) - last_isr = ISR; - else if (wr_cnt != 0) begin - if (wr_cnt == 10) begin - wr_cnt = 0; + if (IS_RAM_INIT) begin + //report_wr_en = 1; + //report_data_wadr = report_data_wadr + 1; + //report_data_wr = 0; + wr_cnt = wr_cnt + 1; + if ((wr_cnt == 0) && (report_wr_en == 0)) + report_wr_en = 1; + else if ((wr_cnt == 0) && (report_wr_en == 1)) begin report_wr_en = 0; + IS_RAM_INIT = 0; end - else begin - report_data_wadr = ring_wr * 10 + wr_cnt; - if ((wr_cnt == 1) || (wr_cnt == 3)) - report_data_wr = 0; - else if (wr_cnt == 2) - report_data_wr = kbd_report [wr_cnt - 2]; - else - report_data_wr = kbd_report [wr_cnt - 3]; - wr_cnt = wr_cnt + 1; - end + /*if (report_data_wadr == 17) begin + report_wr_en = 0; + IS_RAM_INIT = 0; + end*/ end - else if ((last_wr == 0) && (I2C_WR == 1)) begin // I2C NEW BYTE TX/RX - I2C_INPUT_LEN = I2C_COUNTER - 1; - if (I2C_READ == 0) begin // I2C_FROM_HOST + else begin // START OF NON RESET AND NON INIT LOGIC - if (I2C_COUNTER == 2) begin - if ((I2C_RX > 5) || (I2C_RX < 1)) - i2c_input_data_type = 0; - else - i2c_input_data_type = I2C_RX; +// ------------------------- KBD INTERRUPT ------------------------ // + + if ((last_isr == 1/*0*/) && (ISR == 0/*1*/)) begin // INTERRUPT FROM KEYBOARD + if ((ring_wr + 1) != ring_rd) + ring_wr = ring_wr + 1; + report_wr_en = 1; + //report_data_wadr = ring_wr * 16 + 1; + //report_data_wr = 10;//kbd_report [0]; + wr_cnt = 1; + //INT = 0; + //I2C_OUTPUT_TYPE = 2;//3; + //I2C_OUT_DESC_MASK = 8'h00; + end + + else if (wr_cnt != 0) begin // WRITING TO RAM REPORT FROM KEYBOARD + if (wr_cnt == 11) begin + wr_cnt = 0; + report_wr_en = 0; end - else if (I2C_COUNTER == 3) begin - if (I2C_RX != 0) - i2c_input_data_type = 0; + else begin + //report_data_wadr = ring_wr * 16 + wr_cnt + 1; + /*if ((wr_cnt == 1) || (wr_cnt == 3)) + report_data_wr = 0; + else if (wr_cnt == 2) + report_data_wr = kbd_report [wr_cnt - 2]; + else + report_data_wr = kbd_report [wr_cnt - 3];*/ + wr_cnt = wr_cnt + 1; 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 + +// ---------------------------- I2C NEW BYTE TX/RX RISING/FALLING EDGE, RISING - ALL LOGIC, FALLING - UART TX -------------- // + + if ((last_wr == 0) && (I2C_WR == 1)) begin // I2C NEW BYTE TX/RX + //I2C_COUNTER = I2C_COUNTER - 1; + if (I2C_READ == 0) begin // I2C_FROM_HOST + + if (I2C_COUNTER == 0) 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 == 1) begin + if (I2C_RX != 0) + i2c_input_data_type = 0; + end + else if (I2C_COUNTER == 2) 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 == 3) 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 == 4) begin + if (i2c_input_data_type == 4) + temp_output_report = I2C_RX[2:0]; + 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 == 5) 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 == 8) begin + if (i2c_input_data_type == 7) + temp_output_report = I2C_RX[2:0]; 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 + end - else begin // I2C_TO_HOST - if (I2C_OUTPUT_TYPE == 3) begin - //if ((I2C_COUNTER < 2) || (I2C_COUNTER > (2 + 10 - 1))) - // I2C_TX_REPORT <= 0; - /*else */if (I2C_COUNTER == 2) begin - if (ring_rd != ring_wr) - ring_rd = ring_rd + 1; - report_data_radr = ring_rd * 10; + else begin // I2C_TO_HOST + if (I2C_OUTPUT_TYPE == 2/*3*/) begin + if (I2C_COUNTER == 0) begin + if (ring_rd != ring_wr) + ring_rd = ring_rd + 1; + //report_data_radr = ring_rd * 10; + end + //else + // report_data_radr = report_data_radr + 1; end - else - report_data_radr = report_data_radr + 1; - //else if (I2C_COUNTER == 2) - // I2C_TX_REPORT <= 10; - //else if ((I2C_COUNTER == 3) || (I2C_COUNTER == 5)) begin - // I2C_TX_REPORT <= 0; - // if (ring_rd != ring_wr) - // ring_rd = ring_rd + 1; - // report_data_radr = ring_rd * 10; - //end - /*else if (I2C_COUNTER == 4) - I2C_TX_REPORT <= kbd_report[0];*/ - //else begin - // I2C_TX_REPORT = report_data_rd; - // report_data_radr = report_data_radr + 1; - //I2C_TX_REPORT <= kbd_report[I2C_COUNTER - 5]; - //end end - //else - // I2C_TX_REPORT <= 0; - end - last_wr = I2C_WR; - 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; - last_wr = I2C_WR; - 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_double_ff = 1; - UART_TX_DATA = 8'hFF; - UART_WR = 1; - last_trans = I2C_TRANS; - 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_OUTPUT_TYPE == 1) || (I2C_OUTPUT_TYPE == 2)) - I2C_OUT_DESC_MASK = 8'hFF; + UART_WR <= 0; + if (I2C_COUNTER != 127) + I2C_COUNTER = I2C_COUNTER + 1; + 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 - I2C_OUT_DESC_MASK = 8'h00; - end // END OF I2C_READ == 0 + UART_TX_DATA = I2C_TX; + //UART_TX_DATA = I2C_COUNTER; + end // I2C_NEW_BYTE_NEGEDGE_FOR_UART - END + +// ---------------------- I2C START/STOP CONDITIONS, START - ONLY UART FF TX, STOP - ALL LOGIC ----------------- // + + 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; + I2C_COUNTER = 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_COUNTER != 2)) || ((i2c_input_data_type == 4) && (I2C_COUNTER != 5)) || ((i2c_input_data_type == 5) && (I2C_COUNTER != 4)) || ((i2c_input_data_type == 6) && (I2C_COUNTER != 6)) || ((i2c_input_data_type == 7) && (I2C_COUNTER != 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 - 1; + 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 = 2;//3; + else if (i2c_input_data_type == 5) + rststate <= 4'h0; // RESET COMMAND + + if ((I2C_OUTPUT_TYPE == 1) || (I2C_OUTPUT_TYPE == 0))//2)) + I2C_OUT_DESC_MASK = 8'hFF; + else + I2C_OUT_DESC_MASK = 8'h00; + end // END OF I2C_READ == 0 - else begin - if (((I2C_OUTPUT_TYPE == 3) /*|| (I2C_OUTPUT_TYPE == 0)*/) && (I2C_INPUT_LEN > 1)) begin - // DEACTIVATING INTERRRUPT IF HOST READ INPUT REPORT (LEN 10) AFTER INTERRUPT OR EMPTY DATA (>=2 BYTES) AFTER RESET - //if (ring_rd == ring_wr) + else begin + if ((I2C_OUTPUT_TYPE == 2/*3*/) && (I2C_COUNTER > 1)) begin + // DEACTIVATING INTERRRUPT IF HOST READ INPUT REPORT (LEN 10) AFTER INTERRUPT OR EMPTY DATA (>=2 BYTES) AFTER RESET INT = 1; int_tmr = 0; - - //if (ring_rd != ring_wr) - // ring_rd = ring_rd + 1; + end + I2C_OUTPUT_TYPE = 2;//3; + I2C_OUT_DESC_MASK = 0; end - I2C_OUTPUT_TYPE = 3; - I2C_OUT_DESC_MASK = 0; - end - last_trans = I2C_TRANS; - end // I2C_STOP CONDITION (OR REPEAT START DETECTED) - END + UART_WR <= 0; + //last_trans = I2C_TRANS; + end // I2C_STOP CONDITION (OR REPEAT START DETECTED) - END - else if ((last_uart_active == 1) && (UART_ACTIVE == 0)) begin - if (uart_double_ff == 1) begin - UART_WR = 1; - UART_TX_DATA = 8'hFF; - uart_double_ff = 0; - end - last_uart_active = UART_ACTIVE; - end - else if ((last_uart_active == 0) && (UART_ACTIVE == 1)) - last_uart_active = UART_ACTIVE; +// ---------------- INTERRUPT TO HOST GENERATING LOGIC: DELAY AND INTERRUPT GENERATING (IF NEED) --------------- // - else if (UART_WR == 1) - UART_WR = 0; + //if (int_tmr != ((1<<(INTERRUPT_TMR_REFLESH+1))-1)) + if (int_tmr[INTERRUPT_TMR_REFLESH] != 1) + int_tmr = int_tmr + 1; - else if (int_tmr != ((1<<(INTERRUPT_TMR_REFLESH+1))-1))//[INTERRUPT_TMR_REFLESH] != 1) - int_tmr = int_tmr + 1; + else if ((I2C_OUTPUT_TYPE == 2/*3*/) && (I2C_TRANS == 0)) begin + if (ring_rd != ring_wr) + INT = 0; + end - else if (/*(int_tmr[INTERRUPT_TMR_REFLESH] == 1) &&*/ (I2C_OUTPUT_TYPE == 3) && (I2C_TRANS == 0)) begin - if (ring_rd != ring_wr) - INT = 0; - 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_trans <= I2C_TRANS; + last_wr <= I2C_WR; + last_isr <= ISR; + end // END OF NON RESET AND NON INIT LOGIC end diff --git a/i2c_keyboard/uart.v b/i2c_keyboard/uart.v index b672f3a..87fce84 100644 --- a/i2c_keyboard/uart.v +++ b/i2c_keyboard/uart.v @@ -22,9 +22,10 @@ initial begin tx_line = 1; end -always @ (posedge CLK) begin +always @ (negedge CLK) begin if (RESET == 0) begin - /*tx_data = 0;*/ tx_clk_counter = 0; + /*tx_data = 0;*/ //tx_clk_counter = 0; + tx_activity = 0; end else begin