00001
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include <avr32/io.h>
00049 #include "compiler.h"
00050 #include "board.h"
00051 #include "wdt4.h"
00052
00060 static void wdt_set_ctrl(unsigned long ctrl)
00061 {
00062 AVR32_WDT.ctrl = ctrl | (AVR32_WDT_KEY_VALUE << AVR32_WDT_CTRL_KEY_OFFSET);
00063 AVR32_WDT.ctrl = ctrl | ((unsigned long) (~AVR32_WDT_KEY_VALUE << AVR32_WDT_CTRL_KEY_OFFSET) & AVR32_WDT_CTRL_KEY_MASK);
00064 }
00065
00066
00067 long long wdt_get_us_timeout_period(wdt_opt_t *opt)
00068 {
00069
00070 if (opt->cssel == WDT_CLOCK_SOURCE_SELECT_RCSYS)
00071 {
00072
00073 return (AVR32_WDT.ctrl & AVR32_WDT_CTRL_EN_MASK) ?
00074 ((1ULL << (((AVR32_WDT.ctrl & AVR32_WDT_CTRL_PSEL_MASK) >> AVR32_WDT_CTRL_PSEL_OFFSET) + 1)) *
00075 1000000 + AVR32_SCIF_RCOSC_FREQUENCY / 2) / AVR32_SCIF_RCOSC_FREQUENCY :
00076 -1ULL;
00077 }
00078 else
00079 {
00080
00081 return (AVR32_WDT.ctrl & AVR32_WDT_CTRL_EN_MASK) ?
00082 ((1ULL << (((AVR32_WDT.ctrl & AVR32_WDT_CTRL_PSEL_MASK) >> AVR32_WDT_CTRL_PSEL_OFFSET) + 1)) *
00083 1000000 + AVR32_SCIF_OSC32_FREQUENCY / 2) / AVR32_SCIF_OSC32_FREQUENCY :
00084 -1ULL;
00085 }
00086 }
00087
00088 long long wdt_get_us_timeban_period(wdt_opt_t *opt)
00089 {
00090
00091 if (opt->cssel == WDT_CLOCK_SOURCE_SELECT_RCSYS)
00092 {
00093
00094 return (AVR32_WDT.ctrl & AVR32_WDT_CTRL_EN_MASK) ?
00095 ((1ULL << (((AVR32_WDT.ctrl & AVR32_WDT_CTRL_TBAN_MASK) >> AVR32_WDT_CTRL_TBAN_OFFSET) + 1)) *
00096 1000000 + AVR32_SCIF_RCOSC_FREQUENCY / 2) / AVR32_SCIF_RCOSC_FREQUENCY :
00097 -1ULL;
00098 }
00099 else
00100 {
00101
00102 return (AVR32_WDT.ctrl & AVR32_WDT_CTRL_EN_MASK) ?
00103 ((1ULL << (((AVR32_WDT.ctrl & AVR32_WDT_CTRL_TBAN_MASK) >> AVR32_WDT_CTRL_TBAN_OFFSET) + 1)) *
00104 1000000 + AVR32_SCIF_OSC32_FREQUENCY / 2) / AVR32_SCIF_OSC32_FREQUENCY :
00105 -1ULL;
00106 }
00107 }
00108
00109
00110
00111 void wdt_disable(void)
00112 {
00113 wdt_set_ctrl(AVR32_WDT.ctrl & ~AVR32_WDT_CTRL_EN_MASK);
00114 }
00115
00116
00117 unsigned long long wdt_enable(wdt_opt_t *opt)
00118 {
00119
00120 #define MIN_US_TIMEOUT_PERIOD_RCSYS (((1ULL << 1 ) * 1000000 + AVR32_SCIF_RCOSC_FREQUENCY / 2) / AVR32_SCIF_RCOSC_FREQUENCY)
00121 #define MAX_US_TIMEOUT_PERIOD_RCSYS (((1ULL << (1 << AVR32_WDT_CTRL_PSEL_SIZE)) * 1000000 + AVR32_SCIF_RCOSC_FREQUENCY / 2) / AVR32_SCIF_RCOSC_FREQUENCY)
00122 #define MIN_US_TIMEOUT_PERIOD_OSC32K (((1ULL << 1 ) * 1000000 + AVR32_SCIF_OSC32_FREQUENCY / 2) / AVR32_SCIF_OSC32_FREQUENCY)
00123 #define MAX_US_TIMEOUT_PERIOD_OSC32K (((1ULL << (1 << AVR32_WDT_CTRL_PSEL_SIZE)) * 1000000 + AVR32_SCIF_OSC32_FREQUENCY / 2) / AVR32_SCIF_OSC32_FREQUENCY)
00124
00125 #define MIN_US_TIMEBAN_PERIOD_RCSYS (((1ULL << 1 ) * 1000000 + AVR32_SCIF_RCOSC_FREQUENCY / 2) / AVR32_SCIF_RCOSC_FREQUENCY)
00126 #define MAX_US_TIMEBAN_PERIOD_RCSYS (((1ULL << (1 << AVR32_WDT_CTRL_TBAN_SIZE)) * 1000000 + AVR32_SCIF_RCOSC_FREQUENCY / 2) / AVR32_SCIF_RCOSC_FREQUENCY)
00127 #define MIN_US_TIMEBAN_PERIOD_OSC32K (((1ULL << 1 ) * 1000000 + AVR32_SCIF_OSC32_FREQUENCY / 2) / AVR32_SCIF_OSC32_FREQUENCY)
00128 #define MAX_US_TIMEBAN_PERIOD_OSC32K (((1ULL << (1 << AVR32_WDT_CTRL_TBAN_SIZE)) * 1000000 + AVR32_SCIF_OSC32_FREQUENCY / 2) / AVR32_SCIF_OSC32_FREQUENCY)
00129
00130
00131
00132 if (opt->cssel == WDT_CLOCK_SOURCE_SELECT_RCSYS)
00133 {
00134
00135
00136
00137 wdt_set_ctrl(AVR32_WDT_CTRL_EN_MASK | AVR32_WDT_CTRL_CEN_MASK |
00138 (opt->dar << AVR32_WDT_CTRL_DAR_OFFSET) |
00139 (opt->mode << AVR32_WDT_CTRL_MODE_OFFSET) |
00140 (opt->sfv << AVR32_WDT_CTRL_SFV_OFFSET) |
00141 (opt->fcd << AVR32_WDT_CTRL_FCD_OFFSET) |
00142 (opt->cssel << AVR32_WDT_CTRL_CSSEL_OFFSET) |
00143 ((32 - clz(((((Min(Max(opt->us_timeout_period, MIN_US_TIMEOUT_PERIOD_RCSYS), MAX_US_TIMEOUT_PERIOD_RCSYS) *
00144 AVR32_SCIF_RCOSC_FREQUENCY + 500000) / 1000000) << 1) - 1) >> 1) - 1) <<
00145 AVR32_WDT_CTRL_PSEL_OFFSET) |
00146 ((32 - clz(((((Min(Max(opt->us_timeban_period, MIN_US_TIMEBAN_PERIOD_RCSYS), MAX_US_TIMEBAN_PERIOD_RCSYS) *
00147 AVR32_SCIF_RCOSC_FREQUENCY + 500000) / 1000000) << 1) - 1) >> 1) - 1) <<
00148 AVR32_WDT_CTRL_TBAN_OFFSET));
00149 }
00150 else
00151 {
00152
00153
00154
00155 wdt_set_ctrl(AVR32_WDT_CTRL_EN_MASK | AVR32_WDT_CTRL_CEN_MASK |
00156 (opt->dar << AVR32_WDT_CTRL_DAR_OFFSET) |
00157 (opt->mode << AVR32_WDT_CTRL_MODE_OFFSET) |
00158 (opt->sfv << AVR32_WDT_CTRL_SFV_OFFSET) |
00159 (opt->fcd << AVR32_WDT_CTRL_FCD_OFFSET) |
00160 (opt->cssel << AVR32_WDT_CTRL_CSSEL_OFFSET) |
00161 ((32 - clz(((((Min(Max(opt->us_timeout_period, MIN_US_TIMEOUT_PERIOD_OSC32K), MAX_US_TIMEOUT_PERIOD_OSC32K) *
00162 AVR32_SCIF_OSC32_FREQUENCY + 500000) / 1000000) << 1) - 1) >> 1) - 1) <<
00163 AVR32_WDT_CTRL_PSEL_OFFSET) |
00164 ((32 - clz(((((Min(Max(opt->us_timeout_period, MIN_US_TIMEBAN_PERIOD_OSC32K), MAX_US_TIMEBAN_PERIOD_OSC32K) *
00165 AVR32_SCIF_OSC32_FREQUENCY + 500000) / 1000000) << 1) - 1) >> 1) - 1) <<
00166 AVR32_WDT_CTRL_TBAN_OFFSET));
00167 }
00168
00169 return wdt_get_us_timeout_period(opt);
00170 }
00171
00172
00173 void wdt_reenable(void)
00174 {
00175 wdt_set_ctrl(AVR32_WDT.ctrl | AVR32_WDT_CTRL_EN_MASK | AVR32_WDT_CTRL_CEN_MASK );
00176 }
00177
00178
00179 void wdt_clear(void)
00180 {
00181 AVR32_WDT.clr = 0;
00182 }
00183
00184
00185 void wdt_reset_mcu(void)
00186 {
00187 Disable_global_interrupt();
00188
00189 wdt_enable(0);
00190 while (1);
00191 }