This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TCA8418E application issue

Other Parts Discussed in Thread: TCA8418E, TCA8418E-EVM

Dear All,

We are using TCA8418E with the AVR microcontroller in our application. For testing, a TI TCA8418E-EVM together with an ATMEL STK500 are being used at the moment.

The TCA8418E INT pin is connected to the AVR external interrupt pin INT0. We use 4X4 matrix keypad and the chip is configured as follows.

Write 0x01 = 0x19

/* Set registers to 4X4 keypad mode */

Write 0x1D = 0x0F

Write 0x1E = 0x0F

Write 0x1F = 0x00

/* Enable column debouncing */

Write 0x29 = 0x0F

Write 0x2A = 0x0F

Write 0x2B = 0x00

If a falling edge occurs on INT0, the interrupt is triggered and the steps below are followed.

(1) disable INT0

(2) read 0x02 to determine what event (pressed or released) causes interrupt

(3) read 0x04 to detemine what keys were pressed/released. 

(4) save the key value or do some corresponding operations.

(5) read 0x04 again, if the value>0, go back to (2) and get another key value, otherwise, the keypad scan is completed.

(6) write 0x02 = 0xFF 

(7) enable INT0

All these work correctly. But I have two issues related to our application.

(1) Every time entering the interrupt, only one event is detected, i.e., the register 0x03 would always be read as 01. If the user presses a series of keys, how can we detect all the events while calling the interrupt routine just once?

      PS, when the chip was not working in the interrupt mode, we can actually see all events have been put in the FIFO and the register 0x03 is read as the number of key events occurred. However, in the interrupt mode, as we immediately read the register 0x04, the FIFO does not work as expected to save all events. Any suggestions?

(2) If the user pressed one key and hold it for a period of time, say 5s, how can we approximately check whether this key has been pressed for such a period of time?

Many thanks.

Trevor

  • Hello!

    There are a few things I notice right off:

    When you think you are enabling debounce, you are actually disabling it. If you look at page 18 and 19 of the datasheet, it states that a 1 will disable debounce. By default, debounce is enabled for everything. You can either delete those write lines to registers 0x29 and 0x2A, or change them to write 0x00 to both.

    When you detect an interrupt, there are a few things that are not completely correct, and I'll explain them.

    1) You do not need to disable the interrupt pin, as the interrupt pin on your MCU should be edge triggered. The INT signal from the TCA8418E will not change until you clear all interrupts in the device, this means that you must first read everything from the device and then clear the interrupt before the INT pin will change. SO you do not need to disable interrupts on the TCA8418E device. If you are disabling interrupts inside your Atmel MCU, that is probably OK to do, but you do NOT have to disable the TCA8418E interrupt register.

    2) You are correct that you read 0x02, but 0x02 does not tell you if a key press or release has happened. The key event in the FIFO tells you (see page 17: Key Event Registers (FIFO), KEY_EVENT_A-J). You should read 0x02 to see what interrupt was triggered (depending on what bit is set, it will tell you why the interrupt happened. If you read BIT 0 high (K_INT), this means that a key event has happened (see page 16: Interrupt STatus Register, INT_STAT)

    3) Read 0x04 to see what keys are pressed. The MSB in each read (bit 7) tells you whether it was a key press or key release. Bits 6-0 tell you what key was pressed. You can continously read 0x04 to see the list of keys that were logged (it can store up to 10 events, a single press or release counts as its own event). Once you start reading 0x00, that means the FIFO is empty. You outlined this process in steps 4 and 5.

    6) This is correct, you can write 0xFF to 0x02 to clear your interrupt flags, which will deassert the INT pin from the TCA8418E.

    To answer your questions:

    1) This is dependent on how fast your MCU services the interrupt. If your MCU responds fast enough, then you probably will never see more than 1 event. If your MCU is slower to respond, and several presses happen before it gets to the interrupt, then your FIFO will have more events in it. THis is purely dependent on how fast your MCU responds to the interrupt request.

    2) This is dependent to your MCU. The TCA8418E will tell you when a key press happens, and when a key release happens. You must log each event and wait for the key release to happen (a release that happens 5 serconds later will trigger another interrupt). So this must happen in your code. AN example could be that when a key press happens, you set a timer in your MCU and when you get another interrupt from the TCA8418E, and you see the key release happen, then you can measure how much time has elapsed in your timer.

  • Hi Jonathan,

    Many thanks for your reply.

    Please could you check my comments to your answers below in line in red

    I have another thing here. Considering multiple keys pressed together, I use this way to implement the case (assume two keys) :  when an interrupt occurs, read 0x04, and if the first two events are "pressed", we think two keys are pressed together.

    I don't understand the section "Ghosting", in page 21 of the datasheet. Looks like TCA8418E supports a way to detect multiple key presses accurately. Below are my questions.

    (1) Is there a way you can advise to better implement this case? 

    (2) Application requiring three-key combinations (such as <Ctrl><Alt><Del>) must ensure that the three keys are wired in appropriate key positions to avoid ghosting (or appearing like a 4th key has been pressed).  ----------- How to understand this statement?

    (3) Is the two-key presses different from three-key presses? Otherwise why do you mention three-key presses particularly in the datasheet? 

    Thank you

    Best Regards,

    Trevor

    Jonathan Valdez said:

    Hello!

    There are a few things I notice right off:

    When you think you are enabling debounce, you are actually disabling it. If you look at page 18 and 19 of the datasheet, it states that a 1 will disable debounce. By default, debounce is enabled for everything. You can either delete those write lines to registers 0x29 and 0x2A, or change them to write 0x00 to both.

    For the debouncing, I simply copied lines from 256 to 258 in this file:  lxr.free-electrons.com/.../tca8418_keypad.c

    I checked the datasheet and you're right. I have revised my program as you instructed.

    When you detect an interrupt, there are a few things that are not completely correct, and I'll explain them.

    1) You do not need to disable the interrupt pin, as the interrupt pin on your MCU should be edge triggered. The INT signal from the TCA8418E will not change until you clear all interrupts in the device, this means that you must first read everything from the device and then clear the interrupt before the INT pin will change. SO you do not need to disable interrupts on the TCA8418E device. If you are disabling interrupts inside your Atmel MCU, that is probably OK to do, but you do NOT have to disable the TCA8418E interrupt register.

    Yes. After a key event interrupt is triggered in TCA8418E, it seems that the INT pin will keep low unless power-on reset or write a 1 to K_INT bit in 0x02. 

    2) You are correct that you read 0x02, but 0x02 does not tell you if a key press or release has happened. The key event in the FIFO tells you (see page 17: Key Event Registers (FIFO), KEY_EVENT_A-J). You should read 0x02 to see what interrupt was triggered (depending on what bit is set, it will tell you why the interrupt happened. If you read BIT 0 high (K_INT), this means that a key event has happened (see page 16: Interrupt STatus Register, INT_STAT)

    3) Read 0x04 to see what keys are pressed. The MSB in each read (bit 7) tells you whether it was a key press or key release. Bits 6-0 tell you what key was pressed. You can continously read 0x04 to see the list of keys that were logged (it can store up to 10 events, a single press or release counts as its own event). Once you start reading 0x00, that means the FIFO is empty. You outlined this process in steps 4 and 5.

    6) This is correct, you can write 0xFF to 0x02 to clear your interrupt flags, which will deassert the INT pin from the TCA8418E.

    To answer your questions:

    1) This is dependent on how fast your MCU services the interrupt. If your MCU responds fast enough, then you probably will never see more than 1 event. If your MCU is slower to respond, and several presses happen before it gets to the interrupt, then your FIFO will have more events in it. THis is purely dependent on how fast your MCU responds to the interrupt request.

    2) This is dependent to your MCU. The TCA8418E will tell you when a key press happens, and when a key release happens. You must log each event and wait for the key release to happen (a release that happens 5 serconds later will trigger another interrupt). So this must happen in your code. AN example could be that when a key press happens, you set a timer in your MCU and when you get another interrupt from the TCA8418E, and you see the key release happen, then you can measure how much time has elapsed in your timer.

    Regarding this, I decide to use two buffers in MCU, one stores all key events read from 0x04 and another buffer to store the time point on reading each event (a timer/counter starts when the first event comes). In this way I will be able to log each event and know the time interval between the any two of the all events.

    I'm not sure about "a release that happens 5 serconds later will trigger another interrupt". Is it possible for TCA8418E to generate another interrupt on releasing the key after holding it for a period of time?

  • Hello,

    Ghosting: Ghosting is when you press multiple keys (normally 3+ keys) and not all of the ones you are pressing are being detected. This happens when 3 keys share the same 2 rows/columns and it then becomes impossible for the device to tell which buttons are being pressed. I would suggest searching for "keypad ghosting" on any search engine, as there are some good explanations and illustrations of this phenomenon on some websites.

    1) Ghosting is dependent on how you physically connect the switches to the device. Care needs to be taken to make sure that your multiple key combinations don't use the same lines as each other. Again, i would suggest searching for some illustrations/explanations of this on a search engine to better understand what is needed on your end.

    2) This goes back to how you physically wire in the keys to make sure you don't cause any ghosting.

    3) Yes, 3 key combinations are typically where this issue can appear, because the 3rd key can be hidden by the other 2 keys depending on how they are wired up.

    Red Comment 1: Thank you for the link, I've sent an email to them suggesting they update their code.

    Red comment 2: You are correct. This is the normal behavoir of the INT pin. When you have an interrupt enabled for a certain type of interrupt (CAD, Key event, GPI, overflow, etc), if the corresponding interrupt flag in the 0x02 register is set, the INT pin will be pulled low by the device and will not be released until that interrupt bit (and any other interrupt bits which can trigger the INT pin) are cleared by writing a 1 to them.

    Most interrupts on a MCU/processor are transition triggered, meaning that they will only trigger the interrupt when the INT pin switches from high to low. Since the INT pin will remain low while the MCU/processor retrieves information from the device, this should not cause any issues for the processor. You should make sure that you interrupt input on the processor is set to only trigger on the high to low transition.

    Red Comment 3: When I say a release that happens 5 seconds later will trigger another interrupt, I make the assumption that when the key PRESS interrupt is triggered, you will service that interrupt and clear the flags (causing the INT pin to go high) within 5 seconds. When you release the key, this will trigger another key event interrupt (added to the FIFO and the KE_INT bit will be set) causing INT to go low again.

    It is important to realize that each key press and release are different and are treated the same as 2 different buttons being pressed. You will be notified when the button is pressed down with it being placed in the FIFO, and then you will be alerted again when the button is released (placed in FIFO).

    The TCA8418E does not have any internal way of measuring how long a key is pressed, it simply reports to you when a key is pressed and released. Since 5 seconds for a computer/MCU is a VERY long time, the general process would go like this:

    1) User presses Key A (just giving it an arbitrary name)

    2) TCA device sees that Key A is being pressed low and will then add an event to the FIFO that KEY A is pressed and set the INT flag, pulling INT pin low.

    3) MCU see's the TCA interrupt request and communicates with the TCA device, reading the interrupt register and the FIFO, seeing that KEY A is being pressed.

    4) MCU knows that Key A is being pressed and has not been released yet because no key A release event was stored. MCU starts a timer to keep track of button press time. MCU clears INT register and INT pin goes high.

    5) Steps 1-4 happen within microseconds to very low milliseconds depending on speed. Key A is held for another 5 seconds, but since the TCA has already signaled that Key A has been rpessed, it does not add it to the FIFO until after a key release has happened.

    6) 5 seconds later, Key A gets released by the user. TCA device sees this and adds a Key A Release event to the FIFO, setting the INT bit and pulling INT pin low.

    7) MCU sees Int request and communicates, seeing that the Key A button has been released. MCU loooks at timer and determines entire time of key press to release took 5 seconds.

    Additional Feedback

    I have additional feedback concerning how you know if 2 buttons are pressed together. Your assumption that both keys will show up in the FIFO when you get the interrupt is not necessarily correct. While it is possible for both keys to be pressed close enough together that they will both show up in the FIFO, consider that when the first key is pressed, the MCU/processor will probably service the interrupt before the user can press the 2nd key. For both keys to be in the same interrupt, the user would have to press them within milliseconds of each other. You will need to look at the individual key press and release events to determine if keys are pressed together or not. I'll give an example process below. Lets say you want to know when Key A and Key B are pressed at the same time, keep in mind that to a computer, this will not look like the same time.

    1) User presses Key A. TCA device adds Key A Press event to FIFO and INT pin goes low.

    2) MCU responds to int and reads FIFO, seeing that Key A Press happened, and will keep note of this. MCU clears TCA flags and INT pin goes high

    3) User presses Key B (seems like the same time as key A to a human), adds Key B Press to FIFO and INT pin goes low.

    4) MCU responds to int and reads FIFO, seeing that Key B Press happened, also notices that Key A is still being held low and knows Key A and Key B are both being held right now. It can treat this as a 2 key combination and do whatever is needed. MCU will clear TCA flags and INT pin goes high

    5) Some time later, user will release the keys and the same steps as 1-4 will happen, except the event logged in the FIFO will be a Key A/B Release instead of a press.

  • Hi Jonathan,

    It was very nice of you to give such a detailed answer.

    The way you suggest on detecting "two keys pressed together" is the same as mine but you explained it more clearly. Surely it is impossible for a user to press both buttons in milliseconds and for MCU to see two keys presses within one interrupt.

    I assume that detecting "three buttons pressed at the same time" would use the the same flow but just have to avoid ghosting, right?

    I would check on line for more information on ghosting. Is it all about physical connections between the keypad and TCA8418E? My understanding based on your comments is that we shall carefully design the circuit according to our use case to avoid that three keys share the same 2 rows/columns.

    Thank you 

    Best Regards,

    Trevor

  • Hello,

    You are correct. Your 3 button press detection will be very much the same as a 2 button press, but you need to make sure your buttons are not configured in a way that could cause ghosting on those 3 button combinations.

    You are correct in your assumption on ghosting. I am not permitted to give you direct links to other websites, but this is why I had suggested you search any search engine about 'keyboard ghosting'. There are a lot of excellent resources

  • Hi Jonathan,

    All clear now. Thank you very much.

    Best Regards,

    Trevor

  • Hi Jonathan,

    You suggested a way (please refer to the  Additional Feedback in the above answers) to detect multiple keys pressed at the same time, which is applicable to both two and three keys cases. But I notice that the TCA8418E also provides a interrupt CAD_INT to detect the three keys press behavior.

    Below are copied from the datasheet:

    Also, for the YFP package, a CAD_INT pin is included to indicate the detection of CTRL-ALT-DEL (i.e., 1, 11, 21) key press action. (page 1)

    As each word is read, the user knows if it is a key press or key release that occurred. Key presses such as CTRL+ALT+DEL are stored as 3 simultaneous key presses. Key presses and releases generate key event interrupts. (page 17)

    I was wondering whether this CAD_INT Pin is used to detect (1, 11, 21) presses only or any three keys presses?

    If this  CAD_INT interrupt is also an alternative way to detect the three keys pressed at the same time, which method do you think is better (comparing to the one you suggested before)?

    Thanks

    Trevor

  • Hello Trevor,

    The CAD_INT pin is an additional interrupt pin which can be used to signal that 3 buttons (only the 1, 11, and 21 keys). It is intended to be used if the user cares about a specific 3 button combinations over regular key events (such as a CAD), allowing the processor to see the specific 1, 11, and 21 key press as a higher priority and responding to it faster if needed.

    You will still need to read and manage the FIFO the same way you would with a regular key press. So it does not really change how you would handle the interrupt, it just lets you know that you have a specific 3 button combination has happened.

    If you wish to treat all key presses with the same response time/priority, you do not need to use the CAD_INT pin.

  • Trevor,

    I have updated my previous post to reflect a mistake I had.

    the CAD_INT pin is used to ONLY detect 1, 11, and 21 key presses.