Keyboard firmwares for Atmel AVR and Cortex-M
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wd.h 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /* This is from http://www.mtcnet.net/~henryvm/wdt/ */
  2. #ifndef _AVR_WD_H_
  3. #define _AVR_WD_H_
  4. #include <avr/io.h>
  5. /*
  6. Copyright (c) 2009, Curt Van Maanen
  7. Permission to use, copy, modify, and/or distribute this software for any
  8. purpose with or without fee is hereby granted, provided that the above
  9. copyright notice and this permission notice appear in all copies.
  10. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. include usage-
  18. #include "wd.h" //if in same directory as project
  19. #include <avr/wd.h> //if wd.h is in avr directory
  20. set watchdog modes and prescale
  21. usage-
  22. WD_SET(mode,[timeout]); //prescale always set
  23. modes-
  24. WD_OFF disabled
  25. WD_RST normal reset mode
  26. WD_IRQ interrupt only mode (if supported)
  27. WD_RST_IRQ interrupt+reset mode (if supported)
  28. timeout-
  29. WDTO_15MS default if no timeout provided
  30. WDTO_30MS
  31. WDTO_60MS
  32. WDTO_120MS
  33. WDTO_250MS
  34. WDTO_500MS
  35. WDTO_1S
  36. WDTO_2S
  37. WDTO_4S (if supported)
  38. WDTO_8S (if supported)
  39. examples-
  40. WD_SET(WD_RST,WDTO_1S); //reset mode, 1s timeout
  41. WD_SET(WD_OFF); //watchdog disabled (if not fused on)
  42. WD_SET(WD_RST); //reset mode, 15ms (default timeout)
  43. WD_SET(WD_IRQ,WDTO_120MS); //interrupt only mode, 120ms timeout
  44. WD_SET(WD_RST_IRQ,WDTO_2S); //interrupt+reset mode, 2S timeout
  45. for enhanced watchdogs, if the watchdog is not being used WDRF should be
  46. cleared on every power up or reset, along with disabling the watchdog-
  47. WD_DISABLE(); //clear WDRF, then turn off watchdog
  48. */
  49. //reset registers to the same name (MCUCSR)
  50. #if !defined(MCUCSR)
  51. #define MCUCSR MCUSR
  52. #endif
  53. //watchdog registers to the same name (WDTCSR)
  54. #if !defined(WDTCSR)
  55. #define WDTCSR WDTCR
  56. #endif
  57. //if enhanced watchdog, define irq values, create disable macro
  58. #if defined(WDIF)
  59. #define WD_IRQ 0xC0
  60. #define WD_RST_IRQ 0xC8
  61. #define WD_DISABLE() do{ \
  62. MCUCSR &= ~(1<<WDRF); \
  63. WD_SET(WD_OFF); \
  64. }while(0)
  65. #endif
  66. //all watchdogs
  67. #define WD_RST 8
  68. #define WD_OFF 0
  69. //prescale values
  70. #define WDTO_15MS 0
  71. #define WDTO_30MS 1
  72. #define WDTO_60MS 2
  73. #define WDTO_120MS 3
  74. #define WDTO_250MS 4
  75. #define WDTO_500MS 5
  76. #define WDTO_1S 6
  77. #define WDTO_2S 7
  78. //prescale values for avrs with WDP3
  79. #if defined(WDP3)
  80. #define WDTO_4S 0x20
  81. #define WDTO_8S 0x21
  82. #endif
  83. //watchdog reset
  84. #define WDR() __asm__ __volatile__("wdr")
  85. //avr reset using watchdog
  86. #define WD_AVR_RESET() do{ \
  87. __asm__ __volatile__("cli"); \
  88. WD_SET_UNSAFE(WD_RST); \
  89. while(1); \
  90. }while(0)
  91. /*set the watchdog-
  92. 1. save SREG
  93. 2. turn off irq's
  94. 3. reset watchdog timer
  95. 4. enable watchdog change
  96. 5. write watchdog value
  97. 6. restore SREG (restoring irq status)
  98. */
  99. #define WD_SET(val,...) \
  100. __asm__ __volatile__( \
  101. "in __tmp_reg__,__SREG__" "\n\t" \
  102. "cli" "\n\t" \
  103. "wdr" "\n\t" \
  104. "sts %[wdreg],%[wden]" "\n\t" \
  105. "sts %[wdreg],%[wdval]" "\n\t" \
  106. "out __SREG__,__tmp_reg__" "\n\t" \
  107. : \
  108. : [wdreg] "M" (&WDTCSR), \
  109. [wden] "r" ((uint8_t)(0x18)), \
  110. [wdval] "r" ((uint8_t)(val|(__VA_ARGS__+0))) \
  111. : "r0" \
  112. )
  113. /*set the watchdog when I bit in SREG known to be clear-
  114. 1. reset watchdog timer
  115. 2. enable watchdog change
  116. 5. write watchdog value
  117. */
  118. #define WD_SET_UNSAFE(val,...) \
  119. __asm__ __volatile__( \
  120. "wdr" "\n\t" \
  121. "sts %[wdreg],%[wden]" "\n\t" \
  122. "sts %[wdreg],%[wdval]" "\n\t" \
  123. : \
  124. : [wdreg] "M" (&WDTCSR), \
  125. [wden] "r" ((uint8_t)(0x18)), \
  126. [wdval] "r" ((uint8_t)(val|(__VA_ARGS__+0))) \
  127. )
  128. //for compatibility with avr/wdt.h
  129. #define wdt_enable(val) WD_SET(WD_RST,val)
  130. #define wdt_disable() WD_SET(WD_OFF)
  131. #endif /* _AVR_WD_H_ */