Files
LFP_48V_mBMS_FW/APP_R3323/App/Hardware/rtc_io.c

368 lines
10 KiB
C

/**
******************************************************************************
* @file rtc_io.c
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the code of the realtime clock functions.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
//////////////////////////////////////////////////////////////////////////
//// DS1302.C ////
//// Driver for Real Time Clock ////
//// ////
//// rtc_init() Call after power up////
//// ////
//// rtc_set_datetime(day,mth,year,dow,hour,min) Set the date/time ////
//// ////
//// rtc_get_date(day,mth,year,dow) Get the date ////
//// ////
//// rtc_get_time(hr,min,sec) Get the time ////
//// ////
//// rtc_write_nvr(address,data) Write to NVR ////
//// ////
//// data = rtc_read_nvr(address) Read from NVR ////
//// ////
//////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
//////////////////////////////////////////////////////////////////////////
/** @addtogroup mBMS2
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "rtc_io.h"
#include "delay.h"
#include "stdio.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* RTC IO Port/Pin definition */
#define RTC_IO_CLK_PORT (PortD)
#define RTC_IO_CLK_PIN (Pin11)
#define RTC_IO_DAT_PORT (PortD)
#define RTC_IO_DAT_PIN (Pin10)
#define RTC_IO_RST_PORT (PortD)
#define RTC_IO_RST_PIN (Pin09)
// --------------------------------------------------------------------------------
// RTC-Bus-Line
// --------------------------------------------------------------------------------
#define RTC_CLK_LOW PORT_ResetBits(RTC_IO_CLK_PORT, RTC_IO_CLK_PIN) // rtc data line Low-Level
#define RTC_CLK_HIGH PORT_SetBits(RTC_IO_CLK_PORT, RTC_IO_CLK_PIN) // rtc data line High-Level
#define RTC_DAT_LOW PORT_ResetBits(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN) // rtc data line Low-Level
#define RTC_DAT_HIGH PORT_SetBits(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN) // rtc data line High-Level
#define RTC_DAT_IN PORT_GetBit(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN) // rtc data line read
#define RTC_RST_LOW PORT_ResetBits(RTC_IO_RST_PORT, RTC_IO_RST_PIN) // rtc data line Low-Level
#define RTC_RST_HIGH PORT_SetBits(RTC_IO_RST_PORT, RTC_IO_RST_PIN) // rtc data line High-Level
#define CLK_DIV 10
#define Tdc 200 / CLK_DIV // Min.
#define Tcdh 280 / CLK_DIV // Min.
#define Tcdd 800 / CLK_DIV // Max.
#define Tcl 1000 / CLK_DIV // Min.
#define Tch 1000 / CLK_DIV // Min.
#define Tcc 4000 / CLK_DIV // Min.
#define Tcch 240 / CLK_DIV // Min.
#define Tcwh 4000 / CLK_DIV // Min.
#define Tcdz 280 / CLK_DIV // Max.
#define Tccz 280 / CLK_DIV // Max.
#define RD_ADDR_RTC_YEAR 0x8D
#define RD_ADDR_RTC_MONTH 0x89
#define RD_ADDR_RTC_DATE 0x87
#define RD_ADDR_RTC_WDAY 0x8B
#define RD_ADDR_RTC_HOUR 0x85
#define RD_ADDR_RTC_MIN 0x83
#define RD_ADDR_RTC_SEC 0x81
#define WR_ADDR_RTC_YEAR 0x8C
#define WR_ADDR_RTC_MONTH 0x88
#define WR_ADDR_RTC_DATE 0x86
#define WR_ADDR_RTC_WDAY 0x8A
#define WR_ADDR_RTC_HOUR 0x84
#define WR_ADDR_RTC_MIN 0x82
#define WR_ADDR_RTC_SEC 0x80
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private prototype functions -----------------------------------------------*/
// send 'databyte' to 'port'
void outp(uint8_t HighLow);
// read byte from 'port'
uint8_t inp(void);
// 1-Wire Timing Generation
// Pause for exactly 'tick' number of ticks = 0.25us
void tickDelay(uint16_t tick); // Implementation is platform specific
//-----------------------------------------------------------------------------
// Set the 1-Wire timing to 'standard' (standard=1) or 'overdrive' (standard=0).
//
/* Private functions ---------------------------------------------------------*/
void tickDelay(uint16_t tick)
{
delay_us(tick);
}
void RTC_IO_Config(void)
{
stc_port_init_t stcPortInit;
/* configuration structure initialization */
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinMode = Pin_Mode_Out;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Disable;
/* LED Port/Pin initialization */
PORT_Init(RTC_IO_CLK_PORT, RTC_IO_CLK_PIN, &stcPortInit);
PORT_Init(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN, &stcPortInit);
PORT_Init(RTC_IO_RST_PORT, RTC_IO_RST_PIN, &stcPortInit);
PORT_ResetBits(RTC_IO_CLK_PORT, RTC_IO_CLK_PIN);
PORT_ResetBits(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN);
PORT_ResetBits(RTC_IO_RST_PORT, RTC_IO_RST_PIN);
}
void rtc_dat_config(uint8_t inout)
{
stc_port_init_t stcPortInit;
/* configuration structure initialization */
MEM_ZERO_STRUCT(stcPortInit);
if (inout == 1)
{
// Output
stcPortInit.enPinMode = Pin_Mode_Out;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Disable;
PORT_ResetBits(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN);
PORT_Init(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN, &stcPortInit);
}
else
{
// Input
stcPortInit.enPinMode = Pin_Mode_In;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Disable;
PORT_Init(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN, &stcPortInit);
}
}
void outp(uint8_t HighLow)
{
if (HighLow) RTC_DAT_HIGH;
else RTC_DAT_LOW;
}
uint8_t inp(void)
{
return RTC_DAT_IN;
}
void write_ds1302_byte(uint8_t cmd)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
outp((cmd >> i) & 0x01);
delay_ns(Tcl);
RTC_CLK_HIGH;
delay_ns(Tch);
RTC_CLK_LOW;
}
}
void write_ds1302(uint8_t cmd, uint8_t data)
{
rtc_dat_config(1);
RTC_RST_HIGH;
delay_ns(Tcc);
write_ds1302_byte(cmd);
write_ds1302_byte(data);
RTC_RST_LOW;
delay_ns(Tcwh);
}
uint8_t read_ds1302(uint8_t cmd)
{
uint8_t data = 0;
rtc_dat_config(1);
if (cmd == 0)
cmd = cmd;
RTC_RST_HIGH;
delay_ns(Tcc - Tcl);
write_ds1302_byte(cmd);
rtc_dat_config(0);
for (int i = 0; i < 8; i++)
{
delay_ns(Tcdd);
data |= (inp() << i);
delay_ns(Tcl-Tcdd);
RTC_CLK_HIGH;
delay_ns(Tch);
RTC_CLK_LOW;
}
RTC_RST_LOW;
rtc_dat_config(1);
delay_ns(Tcwh);
return (data);
}
void rtc_init(void)
{
uint8_t x;
RTC_IO_Config();
RTC_RST_HIGH;
delay_ns(Tch);
RTC_CLK_LOW;
write_ds1302(0x8e, 0);
write_ds1302(0x90, 0xa6);
x = read_ds1302(0x81);
if ((x & 0x80) != 0)
write_ds1302(0x80, 0);
}
uint8_t bcd2byte(uint8_t bcd)
{
return ((bcd >> 4) * 10) + (bcd & 0x0F);
}
uint8_t byte2bcd(uint8_t byte)
{
return ((byte / 10) << 4) + (byte % 10);
}
void rtc_set_datetime(uint8_t *DateTime)
{
int i = 0;
write_ds1302(WR_ADDR_RTC_YEAR , byte2bcd(DateTime[i++]));
write_ds1302(WR_ADDR_RTC_MONTH, byte2bcd(DateTime[i++]));
write_ds1302(WR_ADDR_RTC_DATE , byte2bcd(DateTime[i++]));
write_ds1302(WR_ADDR_RTC_HOUR , byte2bcd(DateTime[i++]));
write_ds1302(WR_ADDR_RTC_MIN , byte2bcd(DateTime[i++]));
write_ds1302(WR_ADDR_RTC_SEC , byte2bcd(DateTime[i++]));
}
void rtc_get_datetime(uint8_t *DateTime)
{
int i = 0;
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_YEAR));
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_MONTH));
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_DATE));
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_WDAY));
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_HOUR));
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_MIN));
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_SEC));
}
uint8_t rtc_get_year(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_YEAR));
}
uint8_t rtc_get_month(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_MONTH));
}
uint8_t rtc_get_date(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_DATE));
}
uint8_t rtc_get_wday(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_WDAY));
}
uint8_t rtc_get_hour(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_HOUR));
}
uint8_t rtc_get_min(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_MIN));
}
uint8_t rtc_get_sec(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_SEC));
}
void rtc_get_date1(uint8_t *day, uint8_t *mth, uint8_t *year, uint8_t *dow)
{
*day = read_ds1302(0x87);
*mth = read_ds1302(0x89);
*year = read_ds1302(0x8d);
*dow = read_ds1302(0x8b);
}
void rtc_get_time(uint8_t *hr, uint8_t *min, uint8_t *sec)
{
*hr = read_ds1302(0x85);
*min = read_ds1302(0x83);
*sec = read_ds1302(0x81);
}
void rtc_write_nvr(uint8_t address, uint8_t data)
{
write_ds1302((address << 1) | 0xc0, data);
}
uint8_t rtc_read_nvr(uint8_t address)
{
return (read_ds1302((address << 1) | 0xc1));
}
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/