Skip to content

Commit d3a5d40

Browse files
authored
Merge pull request adafruit#785 from notro/rtc_calibration
atmel-samd/samd21: Rework clock setup + calibration
2 parents 64bd95e + 5d5d147 commit d3a5d40

14 files changed

Lines changed: 878 additions & 76 deletions

File tree

ports/atmel-samd/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ SRC_C = \
225225
audio_dma.c \
226226
background.c \
227227
clocks.c \
228+
$(CHIP_FAMILY)_clocks.c \
228229
events.c \
229230
fatfs_port.c \
230231
flash_api.c \
@@ -238,6 +239,8 @@ SRC_C = \
238239
timers.c \
239240
usb.c \
240241
usb_mass_storage.c \
242+
bindings/samd/__init__.c \
243+
bindings/samd/Clock.c \
241244
boards/$(BOARD)/board.c \
242245
boards/$(BOARD)/pins.c \
243246
lib/oofatfs/ff.c \

ports/atmel-samd/README.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,9 @@ Mass storage
231231

232232
All boards will also show up as a mass storage device. Make sure to eject it
233233
before resetting or disconnecting the board.
234+
235+
Port Specific modules
236+
---------------------
237+
238+
.. toctree::
239+
bindings/samd/__init__

ports/atmel-samd/asf4_conf/samd21/hpl_sysctrl_config.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,15 @@
109109
// <i> Indicates whether configuration for OSC32K is enabled or not
110110
// <id> enable_osc32k
111111
#ifndef CONF_OSC32K_CONFIG
112-
#define CONF_OSC32K_CONFIG 0
112+
#define CONF_OSC32K_CONFIG 1
113113
#endif
114114

115115
// <h> 32kHz Internal Oscillator (OSC32K) Control
116116
// <q> Internal 32K Oscillator Enable
117117
// <i> Indicates whether Internal 32K Oscillator is enabled or not
118118
// <id> osc32k_arch_enable
119119
#ifndef CONF_OSC32K_ENABLE
120-
#define CONF_OSC32K_ENABLE 0
120+
#define CONF_OSC32K_ENABLE 1
121121
#endif
122122

123123
// <q> On Demand Control
@@ -142,7 +142,7 @@
142142
// <i> Enable 32 Khz Output
143143
// <id> osc32k_arch_en32k
144144
#ifndef CONF_OSC32K_EN32K
145-
#define CONF_OSC32K_EN32K 0
145+
#define CONF_OSC32K_EN32K 1
146146
#endif
147147

148148
// <q> Enable 1K
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2018 Noralf Trønnes
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "clocks.h"
28+
#include "bindings/samd/Clock.h"
29+
30+
#include "py/obj.h"
31+
#include "py/objproperty.h"
32+
#include "py/runtime.h"
33+
34+
//| .. currentmodule:: samd
35+
//|
36+
//| :class:`Clock` --- Clock reference
37+
//| ------------------------------------------
38+
//|
39+
//| Identifies a clock on the microcontroller.
40+
//|
41+
//| .. class:: Clock
42+
//|
43+
//| Identifies a clock on the microcontroller. They are fixed by the
44+
//| hardware so they cannot be constructed on demand. Instead, use
45+
//| `samd.clock` to reference the desired clock.
46+
//|
47+
48+
STATIC void samd_clock_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
49+
samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in);
50+
51+
mp_printf(print, "%q.%q.%s(", MP_QSTR_samd, MP_QSTR_clock, self->name);
52+
if (clock_get_enabled(self->type, self->index)) {
53+
mp_printf(print, "frequency=%u", clock_get_frequency(self->type, self->index));
54+
uint32_t calibration = clock_get_calibration(self->type, self->index);
55+
if (calibration) {
56+
mp_printf(print, ", calibration=%u", calibration);
57+
}
58+
}
59+
mp_printf(print, ")");
60+
}
61+
62+
//| .. attribute:: enabled
63+
//|
64+
//| Is the clock enabled? (read-only)
65+
//|
66+
STATIC mp_obj_t samd_clock_get_enabled(mp_obj_t self_in) {
67+
samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in);
68+
return mp_obj_new_bool(clock_get_enabled(self->type, self->index));
69+
}
70+
71+
MP_DEFINE_CONST_FUN_OBJ_1(samd_clock_get_enabled_obj, samd_clock_get_enabled);
72+
73+
const mp_obj_property_t samd_clock_enabled_obj = {
74+
.base.type = &mp_type_property,
75+
.proxy = {(mp_obj_t)&samd_clock_get_enabled_obj,
76+
(mp_obj_t)&mp_const_none_obj,
77+
(mp_obj_t)&mp_const_none_obj,
78+
},
79+
};
80+
81+
//| .. attribute:: parent
82+
//|
83+
//| Clock parent. (read-only)
84+
//|
85+
STATIC mp_obj_t samd_clock_get_parent(mp_obj_t self_in) {
86+
samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in);
87+
uint8_t p_type, p_index;
88+
if (!clock_get_parent(self->type, self->index, &p_type, &p_index))
89+
return mp_const_none;
90+
91+
const mp_map_t* samd_map = &samd_clock_globals.map;
92+
for (uint8_t i = 0; i < samd_map->alloc; i++) {
93+
samd_clock_obj_t *iter = samd_map->table[i].value;
94+
if (iter->type == p_type && iter->index == p_index)
95+
return iter;
96+
}
97+
return mp_const_none;
98+
}
99+
100+
MP_DEFINE_CONST_FUN_OBJ_1(samd_clock_get_parent_obj, samd_clock_get_parent);
101+
102+
const mp_obj_property_t samd_clock_parent_obj = {
103+
.base.type = &mp_type_property,
104+
.proxy = {(mp_obj_t)&samd_clock_get_parent_obj,
105+
(mp_obj_t)&mp_const_none_obj,
106+
(mp_obj_t)&mp_const_none_obj,
107+
},
108+
};
109+
110+
//| .. attribute:: frequency
111+
//|
112+
//| Clock frequency. (read-only)
113+
//|
114+
STATIC mp_obj_t samd_clock_get_frequency(mp_obj_t self_in) {
115+
samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in);
116+
return mp_obj_new_int_from_uint(clock_get_frequency(self->type, self->index));
117+
}
118+
119+
MP_DEFINE_CONST_FUN_OBJ_1(samd_clock_get_frequency_obj, samd_clock_get_frequency);
120+
121+
const mp_obj_property_t samd_clock_frequency_obj = {
122+
.base.type = &mp_type_property,
123+
.proxy = {(mp_obj_t)&samd_clock_get_frequency_obj,
124+
(mp_obj_t)&mp_const_none_obj,
125+
(mp_obj_t)&mp_const_none_obj,
126+
},
127+
};
128+
129+
//| .. attribute:: calibration
130+
//|
131+
//| Clock calibration. Not all clocks can be calibrated.
132+
//|
133+
STATIC mp_obj_t samd_clock_get_calibration(mp_obj_t self_in) {
134+
samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in);
135+
return mp_obj_new_int_from_uint(clock_get_calibration(self->type, self->index));
136+
}
137+
138+
MP_DEFINE_CONST_FUN_OBJ_1(samd_clock_get_calibration_obj, samd_clock_get_calibration);
139+
140+
STATIC mp_obj_t samd_clock_set_calibration(mp_obj_t self_in, mp_obj_t calibration) {
141+
samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in);
142+
int ret = clock_set_calibration(self->type, self->index, mp_obj_get_int(calibration));
143+
if (ret == -2)
144+
mp_raise_AttributeError("calibration is read only");
145+
if (ret == -1)
146+
mp_raise_ValueError("calibration is out of range");
147+
return mp_const_none;
148+
}
149+
150+
MP_DEFINE_CONST_FUN_OBJ_2(samd_clock_set_calibration_obj, samd_clock_set_calibration);
151+
152+
const mp_obj_property_t samd_clock_calibration_obj = {
153+
.base.type = &mp_type_property,
154+
.proxy = {(mp_obj_t)&samd_clock_get_calibration_obj,
155+
(mp_obj_t)&samd_clock_set_calibration_obj,
156+
(mp_obj_t)&mp_const_none_obj,
157+
},
158+
};
159+
160+
STATIC const mp_rom_map_elem_t samd_clock_locals_dict_table[] = {
161+
{ MP_ROM_QSTR(MP_QSTR_enabled), MP_ROM_PTR(&samd_clock_enabled_obj) },
162+
{ MP_ROM_QSTR(MP_QSTR_parent), MP_ROM_PTR(&samd_clock_parent_obj) },
163+
{ MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&samd_clock_frequency_obj) },
164+
{ MP_ROM_QSTR(MP_QSTR_calibration), MP_ROM_PTR(&samd_clock_calibration_obj) },
165+
};
166+
167+
STATIC MP_DEFINE_CONST_DICT(samd_clock_locals_dict, samd_clock_locals_dict_table);
168+
169+
const mp_obj_type_t samd_clock_type = {
170+
{ &mp_type_type },
171+
.name = MP_QSTR_Clock,
172+
.print = samd_clock_print,
173+
.locals_dict = (mp_obj_t)&samd_clock_locals_dict,
174+
};
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2018 Noralf Trønnes
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_BINDINGS_SAMD_CLOCK_H
28+
#define MICROPY_INCLUDED_ATMEL_SAMD_BINDINGS_SAMD_CLOCK_H
29+
30+
#include "py/obj.h"
31+
32+
typedef struct {
33+
mp_obj_base_t base;
34+
const char *name;
35+
uint8_t type;
36+
uint8_t index;
37+
} samd_clock_obj_t;
38+
39+
#define CLOCK(_name, _type, _index) \
40+
const samd_clock_obj_t clock_ ## _name = { \
41+
{ &samd_clock_type }, \
42+
.name = #_name, \
43+
.type = _type, \
44+
.index = _index, \
45+
}
46+
47+
#define CLOCK_SOURCE(_name) \
48+
const samd_clock_obj_t clock_ ## _name = { \
49+
{ &samd_clock_type }, \
50+
.name = #_name, \
51+
.type = 0, \
52+
.index = GCLK_SOURCE_ ## _name, \
53+
}
54+
55+
#define CLOCK_GCLK(_name) \
56+
const samd_clock_obj_t clock_ ## _name = { \
57+
{ &samd_clock_type }, \
58+
.name = #_name, \
59+
.type = 1, \
60+
.index = _name ## _GCLK_ID, \
61+
}
62+
63+
#define CLOCK_GCLK_(_name, _extra) \
64+
const samd_clock_obj_t clock_ ## _name ## _ ## _extra = { \
65+
{ &samd_clock_type }, \
66+
.name = #_name "_" #_extra, \
67+
.type = 1, \
68+
.index = _name ## _GCLK_ID_ ## _extra, \
69+
}
70+
71+
#define CLOCK_ENTRY(_name) { MP_ROM_QSTR(MP_QSTR_ ## _name), MP_ROM_PTR(&clock_ ## _name) }
72+
#define CLOCK_ENTRY_(_name, _extra) { MP_ROM_QSTR(MP_QSTR_ ## _name ## _ ## _extra), MP_ROM_PTR(&clock_ ## _name ## _ ## _extra) }
73+
74+
extern const mp_obj_type_t samd_clock_type;
75+
extern const mp_obj_dict_t samd_clock_globals;
76+
77+
#endif // MICROPY_INCLUDED_ATMEL_SAMD_BINDINGS_SAMD_CLOCK_H
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2018 Noralf Trønnes
7+
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#include "py/obj.h"
29+
#include "py/runtime.h"
30+
31+
#include "bindings/samd/Clock.h"
32+
33+
//| :mod:`samd` --- SAMD implementation settings
34+
//| =================================================
35+
//|
36+
//| .. module:: samd
37+
//| :synopsis: SAMD implementation settings
38+
//| :platform: SAMD21
39+
//|
40+
//| Libraries
41+
//|
42+
//| .. toctree::
43+
//| :maxdepth: 3
44+
//|
45+
//| Clock
46+
//|
47+
48+
//| :mod:`samd.clock` --- samd clock names
49+
//| --------------------------------------------------------
50+
//|
51+
//| .. module:: samd.clock
52+
//| :synopsis: samd clock names
53+
//| :platform: SAMD21
54+
//|
55+
//| References to clocks as named by the microcontroller
56+
//|
57+
const mp_obj_module_t samd_clock_module = {
58+
.base = { &mp_type_module },
59+
.globals = (mp_obj_dict_t*)&samd_clock_globals,
60+
};
61+
62+
STATIC const mp_rom_map_elem_t samd_module_globals_table[] = {
63+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_samd) },
64+
{ MP_ROM_QSTR(MP_QSTR_clock), MP_ROM_PTR(&samd_clock_module) },
65+
};
66+
67+
STATIC MP_DEFINE_CONST_DICT(samd_module_globals, samd_module_globals_table);
68+
69+
const mp_obj_module_t samd_module = {
70+
.base = { &mp_type_module },
71+
.globals = (mp_obj_dict_t*)&samd_module_globals,
72+
};

ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,5 @@
4646
GD25Q16C
4747

4848
#include "external_flash/external_flash.h"
49+
50+
#define BOARD_HAS_CRYSTAL 1

ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,5 @@
4747
GD25Q16C
4848

4949
#include "external_flash/external_flash.h"
50+
51+
#define BOARD_HAS_CRYSTAL 1

0 commit comments

Comments
 (0)