Skip to content

Commit 1e3241e

Browse files
authored
Merge branch 'main' into esp32s2-bssid
2 parents 6a323a5 + c55deb5 commit 1e3241e

File tree

32 files changed

+1080
-119
lines changed

32 files changed

+1080
-119
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ jobs:
416416
- "espressif_saola_1_wroom"
417417
- "espressif_saola_1_wrover"
418418
- "microdev_micro_s2"
419+
- "muselab_nanoesp32_s2"
419420
- "unexpectedmaker_feathers2"
420421

421422
steps:

locale/circuitpython.pot

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ msgstr ""
430430
msgid "Buffer is not a bytearray."
431431
msgstr ""
432432

433-
#: shared-bindings/displayio/Display.c
433+
#: ports/cxd56/common-hal/camera/Camera.c shared-bindings/displayio/Display.c
434434
#: shared-bindings/framebufferio/FramebufferDisplay.c
435435
msgid "Buffer is too small"
436436
msgstr ""
@@ -615,6 +615,10 @@ msgstr ""
615615
msgid "Corrupt raw code"
616616
msgstr ""
617617

618+
#: ports/cxd56/common-hal/camera/Camera.c
619+
msgid "Could not initialize Camera"
620+
msgstr ""
621+
618622
#: ports/cxd56/common-hal/gnss/GNSS.c
619623
msgid "Could not initialize GNSS"
620624
msgstr ""
@@ -841,6 +845,10 @@ msgstr ""
841845
msgid "File exists"
842846
msgstr ""
843847

848+
#: ports/cxd56/common-hal/camera/Camera.c
849+
msgid "Format not supported"
850+
msgstr ""
851+
844852
#: shared-module/framebufferio/FramebufferDisplay.c
845853
#, c-format
846854
msgid "Framebuffer requires %d bytes"
@@ -905,6 +913,10 @@ msgstr ""
905913
msgid "Incorrect buffer size"
906914
msgstr ""
907915

916+
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
917+
msgid "Input taking too long"
918+
msgstr ""
919+
908920
#: py/moduerrno.c
909921
msgid "Input/output error"
910922
msgstr ""
@@ -1503,6 +1515,10 @@ msgstr ""
15031515
msgid "Server side context cannot have hostname"
15041516
msgstr ""
15051517

1518+
#: ports/cxd56/common-hal/camera/Camera.c
1519+
msgid "Size not supported"
1520+
msgstr ""
1521+
15061522
#: shared-bindings/nvm/ByteArray.c
15071523
msgid "Slice and value different lengths."
15081524
msgstr ""

ports/atmel-samd/common-hal/pulseio/PulseIn.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,14 @@
4444
#include "shared-bindings/pulseio/PulseIn.h"
4545
#include "supervisor/shared/tick.h"
4646
#include "supervisor/shared/translate.h"
47+
#include "supervisor/port.h"
4748

4849
// This timer is shared amongst all PulseIn objects as a higher resolution clock.
4950
static uint8_t refcount = 0;
5051
static uint8_t pulsein_tc_index = 0xff;
5152

5253
volatile static uint32_t overflow_count = 0;
54+
volatile static uint32_t start_overflow = 0;
5355

5456
void pulsein_timer_interrupt_handler(uint8_t index) {
5557
if (index != pulsein_tc_index) return;
@@ -77,6 +79,8 @@ static void pulsein_set_config(pulseio_pulsein_obj_t* self, bool first_edge) {
7779
}
7880

7981
void pulsein_interrupt_handler(uint8_t channel) {
82+
// Turn off interrupts while in handler
83+
common_hal_mcu_disable_interrupts();
8084
// Grab the current time first.
8185
uint32_t current_overflow = overflow_count;
8286
Tc* tc = tc_insts[pulsein_tc_index];
@@ -88,10 +92,8 @@ void pulsein_interrupt_handler(uint8_t channel) {
8892
uint32_t current_count = tc->COUNT16.COUNT.reg;
8993

9094
pulseio_pulsein_obj_t* self = get_eic_channel_data(channel);
91-
if (!supervisor_background_tasks_ok() || self->errored_too_fast) {
92-
self->errored_too_fast = true;
93-
common_hal_pulseio_pulsein_pause(self);
94-
return;
95+
if (self->len == 0 ) {
96+
start_overflow = overflow_count;
9597
}
9698
if (self->first_edge) {
9799
self->first_edge = false;
@@ -112,6 +114,13 @@ void pulsein_interrupt_handler(uint8_t channel) {
112114
if (total_diff < duration) {
113115
duration = total_diff;
114116
}
117+
//check if the input is taking too long, 15 timer overflows is approx 1 second
118+
if (current_overflow - start_overflow > 15) {
119+
self->errored_too_fast = true;
120+
common_hal_pulseio_pulsein_pause(self);
121+
common_hal_mcu_enable_interrupts();
122+
return;
123+
}
115124

116125
uint16_t i = (self->start + self->len) % self->maxlen;
117126
self->buffer[i] = duration;
@@ -123,6 +132,7 @@ void pulsein_interrupt_handler(uint8_t channel) {
123132
}
124133
self->last_overflow = current_overflow;
125134
self->last_count = current_count;
135+
common_hal_mcu_enable_interrupts();
126136
}
127137

128138
void pulsein_reset() {
@@ -264,9 +274,6 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self,
264274
// Make sure we're paused.
265275
common_hal_pulseio_pulsein_pause(self);
266276

267-
// Reset erroring
268-
self->errored_too_fast = false;
269-
270277
// Send the trigger pulse.
271278
if (trigger_duration > 0) {
272279
gpio_set_pin_pull_mode(self->pin, GPIO_PULL_OFF);
@@ -280,6 +287,7 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self,
280287
self->first_edge = true;
281288
self->last_overflow = 0;
282289
self->last_count = 0;
290+
self->errored_too_fast = false;
283291
gpio_set_pin_function(self->pin, GPIO_PIN_FUNCTION_A);
284292
uint32_t mask = 1 << self->channel;
285293
// Clear previous interrupt state and re-enable it.
@@ -300,12 +308,15 @@ uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) {
300308
if (self->len == 0) {
301309
mp_raise_IndexError_varg(translate("pop from empty %q"), MP_QSTR_PulseIn);
302310
}
311+
if (self->errored_too_fast) {
312+
self->errored_too_fast = 0;
313+
mp_raise_RuntimeError(translate("Input taking too long"));
314+
}
303315
common_hal_mcu_disable_interrupts();
304316
uint16_t value = self->buffer[self->start];
305317
self->start = (self->start + 1) % self->maxlen;
306318
self->len--;
307319
common_hal_mcu_enable_interrupts();
308-
309320
return value;
310321
}
311322

ports/cxd56/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ all: $(BUILD)/firmware.spk
201201
$(FIRMWARE):
202202
$(ECHO) ""
203203
$(ECHO) "Download the spresense binaries zip archive from:"
204-
$(ECHO) "https://developer.sony.com/file/download/download-spresense-firmware-v1-4-000"
204+
$(ECHO) "https://developer.sony.com/file/download/download-spresense-firmware-v2-0-000"
205205
$(ECHO) "Extract spresense binaries to $(FIRMWARE)"
206206
$(ECHO) ""
207207
$(ECHO) "run make flash-bootloader again to flash bootloader."
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright 2020 Sony Semiconductor Solutions Corporation
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 <string.h>
28+
#include <fcntl.h>
29+
30+
#include <arch/board/board.h>
31+
#include <nuttx/video/video.h>
32+
#include <nuttx/arch.h>
33+
34+
#include "py/runtime.h"
35+
36+
#include "shared-bindings/camera/Camera.h"
37+
38+
typedef struct {
39+
const char* devpath;
40+
int fd;
41+
} camera_dev_t;
42+
43+
STATIC camera_dev_t camera_dev = {"/dev/video", -1};
44+
45+
typedef struct {
46+
uint16_t width;
47+
uint16_t height;
48+
} image_size_t;
49+
50+
STATIC const image_size_t image_size_table[] = {
51+
{ VIDEO_HSIZE_QVGA, VIDEO_VSIZE_QVGA },
52+
{ VIDEO_HSIZE_VGA, VIDEO_VSIZE_VGA },
53+
{ VIDEO_HSIZE_HD, VIDEO_VSIZE_HD },
54+
{ VIDEO_HSIZE_QUADVGA, VIDEO_VSIZE_QUADVGA },
55+
{ VIDEO_HSIZE_FULLHD, VIDEO_VSIZE_FULLHD },
56+
{ VIDEO_HSIZE_3M, VIDEO_VSIZE_3M },
57+
{ VIDEO_HSIZE_5M, VIDEO_VSIZE_5M },
58+
};
59+
60+
static bool camera_check_width_and_height(uint16_t width, uint16_t height) {
61+
for (int i = 0; i < MP_ARRAY_SIZE(image_size_table); i++) {
62+
if (image_size_table[i].width == width && image_size_table[i].height == height) {
63+
return true;
64+
}
65+
}
66+
return false;
67+
}
68+
69+
static bool camera_check_buffer_length(uint16_t width, uint16_t height, camera_imageformat_t format, size_t length) {
70+
if (format == IMAGEFORMAT_JPG) {
71+
// In SPRESENSE SDK, JPEG compression quality=80 by default.
72+
// In such setting, the maximum actual measured size of JPEG image
73+
// is about width * height * 2 / 9.
74+
return length >= (size_t)(width * height * 2 / 9);
75+
} else {
76+
return false;
77+
}
78+
}
79+
80+
static bool camera_check_format(camera_imageformat_t format) {
81+
return format == IMAGEFORMAT_JPG;
82+
}
83+
84+
static void camera_set_format(enum v4l2_buf_type type, uint32_t pixformat, uint16_t width, uint16_t height) {
85+
v4l2_requestbuffers_t req = {0};
86+
87+
// Set Buffer Mode.
88+
req.type = type;
89+
req.memory = V4L2_MEMORY_USERPTR;
90+
req.count = 1;
91+
req.mode = V4L2_BUF_MODE_RING;
92+
ioctl(camera_dev.fd, VIDIOC_REQBUFS, (unsigned long)&req);
93+
v4l2_format_t fmt = {0};
94+
95+
// Set Format.
96+
fmt.type = type;
97+
fmt.fmt.pix.width = width;
98+
fmt.fmt.pix.height = height;
99+
fmt.fmt.pix.field = V4L2_FIELD_ANY;
100+
fmt.fmt.pix.pixelformat = pixformat;
101+
ioctl(camera_dev.fd, VIDIOC_S_FMT, (unsigned long)&fmt);
102+
}
103+
104+
static void camera_start_streaming(enum v4l2_buf_type type) {
105+
ioctl(camera_dev.fd, VIDIOC_STREAMON, (unsigned long)&type);
106+
}
107+
108+
static void camera_start_preview() {
109+
camera_set_format(V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_PIX_FMT_UYVY, VIDEO_HSIZE_QVGA, VIDEO_VSIZE_QVGA);
110+
111+
v4l2_buffer_t buf;
112+
113+
memset(&buf, 0, sizeof(v4l2_buffer_t));
114+
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
115+
buf.memory = V4L2_MEMORY_USERPTR;
116+
ioctl(camera_dev.fd, VIDIOC_QBUF, (unsigned long)&buf);
117+
118+
camera_start_streaming(V4L2_BUF_TYPE_VIDEO_CAPTURE);
119+
}
120+
121+
void common_hal_camera_construct(camera_obj_t *self) {
122+
if (camera_dev.fd < 0) {
123+
if (video_initialize(camera_dev.devpath) < 0) {
124+
mp_raise_ValueError(translate("Could not initialize Camera"));
125+
}
126+
camera_dev.fd = open(camera_dev.devpath, 0);
127+
if (camera_dev.fd < 0) {
128+
mp_raise_ValueError(translate("Could not initialize Camera"));
129+
}
130+
}
131+
132+
camera_start_preview();
133+
134+
camera_start_streaming(V4L2_BUF_TYPE_STILL_CAPTURE);
135+
136+
sleep(1);
137+
}
138+
139+
void common_hal_camera_deinit(camera_obj_t *self) {
140+
if (common_hal_camera_deinited(self)) {
141+
return;
142+
}
143+
144+
video_uninitialize();
145+
146+
close(camera_dev.fd);
147+
camera_dev.fd = -1;
148+
}
149+
150+
bool common_hal_camera_deinited(camera_obj_t *self) {
151+
return camera_dev.fd < 0;
152+
}
153+
154+
size_t common_hal_camera_take_picture(camera_obj_t *self, uint8_t *buffer, size_t len, uint16_t width, uint16_t height, camera_imageformat_t format) {
155+
if (!camera_check_width_and_height(width, height)) {
156+
mp_raise_ValueError(translate("Size not supported"));
157+
}
158+
if (!camera_check_buffer_length(width, height, format, len)) {
159+
mp_raise_ValueError(translate("Buffer is too small"));
160+
}
161+
if (!camera_check_format(format)) {
162+
mp_raise_ValueError(translate("Format not supported"));
163+
}
164+
165+
camera_set_format(V4L2_BUF_TYPE_STILL_CAPTURE, V4L2_PIX_FMT_JPEG, width, height);
166+
167+
v4l2_buffer_t buf;
168+
169+
memset(&buf, 0, sizeof(v4l2_buffer_t));
170+
buf.type = V4L2_BUF_TYPE_STILL_CAPTURE;
171+
buf.memory = V4L2_MEMORY_USERPTR;
172+
buf.m.userptr = (unsigned long)buffer;
173+
buf.length = len;
174+
ioctl(camera_dev.fd, VIDIOC_QBUF, (unsigned long)&buf);
175+
176+
ioctl(camera_dev.fd, VIDIOC_TAKEPICT_START, 0);
177+
178+
ioctl(camera_dev.fd, VIDIOC_DQBUF, (unsigned long)&buf);
179+
180+
ioctl(camera_dev.fd, VIDIOC_TAKEPICT_STOP, false);
181+
182+
return (size_t)buf.bytesused;
183+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright 2020 Sony Semiconductor Solutions Corporation
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_CXD56_COMMON_HAL_CAMERA_CAMERA_H
28+
#define MICROPY_INCLUDED_CXD56_COMMON_HAL_CAMERA_CAMERA_H
29+
30+
#include "py/obj.h"
31+
32+
typedef struct {
33+
mp_obj_base_t base;
34+
} camera_obj_t;
35+
36+
#endif // MICROPY_INCLUDED_CXD56_COMMON_HAL_CAMERA_CAMERA_H
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// No camera module functions.

ports/cxd56/configs/circuitpython/defconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ CONFIG_USBDEV=y
165165
CONFIG_USBDEV_DMA=y
166166
CONFIG_USBDEV_DUALSPEED=y
167167
CONFIG_USEC_PER_TICK=1000
168-
CONFIG_USERMAIN_STACKSIZE=1064960
169168
CONFIG_USER_ENTRYPOINT="spresense_main"
170169
CONFIG_VIDEO_ISX012=y
171170
CONFIG_VIDEO_STREAM=y

0 commit comments

Comments
 (0)