|
/**
|
|
* @mainpage
|
|
* @section Information
|
|
* @brief Maxim Serial Alarm Real-Time Clock DS1305 functions for Atmel AVR
|
|
* @author Patrice Nadeau <patricen@telwarwick.net>
|
|
* @n www : http://nadeaup.homeip.net:8080/
|
|
* @note For the moment, only the the SPI protocol will be developed
|
|
* @note Minimum year is 2000, maximum year is 2099 but it will be able to
|
|
* roll over to 2100 (hardware limitation of the ds1305)
|
|
* @todo Trickle charging functions
|
|
* @todo 3-Wire mode
|
|
* @pre Voltage required :
|
|
* - Vcc1 > Vbat + 0.2V
|
|
* @section Specifications
|
|
* @subsection Language
|
|
* C (c99)
|
|
* @subsection Compiler
|
|
* avr-gcc
|
|
* @subsection Target
|
|
* uC tested are in @b bold
|
|
* - ATmega48
|
|
* - ATmega88
|
|
* - @b ATmega168
|
|
* - @b ATmega328
|
|
*
|
|
* @par Datasheet
|
|
* http://datasheets.maxim-ic.com/en/ds/DS1305.pdf
|
|
*
|
|
* @section License
|
|
* BSD 3-Clause License
|
|
* @n Copyright (c) 2010, 2011,2012 Patrice Nadeau
|
|
* @n All rights reserved.
|
|
* @n Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
- Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
- 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.
|
|
- Neither the name of Patrice Nadeau nor the
|
|
names of its contributors may be used to endorse or promote products
|
|
derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Patrice Nadeau 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.
|
|
*/
|
|
|
|
|
|
/**
|
|
* @file ds1305.h
|
|
* @author Patrice Nadeau <patricen@telwarwick.net>
|
|
* @todo use same option for ReadTimeAscii and WriteTimeAscii
|
|
* should probably have
|
|
* - WriteDateAscii
|
|
* - WriteTimeAscii
|
|
* - WriteAlarmAscii
|
|
*/
|
|
|
|
#ifndef DS1305_H_
|
|
#define DS1305_H_
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
|
|
#include "utils/utils.h"
|
|
#include "spi/spi.h"
|
|
#include "ascii/ascii.h"
|
|
#include "binary/binary.h"
|
|
#include "date/date.h"
|
|
|
|
|
|
/**
|
|
* @name To specify the functions
|
|
* @{
|
|
*/
|
|
#define ds1305_ALARM0 0
|
|
#define ds1305_ALARM1 1
|
|
#define ds1305_TIMER 2
|
|
/** @} */
|
|
|
|
/**
|
|
* @name To specify the alarms intervals
|
|
* @{
|
|
*/
|
|
/** @brief Every seconds */
|
|
#define ds1305_ALARM_ONCE 15
|
|
/** @brief When seconds match */
|
|
#define ds1305_ALARM_SECOND 7
|
|
/** @brief When minutes & seconds match */
|
|
#define ds1305_ALARM_MINUTE 3
|
|
/** @brief When hours, minutes & seconds match */
|
|
#define ds1305_ALARM_HOUR 1
|
|
/** @brief When days, hours, minutes & seconds match */
|
|
#define ds1305_ALARM_DAY 0
|
|
/** @} */
|
|
|
|
/**
|
|
* @name ASCII format and size in ISO 8601 extended
|
|
* @{
|
|
*/
|
|
/** @brief YYYY-MM-DD HH:MM:SS */
|
|
#define ds1305_ASCII_FMT_FULL_EXT 19
|
|
/** @brief Format HH:MM:SS */
|
|
#define ds1305_ASCII_FMT_TIME_EXT 8
|
|
/** @brief Format YYYY-MM-DD */
|
|
#define ds1305_ASCII_FMT_DATE_EXT 10
|
|
/** @brief Format : Day, HH:MM:SS AM/PM */
|
|
#define ds1305_ASCII_FMT_ALARM 4
|
|
/** @}*/
|
|
|
|
/**
|
|
* @name ASCII errors
|
|
* @{
|
|
*/
|
|
/** @brief Error code string is empty */
|
|
#define ds1305_ASCII_ERR_EMPTY 10
|
|
/** @brief Error code string is too long */
|
|
#define ds1305_ASCII_ERR_LONG 11
|
|
/** @brief Error code string is too short */
|
|
#define ds1305_ASCII_ERR_SHORT 12
|
|
/** @brief Error code string is invalid */
|
|
#define ds1305_ASCII_ERR_INVALID 13
|
|
/** @brief Error code date is wrong format */
|
|
#define ds1305_ASCII_ERR_DATE_FORMAT 14
|
|
/** @brief Error code time is wrong format */
|
|
#define ds1305_ASCII_ERR_TIME_FORMAT 15
|
|
/** @brief Error code date is out of range */
|
|
#define ds1305_ASCII_ERR_DATE_RANGE 16
|
|
/** @brief Error code time is out of range */
|
|
#define ds1305_ASCII_ERR_TIME_RANGE 17
|
|
/** @brief Error code unknown */
|
|
#define ds1305_ASCII_UNDEFINED 255
|
|
/** @} */
|
|
|
|
/**
|
|
* @brief Structure for time and alarms.
|
|
* @note Alarms don't use the following fields :
|
|
* - @b year
|
|
* - @b month
|
|
* - @b date
|
|
* */
|
|
struct ds1305_time {
|
|
/** @brief 00 - 99 */
|
|
uint8_t year;
|
|
/** @brief 01 - 12 */
|
|
uint8_t month;
|
|
/** @brief 01 - 31 */
|
|
uint8_t date;
|
|
/** @brief 1 - 7 */
|
|
uint8_t day;
|
|
/** @brief 00 - 23 */
|
|
uint8_t hours;
|
|
/** @brief 00 - 59 */
|
|
uint8_t minutes;
|
|
/** @brief 00 - 59 */
|
|
uint8_t seconds;
|
|
};
|
|
|
|
/**
|
|
* @brief Structure for the 96 bytes of RAM */
|
|
struct ds1305_ram {
|
|
/** @brief 1 byte, from 0 to 95 */
|
|
uint8_t byte[96];
|
|
};
|
|
|
|
|
|
/**
|
|
* @brief Initialize the DS1305 for the SPI protocol
|
|
*/
|
|
void ds1305_SPIInit(void);
|
|
|
|
/**
|
|
* @brief Return the date in a struct
|
|
* @param[out] *date A pointer to a structure of type @a ds1305_time
|
|
*/
|
|
void ds1305_ReadDate (struct ds1305_time *date);
|
|
|
|
/**
|
|
* @brief Return the time in a struct
|
|
* @param[out] *time A pointer to a structure of type @a ds1305_time
|
|
*/
|
|
void ds1305_ReadTime (struct ds1305_time *time);
|
|
|
|
/**
|
|
* @brief Set the date
|
|
* @param[in] date A structure of type @a ds1305_time
|
|
*/
|
|
void ds1305_WriteDate (struct ds1305_time date);
|
|
|
|
/**
|
|
* @brief Set the time
|
|
* @param[in] time A structure of type @a ds1305_time
|
|
*/
|
|
void ds1305_WriteTime (struct ds1305_time time);
|
|
|
|
/**
|
|
* @brief Write the time and interval into one of the alarms
|
|
* @param[in] time Structure of type @a ds1305_time
|
|
* @param[in] alarm Alarm number to write
|
|
* - ds1305_ALARM0
|
|
* - ds1305_ALARM1
|
|
* @param[in] interval Interval of the alarm
|
|
* - ds1305_ALARM_ONCE Once every seconds
|
|
* - ds1305_ALARM_SECOND When seconds matches
|
|
* - ds1305_ALARM_MINUTE When seconds and minutes matches
|
|
* - ds1305_ALARM_HOUR When seconds, minutes and hours matches
|
|
* - ds1305_ALARM_DAY When seconds, minutes, hours and days matches
|
|
* @par Example
|
|
* Set Alarm0 every 10 seconds
|
|
* @code
|
|
* struct ds1305_time time;
|
|
* time.seconds = 10;
|
|
* ds1305_WriteAlarm(time, ds1305_ALARM0, ds1305_ALARM_SECOND);
|
|
* @endcode
|
|
* @todo Documentation could be a lot more clear
|
|
*/
|
|
void ds1305_WriteAlarm (struct ds1305_time time, uint8_t alarm,
|
|
uint8_t interval);
|
|
|
|
/**
|
|
* @brief Read the @a time for alarm # @a alarm
|
|
* @param[in] alarm Alarm number to read
|
|
* - ds1305_ALARM0
|
|
* - ds1305_ALARM1
|
|
* @param[out] *time A pointer to a structure of type @a ds1305_time
|
|
* @return Interval of the alarm
|
|
* @retval ds1305_ALARM_ONCE One time
|
|
* @retval ds1305_ALARM_SECOND Every seconds
|
|
* @retval ds1305_ALARM_MINUTE Every minutes
|
|
* @retval ds1305_ALARM_HOUR Every hours
|
|
* @retval ds1305_ALARM_DAY Every days
|
|
*/
|
|
uint8_t ds1305_ReadAlarm (struct ds1305_time *time, uint8_t alarm);
|
|
|
|
/**
|
|
* @brief Write all the 96 Bytes to RAM
|
|
* @param[in] ram Structure of type ds1305_ram
|
|
*/
|
|
void ds1305_WriteRAM(struct ds1305_ram ram);
|
|
|
|
/**
|
|
* @brief Read all the 96 Bytes from RAM
|
|
* @param[out] *ram A pointer to a structure of type @a ds1305_ram
|
|
*/
|
|
void ds1305_ReadRAM(struct ds1305_ram *ram);
|
|
|
|
/**
|
|
* @brief Convert a structure of type @a ds1305_time to a string
|
|
* @param[in] time Structure of type @a ds1305_time
|
|
* @param[out] string Pointer to a string
|
|
* @param[in] format One of the ASCII format
|
|
* - ds1305_ASCII_FMT_TIME
|
|
* - ds1305_ASCII_FMT_DATE
|
|
* - ds1305_ASCII_FMT_ALARM
|
|
*/
|
|
void ds1305_TimeToStr(struct ds1305_time time, char *string, uint8_t format);
|
|
|
|
/**
|
|
* @brief Read the current date in format ds1305_ASCII_FMT_DATE_EXT
|
|
* @param[out] string A pointer to the output string
|
|
*/
|
|
void ds1305_ReadDateAscii(char *string);
|
|
|
|
/**
|
|
* @brief Read the current time in format ds1305_ASCII_FMT_TIME_EXT
|
|
* @param[out] string A pointer to the output string
|
|
*/
|
|
void ds1305_ReadTimeAscii(char *string);
|
|
|
|
/**
|
|
* @brief Read the current alarm in format ds1305_ASCII_FMT_ALARM
|
|
* @param[out] string A pointer to the output string
|
|
*/
|
|
void ds1305_ReadAlarmAscii(char *string);
|
|
|
|
/**
|
|
* @brief Validate a string
|
|
* @param[in] string A pointer to a string
|
|
* @param[in] format One of the following
|
|
* - ds1305_ASCII_FMT_FULL_EXT
|
|
* - ds1305_ASCII_FMT_TIME_EXT
|
|
* - ds1305_ASCII_FMT_DATE_EXT
|
|
* - ds1305_ASCII_FMT_ALARM
|
|
* @return Error code
|
|
* @retval 0 If valid
|
|
* @retval ds1305_ASCII_ERR_XX Any other error code
|
|
* @par Example :
|
|
*
|
|
* @code
|
|
* ...
|
|
* switch (ds1305_ValidateAscii(str, ds1305_ASCII_FMT_TIME_EXT)) {
|
|
* case ds1305_ASCII_ERR_LONG :
|
|
* printf("String too long\n");
|
|
* break;
|
|
* case ds1305_ASCII_ERR_SHORT :
|
|
* printf("String too short\n");
|
|
* break;
|
|
* };
|
|
* ...
|
|
* @endcode
|
|
*/
|
|
uint8_t ds1305_ValidateAscii(char *string, uint8_t format);
|
|
|
|
|
|
/**
|
|
* @brief Write an ASCII string representing date into the RTC
|
|
* @param[in] string A pointer to a string
|
|
* @return Status of the operation
|
|
* @retval 0 Successful
|
|
* @note Format : YYYY-MM-DD
|
|
* @pre The string must be validated before with @e ds1305_ValidateAscii
|
|
* @par Example :
|
|
*
|
|
* @code
|
|
* ...
|
|
* if (ds1305_ValidateAscii(str, ds1305_ASCII_FMT_DATE_EXT) == 0)
|
|
* ds1305_WriteDateAscii(str);
|
|
* else
|
|
* error();
|
|
* ...
|
|
* @endcode
|
|
*/
|
|
void ds1305_WriteDateAscii(const char *string);
|
|
|
|
/**
|
|
* @brief Write an ASCII string representing time into the RTC
|
|
* @param[in] string A pointer to a string
|
|
* @return Status of the operation
|
|
* @retval 0 Successful
|
|
* @note Format : HH:MM:SS
|
|
* @pre The string must be validated before with @e ds1305_ValidateAscii
|
|
* @par Example :
|
|
*
|
|
* @code
|
|
* ...
|
|
* if (ds1305_ValidateAscii(str) == 0) // the string is OK
|
|
* ds1305_WriteTimeAscii(str);
|
|
* else
|
|
* error();
|
|
* ...
|
|
* @endcode
|
|
*/
|
|
void ds1305_WriteTimeAscii(const char *string);
|
|
|
|
/**
|
|
* @brief Set the use of one pin (INT0) for INT0 and INT1, set INT0 and INT1
|
|
* @param[in] one_pin Use of one pin for both int
|
|
* - @n true
|
|
* - @n false
|
|
* @param[in] int0 Enable int0
|
|
* - @n true
|
|
* - @n false
|
|
* @param[in] int1 Enable int1
|
|
* - @n true
|
|
* - @n false
|
|
* @warning Don't forget the external pull-up (resistor or AVR internal
|
|
* pull-up) !
|
|
*/
|
|
void ds1305_EnableInt (uint8_t one_pin, uint8_t int0, uint8_t int1);
|
|
|
|
/**
|
|
* @brief Clear the interrupt flag for an alarm
|
|
* @param[in] nb Alarm number to clear
|
|
* - ds1305_ALARM0
|
|
* - ds1305_ALARM1
|
|
*/
|
|
void ds1305_ClearInt (uint8_t nb);
|
|
|
|
/*
|
|
* @brief Return the Status Register value
|
|
* @return The content of the status Register
|
|
*/
|
|
//uint8_t ds1305_ReadStatusRegister(void);
|
|
|
|
/*
|
|
* @brief Return the value of the Control Register
|
|
* @return The contents of the status Register
|
|
*/
|
|
//uint8_t ds1305_ReadControlRegister(void);
|
|
|
|
#endif /* DS1305_H_ */
|
|
|
|
/* change log
|
|
* 2010-09-08 Patrice Nadeau
|
|
* First draft
|
|
* 2010-09-26 Patrice Nadeau
|
|
* First release
|
|
* 2010-09-27 Patrice Nadeau
|
|
* added ds1305_EnableInt() & ds1305_ClearInt()
|
|
* 2011-01-08 Patrice Nadeau
|
|
* Changed comments for Doxygen
|
|
* 2011-11-16 Patrice Nadeau
|
|
* Added ds1395_WriteTimeAScii()
|
|
* 2011-02-12 PatriceNadeau
|
|
* ds1305_WriteAlarm : changed the name of the parameters to be more concise
|
|
* 2011-01-13 Patrice Nadeau
|
|
* ds1305_TimeToStr ; added
|
|
* ds1305_ReadStatusRegister : added
|
|
* ds1305_ReadControlRegister : added
|
|
* 2011-02-19 Patrice Nadeau
|
|
* #define ds1305_ALARM0 & ds1305_ALARM1 : added
|
|
* More Doxygen comments
|
|
* 2011-02-26 Patrice Nadeau
|
|
* Removed the bug about interrupts and alarms
|
|
* Removed the to do about testing the Read/Write functions for the RAM
|
|
* 2011-03-02 Patrice Nadeau
|
|
* Correction for some comments
|
|
* 2011-03-05 Patrice Nadeau
|
|
* Correction for some comments
|
|
* 2011-04-14 Patrice Nadeau
|
|
* ds1305_WriteTimeAscii : char *string -> const char *string
|
|
*/
|