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 long long wdt_get_us_timeout_period(wdt_opt_t *opt)
00067 {
00068
00069 if (opt->cssel == WDT_CLOCK_SOURCE_SELECT_RCSYS)
00070 {
00071
00072 return (AVR32_WDT.ctrl & AVR32_WDT_CTRL_EN_MASK) ?
00073 ((1ULL << (((AVR32_WDT.ctrl & AVR32_WDT_CTRL_PSEL_MASK) >> AVR32_WDT_CTRL_PSEL_OFFSET) + 1)) *
00074 1000000 + AVR32_SCIF_RCOSC_FREQUENCY / 2) / AVR32_SCIF_RCOSC_FREQUENCY :
00075 -1ULL;
00076 }
00077 else
00078 {
00079
00080 return (AVR32_WDT.ctrl & AVR32_WDT_CTRL_EN_MASK) ?
00081 ((1ULL << (((AVR32_WDT.ctrl & AVR32_WDT_CTRL_PSEL_MASK) >> AVR32_WDT_CTRL_PSEL_OFFSET) + 1)) *
00082 1000000 + AVR32_SCIF_OSC32_FREQUENCY / 2) / AVR32_SCIF_OSC32_FREQUENCY :
00083 -1ULL;
00084 }
00085 }
00086
00087 long long wdt_get_us_timeban_period(wdt_opt_t *opt)
00088 {
00089
00090 if (opt->cssel == WDT_CLOCK_SOURCE_SELECT_RCSYS)
00091 {
00092
00093 return (AVR32_WDT.ctrl & AVR32_WDT_CTRL_EN_MASK) ?
00094 ((1ULL << (((AVR32_WDT.ctrl & AVR32_WDT_CTRL_TBAN_MASK) >> AVR32_WDT_CTRL_TBAN_OFFSET) + 1)) *
00095 1000000 + AVR32_SCIF_RCOSC_FREQUENCY / 2) / AVR32_SCIF_RCOSC_FREQUENCY :
00096 -1ULL;
00097 }
00098 else
00099 {
00100
00101 return (AVR32_WDT.ctrl & AVR32_WDT_CTRL_EN_MASK) ?
00102 ((1ULL << (((AVR32_WDT.ctrl & AVR32_WDT_CTRL_TBAN_MASK) >> AVR32_WDT_CTRL_TBAN_OFFSET) + 1)) *
00103 1000000 + AVR32_SCIF_OSC32_FREQUENCY / 2) / AVR32_SCIF_OSC32_FREQUENCY :
00104 -1ULL;
00105 }
00106 }
00107
00108 void wdt_disable(void)
00109 {
00110 wdt_set_ctrl(AVR32_WDT.ctrl & ~AVR32_WDT_CTRL_EN_MASK);
00111 }
00112
00113 unsigned long long wdt_enable(wdt_opt_t *opt)
00114 {
00115
00116 #define MIN_US_TIMEOUT_PERIOD_RCSYS (((1ULL << 1 ) * 1000000 + AVR32_SCIF_RCOSC_FREQUENCY / 2) / AVR32_SCIF_RCOSC_FREQUENCY)
00117 #define MAX_US_TIMEOUT_PERIOD_RCSYS (((1ULL << (1 << AVR32_WDT_CTRL_PSEL_SIZE)) * 1000000 + AVR32_SCIF_RCOSC_FREQUENCY / 2) / AVR32_SCIF_RCOSC_FREQUENCY)
00118 #define MIN_US_TIMEOUT_PERIOD_OSC32K (((1ULL << 1 ) * 1000000 + AVR32_SCIF_OSC32_FREQUENCY / 2) / AVR32_SCIF_OSC32_FREQUENCY)
00119 #define MAX_US_TIMEOUT_PERIOD_OSC32K (((1ULL << (1 << AVR32_WDT_CTRL_PSEL_SIZE)) * 1000000 + AVR32_SCIF_OSC32_FREQUENCY / 2) / AVR32_SCIF_OSC32_FREQUENCY)
00120
00121 #define MIN_US_TIMEBAN_PERIOD_RCSYS (((1ULL << 1 ) * 1000000 + AVR32_SCIF_RCOSC_FREQUENCY / 2) / AVR32_SCIF_RCOSC_FREQUENCY)
00122 #define MAX_US_TIMEBAN_PERIOD_RCSYS (((1ULL << (1 << AVR32_WDT_CTRL_TBAN_SIZE)) * 1000000 + AVR32_SCIF_RCOSC_FREQUENCY / 2) / AVR32_SCIF_RCOSC_FREQUENCY)
00123 #define MIN_US_TIMEBAN_PERIOD_OSC32K (((1ULL << 1 ) * 1000000 + AVR32_SCIF_OSC32_FREQUENCY / 2) / AVR32_SCIF_OSC32_FREQUENCY)
00124 #define MAX_US_TIMEBAN_PERIOD_OSC32K (((1ULL << (1 << AVR32_WDT_CTRL_TBAN_SIZE)) * 1000000 + AVR32_SCIF_OSC32_FREQUENCY / 2) / AVR32_SCIF_OSC32_FREQUENCY)
00125
00126
00127
00128 if (opt->cssel == WDT_CLOCK_SOURCE_SELECT_RCSYS)
00129 {
00130
00131
00132
00133 wdt_set_ctrl(AVR32_WDT_CTRL_EN_MASK | AVR32_WDT_CTRL_CEN_MASK |
00134 (opt->dar << AVR32_WDT_CTRL_DAR_OFFSET) |
00135 (opt->mode << AVR32_WDT_CTRL_MODE_OFFSET) |
00136 (opt->sfv << AVR32_WDT_CTRL_SFV_OFFSET) |
00137 (opt->fcd << AVR32_WDT_CTRL_FCD_OFFSET) |
00138 (opt->cssel << AVR32_WDT_CTRL_CSSEL_OFFSET) |
00139 ((32 - clz(((((Min(Max(opt->us_timeout_period, MIN_US_TIMEOUT_PERIOD_RCSYS), MAX_US_TIMEOUT_PERIOD_RCSYS) *
00140 AVR32_SCIF_RCOSC_FREQUENCY + 500000) / 1000000) << 1) - 1) >> 1) - 1) <<
00141 AVR32_WDT_CTRL_PSEL_OFFSET) |
00142 ((32 - clz(((((Min(Max(opt->us_timeban_period, MIN_US_TIMEBAN_PERIOD_RCSYS), MAX_US_TIMEBAN_PERIOD_RCSYS) *
00143 AVR32_SCIF_RCOSC_FREQUENCY + 500000) / 1000000) << 1) - 1) >> 1) - 1) <<
00144 AVR32_WDT_CTRL_TBAN_OFFSET));
00145 }
00146 else
00147 {
00148
00149
00150
00151 wdt_set_ctrl(AVR32_WDT_CTRL_EN_MASK | AVR32_WDT_CTRL_CEN_MASK |
00152 (opt->dar << AVR32_WDT_CTRL_DAR_OFFSET) |
00153 (opt->mode << AVR32_WDT_CTRL_MODE_OFFSET) |
00154 (opt->sfv << AVR32_WDT_CTRL_SFV_OFFSET) |
00155 (opt->fcd << AVR32_WDT_CTRL_FCD_OFFSET) |
00156 (opt->cssel << AVR32_WDT_CTRL_CSSEL_OFFSET) |
00157 ((32 - clz(((((Min(Max(opt->us_timeout_period, MIN_US_TIMEOUT_PERIOD_OSC32K), MAX_US_TIMEOUT_PERIOD_OSC32K) *
00158 AVR32_SCIF_OSC32_FREQUENCY + 500000) / 1000000) << 1) - 1) >> 1) - 1) <<
00159 AVR32_WDT_CTRL_PSEL_OFFSET) |
00160 ((32 - clz(((((Min(Max(opt->us_timeout_period, MIN_US_TIMEBAN_PERIOD_OSC32K), MAX_US_TIMEBAN_PERIOD_OSC32K) *
00161 AVR32_SCIF_OSC32_FREQUENCY + 500000) / 1000000) << 1) - 1) >> 1) - 1) <<
00162 AVR32_WDT_CTRL_TBAN_OFFSET));
00163 }
00164
00165 return wdt_get_us_timeout_period(opt);
00166 }
00167
00168 void wdt_reenable(void)
00169 {
00170 wdt_set_ctrl(AVR32_WDT.ctrl | AVR32_WDT_CTRL_EN_MASK | AVR32_WDT_CTRL_CEN_MASK );
00171 }
00172
00173 void wdt_clear(void)
00174 {
00175 AVR32_WDT.clr = 0;
00176 }
00177
00178 void wdt_reset_mcu(void)
00179 {
00180 Disable_global_interrupt();
00181
00182 wdt_enable(0);
00183 while (1);
00184 }