aboutsummaryrefslogtreecommitdiff
path: root/src/mcu/peripheral/rtl876x_aon_wdg.c
blob: 04c3c83e302ea5fbfa8026a9771bcafeb3959d7b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/**
***************************************************************************************************
*        Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
***************************************************************************************************
* @file     rtl876x_aon_wdg.c
* @brief    This file provides all the AON Watch Dog firmware functions.
* @details
* @author   Serval Li
* @date     2017-06-27
* @version  v0.1
***************************************************************************************************
*/

#include "rtl876x.h"
#include "rtl876x_aon_wdg.h"


#define REG_RTC_FAST_WRITE_BASE_ADDR    (0x40000100UL)
#define REG_RTC_FAST_WDATA              (0x400001f0UL)
#define REG_RTC_FAST_ADDR               (0x400001f4UL)
#define REG_RTC_WR_STROBE               (0x400001f8UL)

/* Enable Write to CRT register */
#define AON_WDG_EnableWriteCRT() AON_WDG_WriteReg((uint32_t)&AON_WDG->WP - SYSTEM_REG_BASE, AON_WDG->WP | BIT0)

/* Disable Write to CRT register */
#define AON_WDG_DisableWriteCRT() AON_WDG_WriteReg((uint32_t)&AON_WDG->WP - SYSTEM_REG_BASE, AON_WDG->WP & ~BIT0);

/**
  * @brief  Fast write RTC register.
  * @param  offset: the offset of RTC register.
  * @param  data: data which write to register.
  * @retval None
  */
static void AON_WDG_WriteReg(uint32_t offset, uint32_t data)
{
    static bool is_called = false;

    if (is_called == false)
    {
        *((volatile uint32_t *)0x40000014) |= BIT(9);//no need run this every time
        is_called = true;
    }

    /* Write data */
    *((volatile uint32_t *)REG_RTC_FAST_WDATA) = data;
    /* Write RTC register address. Only offset */
    *((volatile uint32_t *)REG_RTC_FAST_ADDR) = offset - REG_RTC_FAST_WRITE_BASE_ADDR;
    *((volatile uint32_t *)REG_RTC_WR_STROBE) = 1;
}

void AON_WDG_Config(uint8_t reset_level, uint32_t comp, uint8_t cnt_ctl, uint8_t cnt_reload)
{
    AON_WDG_TypeDef aon_wdg;

    aon_wdg.u.CRT = AON_WDG->u.CRT;

    aon_wdg.u.CRT_BITS.RST_LVL = reset_level;
    aon_wdg.u.CRT_BITS.COMP = comp;
    aon_wdg.u.CRT_BITS.CNT_CTL = cnt_ctl;
    aon_wdg.u.CRT_BITS.CNT_RELOAD = cnt_reload;

    AON_WDG_EnableWriteCRT();
    AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
    AON_WDG_DisableWriteCRT();
}

void AON_WDG_ConfigResetLevel(uint8_t reset_level)
{
    AON_WDG_TypeDef aon_wdg;

    aon_wdg.u.CRT = AON_WDG->u.CRT;
    aon_wdg.u.CRT_BITS.RST_LVL = reset_level;

    AON_WDG_EnableWriteCRT();
    AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
    AON_WDG_DisableWriteCRT();
}

void AON_WDG_ConfigComp(uint32_t comp)
{
    AON_WDG_TypeDef aon_wdg;

    aon_wdg.u.CRT = AON_WDG->u.CRT;
    aon_wdg.u.CRT_BITS.COMP = comp;

    AON_WDG_EnableWriteCRT();
    AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
    AON_WDG_DisableWriteCRT();
}

void AON_WDG_ConfigCntCtl(uint8_t cnt_ctl)
{
    AON_WDG_TypeDef aon_wdg;

    aon_wdg.u.CRT = AON_WDG->u.CRT;
    aon_wdg.u.CRT_BITS.CNT_CTL = cnt_ctl;

    AON_WDG_EnableWriteCRT();
    AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
    AON_WDG_DisableWriteCRT();
}

void AON_WDG_ConfigCntReload(uint8_t cnt_reload)
{
    AON_WDG_TypeDef aon_wdg;

    aon_wdg.u.CRT = AON_WDG->u.CRT;
    aon_wdg.u.CRT_BITS.CNT_RELOAD = cnt_reload;

    AON_WDG_EnableWriteCRT();
    AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
    AON_WDG_DisableWriteCRT();
}

void AON_WDG_Enable(void)
{
    AON_WDG_TypeDef aon_wdg;

    aon_wdg.u.CRT = AON_WDG->u.CRT;
    aon_wdg.u.CRT_BITS.EN = 1;

    AON_WDG_EnableWriteCRT();
    AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
    AON_WDG_DisableWriteCRT();
}

void AON_WDG_Disable(void)
{
    AON_WDG_TypeDef aon_wdg;

    aon_wdg.u.CRT = AON_WDG->u.CRT;
    aon_wdg.u.CRT_BITS.EN = 2;

    AON_WDG_EnableWriteCRT();
    AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT);
    AON_WDG_DisableWriteCRT();
}

void AON_WDG_Restart(void)
{
    AON_WDG_WriteReg((uint32_t)&AON_WDG->CNT_CLR, 1);
    AON_WDG_WriteReg((uint32_t)&AON_WDG->CNT_CLR, 0);
}

void AON_WDG_SystemReset(void)
{
    AON_WDG_Config(1, 1, 1, 0);
    AON_WDG_Enable();

    while (1); /* wait until reset */
}