Skip to content

Commit 41606e8

Browse files
committed
Migrate to new board, fix data loss
Removes use of the m5stack_cardputer base definition and adds a ros-specific m5stack_cardputer_ros version. Also repairs some lost changes intended for the prior commit that were dropped in an accidental reset. Compiles, but has a memory access error.
1 parent f171c44 commit 41606e8

File tree

14 files changed

+706
-23
lines changed

14 files changed

+706
-23
lines changed

ports/espressif/boards/m5stack_cardputer/board.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "py/ringbuf.h"
1818
#include "shared/runtime/interrupt_char.h"
1919

20+
2021
#define DELAY 0x80
2122

2223
uint8_t display_init_sequence[] = {
@@ -41,7 +42,6 @@ uint8_t display_init_sequence[] = {
4142

4243
// Overrides the weakly linked function from supervisor/shared/board.c
4344
void board_init(void) {
44-
4545
busio_spi_obj_t *spi = common_hal_board_create_spi(0);
4646
fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus;
4747
bus->base.type = &fourwire_fourwire_type;

ports/espressif/boards/m5stack_cardputer/mpconfigboard.mk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ CIRCUITPY_ESP_FLASH_MODE = qio
99
CIRCUITPY_ESP_FLASH_FREQ = 80m
1010
CIRCUITPY_ESP_FLASH_SIZE = 8MB
1111
CIRCUITPY_ESPCAMERA = 0
12-
CIRCUITPY_RCLCPY = 1
1312

1413
CIRCUITPY_GIFIO = 1
1514
CIRCUITPY_MAX3421E = 0
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// This file is part of the CircuitPython project: https://circuitpython.org
2+
//
3+
// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
4+
//
5+
// SPDX-License-Identifier: MIT
6+
7+
#include "mpconfigboard.h"
8+
#include "supervisor/board.h"
9+
#include "supervisor/shared/serial.h"
10+
#include "shared-bindings/busio/SPI.h"
11+
#include "shared-bindings/fourwire/FourWire.h"
12+
#include "shared-bindings/microcontroller/Pin.h"
13+
#include "shared-module/displayio/__init__.h"
14+
#include "shared-module/displayio/mipi_constants.h"
15+
#include "shared-bindings/board/__init__.h"
16+
#include "py/runtime.h"
17+
#include "py/ringbuf.h"
18+
#include "shared/runtime/interrupt_char.h"
19+
20+
#define DELAY 0x80
21+
22+
uint8_t display_init_sequence[] = {
23+
// SWRESET and Delay 140ms
24+
0x01, 0 | DELAY, 140,
25+
// SLPOUT and Delay 10ms
26+
0x11, 0 | DELAY, 10,
27+
// COLMOD 65k colors and 16 bit 5-6-5
28+
0x3A, 1, 0x55,
29+
// INVON Iiversion on
30+
0x21, 0,
31+
// NORON normal operation (full update)
32+
0x13, 0,
33+
// MADCTL columns RTL, page/column reverse order
34+
0x36, 1, 0x60,
35+
// RAMCTRL color word little endian
36+
0xB0, 2, 0x00, 0xF8,
37+
// DIPON display on
38+
0x29, 0,
39+
};
40+
41+
42+
// Overrides the weakly linked function from supervisor/shared/board.c
43+
void board_init(void) {
44+
45+
busio_spi_obj_t *spi = common_hal_board_create_spi(0);
46+
fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus;
47+
bus->base.type = &fourwire_fourwire_type;
48+
49+
// see here for inspiration: https://github.com/m5stack/M5GFX/blob/33d7d3135e816a86a008fae8ab3757938cee95d2/src/M5GFX.cpp#L1350
50+
common_hal_fourwire_fourwire_construct(
51+
bus,
52+
spi,
53+
&pin_GPIO34, // DC
54+
&pin_GPIO37, // CS
55+
&pin_GPIO33, // RST
56+
40000000, // baudrate
57+
0, // polarity
58+
0 // phase
59+
);
60+
busdisplay_busdisplay_obj_t *display = &allocate_display()->display;
61+
display->base.type = &busdisplay_busdisplay_type;
62+
63+
common_hal_busdisplay_busdisplay_construct(
64+
display,
65+
bus,
66+
240, // width (after rotation)
67+
135, // height (after rotation)
68+
40, // column start
69+
53, // row start
70+
0, // rotation
71+
16, // color depth
72+
false, // grayscale
73+
false, // pixels in a byte share a row. Only valid for depths < 8
74+
1, // bytes per cell. Only valid for depths < 8
75+
false, // reverse_pixels_in_byte. Only valid for depths < 8
76+
false, // reverse_pixels_in_word
77+
MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command
78+
MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command
79+
MIPI_COMMAND_WRITE_MEMORY_START, // write memory command
80+
display_init_sequence,
81+
sizeof(display_init_sequence),
82+
&pin_GPIO38, // backlight pin
83+
NO_BRIGHTNESS_COMMAND,
84+
1.0f, // brightness
85+
false, // single_byte_bounds
86+
false, // data_as_commands
87+
true, // auto_refresh
88+
60, // native_frames_per_second
89+
true, // backlight_on_high
90+
false, // SH1107_addressing
91+
350 // backlight pwm frequency
92+
);
93+
}
94+
95+
// TODO: Should we turn off the display when asleep, in board_deinit() ?
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
// This file is part of the CircuitPython project: https://circuitpython.org
2+
//
3+
// SPDX-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft
4+
//
5+
// SPDX-License-Identifier: MIT
6+
7+
#include "py/obj.h"
8+
#include "py/objstr.h"
9+
#include "py/runtime.h"
10+
11+
#include "supervisor/shared/serial.h"
12+
#include "shared-bindings/keypad/EventQueue.h"
13+
#include "shared-bindings/keypad_demux/DemuxKeyMatrix.h"
14+
#include "shared-bindings/microcontroller/Pin.h"
15+
#include "shared-module/keypad/EventQueue.h"
16+
#include "shared-module/keypad_demux/DemuxKeyMatrix.h"
17+
#include "supervisor/shared/reload.h"
18+
19+
#include "keymap.h"
20+
21+
//| """M5Stack Cardputer keyboard integration.
22+
//| """
23+
//|
24+
//| """The KEYBOARD object is an instance of DemuxKeyMatrix, configured with correct pins.
25+
//| The pins cannot be used for any other purposes (even though exposed in the board module).
26+
//| By default all keyboard events are consumed and routed to the standard input - there is
27+
//| not much use of the KEYBOARD object in this configuration - just read the input via sys.stdin.
28+
//|
29+
//| If you need to manually process individual key up / key down events via KEYBOARD.events,
30+
//| call `detach_serial()`.
31+
//| """"
32+
//| KEYBOARD: keypad_demux.DemuxKeymatrix
33+
//|
34+
keypad_demux_demuxkeymatrix_obj_t cardputer_keyboard_obj;
35+
bool cardputer_keyboard_serial_attached = false;
36+
37+
void cardputer_keyboard_init(void);
38+
void keyboard_seq(const char *seq);
39+
void update_keyboard(keypad_eventqueue_obj_t *queue);
40+
41+
//| def detach_serial() -> None:
42+
//| """Stops consuming keyboard events and routing them to sys.stdin."""
43+
//| ...
44+
//|
45+
static mp_obj_t detach_serial(void) {
46+
cardputer_keyboard_serial_attached = false;
47+
common_hal_keypad_eventqueue_set_event_handler(cardputer_keyboard_obj.events, NULL);
48+
return mp_const_none;
49+
}
50+
static MP_DEFINE_CONST_FUN_OBJ_0(detach_serial_obj, detach_serial);
51+
52+
//| def attach_serial() -> None:
53+
//| """Starts consuming keyboard events and routing them to sys.stdin."""
54+
//| ...
55+
//|
56+
static mp_obj_t attach_serial(void) {
57+
common_hal_keypad_eventqueue_set_event_handler(cardputer_keyboard_obj.events, update_keyboard);
58+
cardputer_keyboard_serial_attached = true;
59+
return mp_const_none;
60+
}
61+
static MP_DEFINE_CONST_FUN_OBJ_0(attach_serial_obj, attach_serial);
62+
63+
//| def key_to_char(key: int, shifted: bool) -> str | None:
64+
//| """Converts a key index to the respective key (with or without shift modifier).
65+
//| Returns None for functional & modifier keys or whenever not 0 <= key < 56.
66+
//| """
67+
//| ...
68+
//|
69+
static mp_obj_t key_to_char(mp_obj_t key_obj, mp_obj_t shifted_obj) {
70+
mp_int_t key = mp_obj_get_int(key_obj);
71+
if (key < 0 || key > (mp_int_t)(sizeof keymap / sizeof *keymap) || keymap[key] == 0) {
72+
return mp_const_none;
73+
} else if (shifted_obj == mp_const_true) {
74+
return mp_obj_new_str(&keymap_shifted[key], 1);
75+
} else {
76+
return mp_obj_new_str(&keymap[key], 1);
77+
}
78+
}
79+
static MP_DEFINE_CONST_FUN_OBJ_2(key_to_char_obj, key_to_char);
80+
81+
// Ring buffer of characters consumed from keyboard events (when serial attached)
82+
ringbuf_t keyqueue;
83+
char keybuf[32];
84+
85+
keypad_event_obj_t event;
86+
char keystate[56];
87+
88+
// Keyboard pins
89+
const mcu_pin_obj_t *row_addr_pins[] = {
90+
&pin_GPIO8,
91+
&pin_GPIO9,
92+
&pin_GPIO11,
93+
};
94+
95+
const mcu_pin_obj_t *column_pins[] = {
96+
&pin_GPIO13,
97+
&pin_GPIO15,
98+
&pin_GPIO3,
99+
&pin_GPIO4,
100+
&pin_GPIO5,
101+
&pin_GPIO6,
102+
&pin_GPIO7
103+
};
104+
105+
void cardputer_keyboard_init(void) {
106+
cardputer_keyboard_obj.base.type = &keypad_demux_demuxkeymatrix_type;
107+
common_hal_keypad_demux_demuxkeymatrix_construct(
108+
&cardputer_keyboard_obj, // self
109+
3, // num_row_addr_pins
110+
row_addr_pins, // row_addr_pins
111+
7, // num_column_pins
112+
column_pins, // column_pins
113+
0.01f, // interval
114+
20, // max_events
115+
2 // debounce_threshold
116+
);
117+
demuxkeymatrix_never_reset(&cardputer_keyboard_obj);
118+
119+
ringbuf_init(&keyqueue, (uint8_t *)keybuf, sizeof(keybuf));
120+
attach_serial();
121+
}
122+
123+
// Overrides the weakly linked function from supervisor/shared/serial.c
124+
void board_serial_init(void) {
125+
cardputer_keyboard_init();
126+
}
127+
128+
// Overrides the weakly linked function from supervisor/shared/serial.c
129+
bool board_serial_connected(void) {
130+
return cardputer_keyboard_serial_attached;
131+
}
132+
133+
// Overrides the weakly linked function from supervisor/shared/serial.c
134+
uint32_t board_serial_bytes_available(void) {
135+
if (cardputer_keyboard_serial_attached) {
136+
return ringbuf_num_filled(&keyqueue);
137+
} else {
138+
return 0;
139+
}
140+
}
141+
142+
// Overrides the weakly linked function from supervisor/shared/serial.c
143+
char board_serial_read(void) {
144+
if (cardputer_keyboard_serial_attached) {
145+
return ringbuf_get(&keyqueue);
146+
} else {
147+
return 0;
148+
}
149+
}
150+
151+
void keyboard_seq(const char *seq) {
152+
while (*seq) {
153+
ringbuf_put(&keyqueue, *seq++);
154+
}
155+
}
156+
157+
void update_keyboard(keypad_eventqueue_obj_t *queue) {
158+
uint8_t ascii = 0;
159+
160+
if (common_hal_keypad_eventqueue_get_length(queue) == 0) {
161+
return;
162+
}
163+
164+
while (common_hal_keypad_eventqueue_get_into(queue, &event)) {
165+
if (event.pressed) {
166+
keystate[event.key_number] = 1;
167+
168+
if (keystate[KEY_CTRL]) {
169+
if (keystate[KEY_ALT] && keystate[KEY_BACKSPACE]) {
170+
reload_initiate(RUN_REASON_REPL_RELOAD);
171+
}
172+
ascii = keymap[event.key_number];
173+
if (ascii >= 'a' && ascii <= 'z') {
174+
ascii -= 'a' - 1;
175+
}
176+
177+
if (ascii == mp_interrupt_char) {
178+
mp_sched_keyboard_interrupt();
179+
}
180+
} else if (keystate[KEY_SHIFT]) {
181+
ascii = keymap_shifted[event.key_number];
182+
} else if (keystate[KEY_FN] && event.key_number != KEY_FN) {
183+
switch (event.key_number | FN_MOD)
184+
{
185+
case KEY_DOWN:
186+
keyboard_seq("\e[B");
187+
break;
188+
case KEY_UP:
189+
keyboard_seq("\e[A");
190+
break;
191+
case KEY_DELETE:
192+
keyboard_seq("\e[3~");
193+
break;
194+
case KEY_LEFT:
195+
keyboard_seq("\e[D");
196+
break;
197+
case KEY_RIGHT:
198+
keyboard_seq("\e[C");
199+
break;
200+
case KEY_ESC:
201+
ringbuf_put(&keyqueue, '\e');
202+
break;
203+
}
204+
} else {
205+
ascii = keymap[event.key_number];
206+
}
207+
208+
if (ascii > 0) {
209+
if (keystate[KEY_ALT]) {
210+
ringbuf_put(&keyqueue, '\e');
211+
} else if (keystate[KEY_OPT]) {
212+
ringbuf_put(&keyqueue, '\x10');
213+
}
214+
ringbuf_put(&keyqueue, ascii);
215+
}
216+
} else {
217+
keystate[event.key_number] = 0;
218+
}
219+
}
220+
}
221+
222+
static const mp_rom_map_elem_t cardputer_keyboard_module_globals_table[] = {
223+
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cardputer_keyboard)},
224+
{MP_ROM_QSTR(MP_QSTR_KEYBOARD), MP_ROM_PTR(&cardputer_keyboard_obj)},
225+
{MP_ROM_QSTR(MP_QSTR_attach_serial), MP_ROM_PTR(&attach_serial_obj)},
226+
{MP_ROM_QSTR(MP_QSTR_detach_serial), MP_ROM_PTR(&detach_serial_obj)},
227+
{MP_ROM_QSTR(MP_QSTR_key_to_char), MP_ROM_PTR(&key_to_char_obj)},
228+
};
229+
MP_DEFINE_CONST_DICT(cardputer_keyboard_module_globals, cardputer_keyboard_module_globals_table);
230+
231+
const mp_obj_module_t cardputer_keyboard_module = {
232+
.base = {&mp_type_module},
233+
.globals = (mp_obj_dict_t *)&cardputer_keyboard_module_globals,
234+
};
235+
236+
MP_REGISTER_MODULE(MP_QSTR_cardputer_keyboard, cardputer_keyboard_module);

0 commit comments

Comments
 (0)