[Original black gold tutorial] [FPGA-driver I] experiment 8: PS/2 module ②-keyboard and key combination

Source: Internet
Author: User
Experiment 8: PS/2 module ②-keyboard and key combination

In experiment 7, we learned how to read the code and the code break sent from the PS/2 keyboard. However, the experiment content is just a one-click press and then release, just a simple button. However, in experiment 8, we learned the key combination behavior.

Do you have similar experiences? When we use the keyboard, if ~ 6. Press the button at the same time, and the computer will beep and the keyboard will immediately become invalid. This is a keyboard restriction design. Different products also have different limits on the number of buttons. By default, the maximum number of buttons is 5 ~ 7. A key combination is a valid key generated by more than two buttons. For example, press the <A> button to output "character a" and press <shift> + <A> to output "character ". However, to achieve the combination of keys, we must have a deep understanding of the keyboard's key actions.

Figure 8.1 press and release immediately.

PS/2 The most common keyboard button behavior is to release immediately after pressing, assuming that the author presses the <A> key and immediately releases <A> key, then the PS/2 Keyboard generates a sequence similar to Figure 8.1. As shown in Figure 8.1, when I press <A>, the PS/2 Keyboard will send the 8' H1c code. Otherwise, if <A> is released, the PS2 Keyboard will immediately send the 8'hf0 8' H1c disconnection code.

Figure 8.2 press and release immediately.

If you press <A> to hide it, the PS/2 Keyboard will send a ms interval of 8 'h1c. During this period, if the author releases <A>, the PS/2 Keyboard will send an 8'hf0 8' H1c disconnection code, as shown in the timing result 8.2. Both Figure 8.1 and figure 8.2 are the most common button actions on the PS/2 keyboard, that is, single-key actions. Even so, single-key behavior is not only the most basic button behavior, but also the multi-key behavior must be based on it.

Figure 8.3 multi-key behavior: First press and then place ①.

The multi-key action is different from the single-key action. Because more than two buttons are pressed at the same time, the multi-key action is followed by first, and so on. Assume that the author presses <A> and then presses <lshift>. Then, the PS/2 Keyboard will send the H1c and 8' H12 codes. If the author wants to release it, <lshift> must be released in advance, and <A>, as a result, the keyboard of PS/2 continuously sends the disconnection codes of 8'hf0 8' H12 and 8'hf0 8' H1c.

Figure 8.3 multi-key behavior, first press and then put ②.

Then let's assume that the author presses <A> and then presses <lshift> and does not immediately release any buttons. As the last button, the execution right can be obtained. As shown in Figure 8.3, the author first presses <A> and then presses <shift>, then the PS/2 Keyboard will continue to send 8 'h1c and 8 'h12 and other code. If the finger paralysis of the author does not immediately release any buttons, then <lshift> will get the execution right, and the result will remain in the long-pressed state. At this moment, the PS/2 Keyboard will not stop sending the <lshift> passcode.

Once the finger is aware, release <lshift> first and then release <A>

, The PS/2 Keyboard will send the 8'hf0 8' H12 and 8'hf0 8' H1c and other broken codes.

Figure 8.5 multi-key behavior, first press first put.

If the reader presses <A> first and then <lshift> in the order of not putting first... as shown in Figure 8.5, if I press <A> and then press <lshift>, the PS/2 Keyboard will send the 8' H1c and 8' H12 communication codes. During this period, I suddenly raised my hand and thought it was quite fun to put it first, so I deliberately released <A>. At this moment, the PS/2 Keyboard will send a code disconnection of 8 'hf0 8' H1c.

At the same time, <lshift> also keeps the pressed position. After the PS/2 Keyboard is sent <A>, the PS/2 Keyboard also keeps sending the <lshift> passcode... until the author releases <lshift>, the PS/2 keyboard sends an 8'hf0 8' H12 code.

The end of Multi-key behavior is "first press and then put" or "first press first put ". In any order, the next button will snatch the execution right and long-pressed status of the last button. However, according to the habits, the first-to-second release has become the mainstream, and only the accident or the nervous and uncoordinated fool will choose the first-to-first release order. When we understand the multi-key behavior of the PS/2 keyboard, we can start to implement the key combination.

According to my understanding, the PS/2 Keyboard also has key categories, such as <shift>, <Ctrl> and <alt>, which are common combination (subsidy) buttons. In addition, the notebook or some special keyboards have different keys, such as <FN> and <win>. In general, we all think that key combinations are software work. Although this is a fact, we only need to change the way we use it. In this regard, we only need to regard a combination of keys as a flag State, all problems can be solved.

Figure 8.6 combination key and flag status.

If I press <lctrl> and <lshift>, the isctrl flag is set after the <lctrl> passcode is sent on the PS/2 Keyboard. Then, the PS/2 Keyboard will send the <l shift> passcode, and then the isshift will also flag.

After the event, the author releases <lshift> and then releases <lctrl>, then the PS/2 Keyboard will continue to send the <lshift> and <lctrl> broken code. <Lshift> after the code is sent, isshift eliminates the flag. Similarly, after the <lctrl> disconnection code is sent, the isctrl flag is also removed.

Figure 8.7 valid key combination ①.

In order to express the effective key combination, we still need the isdone high pulse. Although we know that isdone generates high pulses after the general code output. However, the key combination is not considered as a general code. As shown in figure 8.7, assume that the author presses <lshift> and <A>. After the <lshift> code is sent, the isshift flag is set up. <A> after the code is sent, the isdone is increased for a while. If isshift is in the pull-up status and the Code <A> is valid, the valid key combination <shift> + <A> is generated.

After the release, the author releases the <A> release <lshift>, and the PS/2 Keyboard will continue to send the <A> and <lshift> code. The <A> code disconnection does not produce any effect. The <lshift> code disconnection eliminates the flag status of isshift.

Figure 8.8 valid key combination ②.

In order to generate a variety of valid keys, it is impossible for us to continuously press and release them... in other words, the guy who keeps switching is only a key combination, and the key combination remains valid until the code is sent. As shown in figure 8.8, if I press <lshift> and <A> and <lshift> to enable isshift to flag, <A> to enable isdone to generate a high pulse, <shift> + <A> is complete.

Then, the author releases the <A>, and the PS/2 keyboard sends the <A> disconnection code. In a short time, I press <B>, <B> the code causes isdone to generate a high pulse, and the result is the combination of keys <shift> + <B>. After the event, the author releases <B> and releases <lshift>, and the PS/2 Keyboard will send a disconnect Code <B> and <lshift>, <B> no exception in the code, <lshift> If the code is disconnected, the flag status of isshift is eliminated.

Figure 8.9 multi-state key combinations.

In addition to being a key combination (an immediate state), multiple key combinations can also be implemented in the same way (multiple flag States ). As shown in Figure 8.9, the author first presses <lctrl> and then <lshift>, <lctrl> flag isctrl status, and <lshift> flag isshift status. Then I press <A> and <A> the code causes isdone to generate a high pulse. At this moment, the key combination <Ctrl> + <shift> + <A> has been completed. Then the author releases <A> to generate <A> code disconnection.

After a while, I press <B> and the result <B> the code drive isdone generates another high pulse. At this moment, the key combination <Ctrl> + <shift> + <B> has been completed. Satisfied author releases <B>, <lshift>, and <lctrl>. <B> the error code is not unusual. <lshift> the error code is removed from the flag status of isshift. <lctrl> the error code is removed from the flag status of isctrl.

Generally, a key combination can reach up to three levels, that is, <Ctrl> + <shift> + <alt> + ?. Even so, unless the opponent's fingers are more flexible than the monkeys, it is easy to hurt the fingers by pressing four buttons in order at the same time. In other words, the primary and secondary keys are enough for application. Theoretically, there is no problem with the number of levels of keys to be implemented in each of the three keywords. However, too many functions are just a waste.

Now, after understanding the above content, we can start modeling!

Figure 8.10 experiment 8 model creation Diagram.

Figure 8.10 is the modeling diagram of experiment 8. A combination module named ps2_demo contains the PS/2 function module and the basic digital module. The left side of the PS/2 function module is the input of top-level signals such as ps2_clk and ps2_dat, and the right side is the basic module of the digital tube driven by the combination of odata and otag. In this regard, in addition to the output code, the digital tube also indicates the effective status of the key combination.

Ps2_funcmod.v

Figure 8.11 modeling of PS/2 functional modules.

Compared with figure 8.10 and figure 8.11, the PS/2 function module in Figure 8.11 also has otrig, which is used to send high pulses of isdone. For details, let's look at the Code:

1.    module ps2_funcmod
2.    (
3.         input CLOCK, RESET,
4.         input PS2_CLK, PS2_DAT,
5.         output oTrig,
6.         output [7:0]oData,
7.         output [2:0]oTag
8.    );

The above content is the access statement.

9.    
10.         parameter LSHIFT = 8‘h12, LCTRL = 8‘h14, LALT = 8‘h11, BREAK = 8‘hF0;
11.         parameter FF_Read= 5‘d5;
12.    
13.         /*******************************/ // sub1
14.         
15.        reg F2,F1; 
16.         
17.        always @ ( posedge CLOCK or negedge RESET )
18.             if( !RESET )
19.                  { F2,F1 } <= 2‘b11;
20.              else
21.                  { F2, F1 } <= { F1, PS2_CLK };
22.    
23.         /*******************************/ // core
24.         
25.         wire isH2L = ( F2 == 1‘b1 && F1 == 1‘b0 );

The preceding content is a constant declaration, peripheral operations, and instant declaration. The first line is the constant declaration of lshift, lctrl and lalt. In addition, there is also the first frame of break code breaking data, as well as the pseudo function entry (11th rows ). 15th ~ 21 rows are peripheral operations used to detect level changes, and 25th rows are instant declarations of descent edges.

26.         reg [7:0]D1;
27.         reg [2:0]isTag;  // [2] isShift, [1] isCtrl, [0] isAlt
28.         reg [4:0]i,Go;
29.         reg isDone;
30.         
31.         always @ ( posedge CLOCK or negedge RESET )
32.             if( !RESET )
33.                  begin
34.                         D1 <= 8‘d0;
35.                         isTag <= 3‘d0;
36.                         i <= 5‘d0;
37.                         Go <= 5‘d0;
38.                         isDone <= 1‘b0;
39.                    end
40.               else

The above content is related to the Register declaration and reset operation. During this period, istag is the Status Register. istag [2] indicates isshift, istag [1] indicates isctrl, and istag [0] indicates isalt. 33rd ~ The 38 rows are the reset operation of the Register.

65.                          /****************/ // PS2 Read Function
66.                          
67.                          5:  // Start bit
68.                          if( isH2L ) i <= i + 1‘b1; 
69.                          
70.                          6,7,8,9,10,11,12,13:  // Data byte
71.                          if( isH2L ) begin i <= i + 1‘b1; D1[ i-6 ] <= PS2_DAT; end
72.                          
73.                          14: // Parity bit
74.                          if( isH2L ) i <= i + 1‘b1;
75.                          
76.                          15: // Stop bit
77.                          if( isH2L ) i <= Go;
78.                            
79.                     endcase

The preceding content is a pseudo function of some core operations. This pseudo function reads 1 frame of PS/2 data.

41.                    case( i )
42.                          
43.                          0: // Read Make
44.                          begin i <= FF_Read; Go <= i + 1‘b1; end
45.                          
46.                          1: // Set Flag
47.                          if( D1 == LSHIFT ) begin isTag[2] <= 1‘b1; D1 <= 8‘d0; i <= 5‘d0;end
48.                          else if( D1 == LCTRL ) begin isTag[1] <= 1‘b1; D1 <= 8‘d0; i <= 5‘d0; end
49.                          else if( D1 == LALT ) begin isTag[0] <= 1‘b1; D1 <= 8‘d0; i <= 5‘d0; end
50.                          else if( D1 == BREAK ) begin i <= FF_Read; Go <= i + 5‘d3; end
51.                          else begin i <= i + 1‘b1; end
52.                          
53.                          2:
54.                          begin isDone <= 1‘b1; i <= i + 1‘b1; end
55.                          
56.                          3:
57.                          begin isDone <= 1‘b0; i <= 5‘d0; end
58.                          
59.                          4: // Clear Flag
60.                          if( D1 == LSHIFT  ) begin isTag[2] <= 1‘b0; D1 <= 8‘d0; i <= 5‘d0;  end
61.                          else if( D1 == LCTRL ) begin isTag[1] <= 1‘b0; D1 <= 8‘d0; i <= 5‘d0; end
62.                          else if( D1 == LALT ) begin isTag[0] <= 1‘b0; D1 <= 8‘d0; i <= 5‘d0;  end
63.                          else begin D1 <= 8‘d0; i <= 5‘d0; end

The above content is the core operation. The operation process is as follows:

Step 0: Enter the pseudofunction to wait for the read passcode, And go points to the next step.

Step 1: Check the key combination and code disconnection. If it is lshift, The istag [2] flag is set, and then step 0 is returned. If it is lctrl, The istag [1] flag is set and Step 0 is returned; if it is lalt, The istag [0] flag, and then return STEP 0. If it is break, it enters the pseudo function and go points to step 4. If nothing happens, go to step 2 ~ 3.

Step 2 ~ 3. Generate the completion signal and return STEP 0.

Step 4: remove the flag status. Step 1 is break. If the code is lshift, istag [2] is eliminated, istag [1] is eliminated by lctrl, istag [0] is eliminated by lalt, and other code is ignored. Step 0 is returned.

80.         
81.         assign oTrig = isDone;
82.         assign oData = D1;
83.         assign oTag = isTag;
84.        
85.    endmodule

81st ~ Line 83 is the output driver declaration.

Ps2_demo.v

I will not re-paste the modeling diagram here. Please review figure 8.10 on your own.

1.    module ps2_demo
2.    (
3.         input CLOCK, RESET,
4.         input PS2_CLK, PS2_DAT,
5.         output [7:0]DIG,
6.         output [5:0]SEL
7.    );
8.         wire [7:0]DataU1;
9.         wire [2:0]TagU1;
10.    
11.         ps2_funcmod U1
12.         (
13.              .CLOCK( CLOCK ),
14.              .RESET( RESET ),
15.              .PS2_CLK( PS2_CLK ), // < top
16.              .PS2_DAT( PS2_DAT ), // < top
17.              .oTrig(),
18.              .oData( DataU1 ),  // > U2
19.              .oTag( TagU1 ) // > U2
20.         );
21.         
22.       smg_basemod U2
23.        (
24.            .CLOCK( CLOCK ),
25.            .RESET( RESET ),
26.            .DIG( DIG ),  // > top
27.            .SEL( SEL ),  // > top
28.            .iData( { 12‘h000 , 1‘b0, TagU1, DataU1 } ) // < U1
29.        );
30.                 
31.    endmodule

Basically, the content of ps2_demo is not difficult. All connections are deployed according to Figure 8.10. For row 3, datau1 also has the idata of the tagu1 integrated drive Digital Basic module. In other words, 1 ~ 3-bit, 4th-bit digital display of the key combination status, 5th ~ The 6-digit digital tube shows the pass code.

Download the program after compilation. If you press <lshift> + <lctrl> + <lalt> at the same time, the 4th-bit digital tube will display 4'h7, that is, 4'b0111, or istag [2 .. 0. If you press another button, such as <A>, then 5th ~ The six-digit digital display displays 8'h1c. If <lshift> is released, the 4th-bit digital tube will display 4'h3, that is, 4'b0011, or istag [1 .. 0. Release <A>, 5th ~ The 6-digit digital display will display 8'h00.

Details 1: complete individual module

Figure 8.12 PS/2 keyboard function module.

Figure 8.12 is the PS/2 keyboard function module. The content is basically the same as the PS/2 function module. The difference is to put on other vests.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.