Skip to content

Commit d4e84a9

Browse files
committed
Merge branch 'master' into fix_nrf52840_serial
2 parents 3525d65 + 617351a commit d4e84a9

File tree

19 files changed

+97
-28
lines changed

19 files changed

+97
-28
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@
7070
[submodule "ports/atmel-samd/peripherals"]
7171
path = ports/atmel-samd/peripherals
7272
url = https://github.com/adafruit/samd-peripherals.git
73+
[submodule "frozen/Adafruit_CircuitPython_Crickit"]
74+
path = frozen/Adafruit_CircuitPython_Crickit
75+
url = https://github.com/adafruit/Adafruit_CircuitPython_Crickit
7376
[submodule "ports/nrf/nrfx"]
7477
path = ports/nrf/nrfx
7578
url = https://github.com/NordicSemiconductor/nrfx.git

docs/drivers.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ These provide functionality similar to `analogio`, `digitalio`, `pulseio`, and `
191191

192192
Adafruit SeeSaw <https://circuitpython.readthedocs.io/projects/seesaw/en/latest/>
193193
ADS1x15 Analog-to-Digital Converter <https://circuitpython.readthedocs.io/projects/ads1x15/en/latest/>
194+
Crickit Robotics Boards <<https://circuitpython.readthedocs.io/projects/crickit/en/latest/>
194195
DS2413 OneWire GPIO Expander <https://circuitpython.readthedocs.io/projects/ds2413/en/latest/>
195196
FocalTech Capacitive Touch <https://circuitpython.readthedocs.io/projects/focaltouch/en/latest/>
196197
MCP230xx GPIO Expander <https://circuitpython.readthedocs.io/projects/mcp230xx/en/latest/>
@@ -200,7 +201,6 @@ These provide functionality similar to `analogio`, `digitalio`, `pulseio`, and `
200201
TLC59711 12 x 16-bit PWM Driver <https://circuitpython.readthedocs.io/projects/tlc59711/en/latest/>
201202
MPR121 Capacitive Touch Sensor <https://circuitpython.readthedocs.io/projects/mpr121/en/latest/>
202203

203-
204204
Miscellaneous
205205
----------------
206206

ports/atmel-samd/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ else
119119
ifdef INTERNAL_FLASH_FILESYSTEM
120120
CFLAGS += -finline-limit=55
121121
endif
122+
ifdef CFLAGS_INLINE_LIMIT
123+
CFLAGS += -finline-limit=$(CFLAGS_INLINE_LIMIT)
124+
endif
122125
CFLAGS += -flto
123126
endif
124127

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ LONGINT_IMPL = NONE
1111
CHIP_VARIANT = SAMD21G18A
1212
CHIP_FAMILY = samd21
1313

14+
CFLAGS_INLINE_LIMIT = 55
15+
1416
# Include these Python libraries in firmware.
1517
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
1618
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground
19+
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Crickit
1720
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH
1821
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor
1922
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ LONGINT_IMPL = MPZ
1010
CHIP_VARIANT = SAMD21G18A
1111
CHIP_FAMILY = samd21
1212

13+
CFLAGS_INLINE_LIMIT = 55
14+
1315
# Include these Python libraries in firmware.
1416
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
17+
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Crickit
1518
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor
1619
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
1720
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_seesaw

ports/atmel-samd/common-hal/digitalio/DigitalInOut.c

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ digitalinout_result_t common_hal_digitalio_digitalinout_construct(
4040
claim_pin(pin);
4141
self->pin = pin;
4242

43-
gpio_set_pin_pull_mode(pin->pin, GPIO_PULL_OFF);
43+
// Must set pull after setting direction.
4444
gpio_set_pin_direction(pin->pin, GPIO_DIRECTION_IN);
45+
gpio_set_pin_pull_mode(pin->pin, GPIO_PULL_OFF);
4546
return DIGITALINOUT_OK;
4647
}
4748

@@ -60,7 +61,7 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self
6061
void common_hal_digitalio_digitalinout_switch_to_input(
6162
digitalio_digitalinout_obj_t* self, digitalio_pull_t pull) {
6263
self->output = false;
63-
64+
// This also sets direction to input.
6465
common_hal_digitalio_digitalinout_set_pull(self, pull);
6566
}
6667

@@ -69,13 +70,13 @@ void common_hal_digitalio_digitalinout_switch_to_output(
6970
digitalio_drive_mode_t drive_mode) {
7071
const uint8_t pin = self->pin->pin;
7172
gpio_set_pin_pull_mode(pin, GPIO_PULL_OFF);
72-
gpio_set_pin_direction(pin, GPIO_DIRECTION_OUT);
73-
7473
// Turn on "strong" pin driving (more current available). See DRVSTR doc in datasheet.
7574
hri_port_set_PINCFG_DRVSTR_bit(PORT, (enum gpio_port)GPIO_PORT(pin), GPIO_PIN(pin));
7675

7776
self->output = true;
7877
self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN;
78+
79+
// Direction is set in set_value. We don't need to do it here.
7980
common_hal_digitalio_digitalinout_set_value(self, value);
8081
}
8182

@@ -86,16 +87,22 @@ digitalio_direction_t common_hal_digitalio_digitalinout_get_direction(
8687

8788
void common_hal_digitalio_digitalinout_set_value(
8889
digitalio_digitalinout_obj_t* self, bool value) {
90+
const uint8_t pin = self->pin->pin;
91+
const uint8_t port = GPIO_PORT(pin);
92+
const uint32_t pin_mask = 1U << GPIO_PIN(pin);
8993
if (value) {
9094
if (self->open_drain) {
91-
gpio_set_pin_direction(self->pin->pin, GPIO_DIRECTION_IN);
95+
// Assertion: pull is off, so the pin is floating in this case.
96+
// We do open-drain high output (no sinking of current)
97+
// by changing the direction to input with no pulls.
98+
hri_port_clear_DIR_DIR_bf(PORT, port, pin_mask);
9299
} else {
93-
gpio_set_pin_level(self->pin->pin, true);
94-
gpio_set_pin_direction(self->pin->pin, GPIO_DIRECTION_OUT);
100+
hri_port_set_DIR_DIR_bf(PORT, port, pin_mask);
101+
hri_port_set_OUT_OUT_bf(PORT, port, pin_mask);
95102
}
96103
} else {
97-
gpio_set_pin_level(self->pin->pin, false);
98-
gpio_set_pin_direction(self->pin->pin, GPIO_DIRECTION_OUT);
104+
hri_port_set_DIR_DIR_bf(PORT, port, pin_mask);
105+
hri_port_clear_OUT_OUT_bf(PORT,port, pin_mask);
99106
}
100107
}
101108

@@ -105,10 +112,10 @@ bool common_hal_digitalio_digitalinout_get_value(
105112
if (!self->output) {
106113
return gpio_get_pin_level(pin);
107114
} else {
108-
if (self->open_drain && hri_port_get_DIR_reg(PORT, (enum gpio_port)GPIO_PORT(pin), 1U << GPIO_PIN(pin)) == 0) {
115+
if (self->open_drain && hri_port_get_DIR_reg(PORT, GPIO_PORT(pin), 1U << GPIO_PIN(pin)) == 0) {
109116
return true;
110117
} else {
111-
return hri_port_get_OUT_reg(PORT, (enum gpio_port)GPIO_PORT(pin), 1U << GPIO_PIN(pin));
118+
return hri_port_get_OUT_reg(PORT, GPIO_PORT(pin), 1U << GPIO_PIN(pin));
112119
}
113120
}
114121
}
@@ -119,7 +126,7 @@ void common_hal_digitalio_digitalinout_set_drive_mode(
119126
bool value = common_hal_digitalio_digitalinout_get_value(self);
120127
self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN;
121128
// True is implemented differently between modes so reset the value to make
122-
// sure its correct for the new mode.
129+
// sure it's correct for the new mode.
123130
if (value) {
124131
common_hal_digitalio_digitalinout_set_value(self, value);
125132
}
@@ -148,6 +155,8 @@ void common_hal_digitalio_digitalinout_set_pull(
148155
default:
149156
break;
150157
}
158+
// Must set pull after setting direction.
159+
gpio_set_pin_direction(self->pin->pin, GPIO_DIRECTION_IN);
151160
gpio_set_pin_pull_mode(self->pin->pin, asf_pull);
152161
}
153162

@@ -158,9 +167,9 @@ digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(
158167
mp_raise_AttributeError("Cannot get pull while in output mode");
159168
return PULL_NONE;
160169
} else {
161-
if (hri_port_get_PINCFG_PULLEN_bit(PORT, (enum gpio_port)GPIO_PORT(pin), GPIO_PIN(pin)) == 0) {
170+
if (hri_port_get_PINCFG_PULLEN_bit(PORT, GPIO_PORT(pin), GPIO_PIN(pin)) == 0) {
162171
return PULL_NONE;
163-
} if (hri_port_get_OUT_reg(PORT, (enum gpio_port)GPIO_PORT(pin), 1U << GPIO_PIN(pin)) > 0) {
172+
} if (hri_port_get_OUT_reg(PORT, GPIO_PORT(pin), 1U << GPIO_PIN(pin)) > 0) {
164173
return PULL_UP;
165174
} else {
166175
return PULL_DOWN;

ports/atmel-samd/mphalport.c

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2016 Scott Shawcroft
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+
127
#include <string.h>
228

329
#include "lib/mp-readline/readline.h"
@@ -14,6 +40,7 @@
1440
#include "hal/include/hal_delay.h"
1541
#include "hal/include/hal_gpio.h"
1642
#include "hal/include/hal_sleep.h"
43+
#include "sam.h"
1744

1845
#include "mpconfigboard.h"
1946
#include "mphalport.h"
@@ -22,6 +49,7 @@
2249
#include "usb.h"
2350

2451
extern struct usart_module usart_instance;
52+
extern uint32_t common_hal_mcu_processor_get_frequency(void);
2553

2654
int mp_hal_stdin_rx_chr(void) {
2755
for (;;) {
@@ -71,8 +99,23 @@ void mp_hal_delay_ms(mp_uint_t delay) {
7199
}
72100
}
73101

102+
// Use mp_hal_delay_us() for timing of less than 1ms.
103+
// Do a simple timing loop to wait for a certain number of microseconds.
104+
// Can be used when interrupts are disabled, which makes tick_delay() unreliable.
105+
//
106+
// Testing done at 48 MHz on SAMD21 and 120 MHz on SAMD51, multiplication and division cancel out.
107+
// But get the frequency just in case.
108+
#ifdef SAMD21
109+
#define DELAY_LOOP_ITERATIONS_PER_US ( (10U*48000000U) / common_hal_mcu_processor_get_frequency())
110+
#endif
111+
#ifdef SAMD51
112+
#define DELAY_LOOP_ITERATIONS_PER_US ( (30U*120000000U) / common_hal_mcu_processor_get_frequency())
113+
#endif
114+
74115
void mp_hal_delay_us(mp_uint_t delay) {
75-
tick_delay(delay);
116+
for (uint32_t i = delay*DELAY_LOOP_ITERATIONS_PER_US; i > 0; i--) {
117+
asm volatile("nop");
118+
}
76119
}
77120

78121
void mp_hal_disable_all_interrupts(void) {

ports/atmel-samd/mphalport.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ int receive_usb(void);
4848
void mp_hal_set_interrupt_char(int c);
4949

5050
void mp_hal_disable_all_interrupts(void);
51-
5251
void mp_hal_enable_all_interrupts(void);
5352

5453
#endif // MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H

ports/atmel-samd/tick.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ void tick_init() {
6464
for (uint16_t i = 0; i < PERIPH_COUNT_IRQn; i++) {
6565
NVIC_SetPriority(i, (1UL << __NVIC_PRIO_BITS) - 1UL);
6666
}
67-
// Bump up the systick interrupt.
68-
NVIC_SetPriority(SysTick_IRQn, 1);
67+
// Bump up the systick interrupt so nothing else interferes with timekeeping.
68+
NVIC_SetPriority(SysTick_IRQn, 0);
6969
#ifdef SAMD21
7070
NVIC_SetPriority(USB_IRQn, 1);
7171
#endif

ports/nrf/common-hal/microcontroller/__init__.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#include "supervisor/filesystem.h"
3535
#include "nrfx_glue.h"
3636

37+
// This routine should work even when interrupts are disabled. Used by OneWire
38+
// for precise timing.
3739
void common_hal_mcu_delay_us(uint32_t delay) {
3840
NRFX_DELAY_US(delay);
3941
}
@@ -60,4 +62,3 @@ const mcu_processor_obj_t common_hal_mcu_processor_obj = {
6062
.type = &mcu_processor_type,
6163
},
6264
};
63-

ports/nrf/mphalport.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,3 @@ void mp_hal_delay_ms(mp_uint_t ms);
4949
#define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us))
5050

5151
#endif
52-

py/runtime.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,7 +1060,8 @@ void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t
10601060
dest[1] = self;
10611061
}
10621062
#if MICROPY_PY_BUILTINS_PROPERTY
1063-
} else if (MP_OBJ_IS_TYPE(member, &mp_type_property) && mp_obj_is_native_type(type)) {
1063+
// If self is MP_OBJ_NULL, we looking at the class itself, not an instance.
1064+
} else if (MP_OBJ_IS_TYPE(member, &mp_type_property) && mp_obj_is_native_type(type) && self != MP_OBJ_NULL) {
10641065
// object member is a property; delegate the load to the property
10651066
// Note: This is an optimisation for code size and execution time.
10661067
// The proper way to do it is have the functionality just below
@@ -1161,7 +1162,8 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) {
11611162
assert(type->locals_dict->base.type == &mp_type_dict); // Micro Python restriction, for now
11621163
mp_map_t *locals_map = &type->locals_dict->map;
11631164
mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP);
1164-
if (elem != NULL && MP_OBJ_IS_TYPE(elem->value, &mp_type_property)) {
1165+
// If base is MP_OBJ_NULL, we looking at the class itself, not an instance.
1166+
if (elem != NULL && MP_OBJ_IS_TYPE(elem->value, &mp_type_property) && base != MP_OBJ_NULL) {
11651167
// attribute exists and is a property; delegate the store/delete
11661168
// Note: This is an optimisation for code size and execution time.
11671169
// The proper way to do it is have the functionality just below in

shared-module/bitbangio/OneWire.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ void shared_module_bitbangio_onewire_deinit(bitbangio_onewire_obj_t* self) {
4949
common_hal_digitalio_digitalinout_deinit(&self->pin);
5050
}
5151

52+
// We use common_hal_mcu_delay_us(). It should not be dependent on interrupts
53+
// to do accurate timekeeping, since we disable interrupts during the delays below.
54+
5255
bool shared_module_bitbangio_onewire_reset(bitbangio_onewire_obj_t* self) {
5356
common_hal_mcu_disable_interrupts();
5457
common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN);

0 commit comments

Comments
 (0)