1 | /*------------------------------------------------------------
|
2 | ATtiny402
|
3 |
|
4 | +3V --- VDD 1|‾‾‾‾‾‾‾|8 GND
|
5 | PA6 2| |7 PA3 --- LED
|
6 | PA7 3| |6 UPDI
|
7 | piezo buzzer --- PA1 4|_______|5 PA2 --- piezo buzzer
|
8 |
|
9 | ---------------------------------------------------------------*/
|
10 |
|
11 | #include <avr/io.h>
|
12 | #include <avr/interrupt.h>
|
13 | #include <avr/sleep.h>
|
14 |
|
15 | volatile uint8_t pit; // SW PIT interrupt flag
|
16 | uint8_t count; // SW counter
|
17 | uint8_t cmpv = 180; // TCA CMP Value
|
18 |
|
19 | ISR(RTC_CNT_vect)
|
20 | {
|
21 | RTC.PITINTCTRL = RTC_PI_bm; // enable PIT interrupt
|
22 | RTC.INTFLAGS = RTC_OVF_bm; // clear RTC OVF interrupt flag
|
23 | }
|
24 |
|
25 | ISR(RTC_PIT_vect)
|
26 | {
|
27 | pit = 1; // set SW PIT interrupt flag
|
28 | RTC.PITINTFLAGS = RTC_PI_bm; // clear PIT interrupt flag
|
29 | }
|
30 |
|
31 | int main(void)
|
32 | {
|
33 | PORTA.PIN1CTRL = PORT_ISC_INPUT_DISABLE_gc; // disable digital input buffer
|
34 | PORTA.PIN2CTRL = PORT_ISC_INPUT_DISABLE_gc; // disable digital input buffer
|
35 | PORTA.PIN3CTRL = PORT_ISC_INPUT_DISABLE_gc; // disable digital input buffer
|
36 | PORTA.PIN6CTRL = PORT_ISC_INPUT_DISABLE_gc; // disable digital input buffer
|
37 | PORTA.PIN7CTRL = PORT_ISC_INPUT_DISABLE_gc; // disable digital input buffer
|
38 |
|
39 | PORTA.DIRSET = PIN3_bm; // PA3 output (LED)
|
40 | PORTA.DIRSET = PIN1_bm; // PA1 output (TCA WO1)
|
41 | PORTA.DIRSET = PIN2_bm; // PA2 output (TCA WO2)
|
42 | PORTA.PIN2CTRL = PORT_INVEN_bm; // invert PA2 (TCA WO2, antiphase for piezo buzzer)
|
43 |
|
44 | RTC.CLKSEL = RTC_CLKSEL_INT1K_gc; // 1024 Hz from OSCULP32K
|
45 | while (RTC.STATUS > 0) {} // wait for all register to be synchronized
|
46 | RTC.PER = 0x0E0F; // RTC period (60 min @ 1Hz)
|
47 | RTC.INTCTRL = RTC_OVF_bm; // enable RTC OVF interrupt
|
48 | RTC.CTRLA = RTC_RUNSTDBY_bm | RTC_PRESCALER_DIV1024_gc | RTC_RTCEN_bm; // Run In Standby, 1Hz clock, enable RTC
|
49 |
|
50 | TCA0.SINGLE.CTRLB = TCA_SINGLE_CMP1EN_bm | TCA_SINGLE_CMP2EN_bm | TCA_SINGLE_WGMODE_SINGLESLOPE_gc; // enable compare channel 1 and 2, single-slope PWM
|
51 | TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV2_gc | TCA_SINGLE_ENABLE_bm; // set clock source (1.666MHz), start TCA
|
52 |
|
53 | while (RTC.PITSTATUS > 0) {} // wait for RTC.PITCTRLA synchronization
|
54 | RTC.PITCTRLA = RTC_PERIOD_CYC64_gc | RTC_PITEN_bm; // 62.5ms PIT time-out period, enable PIT
|
55 | RTC.PITINTCTRL = RTC_PI_bm; // enable PIT interrupt
|
56 |
|
57 | SLPCTRL.CTRLA = SLPCTRL_SMODE_STDBY_gc; // select STANDBY sleep mode
|
58 | sei(); // enable interrupts
|
59 |
|
60 | while(1)
|
61 | {
|
62 | PORTA.OUTSET = PIN3_bm; // PA3 on (LED on)
|
63 | if(pit) // if PIT interrupt occurred
|
64 | {
|
65 | pit = 0; // clear SW PIT interrupt flag
|
66 | TCA0.SINGLE.PERBUF = (cmpv << 2) - 1; // set period
|
67 | TCA0.SINGLE.CMP1BUF = cmpv; // set compare match
|
68 | TCA0.SINGLE.CMP2BUF = cmpv; // set compare match
|
69 | cmpv = cmpv == 180 ? 190 : 180; // toggle between 180 and 190
|
70 | count++;
|
71 | if(count == 16)
|
72 | {
|
73 | count = 0; // clear SW counter
|
74 | RTC.PITINTCTRL = 0; // disable PIT interrupt
|
75 | PORTA.OUTCLR = PIN3_bm; // PA3 off (LED off)
|
76 | sleep_mode();
|
77 | }
|
78 | }
|
79 | }
|
80 | }
|