Skip to content

Commit

Permalink
Update to WDT library (#299)
Browse files Browse the repository at this point in the history
* Update to WDT library

Adds the capability of using the HFRC oscillator for WDT.

* Update keywords.txt

Lgtwdt keyword added

* Update wdt_interrupt_HF.ino

Line contain "LGTWDT Lgtwdt;" deleted because it is integrated to file WDT.h

* Update WDT.h

Defining name Lgtwdt form class LGTWDT integrated to WHT.h
Users do not need to write it into their own program.

* Update keywords.txt

---------

Co-authored-by: LaZsolt <[email protected]>
  • Loading branch information
gpb01 and LaZsolt authored Sep 12, 2023
1 parent 92df537 commit 6a56938
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 79 deletions.
184 changes: 106 additions & 78 deletions lgt8f/libraries/WDT/WDT.h
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -14,98 +14,126 @@
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St,Fifth Floor,Boston, MA 02110-1301 USA *
* *
* Updated on August 2023 by gpb01 to add the capability to use the *
* internal HFRC oscillator for the WTD. Default is the standard LFRC. *
**************************************************************************/

#ifndef WDT_h
#define WDT_h

#include <avr/wdt.h>
#include "Arduino.h"
#include <avr/wdt.h>

#define WTOH_32MHZ 0
#define WTO_32KHZ 1

#define WTO_64MS 0
#define WTO_128MS 1
#define WTO_256MS 2
#define WTO_512MS 3
#define WTO_1S 4
#define WTO_2S 5
#define WTO_4S 6
#define WTO_8S 7
#define WTO_16S 8
#define WTO_32S 9

class LGTWDT
{
public:
// enable 32kRC for WDT
static void begin() __attribute__((always_inline)) {
uint8_t btmp = PMCR | 0x10;
PMCR = 0x80;
PMCR = btmp;
}
#define WTOH_1MS 0
#define WTOH_2MS 1
#define WTOH_4MS 2
#define WTOH_8MS 3
#define WTOH_16MS 4
#define WTOH_32MS 5
#define WTOH_64MS 6
#define WTOH_128MS 7
#define WTOH_256MS 8
#define WTOH_512MS 9

#define WTO_64MS 0
#define WTO_128MS 1
#define WTO_256MS 2
#define WTO_512MS 3
#define WTO_1S 4
#define WTO_2S 5
#define WTO_4S 6
#define WTO_8S 7
#define WTO_16S 8
#define WTO_32S 9

class LGTWDT {
public:
static void begin(uint8_t clockSource = WTO_32KHZ)
__attribute__((always_inline)) {
uint8_t btmp = 0;

if (clockSource == WTOH_32MHZ) {
// enable 32MHz RC for WDT
btmp = PMCR | (1 << RCMEN); // 0000 0001 (enable RCMEN)
btmp = btmp & ~(1 << WCLKS); // 1110 1111 (select HFRC)
PMCR = (1 << PMCE); // 1000 0000
PMCR = btmp;
} else {
// enable 32KHz RC for WDT
btmp = PMCR | (1 << RCKEN); // 0000 0010 (enable RCKEN)
btmp = btmp | (1 << WCLKS); // 0001 0000 (select LFRC)
PMCR = (1 << PMCE); // 1000 0000
PMCR = btmp;
}
}
};

static void __inline__ __attribute__ ((__always_inline__)) wdt_ienable(const uint8_t value)
{
__asm__ __volatile__ (
"in __tmp_reg__,__SREG__ \n\t"
"cli \n\t"
"wdr \n\t"
"sts %[wdtcsr], %[wdce_wde] \n\t"
"out __SREG__,__tmp_reg__ \n\t"
"sts %[wdtcsr], %[wdie_val] \n\t"
: /* no outputs */
: [wdtcsr] "n" (_SFR_MEM_ADDR(WDTCSR)),
[wdce_wde] "r" ((uint8_t)((1 << WDCE) | (1 << WDE))),
[wdie_val] "r" ((uint8_t) ((1 << WDIE) | (value & 0x08 ? 0x20 : 0x00) | (value & 0x07)))
: "r0"
); }

volatile uint8_t o_sreg __attribute__ ((section (".noinit")));
volatile uint8_t s_tempreg __attribute__ ((section (".noinit")));

void softRepairedWdtIsr(void) __attribute__ ((naked)) __attribute__ ((used)) __attribute__ ((section (".init0")));
void softRepairedWdtIsr(void)
{
__asm__ __volatile__ (
"sts (s_tempreg), r24\n\t" // s_tempreg = uint8_t register temp_reg; Save a register
"in r24, __SREG__ \n\t" // o_sreg = SREG;
"sts (o_sreg) , r24 \n\t"
"lds r24, %[wdtcsr] \n\t" // temp_reg = WDTCSR;
static void __inline__ __attribute__((__always_inline__))
wdt_ienable(const uint8_t value) {
__asm__ __volatile__(
"in __tmp_reg__,__SREG__ \n\t"
"cli \n\t"
"wdr \n\t"
"sts %[wdtcsr], %[wdce_wde] \n\t"
"out __SREG__,__tmp_reg__ \n\t"
"sts %[wdtcsr], %[wdie_val] \n\t"
: /* no outputs */
: [wdtcsr] "n"(_SFR_MEM_ADDR(WDTCSR)),
[wdce_wde] "r"((uint8_t)((1 << WDCE) | (1 << WDE))),
[wdie_val] "r"((uint8_t)((1 << WDIE) | (value & 0x08 ? 0x20 : 0x00) |
(value & 0x07)))
: "r0");
}

volatile uint8_t o_sreg __attribute__((section(".noinit")));
volatile uint8_t s_tempreg __attribute__((section(".noinit")));

void softRepairedWdtIsr(void) __attribute__((naked)) __attribute__((used))
__attribute__((section(".init0")));
void softRepairedWdtIsr(void) {
__asm__ __volatile__(
"sts (s_tempreg), r24\n\t" // s_tempreg = uint8_t register temp_reg;
// Save a register
"in r24, __SREG__ \n\t" // o_sreg = SREG;
"sts (o_sreg) , r24 \n\t"
"lds r24, %[wdtcsr] \n\t" // temp_reg = WDTCSR;
#if defined(__LGT8FX8P__)
"sbrs r24, %[wdif] \n\t" // if (temp_reg & (1 << WDIF))
"sbrs r24, %[wdif] \n\t" // if (temp_reg & (1 << WDIF))
#else
"sbrs r24, %[wdie] \n\t" // if (temp_reg & (1 << WDIE))
"sbrs r24, %[wdie] \n\t" // if (temp_reg & (1 << WDIE))
#endif
"rjmp 1f \n\t"
// WDT interrupt
"andi r24, %[nwdie] \n\t" // WDTCSR = temp_reg & ~(1 << WDIE);
"sts %[wdtcsr] , r24 \n\t"
"lds r24, (o_sreg) \n\t" // SREG = o_sreg;
"out __SREG__ , r24 \n\t"
"lds r24, (s_tempreg)\n\t" // temp_reg = s_tempreg;
"jmp __vector_6 \n\t"
"1: \n\t"

: /* No outputs */
: [wdtcsr] "n" (_SFR_MEM_ADDR(WDTCSR)),
[wdif] "i" (WDIF),
[wdie] "i" (WDIE),
[nwdie] "i" (~(1 << WDIE))
);

/*
o_sreg = SREG;
uint8_t temp_reg = WDTCSR;
if (temp_reg & (1 << WDIF)) {
"rjmp 1f \n\t"
// WDT interrupt
WDTCSR = temp_reg & ~(1 << WDIE);
SREG = o_sreg;
__asm__ __volatile__ ("jmp __vector_6 \n");
}
*/
"andi r24, %[nwdie] \n\t" // WDTCSR = temp_reg & ~(1 << WDIE);
"sts %[wdtcsr] , r24 \n\t"
"lds r24, (o_sreg) \n\t" // SREG = o_sreg;
"out __SREG__ , r24 \n\t"
"lds r24, (s_tempreg)\n\t" // temp_reg = s_tempreg;
"jmp __vector_6 \n\t"
"1: \n\t"

: /* No outputs */
: [wdtcsr] "n"(_SFR_MEM_ADDR(WDTCSR)), [wdif] "i"(WDIF), [wdie] "i"(WDIE),
[nwdie] "i"(~(1 << WDIE)) );

/*
o_sreg = SREG;
uint8_t temp_reg = WDTCSR;
if (temp_reg & (1 << WDIF)) {
// WDT interrupt
WDTCSR = temp_reg & ~(1 << WDIE);
SREG = o_sreg;
__asm__ __volatile__ ("jmp __vector_6 \n");
}
*/
}

extern LGTWDT Lgtwdt;

#endif
54 changes: 54 additions & 0 deletions lgt8f/libraries/WDT/examples/wdt_interrupt_HF/wdt_interrupt_HF.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/********************************************************
* This example shows how the watchdog interrupt works. *
* About every 512ms there will be a wdt interrupt. *
* If you uncomment the line containing wdt_reset() the *
* sketch will not detect wdt interrupt signal. *
* *
* Updated on August 2023 by gpb01 to user the HFRC *
* clock on WDT. *
********************************************************
* When writing an Interrupt Service Routine (ISR): *
* Keep short,don't use delay(), don't do serial prints *
* Make variables shared with the main code volatile *
* Read this: https://gammon.com.au/interrupts *
********************************************************/
#include <WDT.h>

volatile boolean isrflag;

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(19200);
Serial.println(F("Skech started."));
isrflag = false;

Lgtwdt.begin(WTOH_32MHZ); // Select HFRC oscillator for WDT

wdt_ienable(WTOH_512MS);
}

void loop() {
int n = 0;
do {
Serial.print(F(" Elapsed step: "));
Serial.println(n);
delay(128);
if (digitalRead(LED_BUILTIN))
digitalWrite(LED_BUILTIN, LOW );
else
digitalWrite(LED_BUILTIN, HIGH);
if (isrflag) {
Serial.println(F("--There was a wdt interrupt.--"));
isrflag = false;
wdt_ienable(WTOH_512MS);
}
//wdt_reset();
} while( n++ < 1000 );
}

ISR (WDT_vect)
{
isrflag = true;
wdt_reset();
}
18 changes: 17 additions & 1 deletion lgt8f/libraries/WDT/keywords.txt
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@
#######################################
# Datatypes (KEYWORD1)
#######################################

WTOH_32MHZ KEYWORD1
WTO_32KHZ KEYWORD1

WTOH_1MS KEYWORD1
WTOH_2MS KEYWORD1
WTOH_4MS KEYWORD1
WTOH_8MS KEYWORD1
WTOH_16MS KEYWORD1
WTOH_32MS KEYWORD1
WTOH_64MS KEYWORD1
WTOH_128MS KEYWORD1
WTOH_256MS KEYWORD1
WTOH_512MS KEYWORD1

WTO_64MS KEYWORD1
WTO_128MS KEYWORD1
WTO_256MS KEYWORD1
Expand All @@ -19,6 +34,8 @@ WTO_32S KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################

Lgtwdt KEYWORD2
wdt_reset KEYWORD2
wdt_enable KEYWORD2
wdt_ienable KEYWORD2
Expand All @@ -27,4 +44,3 @@ wdt_disable KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

0 comments on commit 6a56938

Please sign in to comment.