Projet

Général

Profil

Publication de fichiers » ds1305.h

Redmine Admin, 2013-02-16 17:28

 
/**
* @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
*/
(2-2/3)