/*********************************************************
*Copyright (C), 2023, Shanghai Eastsoft Microelectronics Co., Ltd
*文件名:  main.c
*作  者:  AE Team
*版  本:  v1.0，编译于iDesigner(v4.2.3.187) + 工具链HRCC(v1.2.0.136)
*日  期:  2023/01/31
*描  述:  RTC演示程序
          PB5：TX
          PB6：RX
          MCU与上位机通信，波特率9600，复位后发送字符串"Please input time. For example: 2023-01-01 00:00:00"，并等待接收时间信息。
		  请按照与“2023-01-01 00:00:00”字符串相同的格式用上位机向MCU发送时间信息。
		  然后MCU循环读取实时时间，并打印到上位机显示，周期5s。
		  循环打印时间期间仍可通过上位机更改时间信息。
*备  注:  本例程适用于ES7P0683芯片，本例程仅供参考
本软件仅供学习和演示使用，对用户直接引用代码所带来的风险或后果不承担任何法律责任。
**********************************************************/
#include <HIC.h>
#include "rtc.h"
#include "time.h"

#define IT_SR

uint8_t time_input[19];

/******************************************************
函数名：void RAMclear(void)
描  述：RAM区数据清零，RAM区地址0x0000~0x03FF
输入值：无
输出值：无
返回值：无
*******************************************************/
void RAMclear(void)
{
    for (IAAH=0; IAAH<=0x03; IAAH++)
    {
        for (IAAL=0; IAAL<0xFF; IAAL++)
            IAD = 0x00;
        IAD = 0x00;
    }
}

/******************************************************
函数名：void GPIOInit(void)
描  述：首先初始化所有未用到的IO口为输出低电平
输入值：无
输出值：无
返回值：无
*******************************************************/
void GPIOInit(void)
{
    ANSL = 0xFF;        //选择对应端口为数字IO功能
	ANSH = 0xFF;
    PAT = 0x00;         //所有IO设为输出低电平
    PBT = 0x00;
    PCT = 0x00;
    PA = 0x00;
    PB = 0x00;
    PC = 0x00;
	PBSMTS = 0;
}

void uart_puts(char *s)
{
	char *c = s;

	while (*c != 0)
    {
		while (!TRMT1);
        TX1B = *c++;
        CLRWDT();
    }
}

void uart_send(unsigned char *data, unsigned char len)
{
	unsigned char i;

	for (i = 0; i < len; ++i) {
		while (!TRMT1);
        TX1B = data[i];
        CLRWDT();
	}
}

const char dec_tab[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
unsigned char cnt = 0;
unsigned char sec_prev = 0;

struct tm tm;

void uart_puts_time(void)
{
	char tmstr[64];
	unsigned char i;
	char *c;

	for (i = 0; i < sizeof(tmstr); ++i) {
		tmstr[i] = 0;
	}

	c = tmstr;

	if (tm.tm_sec == sec_prev) {
		return;
	}

	sec_prev = tm.tm_sec;

	*c++ = dec_tab[cnt / 100 % 10];
	*c++ = dec_tab[cnt / 10 % 10];
	*c++ = dec_tab[cnt % 10];
	*c++ = ' ';
	*c++ = ' ';
	*c++ = '2';
	*c++ = '0';
	*c++ = dec_tab[((tm.tm_year + 1900) / 10) % 10];
	*c++ = dec_tab[(tm.tm_year + 1900) % 10];
	*c++ = '-';
	*c++ = dec_tab[((tm.tm_mon + 1) / 10) % 10];
	*c++ = dec_tab[(tm.tm_mon + 1) % 10];
	*c++ = '-';
	*c++ = dec_tab[(tm.tm_mday / 10) % 10];
	*c++ = dec_tab[tm.tm_mday % 10];
	*c++ = ' ';
	*c++ = dec_tab[(tm.tm_hour / 10) % 10];
	*c++ = dec_tab[tm.tm_hour % 10];
	*c++ = ':';
	*c++ = dec_tab[(tm.tm_min / 10) % 10];
	*c++ = dec_tab[tm.tm_min % 10];
	*c++ = ':';
	*c++ = dec_tab[(tm.tm_sec / 10) % 10];
	*c++ = dec_tab[tm.tm_sec % 10];
	*c++ = '\n';
	*c = 0;

	cnt++;

	uart_send(tmstr, c - tmstr);
}

void Delay5Ms(unsigned int temp)
{
    unsigned char i,j;

   	while(temp--)
   	{
   	   	for(i=0;i<200;i++)
   	   	   	for(j=0;j<27;j++);
   	}
}

void uart_init(void)
{
    PBT5 = 0;       //TX输出
    PBT6 = 1;       //RX输入
    PBPU6 = 1;      //打开上拉
    RX1LEN = 0;     //8位数据接收格式
    TX1LEN = 0;     //8位数据发送格式
    BRGH1 = 0;      //波特率低速模式：波特率=Fosc/(64*(BRR<7:0>+1))
    BR1R = 0x19;    //波特率=16MHz/(64*(25+1))≈9600bps

#ifdef IT_SR 
    RX1IE = 1;       //接收中断
    GIE = 1;        //打开总中断
#endif
    RX1EN = 1;       //打开接收
    TX1EN = 1;       //打开发送
}

typedef struct
{
    uint32_t  offsetAddr;
    uint32_t  *startReadIndex;
    uint32_t  *nextWriteIndex;
    uint32_t  *cnts;
    uint16_t  logSaveMax;
    uint16_t  pageSaveMax;
    uint8_t  logByteLength;
}logPara_t;

logPara_t logPara;

/**********************************************
函数名：void main(void)
描  述：主函数
输入值：无
输出值：无
返回值：无
**********************************************/
static char buf1[]="Please input time.\nFor example: 2023-01-01 00:00:00\n";

unsigned char rxbuf;
unsigned char rxflag=0;
unsigned char rx_hour=0;
unsigned char rx_min=0;
unsigned char rx_sec=0;
unsigned char updateflag=0;

void main(void)
{
    //RAMclear();
    GPIOInit();

	uart_init();
	ds1302_init();
	uart_puts(buf1);

	while(!updateflag);  //等待第一次接收到输入的时间

	while(1)
	{
		if(updateflag)
		{
			t_time.year = (time_input[2] - 0x30) * 10 + (time_input[3] - 0x30);
			t_time.month = (time_input[5] - 0x30) * 10 + (time_input[6] - 0x30);
			t_time.day = (time_input[8] - 0x30) * 10 + (time_input[9] - 0x30);
			t_time.hour = (time_input[11] - 0x30) * 10 + (time_input[12] - 0x30);
			t_time.minute = (time_input[14] - 0x30) * 10 + (time_input[15] - 0x30);
			t_time.second = (time_input[17] - 0x30) * 10 + (time_input[18] - 0x30);
			ds1302_write_time();
			updateflag = 0;
		}

		ds1302_read_time();

		tm.tm_sec = t_time.second;
		tm.tm_min = t_time.minute;
		tm.tm_hour = t_time.hour;
		tm.tm_mday = t_time.day;
		tm.tm_mon = t_time.month - 1;
		tm.tm_year = t_time.year + 2000 - 1900;

		uart_puts_time();
		
        Delay5Ms(1000);
	}
}

/**********************************************
函数名：void isr(void) interrupt
描  述：中断服务程序
输入值：无
输出值：无
返回值：无
**********************************************/
uint8_t g_recv_i = 0;
void isr(void) interrupt
{
    if(RX1IE==1 && RX1IF==1)
	{
		time_input[g_recv_i++] = RX1B;

		if(g_recv_i >= 19)
		{
		    g_recv_i = 0;
			updateflag = 1;
		}
	}
}
