mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Revision:
592:a274ee790e56
Parent:
591:474d026f7d79
Child:
593:78ee8643776a
--- a/targets/hal/TARGET_Atmel/TARGET_SAM21/drivers/rtc/rtc_sam_d_r/rtc_calendar.c	Wed Jul 15 08:15:08 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,653 +0,0 @@
-/**
- * \file
- *
- * \brief SAM RTC Driver (Calendar Mode)
- *
- * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- *    Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-/**
-* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
-*/
-#include "rtc_calendar.h"
-#include <gclk.h>
-
-#if !defined(__DOXYGEN__)
-struct rtc_module *_rtc_instance[RTC_INST_NUM];
-#endif
-
-/**
- * \brief Determines if the hardware module(s) are currently synchronizing to the bus.
- *
- * Checks to see if the underlying hardware peripheral module(s) are currently
- * synchronizing across multiple clock domains to the hardware bus, This
- * function can be used to delay further operations on a module until such time
- * that it is ready, to prevent blocking delays for synchronization in the
- * user application.
- *
- * \param[in]  module  RTC hardware module
- *
- * \return Synchronization status of the underlying hardware module(s).
- *
- * \retval true  if the module has completed synchronization
- * \retval false if the module synchronization is ongoing
- */
-static inline bool rtc_calendar_is_syncing(struct rtc_module *const module)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(module->hw);
-
-    Rtc *const rtc_module = module->hw;
-
-    if (rtc_module->MODE2.STATUS.reg & RTC_STATUS_SYNCBUSY) {
-        return true;
-    }
-
-    return false;
-}
-
-/**
- * \brief Enables the RTC module.
- *
- * Enables the RTC module once it has been configured, ready for use. Most
- * module configuration parameters cannot be altered while the module is enabled.
- *
- * \param[in,out] module  Pointer to the software instance struct
- */
-void rtc_calendar_enable(struct rtc_module *const module)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(module->hw);
-
-    Rtc *const rtc_module = module->hw;
-
-#if RTC_CALENDAR_ASYNC == true
-    system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_RTC);
-#endif
-
-    while (rtc_calendar_is_syncing(module)) {
-        /* Wait for synchronization */
-    }
-
-    /* Enable RTC module. */
-    rtc_module->MODE2.CTRL.reg |= RTC_MODE2_CTRL_ENABLE;
-}
-
-/**
- * \brief Disables the RTC module.
- *
- * Disables the RTC module.
- *
- * \param[in,out] module  Pointer to the software instance struct
- */
-void rtc_calendar_disable(struct rtc_module *const module)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(module->hw);
-
-    Rtc *const rtc_module = module->hw;
-
-#if RTC_CALENDAR_ASYNC == true
-    system_interrupt_disable(SYSTEM_INTERRUPT_MODULE_RTC);
-#endif
-
-    while (rtc_calendar_is_syncing(module)) {
-        /* Wait for synchronization */
-    }
-
-    /* Disable RTC module. */
-    rtc_module->MODE2.CTRL.reg &= ~RTC_MODE2_CTRL_ENABLE;
-}
-
-/**
- * \brief Resets the RTC module
- * Resets the RTC module to hardware defaults.
- *
- * \param[in,out] module  Pointer to the software instance struct
- */
-void rtc_calendar_reset(struct rtc_module *const module)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(module->hw);
-
-    Rtc *const rtc_module = module->hw;
-
-    /* Disable module before reset. */
-    rtc_calendar_disable(module);
-
-#if RTC_CALENDAR_ASYNC == true
-    module->registered_callback = 0;
-    module->enabled_callback    = 0;
-#endif
-
-    while (rtc_calendar_is_syncing(module)) {
-        /* Wait for synchronization */
-    }
-
-    /* Initiate software reset. */
-    rtc_module->MODE2.CTRL.reg |= RTC_MODE2_CTRL_SWRST;
-}
-
-/**
- * \internal Convert time structure to register_value.
- */
-static uint32_t _rtc_calendar_time_to_register_value(
-    struct rtc_module *const module,
-    const struct rtc_calendar_time *const time)
-{
-    /* Initialize return value. */
-    uint32_t register_value;
-
-    /* Set year value into register_value minus initial year. */
-    register_value = (time->year - module->year_init_value) <<
-                     RTC_MODE2_CLOCK_YEAR_Pos;
-
-    /* Set month value into register_value. */
-    register_value |= (time->month << RTC_MODE2_CLOCK_MONTH_Pos);
-
-    /* Set day value into register_value. */
-    register_value |= (time->day << RTC_MODE2_CLOCK_DAY_Pos);
-
-    /* Set 24 hour value into register_value. */
-    register_value |= (time->hour << RTC_MODE2_CLOCK_HOUR_Pos);
-
-    /* Check if 24 h clock and set pm flag. */
-    if (!(module->clock_24h) && (time->pm)) {
-        /* Set pm flag. */
-        register_value |= RTC_MODE2_CLOCK_HOUR_PM;
-    }
-
-    /* Set minute value into register_value. */
-    register_value |= (time->minute << RTC_MODE2_CLOCK_MINUTE_Pos);
-
-    /* Set second value into register_value. */
-    register_value |= (time->second << RTC_MODE2_CLOCK_SECOND_Pos);
-
-    return register_value;
-}
-
-/**
- * \internal Convert register_value to time structure.
- */
-static void _rtc_calendar_register_value_to_time(
-    struct rtc_module *const module,
-    const uint32_t register_value,
-    struct rtc_calendar_time *const time)
-{
-    /* Set year plus value of initial year. */
-    time->year = ((register_value & RTC_MODE2_CLOCK_YEAR_Msk) >>
-                  RTC_MODE2_CLOCK_YEAR_Pos) + module->year_init_value;
-
-    /* Set month value into time struct. */
-    time->month = ((register_value & RTC_MODE2_CLOCK_MONTH_Msk) >>
-                   RTC_MODE2_CLOCK_MONTH_Pos);
-
-    /* Set day value into time struct. */
-    time->day = ((register_value & RTC_MODE2_CLOCK_DAY_Msk) >>
-                 RTC_MODE2_CLOCK_DAY_Pos);
-
-    if (module->clock_24h) {
-        /* Set hour in 24h mode. */
-        time->hour = ((register_value & RTC_MODE2_CLOCK_HOUR_Msk) >>
-                      RTC_MODE2_CLOCK_HOUR_Pos);
-    } else {
-        /* Set hour in 12h mode. */
-        time->hour = ((register_value &
-                       (RTC_MODE2_CLOCK_HOUR_Msk & ~RTC_MODE2_CLOCK_HOUR_PM)) >>
-                      RTC_MODE2_CLOCK_HOUR_Pos);
-
-        /* Set pm flag */
-        time->pm = ((register_value & RTC_MODE2_CLOCK_HOUR_PM) != 0);
-    }
-
-    /* Set minute value into time struct. */
-    time->minute = ((register_value & RTC_MODE2_CLOCK_MINUTE_Msk) >>
-                    RTC_MODE2_CLOCK_MINUTE_Pos);
-
-    /* Set second value into time struct. */
-    time->second = ((register_value & RTC_MODE2_CLOCK_SECOND_Msk) >>
-                    RTC_MODE2_CLOCK_SECOND_Pos);
-}
-
-/**
- * \internal Applies the given configuration.
- *
- * Set the configurations given from the configuration structure to the
- * hardware module.
- *
- * \param[in,out] module  Pointer to the software instance struct
- * \param[in] config  Pointer to the configuration structure.
- */
-static void _rtc_calendar_set_config(
-    struct rtc_module *const module,
-    const struct rtc_calendar_config *const config)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(module->hw);
-
-    Rtc *const rtc_module = module->hw;
-
-    /* Set up temporary register value. */
-    uint16_t tmp_reg;
-
-    /* Set to calendar mode and set the prescaler. */
-    tmp_reg = RTC_MODE2_CTRL_MODE(2) | config->prescaler;
-
-    /* Check clock mode. */
-    if (!(config->clock_24h)) {
-        /* Set clock mode 12h. */
-        tmp_reg |= RTC_MODE2_CTRL_CLKREP;
-    }
-
-    /* Check for clear on compare match. */
-    if (config->clear_on_match) {
-        /* Set clear on compare match. */
-        tmp_reg |= RTC_MODE2_CTRL_MATCHCLR;
-    }
-
-    /* Set temporary value to register. */
-    rtc_module->MODE2.CTRL.reg = tmp_reg;
-
-    /* Check to set continuously clock read update mode. */
-    if (config->continuously_update) {
-        /* Set continuously mode. */
-        rtc_module->MODE2.READREQ.reg |= RTC_READREQ_RCONT;
-    }
-
-    /* Set alarm time registers. */
-    for (uint8_t i = 0; i < RTC_NUM_OF_ALARMS; i++) {
-        rtc_calendar_set_alarm(module, &(config->alarm[i]), (enum rtc_calendar_alarm)i);
-    }
-}
-
-/**
- * \brief Initializes the RTC module with given configurations.
- *
- * Initializes the module, setting up all given configurations to provide
- * the desired functionality of the RTC.
- *
- * \param[out] module  Pointer to the software instance struct
- * \param[in]   hw      Pointer to hardware instance
- * \param[in] config  Pointer to the configuration structure.
- */
-void rtc_calendar_init(
-    struct rtc_module *const module,
-    Rtc *const hw,
-    const struct rtc_calendar_config *const config)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(hw);
-    Assert(config);
-
-    /* Initialize device instance */
-    module->hw = hw;
-
-    /* Turn on the digital interface clock */
-    system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBA, PM_APBAMASK_RTC);
-
-    /* Set up GCLK */
-    struct system_gclk_chan_config gclk_chan_conf;
-    system_gclk_chan_get_config_defaults(&gclk_chan_conf);
-    gclk_chan_conf.source_generator = GCLK_GENERATOR_2;
-    system_gclk_chan_set_config(RTC_GCLK_ID, &gclk_chan_conf);
-    system_gclk_chan_enable(RTC_GCLK_ID);
-
-    /* Reset module to hardware defaults. */
-    rtc_calendar_reset(module);
-
-    /* Save conf_struct internally for continued use. */
-    module->clock_24h           = config->clock_24h;
-    module->continuously_update = config->continuously_update;
-    module->year_init_value     = config->year_init_value;
-
-#if (RTC_INST_NUM == 1)
-    _rtc_instance[0] = module;
-#else
-    /* Register this instance for callbacks*/
-    _rtc_instance[_rtc_get_inst_index(hw)] = module;
-#endif
-
-    /* Set config. */
-    _rtc_calendar_set_config(module, config);
-}
-
-/**
- * \brief Swaps between 12h and 24h clock mode.
- *
- * Swaps the current RTC time mode:
- * - If currently in 12h mode, it will swap to 24h
- * - If currently in 24h mode, it will swap to 12h
- *
- * \note This will not change setting in user's configuration structure.
- *
- * \param[in, out] module  Pointer to the software instance struct
- */
-void rtc_calendar_swap_time_mode(struct rtc_module *const module)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(module->hw);
-
-    Rtc *const rtc_module = module->hw;
-
-    /* Initialize time structure. */
-    struct rtc_calendar_time time;
-    struct rtc_calendar_alarm_time alarm;
-
-    /* Get current time. */
-    rtc_calendar_get_time(module, &time);
-
-    /* Check current mode. */
-    if (module->clock_24h) {
-        /* Set pm flag. */
-        time.pm = (uint8_t)(time.hour / 12);
-
-        /* Set 12h clock hour value. */
-        time.hour = time.hour % 12;
-        if (time.hour == 0) {
-            time.hour = 12;
-        }
-
-        /* Update alarms */
-        for (uint8_t i = 0; i < RTC_NUM_OF_ALARMS; i++) {
-            rtc_calendar_get_alarm(module, &alarm, (enum rtc_calendar_alarm)i);
-            alarm.time.pm = (uint8_t)(alarm.time.hour / 12);
-            alarm.time.hour = alarm.time.hour % 12;
-            if (alarm.time.hour == 0) {
-                alarm.time.hour = 12;
-            }
-            module->clock_24h = false;
-            rtc_calendar_set_alarm(module, &alarm, (enum rtc_calendar_alarm)i);
-            module->clock_24h = true;
-        }
-
-        /* Change value in configuration structure. */
-        module->clock_24h = false;
-    } else {
-        /* Set hour value based on pm flag. */
-        if (time.pm == 1) {
-            time.hour = time.hour + 12;
-
-            time.pm = 0;
-        } else if (time.hour == 12) {
-            time.hour = 0;
-        }
-
-        /* Update alarms */
-        for (uint8_t i = 0; i < RTC_NUM_OF_ALARMS; i++) {
-            rtc_calendar_get_alarm(module, &alarm, (enum rtc_calendar_alarm)i);
-            if (alarm.time.pm == 1) {
-                alarm.time.hour = alarm.time.hour + 12;
-                alarm.time.pm = 0;
-                module->clock_24h = true;
-                rtc_calendar_set_alarm(module, &alarm, (enum rtc_calendar_alarm)i);
-                module->clock_24h = false;
-            } else if (alarm.time.hour == 12) {
-                alarm.time.hour = 0;
-            }
-        }
-
-        /* Change value in configuration structure. */
-        module->clock_24h = true;
-    }
-
-    /* Disable RTC so new configuration can be set. */
-    rtc_calendar_disable(module);
-
-    /* Toggle mode. */
-    rtc_module->MODE2.CTRL.reg ^= RTC_MODE2_CTRL_CLKREP;
-
-    /* Enable RTC. */
-    rtc_calendar_enable(module);
-
-    /* Set new time format in CLOCK register. */
-    rtc_calendar_set_time(module, &time);
-}
-
-/**
- * \brief Set the current calendar time to desired time.
- *
- * Sets the time provided to the calendar.
- *
- * \param[in, out] module  Pointer to the software instance struct
- * \param[in] time  The time to set in the calendar.
- */
-void rtc_calendar_set_time(
-    struct rtc_module *const module,
-    const struct rtc_calendar_time *const time)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(module->hw);
-
-    Rtc *const rtc_module = module->hw;
-
-    uint32_t register_value = _rtc_calendar_time_to_register_value(module, time);
-
-    while (rtc_calendar_is_syncing(module)) {
-        /* Wait for synchronization */
-    }
-
-    /* Write value to register. */
-    rtc_module->MODE2.CLOCK.reg = register_value;
-}
-
-/**
- * \brief Get the current calendar value.
- *
- * Retrieves the current time of the calendar.
- *
- * \param[in, out] module  Pointer to the software instance struct
- * \param[out] time  Pointer to value that will be filled with current time.
- */
-void rtc_calendar_get_time(
-    struct rtc_module *const module,
-    struct rtc_calendar_time *const time)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(module->hw);
-
-    Rtc *const rtc_module = module->hw;
-
-    /* Change of read method based on value of continuously_update value in
-     * the configuration structure. */
-    if (!(module->continuously_update)) {
-        /* Request read on CLOCK register. */
-        rtc_module->MODE2.READREQ.reg = RTC_READREQ_RREQ;
-
-        while (rtc_calendar_is_syncing(module)) {
-            /* Wait for synchronization */
-        }
-    }
-
-    /* Read value. */
-    uint32_t register_value = rtc_module->MODE2.CLOCK.reg;
-
-    /* Convert value to time structure. */
-    _rtc_calendar_register_value_to_time(module, register_value, time);
-}
-
-/**
- * \brief Set the alarm time for the specified alarm.
- *
- * Sets the time and mask specified to the requested alarm.
- *
- * \param[in, out] module  Pointer to the software instance struct
- * \param[in] alarm        The alarm struct to set the alarm with.
- * \param[in] alarm_index  The index of the alarm to set.
- *
- * \return Status of setting alarm.
- * \retval STATUS_OK               If alarm was set correctly.
- * \retval STATUS_ERR_INVALID_ARG  If invalid argument(s) were provided.
- */
-enum status_code rtc_calendar_set_alarm(
-    struct rtc_module *const module,
-    const struct rtc_calendar_alarm_time *const alarm,
-    const enum rtc_calendar_alarm alarm_index)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(module->hw);
-
-    Rtc *const rtc_module = module->hw;
-
-    /* Sanity check. */
-    if ((uint32_t)alarm_index > RTC_NUM_OF_ALARMS) {
-        return STATUS_ERR_INVALID_ARG;
-    }
-
-    /* Get register_value from time. */
-    uint32_t register_value = _rtc_calendar_time_to_register_value(module, &(alarm->time));
-
-    while (rtc_calendar_is_syncing(module)) {
-        /* Wait for synchronization */
-    }
-
-    /* Set alarm value. */
-    rtc_module->MODE2.Mode2Alarm[alarm_index].ALARM.reg = register_value;
-
-    /* Set alarm mask */
-    rtc_module->MODE2.Mode2Alarm[alarm_index].MASK.reg = alarm->mask;
-
-    return STATUS_OK;
-}
-
-/**
- * \brief Get the current alarm time of specified alarm.
- *
- * Retrieves the current alarm time for the alarm specified.
- *
- * \param[in, out] module  Pointer to the software instance struct
- * \param[out] alarm  Pointer to the struct that will be filled with alarm
- *                    time and mask of the specified alarm.
- * \param[in] alarm_index  Index of alarm to get alarm time from.
- *
- * \return Status of getting alarm.
- * \retval STATUS_OK               If alarm was read correctly.
- * \retval STATUS_ERR_INVALID_ARG  If invalid argument(s) were provided.
- */
-enum status_code rtc_calendar_get_alarm(
-    struct rtc_module *const module,
-    struct rtc_calendar_alarm_time *const alarm,
-    const enum rtc_calendar_alarm alarm_index)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(module->hw);
-
-    Rtc *const rtc_module = module->hw;
-
-    /* Sanity check. */
-    if ((uint32_t)alarm_index > RTC_NUM_OF_ALARMS) {
-        return STATUS_ERR_INVALID_ARG;
-    }
-
-    /* Read alarm value. */
-    uint32_t register_value =
-        rtc_module->MODE2.Mode2Alarm[alarm_index].ALARM.reg;
-
-    /* Convert to time structure. */
-    _rtc_calendar_register_value_to_time(module, register_value, &(alarm->time));
-
-    /* Read alarm mask */
-    alarm->mask = (enum rtc_calendar_alarm_mask)rtc_module->MODE2.Mode2Alarm[alarm_index].MASK.reg;
-
-    return STATUS_OK;
-}
-
-/**
- * \brief Calibrate for too-slow or too-fast oscillator.
- *
- * When used, the RTC will compensate for an inaccurate oscillator. The
- * RTC module will add or subtract cycles from the RTC prescaler to adjust the
- * frequency in approximately 1 PPM steps. The provided correction value should
- * be between -127 and 127, allowing for a maximum 127 PPM correction in either
- * direction.
- *
- * If no correction is needed, set value to zero.
- *
- * \note Can only be used when the RTC is operated at 1Hz.
- *
- * \param[in, out] module  Pointer to the software instance struct
- * \param[in] value Between -127 and 127 used for the correction.
- *
- * \return Status of the calibration procedure.
- * \retval STATUS_OK               If calibration was done correctly.
- * \retval STATUS_ERR_INVALID_ARG  If invalid argument(s) were provided.
- */
-enum status_code rtc_calendar_frequency_correction(
-    struct rtc_module *const module,
-    const int8_t value)
-{
-    /* Sanity check arguments */
-    Assert(module);
-    Assert(module->hw);
-
-    Rtc *const rtc_module = module->hw;
-
-    /* Check if valid argument. */
-    if (abs(value) > 0x7F) {
-        /* Value bigger than allowed, return invalid argument. */
-        return STATUS_ERR_INVALID_ARG;
-    }
-
-    uint32_t new_correction_value;
-
-    /* Load the new correction value as a positive value, sign added later */
-    new_correction_value = abs(value);
-
-    /* Convert to positive value and adjust register sign bit. */
-    if (value < 0) {
-        new_correction_value |= RTC_FREQCORR_SIGN;
-    }
-
-    while (rtc_calendar_is_syncing(module)) {
-        /* Wait for synchronization */
-    }
-
-    /* Set value. */
-    rtc_module->MODE2.FREQCORR.reg = new_correction_value;
-
-    return STATUS_OK;
-}