From owner-freebsd-arm@freebsd.org Thu Jul 16 15:36:06 2020 Return-Path: Delivered-To: freebsd-arm@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 55E36365435 for ; Thu, 16 Jul 2020 15:36:06 +0000 (UTC) (envelope-from freebsd-rj@obsigna.com) Received: from mo4-p00-ob.smtp.rzone.de (mo4-p00-ob.smtp.rzone.de [85.215.255.24]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "*.smtp.rzone.de", Issuer "TeleSec ServerPass Class 2 CA" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4B6yyX4kK6z3RxK; Thu, 16 Jul 2020 15:36:04 +0000 (UTC) (envelope-from freebsd-rj@obsigna.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1594913762; s=strato-dkim-0002; d=obsigna.com; h=References:To:Cc:In-Reply-To:Date:Subject:Message-Id:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=KqoJ58LbP4wFWzyCkiF51nbKPwo9GymEo2JpOLpfC9U=; b=ftNsLcYWbvRBM6hgPKftzFBgSO2hW1NO4gKHyhqohhkXzcMmV5Xfxdrw3RMXaI3MWy wb1AVEWsTVM2qZ6lqjPBF7Fa0gc2G54KGTWxcMUw8VKk+i0JmBaJEiHmENeUJ3MJborN kWyVV/sqPqhwOf7KBugx28459yNh1cD62wNm5dU55r/siqULf5GHh1qXeuiKgooGRuap I+gucpBFy3V2gtzcyTc91bTsDkoqyV9ZuUqZB3Rb3o7YTfvusiA6CAhN/RHJKn2gEAyX fcNOl+yZSFcRI11ZxA+B6TQZ9pgxDal8SPnk/OsIpPkfYHXoMm3O4ZOJAtOXo30Wb3xT 9NUw== X-RZG-AUTH: ":O2kGeEG7b/pS1F2rRHW2isrKl4DV03XBEi+I6ZuztdvN9wS3wFGySS4Lw+ldTBio0dVbInGjc9PbZFAm0A==" X-RZG-CLASS-ID: mo00 Received: from mail.obsigna.com by smtp.strato.de (RZmta 46.10.5 DYNA|AUTH) with ESMTPSA id 006e94w6GFa0bKP (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Thu, 16 Jul 2020 17:36:00 +0200 (CEST) Received: from rolf-mini.obsigna.com (rolf-mini.obsigna.com [192.168.222.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.obsigna.com (Postfix) with ESMTPSA id C360F1350F91D; Thu, 16 Jul 2020 12:35:56 -0300 (-03) From: "Dr. Rolf Jansen" Message-Id: Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.14\)) Subject: Re: DS3231 on BeagleBone Black with FreeBSD 13-CURRENT exactly 20 h off backwards Date: Thu, 16 Jul 2020 12:35:55 -0300 In-Reply-To: <99ec5bfbe697e0cbf8b6262783256bffcbf55f55.camel@freebsd.org> Cc: freebsd-arm@freebsd.org To: Ian Lepore References: <3BE2A8B4-AD53-4DFE-8C38-D5BB4063CFE9@obsigna.com> <99ec5bfbe697e0cbf8b6262783256bffcbf55f55.camel@freebsd.org> X-Mailer: Apple Mail (2.3445.104.14) X-Rspamd-Queue-Id: 4B6yyX4kK6z3RxK X-Spamd-Bar: - Authentication-Results: mx1.freebsd.org; dkim=pass header.d=obsigna.com header.s=strato-dkim-0002 header.b=ftNsLcYW; dmarc=none; spf=pass (mx1.freebsd.org: domain of freebsd-rj@obsigna.com designates 85.215.255.24 as permitted sender) smtp.mailfrom=freebsd-rj@obsigna.com X-Spamd-Result: default: False [-1.54 / 15.00]; RCVD_VIA_SMTP_AUTH(0.00)[]; ARC_NA(0.00)[]; R_DKIM_ALLOW(-0.20)[obsigna.com:s=strato-dkim-0002]; NEURAL_HAM_MEDIUM(-1.00)[-1.005]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; MV_CASE(0.50)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; MIME_GOOD(-0.10)[multipart/alternative,text/plain]; R_SPF_ALLOW(-0.20)[+ip4:85.215.255.0/24]; DMARC_NA(0.00)[obsigna.com]; NEURAL_HAM_LONG(-0.95)[-0.955]; RCVD_COUNT_THREE(0.00)[3]; DKIM_TRACE(0.00)[obsigna.com:+]; RCPT_COUNT_TWO(0.00)[2]; RCVD_IN_DNSWL_NONE(0.00)[85.215.255.24:from]; FROM_NAME_HAS_TITLE(1.00)[dr]; NEURAL_HAM_SHORT(-0.58)[-0.583]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+,1:+,2:~]; RWL_MAILSPIKE_VERYGOOD(0.00)[85.215.255.24:from]; ASN(0.00)[asn:6724, ipnet:85.215.255.0/24, country:DE]; RCVD_TLS_ALL(0.00)[]; MID_RHS_MATCH_FROM(0.00)[] Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.33 X-BeenThere: freebsd-arm@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: "Porting FreeBSD to ARM processors." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Jul 2020 15:36:06 -0000 > Am 15.07.2020 um 23:32 schrieb Ian Lepore : >=20 > On Wed, 2020-07-15 at 12:15 -0300, Dr. Rolf Jansen wrote: >>> Am 15.07.2020 um 09:52 schrieb Dr. Rolf Jansen < >>> freebsd-rj@obsigna.com >: >>>=20 >>> I added a DS3231 module to the i2c2 bus of the BBB running 13- >>> CURRENT. Everything work fine, except that when I set a time in >>> the range of 20:00 to 24:00 UTC, then on starting up the RTC >>> reports a date/time of exactly 20 hours off backwards. While, when >>> I set a time in the range from 0:00 to 19:59 UTC, it would be >>> correctly stored by the RTC. >>>=20 >>> Looking at the Maxim DS3231 datasheet ( >>> https://datasheets.maximintegrated.com/en/ds/DS3231.pdf#page=3D11 = < >>> https://datasheets.maximintegrated.com/en/ds/DS3231.pdf#page=3D11 = >), >>> it might be that something gets mixed-up when setting bits 5 and 6 >>> of the hours register. In the history of ds3231.c, I saw that 24 >>> hour mode is not more forced anymore. Perhaps an unresolved >>> ambiguity was introduced by this change. >>>=20 >>> BTW: the following looks strange: >>>=20 >>>=20 > = https://github.com/freebsd/freebsd/blob/b2d136be8c26e5efaf82b7bb25432207a6= 82e250/sys/dev/iicbus/ds3231.c#L526 = >>> < >>> = https://github.com/freebsd/freebsd/blob/b2d136be8c26e5efaf82b7bb25432207a6= 82e250/sys/dev/iicbus/ds3231.c#L526 = >>>>=20 >>>=20 >>> This would add 256 instead of 100 when rolling over the century, >>> really? On real world systems this will let to a Year-2100 problem, >>> better we solve this quickly, since the time is running, and 80 >>> years compares to nothing on the geologic time scale :-D >>=20 >> For the time being I resolved the issue for me, by completely >> dropping AM/PM support - I don=E2=80=99t need it, and I anyway always = need to >> remember that AM means (Am Morgen :-). >>=20 >> DS3231_HOUR_MASK_24HR is definitely wrong, since this prevents the >> setting of times above 20 h. Reading said data sheet, I am almost >> sure, that DS3231_HOUR_MASK_24HR must be the same as >> DS3231_HOUR_MASK_12HR =3D 0x3f. >>=20 >=20 > The driver originally forced the chip into 24-hour mode. I'm the one > who added support for 12 or 24 hour mode, so this is probably my = fault. > It seems nicer to me to try to deal with whatever mode the chip is > already in (in case you're dual-booting into some other OS that wants > it to be a certain way). I'm pretty sure I've got one of those chips > around here somewhere, I'll find some time this weekend to get the > driver fixed. >=20 > -- Ian I appreciate your efforts for AM/PM support, only I am not sufficiently = familiar with the very details of this format, for example I always got = wrong the special meanings of 0:00 AM vs. 0:00 PM and 12:00 AM vs. 12:00 = PM. So, I am the wrong person to bugfix AM/PM issues. I applied the = temporary dirty fix of dropping out AM/PM only for getting the driver = quickly working on my side, and I could continue with my current = project. Once the driver is fixed upstream, I will use that one, of = course. That said, I wrote a sysctl function for directly getting/setting the = time in the RTC with unix time values. Perhaps, something like this = would facilitate your debugging efforts, and here it comes: static int ds3231_unixtime_sysctl(SYSCTL_HANDLER_ARGS) { int c, error; struct timespec ts =3D {}; struct bcd_clocktime bct; struct ds3231_softc *sc =3D (struct ds3231_softc *)arg1; uint8_t data[7]; if (req->newptr =3D=3D NULL) { // get the unixtime /* If the clock halted, we don't have good data. */ if ((error =3D ds3231_status_read(sc)) !=3D 0) { device_printf(sc->sc_dev, "cannot read from = RTC.\n"); return (error); } if (sc->sc_status & DS3231_STATUS_OSF) return (EINVAL); error =3D iicdev_readfrom(sc->sc_dev, DS3231_SECS, data, = sizeof(data), IIC_INTRWAIT); if (error !=3D 0) { device_printf(sc->sc_dev, "cannot read from = RTC.\n"); return (error); } bct.nsec =3D 0; bct.sec =3D data[DS3231_SECS] & DS3231_SECS_MASK; bct.min =3D data[DS3231_MINS] & DS3231_MINS_MASK; bct.hour =3D data[DS3231_HOUR] & DS3231_HOUR_MASK_12HR; bct.day =3D data[DS3231_DATE] & DS3231_DATE_MASK; bct.mon =3D data[DS3231_MONTH] & DS3231_MONTH_MASK; bct.year =3D data[DS3231_YEAR] & DS3231_YEAR_MASK; bct.ispm =3D data[DS3231_HOUR] & DS3231_HOUR_IS_PM; /* * If the century flag has toggled since we last saw it, = there has been * a century rollover. If this is the first time we're = seeing it, * remember the state so we can preserve its polarity on = writes. */ c =3D (data[DS3231_MONTH] & DS3231_C_MASK) ? 1 : 0; if (sc->sc_last_c =3D=3D -1) sc->sc_last_c =3D c; else if (c !=3D sc->sc_last_c) { sc->sc_year0 +=3D 100; sc->sc_last_c =3D c; } bct.year |=3D sc->sc_year0; error =3D clock_bcd_to_ts(&bct, &ts, false); if (error =3D=3D 0) { error =3D sysctl_handle_long(oidp, &ts.tv_sec, = 0, req); } } else if ((error =3D sysctl_handle_long(oidp, &ts.tv_sec, 0, req) = =3D=3D 0)) { // set the unixtime /* * We request a timespec with no resolution-adjustment. = That also * disables utc adjustment, so apply that ourselves. */ ts.tv_sec -=3D utc_offset(); clock_ts_to_bcd(&ts, &bct, false); data[DS3231_SECS] =3D bct.sec; data[DS3231_MINS] =3D bct.min; data[DS3231_HOUR] =3D bct.hour | 0b01000000; data[DS3231_DATE] =3D bct.day; data[DS3231_WEEKDAY] =3D bct.dow + 1; data[DS3231_MONTH] =3D bct.mon; data[DS3231_YEAR] =3D bct.year & 0xff; if (sc->sc_last_c) data[DS3231_MONTH] |=3D DS3231_C_MASK; /* Write the time back to RTC. */ error =3D iicdev_writeto(sc->sc_dev, DS3231_SECS, data, = sizeof(data), IIC_INTRWAIT); if (error !=3D 0) { device_printf(sc->sc_dev, "cannot write to = RTC.\n"); return (error); } /* * Unlike most hardware, the osc-was-stopped bit does = not clear itself * after setting the time, it has to be manually written = to zero. */ if (sc->sc_status & DS3231_STATUS_OSF) { if ((error =3D ds3231_status_read(sc)) !=3D 0) { device_printf(sc->sc_dev, "cannot read = from RTC.\n"); return (error); } sc->sc_status &=3D ~DS3231_STATUS_OSF; if ((error =3D ds3231_status_write(sc, 0, 0)) !=3D= 0) { device_printf(sc->sc_dev, "cannot write = to RTC.\n"); return (error); } } } return (error); } ... /* Date/Time. */ SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "unixtime", CTLFLAG_RW | CTLTYPE_ULONG | CTLFLAG_MPSAFE, sc, 0, ds3231_unixtime_sysctl, "LU", "get/set the Date/Time = formatted as a UNIX time stamp"); /* Temperature. */ ... Then, I wrote a shell script for testing, whether setting/getting the = time works as expected (checkds3231.sh): #!/bin/sh DATE=3D`date "+%Y-%m-%d"` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 00:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 01:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 02:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 03:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 04:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 05:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 06:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 07:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 08:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 09:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 10:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 11:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 12:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 13:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 14:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 15:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 16:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 17:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 18:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 19:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 20:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 21:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 22:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date -jf "%Y-%m-%d %H:%M:%S" "+%s" = $DATE" 23:26:14"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` sysctl dev.ds3231.0.unixtime=3D`date "+%s"` > /dev/null 2>&1 date -jf "%s" "+%Y-%m-%d %H:%M:%S" `sysctl -n dev.ds3231.0.unixtime` The sample output here looks good: 2020-07-16 00:26:14 2020-07-16 01:26:14 2020-07-16 02:26:14 2020-07-16 03:26:14 2020-07-16 04:26:14 2020-07-16 05:26:14 2020-07-16 06:26:14 2020-07-16 07:26:14 2020-07-16 08:26:14 2020-07-16 09:26:14 2020-07-16 10:26:14 2020-07-16 11:26:14 2020-07-16 12:26:14 2020-07-16 13:26:14 2020-07-16 14:26:14 2020-07-16 15:26:14 2020-07-16 16:26:14 2020-07-16 17:26:14 2020-07-16 18:26:14 2020-07-16 19:26:14 2020-07-16 20:26:14 2020-07-16 21:26:14 2020-07-16 22:26:14 2020-07-16 23:26:14 2020-07-16 12:32:12 Best regards Rolf=