saramonteiro commented on a change in pull request #3794: URL: https://github.com/apache/incubator-nuttx/pull/3794#discussion_r644078106
########## File path: arch/risc-v/src/esp32c3/esp32c3_rtc_lowerhalf.c ########## @@ -0,0 +1,575 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c3/esp32c3_rtc_lowerhalf.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <nuttx/spinlock.h> + +#include <sys/types.h> +#include <stdbool.h> +#include <string.h> +#include <errno.h> + +#include <nuttx/arch.h> +#include <nuttx/timers/rtc.h> + +#include "esp32c3_rtc.h" +#include "hardware/esp32c3_tim.h" + +#ifdef CONFIG_RTC_DRIVER + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +struct esp32c3_cbinfo_s +{ + volatile rtc_alarm_callback_t cb; /* Callback when the alarm expires */ + volatile FAR void *priv; /* Private argurment to accompany callback */ +}; +#endif + +/* This is the private type for the RTC state. It must be cast compatible + * with struct rtc_lowerhalf_s. + */ + +struct esp32c3_lowerhalf_s +{ + /* This is the contained reference to the read-only, lower-half + * operations vtable (which may lie in FLASH or ROM) + */ + + FAR const struct rtc_ops_s *ops; +#ifdef CONFIG_RTC_ALARM + /* Alarm callback information */ + + struct esp32c3_cbinfo_s cbinfo[RTC_ALARM_LAST]; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Prototypes for static methods in struct rtc_ops_s */ + +static int rtc_rdtime(FAR struct rtc_lowerhalf_s *lower, + FAR struct rtc_time *rtctime); +static int rtc_settime(FAR struct rtc_lowerhalf_s *lower, + FAR const struct rtc_time *rtctime); +static bool rtc_havesettime(FAR struct rtc_lowerhalf_s *lower); + +#ifdef CONFIG_RTC_ALARM +static void rtc_alarm_callback(FAR void *arg, unsigned int alarmid); +static int rtc_setalarm(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setalarm_s *alarminfo); +static int rtc_setrelative(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setrelative_s *alarminfo); +static int rtc_cancelalarm(FAR struct rtc_lowerhalf_s *lower, + int alarmid); +static int rtc_rdalarm(FAR struct rtc_lowerhalf_s *lower, + FAR struct lower_rdalarm_s *alarminfo); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* ESP32-C3 RTC driver operations */ + +static const struct rtc_ops_s g_rtc_ops = +{ + .rdtime = rtc_rdtime, + .settime = rtc_settime, + .havesettime = rtc_havesettime, +#ifdef CONFIG_RTC_ALARM + .setalarm = rtc_setalarm, + .setrelative = rtc_setrelative, + .cancelalarm = rtc_cancelalarm, + .rdalarm = rtc_rdalarm, +#endif +#ifdef CONFIG_RTC_PERIODIC + .setperiodic = NULL, + .cancelperiodic = NULL, +#endif +#ifdef CONFIG_RTC_IOCTL + .ioctl = NULL, +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + .destroy = NULL, +#endif +}; + +/* ESP32-C3 RTC device state */ + +static struct esp32c3_lowerhalf_s g_rtc_lowerhalf = +{ + .ops = &g_rtc_ops, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rtc_alarm_callback + * + * Description: + * This is the function that is called from the RTC driver when the alarm + * goes off. It just invokes the upper half drivers callback. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static void rtc_alarm_callback(FAR void *arg, unsigned int alarmid) +{ + FAR struct esp32c3_lowerhalf_s *lower; + FAR struct esp32c3_cbinfo_s *cbinfo; + rtc_alarm_callback_t cb; + FAR void *priv; + + DEBUGASSERT((RTC_ALARM0 <= alarmid) && (alarmid < RTC_ALARM_LAST)); + + lower = (struct esp32c3_lowerhalf_s *)arg; + cbinfo = &lower->cbinfo[alarmid]; + + /* Sample and clear the callback information to minimize the window in + * time in which race conditions can occur. + */ + + cb = (rtc_alarm_callback_t)cbinfo->cb; + priv = (FAR void *)cbinfo->priv; + + cbinfo->cb = NULL; + cbinfo->priv = NULL; + + /* Perform the callback */ + + if (cb != NULL) + { + cb(priv, alarmid); + } +} +#endif /* CONFIG_RTC_ALARM */ + +/**************************************************************************** + * Name: rtc_rdtime + * + * Description: + * Implements the rdtime() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * rcttime - The location in which to return the current RTC time. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +static int rtc_rdtime(FAR struct rtc_lowerhalf_s *lower, + FAR struct rtc_time *rtctime) +{ +#if defined(CONFIG_RTC_DATETIME) + /* This operation depends on the fact that struct rtc_time is cast + * compatible with struct tm. + */ + + return up_rtc_getdatetime((FAR struct tm *)rtctime); + +#elif defined(CONFIG_RTC_HIRES) + FAR struct timespec ts; + int ret; + + /* Get the higher resolution time */ + + ret = up_rtc_gettime(&ts); + if (ret < 0) + { + goto errout; + } + + /* Convert the one second epoch time to a struct tm. This operation + * depends on the fact that struct rtc_time and struct tm are cast + * compatible. + */ + + if (!gmtime_r(&ts.tv_sec, (FAR struct tm *)rtctime)) + { + ret = -get_errno(); + goto errout; + } + + return OK; + +errout: + DEBUGASSERT(ret < 0); + return ret; + +#else + time_t timer; + + /* The resolution of time is only 1 second */ + + timer = up_rtc_time(); + + /* Convert the one second epoch time to a struct tm */ + + if (gmtime_r(&timer, (FAR struct tm *)rtctime) == 0) + { + int errcode = get_errno(); + DEBUGASSERT(errcode > 0); + + rtcerr("ERROR: gmtime_r failed: %d\n", errcode); + return -errcode; + } + + return OK; +#endif +} + +/**************************************************************************** + * Name: rtc_settime + * + * Description: + * Implements the settime() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * rcttime - The new time to set + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +static int rtc_settime(FAR struct rtc_lowerhalf_s *lower, + FAR const struct rtc_time *rtctime) +{ + struct timespec ts; + + /* Convert the struct rtc_time to a time_t. Here we assume that struct + * rtc_time is cast compatible with struct tm. + */ + + ts.tv_sec = mktime((FAR struct tm *)rtctime); + ts.tv_nsec = 0; + + /* Now set the time (to one second accuracy) */ + + return up_rtc_settime(&ts); +} + +/**************************************************************************** + * Name: rtc_havesettime + * + * Description: + * Implements the havesettime() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * + * Returned Value: + * Returns true if RTC date-time have been previously set. + * + ****************************************************************************/ + +static bool rtc_havesettime(FAR struct rtc_lowerhalf_s *lower) +{ + if (esp32c3_rtc_get_boot_time() == 0) + { + return false; + } + + return true; +} + +/**************************************************************************** + * Name: rtc_setalarm + * + * Description: + * Set a new alarm. This function implements the setalarm() method of the + * RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * alarminfo - Provided information needed to set the alarm + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int rtc_setalarm(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setalarm_s *alarminfo) +{ + FAR struct esp32c3_lowerhalf_s *priv; + FAR struct esp32c3_cbinfo_s *cbinfo; + struct alm_setalarm_s lowerinfo; + int ret = -EINVAL; Review comment: No need to initialize. It will be overwritten in line 364 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected]
