Forum: Projekte & Code RTC32 mit XMEGA


von Stefan (Gast)


Lesenswert?

Hallo,

ich habe leider im Netz nur ASF Beispiele für den RTC32 aus den Xmegas 
gefunden. Ich wollte aber auf das Framework verzichten und habe mich 
selber drangesetzt.

Es wird ein externer 32kHz Quarz zwischen dem Pin TOSC1 und TOSC2 
benötigt.

Das Programm aktivier die notwendigen Komponenten und versetzt den 
Prozessor dann in den Schlafmodus. Hier verweilt er solange bis der 
RTC32 den Wert im PER-Register überspringt.

Achtung: ich habe lange gedacht, dass ich den RTC32 falsch konfiguriert 
hätte und er überhaupt nicht zählt! Das Atmel Studio zeigt nur den 
richtigen CNT-Wert an, wenn das CNT-Register vorher synchronisiert 
worden ist - hängt mit den Clock-Domänen zusammen.

Getestet habe ich das ganze mit einem ATxmega256A3BU, sollte aber 
natürlich mit jedem anderen Xmega laufen der einen RTC32 besitzt.
1
#include <avr/io.h>
2
#include <util/atomic.h>
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5
#include "avr_compiler.h"
6
7
8
/*! \brief CCP write helper function written in assembly.
9
 *
10
 *  This function is written in assembly because of the timecritial
11
 *  operation of writing to the registers.
12
 *
13
 *  \param address A pointer to the address to write to.
14
 *  \param value   The value to put in to the register.
15
 */
16
void CCPWrite( volatile uint8_t * address, uint8_t value )
17
{
18
  volatile uint8_t * tmpAddr = address;
19
20
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
21
    {
22
#ifdef RAMPZ 
23
        RAMPZ = 0; 
24
#endif
25
        asm volatile(
26
        "movw r30,  %0"        "\n\t"
27
        "ldi  r16,  %2"        "\n\t"
28
        "out   %3, r16"        "\n\t"
29
        "st     Z,  %1"       "\n\t"
30
        :
31
        : "r" (tmpAddr), "r" (value), "M" (CCP_IOREG_gc), "i" (&CCP)
32
        : "r16", "r30", "r31"
33
        );
34
    }
35
}
36
37
/**
38
 * \internal
39
 * \brief Check if RTC32 is busy synchronizing
40
 *
41
 * \retval true  Is busy
42
 * \retval false Is ready
43
 */
44
uint8_t rtc32_is_busy(void)
45
{
46
  return RTC32.SYNCCTRL & RTC32_SYNCBUSY_bm;
47
}
48
49
ISR(RTC32_OVF_vect)
50
{
51
    /* Toggle status led */
52
    PORTR.DIRTGL = PIN0_bm;
53
}
54
55
56
int main(void)
57
{
58
    /* Apply a resetr of the VBAT */
59
    VBAT.CTRL |= VBAT_ACCEN_bm;
60
61
    /* Set access enable bit */
62
    CCPWrite((void *)&VBAT.CTRL, VBAT_RESET_bm);
63
64
    /* Enable 32.768kHz crystal oscillator */
65
    VBAT.CTRL |= VBAT_XOSCEN_bm | VBAT_XOSCSEL_bm;
66
67
    /* Wait until oscillator is stable */
68
    while(!(VBAT.STATUS & VBAT_XOSCRDY_bm));
69
70
    /* Enable low power mode for external oscillator */
71
    OSC.XOSCCTRL = OSC_X32KLPM_bm;
72
73
    /* Reset RTC32 module */
74
    RTC32.CTRL = 0;
75
76
    /* Wait until sync done */
77
    while(rtc32_is_busy());
78
79
    /* Set PER to 1024. CLK source of the RTC32 is 1024 ticks / second = 1 Hz */
80
    RTC32.PER = 1024;
81
82
    /* Reset CNT register */
83
    RTC32.CNT = 0;
84
85
    /* Wait until sync done */
86
    while(rtc32_is_busy());
87
88
    /* Enable overflow interrupts */
89
    RTC32.INTCTRL = RTC32_OVFINTLVL_MED_gc;
90
91
    /* Enable real time module */
92
    RTC32.CTRL = RTC32_ENABLE_bm;
93
94
    /* Wait until sync done */
95
    while(rtc32_is_busy());
96
97
    /* Set port C pin 7 as output */
98
    PORTC.DIRSET = PIN7_bm;
99
100
    /* Enable medium priority interrupts */
101
    PMIC.CTRL = PMIC_MEDLVLEN_bm;
102
103
    /* Set sleep mode and enable sleep */
104
    SLEEP.CTRL = SLEEP_SMODE_PSAVE_gc | SLEEP_SEN_bm;    
105
106
    /* Enable global interrupts */
107
    sei();
108
109
    while(1)
110
    {
111
        /* Go sleeping */
112
        asm("sleep");
113
    }
114
}

Freue mich über Anregungen und Fragen.

Viele Grüße
Stefan

von John Bend (Gast)


Lesenswert?

Thank you so much for sharing this code. I have been battling with this 
for days.

May I use some snippets?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.