Skip to content

Commit 7fd30e7

Browse files
committed
First draft of eveL, the low-level module of the Gameduino (and BridgeTek EVE) bindings.
[#2578]
1 parent 67440ac commit 7fd30e7

File tree

7 files changed

+658
-0
lines changed

7 files changed

+658
-0
lines changed

ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ QSPI_FLASH_FILESYSTEM = 1
1010
EXTERNAL_FLASH_DEVICE_COUNT = 3
1111
EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C"
1212
LONGINT_IMPL = MPZ
13+
14+
CIRCUITPY_EVEL = 1

ports/nrf/boards/metro_nrf52840_express/mpconfigboard.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ MCU_CHIP = nrf52840
88
QSPI_FLASH_FILESYSTEM = 1
99
EXTERNAL_FLASH_DEVICE_COUNT = 1
1010
EXTERNAL_FLASH_DEVICES = "GD25Q16C"
11+
12+
CIRCUITPY_EVEL = 1

py/circuitpy_defns.mk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ endif
157157
ifeq ($(CIRCUITPY_MATH),1)
158158
SRC_PATTERNS += math/%
159159
endif
160+
ifeq ($(CIRCUITPY_EVEL),1)
161+
SRC_PATTERNS += eveL/%
162+
endif
160163
ifeq ($(CIRCUITPY_MICROCONTROLLER),1)
161164
SRC_PATTERNS += microcontroller/%
162165
endif
@@ -298,6 +301,7 @@ $(filter $(SRC_PATTERNS), \
298301
fontio/Glyph.c \
299302
microcontroller/RunMode.c \
300303
math/__init__.c \
304+
eveL/__init__.c \
301305
)
302306

303307
SRC_BINDINGS_ENUMS += \

py/circuitpy_mpconfig.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,13 @@ extern const struct _mp_obj_module_t math_module;
384384
#define MATH_MODULE
385385
#endif
386386

387+
#if CIRCUITPY_EVEL
388+
extern const struct _mp_obj_module_t eveL_module;
389+
#define EVEL_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_eveL), (mp_obj_t)&eveL_module },
390+
#else
391+
#define EVEL_MODULE
392+
#endif
393+
387394
#if CIRCUITPY_MICROCONTROLLER
388395
extern const struct _mp_obj_module_t microcontroller_module;
389396
#define MICROCONTROLLER_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)&microcontroller_module },
@@ -617,6 +624,7 @@ extern const struct _mp_obj_module_t ustack_module;
617624
I2CSLAVE_MODULE \
618625
JSON_MODULE \
619626
MATH_MODULE \
627+
EVEL_MODULE \
620628
MICROCONTROLLER_MODULE \
621629
NEOPIXEL_WRITE_MODULE \
622630
NETWORK_MODULE \

py/circuitpy_mpconfig.mk

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ CIRCUITPY_MATH = $(CIRCUITPY_ALWAYS_BUILD)
174174
endif
175175
CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH)
176176

177+
ifndef CIRCUITPY_EVEL
178+
CIRCUITPY_EVEL = $(CIRCUITPY_ALWAYS_BUILD)
179+
endif
180+
CFLAGS += -DCIRCUITPY_EVEL=$(CIRCUITPY_EVEL)
181+
177182
ifndef CIRCUITPY_MICROCONTROLLER
178183
CIRCUITPY_MICROCONTROLLER = $(CIRCUITPY_DEFAULT_BUILD)
179184
endif

shared-bindings/eveL/__init__.c

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2014 Paul Sokolovsky
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 <stdio.h>
28+
#include <assert.h>
29+
#include <string.h>
30+
31+
#include "py/runtime.h"
32+
#include "py/binary.h"
33+
34+
// #if MICROPY_PY_BUILTINS_EVEL
35+
36+
typedef struct _mp_obj_EVEL_t {
37+
mp_obj_base_t base;
38+
mp_obj_t writer;
39+
mp_obj_t dest[3];
40+
41+
size_t n;
42+
uint8_t buf[512];
43+
} mp_obj_EVEL_t;
44+
45+
STATIC void _write(mp_obj_EVEL_t *EVEL, mp_obj_t b) {
46+
EVEL->dest[2] = b;
47+
mp_call_method_n_kw(1, 0, EVEL->dest);
48+
}
49+
50+
STATIC mp_obj_t _register(mp_obj_t self, mp_obj_t o) {
51+
mp_obj_EVEL_t *EVEL = self;
52+
EVEL->n = 0;
53+
mp_printf(&mp_plat_print, "register %p %d\n", EVEL, EVEL->n);
54+
mp_load_method(o, MP_QSTR_write, EVEL->dest);
55+
return mp_const_none;
56+
}
57+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(register_obj, _register);
58+
59+
STATIC mp_obj_t _flush(mp_obj_t self) {
60+
mp_obj_EVEL_t *EVEL = self;
61+
// mp_printf(&mp_plat_print, "flush %p %d\n", EVEL, EVEL->n);
62+
if (EVEL->n != 0) {
63+
_write(EVEL, mp_obj_new_bytearray_by_ref(EVEL->n, EVEL->buf));
64+
EVEL->n = 0;
65+
}
66+
return mp_const_none;
67+
}
68+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(flush_obj, _flush);
69+
70+
STATIC void *append(mp_obj_EVEL_t *EVEL, size_t m) {
71+
if ((EVEL->n + m) > sizeof(EVEL->buf))
72+
_flush((mp_obj_t)EVEL);
73+
uint8_t *r = EVEL->buf + EVEL->n;
74+
EVEL->n += m;
75+
return (void*)r;
76+
}
77+
78+
STATIC mp_obj_t _cc(mp_obj_t self, mp_obj_t b) {
79+
mp_obj_EVEL_t *EVEL = self;
80+
mp_buffer_info_t buffer_info;
81+
mp_get_buffer_raise(b, &buffer_info, MP_BUFFER_READ);
82+
// mp_printf(&mp_plat_print, "flush %p %d %p\n", EVEL, buffer_info.len, EVEL->writer);
83+
if (buffer_info.len <= sizeof(EVEL->buf)) {
84+
uint8_t *p = (uint8_t*)append(EVEL, buffer_info.len);
85+
// memcpy(p, buffer_info.buf, buffer_info.len);
86+
uint8_t *s = buffer_info.buf;
87+
for (size_t i = 0; i < buffer_info.len; i++)
88+
*p++ = *s++;
89+
} else {
90+
_flush(self);
91+
_write(EVEL, b);
92+
}
93+
94+
return mp_const_none;
95+
}
96+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(cc_obj, _cc);
97+
98+
#define C4(self, u) (*(uint32_t*)append((self), sizeof(uint32_t)) = (u))
99+
100+
#include "modeveL-gen.h"
101+
102+
// Hand-written functions {
103+
104+
STATIC mp_obj_t _cmd0(mp_obj_t self, mp_obj_t n) {
105+
C4(self, (0xffffff00 | mp_obj_get_int_truncated(n)));
106+
return mp_const_none;
107+
}
108+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(cmd0_obj, _cmd0);
109+
110+
STATIC mp_obj_t _vertex2f(mp_obj_t self , mp_obj_t a0, mp_obj_t a1) {
111+
int16_t x = (int16_t)(16 * mp_obj_get_float(a0));
112+
int16_t y = (int16_t)(16 * mp_obj_get_float(a1));
113+
C4(self, (0x40000000 | ((x & 32767) << 15) | (y & 32767)));
114+
return mp_const_none;
115+
}
116+
STATIC MP_DEFINE_CONST_FUN_OBJ_3(vertex2f_obj, _vertex2f);
117+
118+
STATIC mp_obj_t _cmd(size_t n_args, const mp_obj_t *args) {
119+
mp_obj_t self = args[0];
120+
mp_obj_t num = args[1];
121+
mp_buffer_info_t fmt;
122+
mp_get_buffer_raise(args[2], &fmt, MP_BUFFER_READ);
123+
size_t len;
124+
mp_obj_t *items;
125+
mp_obj_tuple_get(args[3], &len, &items);
126+
127+
// Count how many 32-bit words required
128+
size_t n = 0;
129+
for (size_t i = 0; i < fmt.len; n++) {
130+
switch (((char*)fmt.buf)[i]) {
131+
case 'I':
132+
case 'i':
133+
i += 1;
134+
break;
135+
case 'H':
136+
case 'h':
137+
i += 2;
138+
break;
139+
default:
140+
break;
141+
}
142+
}
143+
mp_printf(&mp_plat_print, "n=%d\n", n);
144+
145+
uint32_t *p = (uint32_t*)append(self, sizeof(uint32_t) * (1 + n));
146+
*p++ = 0xffffff00 | mp_obj_get_int_truncated(num);
147+
mp_obj_t *a = items;
148+
uint32_t lo;
149+
150+
for (size_t i = 0; i < fmt.len; ) {
151+
switch (((char*)fmt.buf)[i]) {
152+
case 'I':
153+
case 'i':
154+
*p++ = mp_obj_get_int_truncated(*a++);
155+
mp_printf(&mp_plat_print, " %d %08x\n", p[-1]);
156+
i += 1;
157+
break;
158+
case 'H':
159+
case 'h':
160+
lo = mp_obj_get_int_truncated(*a++) & 0xffff;
161+
*p++ = lo | (mp_obj_get_int_truncated(*a++) << 16);
162+
i += 2;
163+
break;
164+
default:
165+
break;
166+
}
167+
}
168+
return mp_const_none;
169+
}
170+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(cmd_obj, 4, 4, _cmd);
171+
172+
STATIC const mp_rom_map_elem_t EVEL_locals_dict_table[] = {
173+
{ MP_ROM_QSTR(MP_QSTR_register), MP_ROM_PTR(&register_obj) },
174+
{ MP_ROM_QSTR(MP_QSTR_cc), MP_ROM_PTR(&cc_obj) },
175+
{ MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&flush_obj) },
176+
{ MP_ROM_QSTR(MP_QSTR_Vertex2f), MP_ROM_PTR(&vertex2f_obj) },
177+
{ MP_ROM_QSTR(MP_QSTR_cmd), MP_ROM_PTR(&cmd_obj) },
178+
{ MP_ROM_QSTR(MP_QSTR_cmd0), MP_ROM_PTR(&cmd0_obj) },
179+
ROM_DECLS
180+
};
181+
STATIC MP_DEFINE_CONST_DICT(EVEL_locals_dict, EVEL_locals_dict_table);
182+
183+
STATIC void EVEL_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
184+
(void)self_in;
185+
(void)kind;
186+
mp_printf(print, "<EVEL>");
187+
}
188+
189+
STATIC mp_obj_t EVEL_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
190+
// mp_arg_check_num(n_args, kw_args, 1, 1, false);
191+
mp_obj_EVEL_t *o = m_new_obj(mp_obj_EVEL_t);
192+
mp_printf(&mp_plat_print, "EVEL init\n");
193+
o->base.type = type;
194+
return o;
195+
}
196+
197+
// STATIC void EVEL_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
198+
// printf("HERE\n");
199+
// mp_type_type.attr(self_in, attr, dest);
200+
// printf("THERE %p %p\n", dest[0], dest[1]);
201+
// }
202+
203+
STATIC const mp_obj_type_t EVEL_type = {
204+
{ &mp_type_type },
205+
// Save on qstr's, reuse same as for module
206+
.name = MP_QSTR_EVEL,
207+
.print = EVEL_print,
208+
.make_new = EVEL_make_new,
209+
// .attr = EVEL_attr,
210+
.locals_dict = (void*)&EVEL_locals_dict,
211+
};
212+
213+
STATIC const mp_rom_map_elem_t mp_module_eveL_globals_table[] = {
214+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_eveL) },
215+
{ MP_ROM_QSTR(MP_QSTR_EVEL), MP_OBJ_FROM_PTR(&EVEL_type) },
216+
};
217+
218+
STATIC MP_DEFINE_CONST_DICT(mp_module_eveL_globals, mp_module_eveL_globals_table);
219+
220+
const mp_obj_module_t eveL_module = {
221+
.base = { &mp_type_module },
222+
.globals = (mp_obj_dict_t*)&mp_module_eveL_globals,
223+
};
224+
225+
// #endif // MICROPY_PY_BUILTINS_EVEL

0 commit comments

Comments
 (0)