Patchwork [1/4] hw/ds1338.c: Fix handling of HOURS register.

login
register
mail settings
Submitter Antoine Mathys
Date Dec. 2, 2012, 5:14 p.m.
Message ID <50BB8C7A.7010304@gmail.com>
Download mbox | patch
Permalink /patch/203231/
State New
Headers show

Comments

Antoine Mathys - Dec. 2, 2012, 5:14 p.m.
Per the datasheet, the mapping between 12 and 24 hours modes is:
     0      <->  12   PM
     1-12   <->  1-12 AM
     13-23  <->  1-11 PM

Signed-off-by: Antoine Mathys <barsamin@gmail.com>
---
  hw/ds1338.c |   23 +++++++++++++++--------
  1 file changed, 15 insertions(+), 8 deletions(-)
Peter Maydell - Dec. 4, 2012, 5:42 p.m.
On 2 December 2012 17:14, Antoine Mathys <barsamin@gmail.com> wrote:
> Per the datasheet, the mapping between 12 and 24 hours modes is:
>     0      <->  12   PM
>     1-12   <->  1-12 AM
>     13-23  <->  1-11 PM
>
> Signed-off-by: Antoine Mathys <barsamin@gmail.com>

This looks good as far as the logic goes, but I think we
could use some symbolic constants for the 12-hour and PM
bits rather than all the literal 0x20 0x40 0x60.

thanks
-- PMM
Andreas Färber - Dec. 4, 2012, 6:53 p.m.
Am 04.12.2012 18:42, schrieb Peter Maydell:
> On 2 December 2012 17:14, Antoine Mathys <barsamin@gmail.com> wrote:
>> Per the datasheet, the mapping between 12 and 24 hours modes is:
>>     0      <->  12   PM
>>     1-12   <->  1-12 AM
>>     13-23  <->  1-11 PM
>>
>> Signed-off-by: Antoine Mathys <barsamin@gmail.com>
> 
> This looks good as far as the logic goes, but I think we
> could use some symbolic constants for the 12-hour and PM
> bits rather than all the literal 0x20 0x40 0x60.

What about adding qtests like we have for the x86 RTC?
Is I2C as problematic as PCI there?

Andreas

P.S. Antoine, please make sure you thread your patches to a cover letter
so that they stay together on the list.
Antoine Mathys - Dec. 4, 2012, 8:57 p.m.
On 12/04/2012 06:42 PM, Peter Maydell wrote:
> This looks good as far as the logic goes, but I think we could use 
> some symbolic constants for the 12-hour and PM bits rather than all 
> the literal 0x20 0x40 0x60. thanks -- PMM 
I refrained from using symbolic constants for three reasons:
1. You need to refer to the datasheet anyway to understand what is going on.
2. The code is short and it is easy to keep track of a few constants.
3. Symbolic names, which can be quite long, tend to make the code harder 
rather than easier to read

It is largely a matter of preference though and I'm not opposed to the 
idea. I would appreciate naming suggestions though.

I propose not to have symbolic constants for the registers and to use 
CH, OSF, MODE12, PM for the various bits, provided such short names are 
acceptable. I'd really hate something like REG_HOURS_MODE12.
Peter Maydell - Dec. 4, 2012, 9:10 p.m.
On 4 December 2012 20:57, Antoine Mathys <barsamin@gmail.com> wrote:
> On 12/04/2012 06:42 PM, Peter Maydell wrote:
>> This looks good as far as the logic goes, but I think we could use some
>> symbolic constants for the 12-hour and PM bits rather than all the literal
>> 0x20 0x40 0x60. thanks -- PMM
>
> I refrained from using symbolic constants for three reasons:
> 1. You need to refer to the datasheet anyway to understand what is going on.
> 2. The code is short and it is easy to keep track of a few constants.
> 3. Symbolic names, which can be quite long, tend to make the code harder
> rather than easier to read

...I had the datasheet open and I still had to bounce back and forth
several times to work out which bits you were working with, so I
think we definitely disagree on this point...

> It is largely a matter of preference though and I'm not opposed to the idea.
> I would appreciate naming suggestions though.
>
> I propose not to have symbolic constants for the registers and to use CH,
> OSF, MODE12, PM for the various bits, provided such short names are
> acceptable. I'd really hate something like REG_HOURS_MODE12.

Your suggestions are definitely way too short; I'd go for something
in the middle like CTRL_OSF and HOURS_12HR, HOURS_PM.

-- PMM

Patch

diff --git a/hw/ds1338.c b/hw/ds1338.c
index b576d56..1274b22 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -50,9 +50,14 @@  static void capture_current_time(DS1338State *s)
      s->nvram[0] = to_bcd(now.tm_sec);
      s->nvram[1] = to_bcd(now.tm_min);
      if (s->nvram[2] & 0x40) {
-        s->nvram[2] = (to_bcd((now.tm_hour % 12)) + 1) | 0x40;
-        if (now.tm_hour >= 12) {
-            s->nvram[2] |= 0x20;
+        int tmp = now.tm_hour;
+        if (tmp == 0) {
+            tmp = 24;
+        }
+        if (tmp <= 12) {
+            s->nvram[2] = 0x40 | to_bcd(tmp);
+        } else {
+            s->nvram[2] = 0x60 | to_bcd(tmp - 12);
          }
      } else {
          s->nvram[2] = to_bcd(now.tm_hour);
@@ -127,15 +132,17 @@  static int ds1338_send(I2CSlave *i2c, uint8_t data)
              break;
          case 2:
              if (data & 0x40) {
+                int tmp = from_bcd(data & 0x1f);
                  if (data & 0x20) {
-                    data = from_bcd(data & 0x4f) + 11;
-                } else {
-                    data = from_bcd(data & 0x1f) - 1;
+                    tmp += 12;
+                }
+                if (tmp == 24) {
+                    tmp = 0;
                  }
+                now.tm_hour = tmp;
              } else {
-                data = from_bcd(data);
+                now.tm_hour = from_bcd(data & 0x3f);
              }
-            now.tm_hour = data;
              break;
          case 3:
              now.tm_wday = from_bcd(data & 7) - 1;