Post Reply 
HP 15c CE - New firmware update officially available!
08-03-2024, 06:26 PM (This post was last modified: 08-03-2024 06:38 PM by AnnoyedOne.)
Post: #61
RE: HP 15c CE - New firmware update officially available!
(08-03-2024 05:12 PM)rprosperi Wrote:  The initial 12C Platinum machines (Silver face, only 2 of the rightmost keys have blue-shifted functions) are actually notably faster than all that followed...

Interesting!

At least there are only 3 major versions (original, LE, and CE) of the HP-15C and all are easily distinguished.

Perhaps one day Moravia will make the latest HP-12C (of 1234 versions :-)) firmware allow the saving of the memory contents via USB per the HP-15C CE updated release discussed here.

A1

HP-15C (2234A02xxx), HP-16C (2403A02xxx), HP-15C CE (9CJ323-03xxx), HP-20S (2844A16xxx), HP-12C+ (9CJ251)

Find all posts by this user
Quote this message in a reply
08-04-2024, 02:03 AM
Post: #62
RE: HP 15c CE - New firmware update officially available!
I have a comment and a request:

First Im really happy and impressed that the firmware is released, and that the cable has been made available. I have a cable on its way from Jose.

But I think the guidance for getting it all going has a few steps where those such as myself, who are not IT professionals/experienced IT enthusiasts/system administrators etc, will appreciate some more help. Your customers are mostly all enthusiasts, but for the calculators, but not necessarily for their inner workings.

For example: Ahead of having the cable, I followed my nose using the guidance available, to the Sam-Ba 2.18 software. I think I have it installed on my old Win10 laptop, but a few screen shots and step-by step along the way would have given me confidence, assuming I have indeed done it right, which I don't know yet.
Find all posts by this user
Quote this message in a reply
08-05-2024, 05:58 PM (This post was last modified: 08-05-2024 07:06 PM by AnnoyedOne.)
Post: #63
RE: HP 15c CE - New firmware update officially available!
I received my HP-15C CE programming cable today and have successful updated the firmware to the latest (2024-06-03, 0A0Ah) version. Some notes.

1) I installed SAM-BA v2.18 in a Win7 SP1 (32-bit) VM. When I put the HP-15C CE into bootloader mode via the cable the host automatically installed a USB driver. However the 32-bit VM tried but failed to do so. I had to "update" the VM driver by pointing to the SAM-BA program "drv" folder.

2) I tried to read and save the existing (2023-01-05, 9090h) firmware to a file. However, unfortunately, SAM-BA v2.18 reset (for reasons unknown) the read offset from 0x4000 to 0x0000 so that resulted in an incorrect read. Unfortunately I wrote the new firmware before checking and thus don't have a copy of the original firmware. No big deal. I wanted to save that in case of issues with the updated version.

3) I then used VoyagerSave to create a blank memory image. I then (re)entered the program I keep in the unit and saved that.

All in all (despite the VM driver issue) everything went fine. Thanks to Moravia.

A1

HP-15C (2234A02xxx), HP-16C (2403A02xxx), HP-15C CE (9CJ323-03xxx), HP-20S (2844A16xxx), HP-12C+ (9CJ251)

Find all posts by this user
Quote this message in a reply
08-05-2024, 06:07 PM
Post: #64
RE: HP 15c CE - New firmware update officially available!
(08-05-2024 05:58 PM)AnnoyedOne Wrote:  Unfortunately I wrote the new firmware before checking and thus don't have a copy of the original firmware. No big deal. I wanted to save that in case of issues with the updated version.

I *do* have it if you want it.

RPNerd

Current daily drivers: HP-41CL, HP-15C, HP-16C
Find all posts by this user
Quote this message in a reply
08-05-2024, 06:09 PM
Post: #65
RE: HP 15c CE - New firmware update officially available!
(08-05-2024 06:07 PM)RPNerd Wrote:  I *do* have it if you want it.
Thanks! By all means PM/email it.

HP-15C (2234A02xxx), HP-16C (2403A02xxx), HP-15C CE (9CJ323-03xxx), HP-20S (2844A16xxx), HP-12C+ (9CJ251)

Find all posts by this user
Quote this message in a reply
08-05-2024, 06:14 PM
Post: #66
RE: HP 15c CE - New firmware update officially available!
PM sent Smile

Current daily drivers: HP-41CL, HP-15C, HP-16C
Find all posts by this user
Quote this message in a reply
08-05-2024, 06:17 PM
Post: #67
RE: HP 15c CE - New firmware update officially available!
I have the file! Thanks.

BTW you have PM receive disabled.

HP-15C (2234A02xxx), HP-16C (2403A02xxx), HP-15C CE (9CJ323-03xxx), HP-20S (2844A16xxx), HP-12C+ (9CJ251)

Find all posts by this user
Quote this message in a reply
08-05-2024, 06:22 PM (This post was last modified: 08-05-2024 06:23 PM by RPNerd.)
Post: #68
RE: HP 15c CE - New firmware update officially available!
(08-05-2024 06:17 PM)AnnoyedOne Wrote:  I have the file! Thanks.

No problem Smile

(08-05-2024 06:17 PM)AnnoyedOne Wrote:  BTW you have PM receive disabled.

It should be enabled now. I remember purposefully deactivating that at one point because I was getting a fair amount of junk sent by PM. We'll see if that is no longer the case.

Current daily drivers: HP-41CL, HP-15C, HP-16C
Find all posts by this user
Quote this message in a reply
08-06-2024, 12:15 PM
Post: #69
RE: HP 15c CE - New firmware update officially available!
Okay, I got mine updated (that was a bit of an ordeal), but the debouncing is way too aggressive. It's basically unusable like this. Try quickly typing in 1000, and there's a good chance it will only register 100. Is there a specific byte/word in the firmware binary I can change to adjust the debounce interval? 120 ms is much too high - I suspect it needs to be about half that.
Visit this user's website Find all posts by this user
Quote this message in a reply
08-06-2024, 01:34 PM (This post was last modified: 08-06-2024 01:36 PM by AnnoyedOne.)
Post: #70
RE: HP 15c CE - New firmware update officially available!
(08-06-2024 12:15 PM)Dave Britten Wrote:  120 ms is much too high...
Agreed. The original HP-15C (1982) used 80ms or so. 50ms is about 2x human reaction time and should be plenty for normal keys/switches.

Perhaps Moravia should create such firmware.

A1

HP-15C (2234A02xxx), HP-16C (2403A02xxx), HP-15C CE (9CJ323-03xxx), HP-20S (2844A16xxx), HP-12C+ (9CJ251)

Find all posts by this user
Quote this message in a reply
08-06-2024, 04:24 PM
Post: #71
RE: HP 15c CE - New firmware update officially available!
(08-06-2024 01:34 PM)AnnoyedOne Wrote:  
(08-06-2024 12:15 PM)Dave Britten Wrote:  120 ms is much too high...
Agreed. The original HP-15C (1982) used 80ms or so. 50ms is about 2x human reaction time and should be plenty for normal keys/switches.

Perhaps Moravia should create such firmware.

I've used 80ms, 100ms, 120ms, and 150ms firmware variations on the 15c CE. As I recall, the 80ms firmware still can get double keystrokes so that is not going to work, much less 50ms.

150ms regularly exhibited the same issue Dave saw with intended keystrokes being missed. 120ms is better but I think 100ms is ideal.

Best of all would be if they allow it to be configurable (like on the 49/50 series), but without that, I think 100ms would be a better choice than the 120ms in the new official firmware. I was actually surprised they released it with 120ms firmware, since I had had good experience with the 100ms firmware that TheCalculatorStore was putting on their units.
Visit this user's website Find all posts by this user
Quote this message in a reply
08-06-2024, 04:53 PM
Post: #72
RE: HP 15c CE - New firmware update officially available!
(08-06-2024 04:24 PM)Eric Rechlin Wrote:  ...
... but I think 100ms is ideal.
...

I would be more careful about stating what is ideal. E.g. on my 15C CE the keys were bouncing even at 100ms. ... Keys with longer debouncing can still be used, I'm just not allowed to race the keyboard to see which of the two of us is faster. On the other hand, bouncing keys make the device unusable. :-)

Prime G2, 15C CE
Find all posts by this user
Quote this message in a reply
08-06-2024, 08:21 PM (This post was last modified: 08-06-2024 09:22 PM by Johnh.)
Post: #73
RE: HP 15c CE - New firmware update officially available!
rI havnt updated yet, but I'd have thought 120ms would be fine, it amounts to more than 8 inputs per second. Even just between a couple of the same digits, I can't put them in faster than about 5 per second and wouldn't expect to be reliably able to do so.

In terms of missing digits, I find that a more common cause is from buttons lightly pressed, particularly if part of the finger or thumb tip or nail contacts the case or other keys It's possible to get the initial 'breakaway' feel of depressing the key, but not quite achieve the 'click' to enter the digit. The most common way this seems to occur is when hand-holding the calculator rather than placing it on a desk, and keying in with thumbs. It's a classic way to operate a Voyager and different to other calculators which are in a vertical format.
Find all posts by this user
Quote this message in a reply
08-07-2024, 01:15 AM
Post: #74
RE: HP 15c CE - New firmware update officially available!
Something I just noticed: the 15C CE debouncing logic seems to be imposing a minimum amount of time between successive key presses. But if you press and hold a key briefly (a second or two), then very quickly release it and press it again, it will still register the second keystroke even if you release and press again much quicker than 120 ms. It seems to me that the debouncing logic should be changed to impose a minimum elapsed time between the previous key *release* and the next press, which would possibly allow decreasing this debouncing delay, and improve reliability of detecting quick - but intended - repeated keystrokes. It's the unintended break-make cycles that need to be filtered out.
Visit this user's website Find all posts by this user
Quote this message in a reply
08-07-2024, 01:28 AM
Post: #75
RE: HP 15c CE - New firmware update officially available!
(08-06-2024 08:21 PM)Johnh Wrote:  rI havnt updated yet, but I'd have thought 120ms would be fine, it amounts to more than 8 inputs per second. Even just between a couple of the same digits, I can't put them in faster than about 5 per second and wouldn't expect to be reliably able to do so.

It's not a desire to press the same key 8 times in a second (8 times averaging under 143ms apart), but rather to press the same key twice at that speed (2 times under 143ms apart).

(08-07-2024 01:15 AM)Dave Britten Wrote:  Something I just noticed: the 15C CE debouncing logic seems to be imposing a minimum amount of time between successive key presses. But if you press and hold a key briefly (a second or two), then very quickly release it and press it again, it will still register the second keystroke even if you release and press again much quicker than 120 ms. It seems to me that the debouncing logic should be changed to impose a minimum elapsed time between the previous key *release* and the next press, which would possibly allow decreasing this debouncing delay, and improve reliability of detecting quick - but intended - repeated keystrokes. It's the unintended break-make cycles that need to be filtered out.

That's a brilliant discovery. If true, it probably explains why there is so much variation between different users' experiences, and if fixed as you suggest, I suspect we'd have a much more reliable keyboard for more users.
Visit this user's website Find all posts by this user
Quote this message in a reply
08-07-2024, 02:58 AM (This post was last modified: 08-07-2024 03:09 AM by brouhaha.)
Post: #76
RE: HP 15c CE - New firmware update officially available!
I have not disassembled the ARM code in the 15C CE, but I suspect that it may be only debouncing the keyboard when the Nut processor simulation code executes a keyboard-related instruction. (But perhaps not.)

In embedded systems I develop, I normally do all of my key scanning and debounce on a timer interrupt, though when the keyboard is in a quiescent state, I stop the timer, and put things into a lower-power state. There are a few refinements to the most rudimentary key scanning code that improve reliability.

Code:

1. Initialization
    a. set all GPIO return lines as inputs iwth internal (weak) pullup

2. In quiescent state  (no keys down)
    a.  drive all  GPIO scan lines actively low
    b.  enable interrupt-on-low or interrupt-on-change for all GPIO retrn lines

2. When the GPIO interrupt occurs:
    a. disable GPIO return line interrupts
    b. set all GPIO scan lines actively high, briefly (perhaps a microsecond)
    c. set all GPIO scan lines as inputs with internal (weak) pullups
    d. set up periodic timer
    e. enable timer interrupt

3. On timer interrupt
    a. init a scan line counter to the first scan line
    b. loop
        i. drive the scan line selected by the scan line counter low (setting it as an output)
        ii. wait a short time (a fraction of a microsecond) (deals with RC time constant of parasitic capacitance and weak pullup on the return lines)
        iii. read the return lines and save the bits into an array, indexed by the scan line counter
        iv. drive the scan line selected by the counter high, briefly (perhaps a microsecond)
        v. set the scan line selected by the scan line counter back to an input with internal (weak) pullup
        vi. increment the scan line counter, and loop if greater than number of scan lines
    c. loop over keys
        i. run debounce algorithm for one key
    d. if the array of return line data has no keys pressed, AND no key in the debounce array is in the "press pending" or release-pending state, go back to the quiescent state

The actual debounce algorithm that I use, based on an array of pre-key state, has for each key two variables:
    1. current debounced state, 0 = released, 1 = pressed
    2. debounce conter, 0 = no change, 1..n = change pending

The per-key debounce algorithm is:
    1. if the key scan state == the current debounce state, reset debounce counter to 0, and return (no change)
    2. [key scan state != current debounce state] increment debounce counter
    3. if new debounce counter value < threshold, return (no change)
    4. Set the debounced state to the key scan state, set the counter back to zero, and return that the key has been pressed or released

There is a way, even on 8-bit micros, to somewhat parallelize the debounce algorithm across multiple keys, by using "vertical counters", which may have been invented by, but certainly were popularized by Scott Dattalo: https://web.archive.org/web/201408290353...ounce.html

A typical timer frequency might be between 50 and 100 Hz. The power consumption will typically be higher for higher timer frequencies, but I wouldn't recommend going much below 50 Hz.

Note that the press threshold and release threshold can be different. The thresolds are set to ceil(debounce_time / timer_interval), or slightly higher. The debounce time should be a little higher than the maximum bounce time specified for the actual switch. For isntance Cherry MX keys, commonly used for high-end computer keyboards, have a specified maximum bounce time of 5ms, assuming 16 inch per second actuation speed. (Third-party MX-compatible keys might not be as good.) Ad-hoc dome-and-contact buttons can have much longer maximum bounce times.

If the keys each have diodes, or the keys are of some other type that doesn't provide bidirectional conductivity, this can provide n-key rollover. Otherwise, it's OK for 2KRO.

I apologize in advance if there are any errors in my algorithm descriptions, as this is just off the top of my head.

The general outline of this algorithm derives from a 1977 Mostek application note by Dan Hammond for the F8 microprocessor and MK3870 microcontroller, "Using Mostek's F8 in a Scanned Keyboard Application". The application note can be found starting at page 290 (PDF page 393) of the Mostek Microcomputer 3870/F8 Data Book, 1978 edition. My main changes are the active deassertion of scan lines, and the quiescent state for more power savings.

I have no idea what the maximum bounce time of the HP 15C CE keys is, and am not going to measure it. Perhaps HP has. But from personal experience, simply increasing the debounce time without having a good debounce algorithm does not produce great results.
Find all posts by this user
Quote this message in a reply
08-07-2024, 09:16 AM
Post: #77
RE: HP 15c CE - New firmware update officially available!
I agree it seems like the debounce algorithm used on the HP 15C CE is at fault, and I have noticed double keypress issues on all ARM-based 15C and 12C calculators I've played with.

To debounce a key properly, there really needs to be a debounce counter similar to what brouhaha describes, and importantly debouncing needs to happen for both the key press and the key release:

Quote:
Code:

The per-key debounce algorithm is:
    1. if the key scan state == the current debounce state, reset debounce counter to 0, and return (no change)
    2. [key scan state != current debounce state] increment debounce counter
    3. if new debounce counter value < threshold, return (no change)
    4. Set the debounced state to the key scan state, set the counter back to zero, and return that the key has been pressed or released

The purpose of the counter is to act as sort of an "integrator" to filter any possible noise. This page describes the implementation of the debounce counter and why it's needed, along with a hybrid "quick-draw"/integrator approach to let the key press be registered immediately instead of waiting for the debounce count (as described by brouhaha).

Now, in comparison, a lot of simplistic debounce algorithms just wait a fixed amount of time (e.g. 100ms or 120ms) without any debounce counter (which needs to run at a higher speed, e.g. every 10ms as in brouhaha's 100Hz example) and without debouncing both the key press and release. The issue is this 100 or 120ms "debounce time" is much longer than necessary (which can lead to missed key strokes), and also doesn't actually fix the bouncing problem completely when key bounce on key release is ignored. We usually think about key bounce more on key press, but actually keys tend to physically bounce on both key press and key release.

The code for a very simple 4-function calculator that ran on the original AT91SAM ARM-based HP 12C (and the HP 15C LE) has been previously posted with a "dev kit" for the original AT91SAM ARM-based HP 12C, and the overall debounce algorithm seems to match what Dave Britten wrote, although the code details have probably changed quite a bit for the new ATSAM4LC2C ARM-based HP 12C and HP 15C CE (and also I think there were power consumption issues while keys were held down on the original AT91SAM calculators' firmware).

I was a little disappointed when I first read through the keyboard handling code to try to figure out why the original AT91SAM calculators had key bounce issues (although I didn't post any angry rants at the time...I think it's great that they released the 15C LE and CE, and that they released any code at all).

I've posted snippets of the code below (should still be publicly available, need to search for a link to where), with some non-relevant stuff edited out with (...), and the code highlighted as php code even though it is actually C/C++ code (because I think highlighting php is all that the forum supports).

The basic gist of it is initially the calculator is sleeping. When a key is pressed, a keyboard interrupt is triggered, and ScanKeyboard() gets called. The keyboard interrupt also starts a timer 0 interrupt every ~60ms (confusingly the interrupt service routine is named TimerInterupt2 instead of 0) which continues calling ScanKeyboard() every ~60ms while keys are pressed. Note that nothin so far is directly related to key debouncing, including the 60ms polling interval.

In the ScanKeyboard() function, the code tracks the current (previous) keys pressed in KeyboardMap and sees if any new keys are pressed. If a new key is pressed, and it's not equal to LastKeyPress, the ScanKeyboard() function registers the keypress (immediately) and also starts a one-shot timer 1 interrupt to fire after ~50ms and call the ResetLastKeyPress() function/interrupt handler. This is the full extent of the debouncing: the ResetLastKeyPress() function just clears LastKeyPress to -1, so that if a new key press is detected by ScanKeyboard() and it's same key as before it will again be registered.

Now here's an example where things go wrong. For the example I will use the following numbers:
  • 100ms as the debounce time (which is different from the 50ms in the code snippet)
  • 60ms as the polling time (which is the value from the code snippet, and probably not frequent enough, although that's not the main issue for the algorithm being considered here)
  • ~30ms as the actual physical key bounce time (which is a reasonable estimate and assumed to be symmetric for both key press and key release)

The sequence of events considered is the key is pressed and held down for 175ms and then released. This should only register 1 keypress, but actually registers 2:
  • t=0 key is pressed
  • KeyboardInterrupt() is called, which calls ScanKeyboard() and also disables keyboard interrupts and sets up a timer to continue calling ScanKeyboard() every 60ms while keys are pressed
  • ScanKeyboard() immediately registers the new keypress, and starts a one-shot timer to call ResetLastKeyPress() after 100ms (the value is ~50ms in the code snippet)
  • ScanKeyboard() also updates System.KeyboardMap, which is used to determine which keys that are pressed are new key presses on subsequent calls to ScanKeyboard()
  • ScanKeyboard() also updates System.LastKeyPress, which is used for debounce purposes
  • from t=0 to ~30ms we assume the key bounces...this doesn't matter though because the ScanKeyboard() function is only called to poll the keyboard every 60ms in the timer. Even if the timer were triggered more frequently than 60ms, System.LastKeyPress is currently set to the current bouncing key and a bounce will be detected (and ignored)
  • at t=~30ms we assume the key is physically completely in the "pressed" state and no longer bouncing
  • at t=~60ms, the polling timer fires (calls TimerInterupt2() in the code) to poll the keyboard by calling ScanKeyboard(), where no new key is detected
  • at t=~100ms, the other timer fires, which calls ResetLastKeyPress(), which clears System.LastKeyPress. It also disables this timer, making it a one-shot timer. (In the actual code, this is a 50ms timer, not a 100ms timer.)
  • at t=~120ms, the polling timer fires again to poll the keyboard by calling ScanKeyboard(), where no new key is detected
  • at t=175ms, we assume the user releases the key and it begins bouncing for ~30ms (from 175ms to ~205ms)
  • at t=~180ms, the polling timer fires again to poll the keyboard by calling ScanKeyboard(), and notices that no key is pressed (we assume that although the key is bouncing between pressed/not pressed, it happens to be not pressed here), so the interrupt service routine disables both timers (although in this example the one-shot timer is already disabled), and also re-enables keyboard interrupts. The call to ScanKeyboard() also updates System.KeyboardMap which tracks which keys are pressed.
  • at some time between ~180ms and ~205ms, since the key continues bouncing for ~30ms from key release (at 175ms), the key gets erroneously detected as a 2nd key press (which is then debounced properly for the remainder of the ~30ms period)

This main problem is the code doesn't seem to consider the possibility of the keys bouncing on key release, but this is a very common problem, and firmware needs to deal with it. There is also annoyingly a lot of luck involved to trigger the issue, since the press duration needs to be slightly less than some multiple of the polling timer duration. Most of the time, the issue doesn't happen, but annoyingly sometimes it does.

Increasing the debounce time to beyond how long most people take to quickly press and release a button plus the bounce time (instead of setting the debounce time to slightly more than the bounce time) does "solve" the issue at the expense of potentially missing fast consecutive actual button presses from the user.

Also as noted in the example above, when holding the button for longer than the debounce time (and then releasing), it is theoretically possible to trigger an unwanted double press. But since users don't typically repeatedly hold buttons for periods longer than 120ms, and the problem doesn't actually trigger that often, users are unlikely to see these double presses.

Keyboard interrupt
PHP Code:
static void KeyboardInterupt()
{
  
Printk("<Keyboard Interupt>");
  
// acknoledge interrupt if needed (even if not!)
  
unsigned int dummyAT91C_BASE_PIOC->PIO_ISRdummydummy;

  
// handle keyboard interupt
  
if (!ScanKeyboard()) // scan keyboard and add keys in buffer..
  
// if keys down...
    
DisableKeyboardInterupt(); // disable keyboard interrupt as
    
EnableTimerInterupt(060TimerInterupt2);
  } else
    
EnableKeyboardInterupt();  // if no keys down, then re-enable the keyboard interrupts...
}

...

/*! \fn static void EnableTimerInterupt(int timer, int time, void(*function)())
 *  @ingroup timerdrv
 *\brief  enable timer causing an interupt every time ms, calling the TimerInterupt function
    \param time specifies the time duration in milli seconds (actually, in 1024th of second, but who is counting), for which the timer has to be enabled.
 **/
void EnableTimerInterupt(int timerint timevoid(*function)())
... 

ScanKeyboard()
PHP Code:
/*! \fn ScanKeyboard
 *\brief  scans the keyboard
 * -#  update the key map
 * -#  update LastKeyPress if a new key was pressed
 * -#  debounce stuff
 * -#  and place stuff in the key buffer if it's a new key press..
 * -#  a key consumer program should call GetKey() to read a key from the buffer
 * -#  return true if no key is pressed..
 **/
static int ScanKeyboard()
{
  
unsigned long long NewKeyMap= ~0LL;

  
// read the 4 lines of the keyboard and create a 64 bit structure
  // 10 bit per line to hold the keyup/down information
  // 1 bit per key...
  
AT91C_BASE_PIOC->PIO_ODRAllKeyboardRows// set as inputs
  
unsigned int t;
  for (
int line=3line>=0line--)
  {
    ...(
NewKeyMap gets populated with pressed buttons)
  }
  
AT91C_BASE_PIOC->PIO_OER=  AllKeyboardRows// all outputs...
  // invert the result as we are working with inverted logic
  
NewKeyMap= ~NewKeyMap;
//  printkeymask(NewKeyMap);
  
if ((AT91C_BASE_PIOC->PIO_PDSR&(1<<10))==0NewKeyMap|= OnKeyInKeyMap// ON Key

  // new key press is the list of the keys that are pressed now, but were not
  // pressed last time...
  
unsigned long long NewKeyPressNewKeyMap & ~System.KeyboardMap;

  
// key released are the keys that are not pressed now, but were presssed last time!
  // in this case, we are not using that information because the software
  // does not do anything on key release... so it's just commented out
  // unsigned long long KeyReleased= KeyboardMap & ~NewKeyMap;

  // save the current key map as the key map
  
System.KeyboardMapNewKeyMap;

  ...

  
// is there a new key down?
  
if (NewKeyPress==0LL)
    return 
System.KeyboardMap==0LL// no, just return true if no key is down at all...
  
  // isolate the first new key down..
  
for (int r=0r<40r+=10)
    for (
int c=0c<10c++)
    {
      if (
NewKeyPress&1!=0// is that key down?
      
{
        if (
NewKeyPress>>1==0// if this is not the only new key down, chances are this is a ghost effect
                               // or the user is mighty good at pressing 2 keys exactly at the same time (give or take
                               // timer delay...) in all cases, if this is a double press, then we can not know which key was pressed first
                               // and should ignore it, and if it's a ghost, we can not know which key is actually pressed and
                               // should also ignore the key press...
        
// ok, so, this is a valid key press... but is it a bounce?
          
int keyr+c;
          if (
System.LastKeyPress!=key// is it a bounce? if yes, ignore key...
          
{
            
System.LastKeyPresskey// not a bounce, save the key for alter bounce detection!
            
AddKeyInBuffer(key);      // send key to the system
            
Printk("<Setup Timer 1 interupt>");
            
EnableTimerInterupt(150ResetLastKeyPress); // program timer for end of bounce time detection
          
}
        }
        return 
0;  // return, and there is at least one key down...
      
}
      
NewKeyPress>>=1// next key.. this is of course inefficient, but hey... good enough for now... and on an arm it's not too bad anyway...
    
}
  return 
0// put here to prevent a warning, but can not happen...


One-shot timer 1 interrupt (single-shot timer which clears LastKeyPress, disabling debounce detection)
PHP Code:
// called after x ms (max bounce time) to disable bounce checking on the last key pressed
static void ResetLastKeyPress()
{
  
Printk("<Timer 1 interupt>");
  
AcknoledgeTimerInterupt(1);
  
System.LastKeyPress= -1;
  
StopTimer(1);


Polling timer 0 interrupt (confusingly named TimerInterupt2() instead of 0, this interrupt continues polling while keys are pressed)
PHP Code:
static void TimerInterupt2()
{
  
Printk("<Timer 0 interupt>");
  
AcknoledgeTimerInterupt(0);

  if (
ScanKeyboard())
  {
    
Printk("<Stop Timer 1 interupt>");
    
StopTimer(0);
    
StopTimer(1);
    
EnableKeyboardInterupt();
  } else
    
EnableTimerInterupt(060TimerInterupt2);

Find all posts by this user
Quote this message in a reply
08-07-2024, 09:21 AM (This post was last modified: 08-07-2024 09:23 AM by borjam.)
Post: #78
RE: HP 15c CE - New firmware update officially available!
(08-07-2024 01:28 AM)Eric Rechlin Wrote:  That's a brilliant discovery. If true, it probably explains why there is so much variation between different users' experiences, and if fixed as you suggest, I suspect we'd have a much more reliable keyboard for more users.

Maybe you can implement a user handshake of sorts. Instead of executing the code associated with a keypress upon detection, hold until the calculator is ready to detect the next keypress. So, if the user presses a number don't update the display until the calculator is ready for the next key press. Or if you run something like a trascendental function, run it but don't update the display until ready.

Actually in the original Voyagers it works in a similar way. The calculator is much slower, so any keypress takes time.

For example I own an original HP-16C with a perfectly reliable keyboard. If I press a number, say, 5 times in the quickest way I can, it will register 4. And that's a timing issue.

The high speed of the calculator is great if you write an expensive program or use an expensive function.

I can't believe that the reliability difference between the old Voyagers and the recent examples (LE(*) or the latest CEs) is only due to the keyboard construction. It must be a timing issue.

(*) The LE is an off topic in this thread discussing Moravia made CEs, but I own an LE and the keyboard is unusable. Bounces, keys that don't register... A pretty prop. Meanwhile an old HP-10C that was in storage for 30 years works perfectly.
Find all posts by this user
Quote this message in a reply
08-07-2024, 03:43 PM
Post: #79
RE: HP 15c CE - New firmware update officially available!
I've read the above (technical) posts and all make a lot of sense to me. I've written keyboard/switch handling code multiple times before (in assembler and 'C') and have used some of the techniques described. What the HP-15C CE uses I have no idea.

I'm reminded of the old TI-30 calculator I had many decades ago. It worked great for a year or so then the keys would "bounce" constantly. I'd press '1' and end up with a display full of them! Totally unusable.

That was a hardware (cheap keyboard) issue mainly. Perhaps poor/non-existent denouncing as well.

I've never had any key bounce issues with my original HP-15C or HP-16C. They're old'n'slow though--just like me :-) Some newer/faster ones might behave differently.

A1

HP-15C (2234A02xxx), HP-16C (2403A02xxx), HP-15C CE (9CJ323-03xxx), HP-20S (2844A16xxx), HP-12C+ (9CJ251)

Find all posts by this user
Quote this message in a reply
08-08-2024, 04:07 AM
Post: #80
RE: HP 15c CE - New firmware update officially available!
I might try writing some keyboard debounce test code to run on the current 12C/15C CE hardware, to evaluate the algorithms jklasdf and I have described, but I won't have time to do that until AFTER next month's HHC conference.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 3 Guest(s)