Skip to content

Commit 5d5d147

Browse files
committed
Add clock representation with calibration
Add a python representation of the clocks with the possibility to change the calbration of clock sources.
1 parent 2893e79 commit 5d5d147

File tree

9 files changed

+651
-0
lines changed

9 files changed

+651
-0
lines changed

ports/atmel-samd/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ SRC_C = \
239239
timers.c \
240240
usb.c \
241241
usb_mass_storage.c \
242+
bindings/samd/__init__.c \
243+
bindings/samd/Clock.c \
242244
boards/$(BOARD)/board.c \
243245
boards/$(BOARD)/pins.c \
244246
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__
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/clocks.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,10 @@ static inline bool board_has_crystal(void) {
6464

6565
void clock_init(void);
6666

67+
bool clock_get_enabled(uint8_t type, uint8_t index);
68+
bool clock_get_parent(uint8_t type, uint8_t index, uint8_t *p_type, uint8_t *p_index);
69+
uint32_t clock_get_frequency(uint8_t type, uint8_t index);
70+
uint32_t clock_get_calibration(uint8_t type, uint8_t index);
71+
int clock_set_calibration(uint8_t type, uint8_t index, uint32_t val);
72+
6773
#endif // MICROPY_INCLUDED_ATMEL_SAMD_CLOCKS_H

ports/atmel-samd/mpconfigport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ extern const struct _mp_obj_module_t math_module;
167167
extern const struct _mp_obj_module_t os_module;
168168
extern const struct _mp_obj_module_t random_module;
169169
extern const struct _mp_obj_module_t rtc_module;
170+
extern const struct _mp_obj_module_t samd_module;
170171
extern const struct _mp_obj_module_t storage_module;
171172
extern const struct _mp_obj_module_t struct_module;
172173
extern const struct _mp_obj_module_t time_module;
@@ -236,6 +237,7 @@ extern const struct _mp_obj_module_t usb_hid_module;
236237
{ MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \
237238
{ MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, \
238239
{ MP_OBJ_NEW_QSTR(MP_QSTR_rtc), (mp_obj_t)&rtc_module }, \
240+
{ MP_OBJ_NEW_QSTR(MP_QSTR_samd),(mp_obj_t)&samd_module }, \
239241
{ MP_OBJ_NEW_QSTR(MP_QSTR_storage), (mp_obj_t)&storage_module }, \
240242
{ MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&struct_module }, \
241243
{ MP_OBJ_NEW_QSTR(MP_QSTR_supervisor), (mp_obj_t)&supervisor_module }, \

0 commit comments

Comments
 (0)