diff options
| -rw-r--r-- | ports/nrf/Makefile | 13 | ||||
| -rw-r--r-- | ports/nrf/boards/board.h | 2 | ||||
| -rw-r--r-- | ports/nrf/boards/feather52/board.c | 42 | ||||
| -rw-r--r-- | ports/nrf/boards/pca10056/board.c | 43 | ||||
| -rw-r--r-- | ports/nrf/boards/pca10056/examples/buttons.py | 26 | ||||
| -rw-r--r-- | ports/nrf/common-hal/time/__init__.c | 2 | ||||
| -rw-r--r-- | ports/nrf/mpconfigport.h | 5 | ||||
| -rw-r--r-- | ports/nrf/supervisor/port.c | 8 | ||||
| -rw-r--r-- | ports/nrf/tick.c | 81 | ||||
| -rw-r--r-- | ports/nrf/tick.h | 46 | ||||
| -rw-r--r-- | shared-bindings/index.rst | 2 |
11 files changed, 176 insertions, 94 deletions
diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 563578d10..9049bdb64 100644 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -139,6 +139,7 @@ SRC_C += \ pin_named_pins.c \ fatfs_port.c \ fifo.c \ + tick.c \ drivers/softpwm.c \ drivers/ticker.c \ drivers/bluetooth/ble_drv.c \ @@ -230,22 +231,24 @@ SRC_SHARED_MODULE = \ os/__init__.c \ random/__init__.c \ storage/__init__.c \ + gamepad/__init__.c \ + gamepad/GamePad.c # bitbangio/__init__.c \ bitbangio/I2C.c \ bitbangio/OneWire.c \ bitbangio/SPI.c \ busio/OneWire.c \ - gamepad/__init__.c \ - gamepad/GamePad.c \ struct/__init__.c \ uheap/__init__.c \ ustack/__init__.c -#SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) +SRC_SHARED_BINDINGS = \ + gamepad/__init__.c \ + gamepad/GamePad.c -SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-module/, $(SRC_SHARED_MODULE)) +SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_BINDINGS)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE)) FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py') FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) diff --git a/ports/nrf/boards/board.h b/ports/nrf/boards/board.h index fecc0fb57..ec98f04fb 100644 --- a/ports/nrf/boards/board.h +++ b/ports/nrf/boards/board.h @@ -31,8 +31,6 @@ #include <stdbool.h> -extern volatile uint32_t ticks_ms; - // Initializes board related state once on start up. void board_init(void); diff --git a/ports/nrf/boards/feather52/board.c b/ports/nrf/boards/feather52/board.c index c550e9061..c0f344597 100644 --- a/ports/nrf/boards/feather52/board.c +++ b/ports/nrf/boards/feather52/board.c @@ -35,52 +35,10 @@ #define BOOTLOADER_VERSION_REGISTER NRF_TIMER2->CC[0] uint32_t bootloaderVersion = 0; -volatile uint32_t ticks_ms = 0; - -#define HAL_LFCLK_FREQ (32768UL) -#define HAL_RTC_FREQ (1024UL) -#define HAL_RTC_COUNTER_PRESCALER ((HAL_LFCLK_FREQ/HAL_RTC_FREQ)-1) - -/* Maximum RTC ticks */ -#define portNRF_RTC_MAXTICKS ((1U<<24)-1U) - void board_init(void) { // Retrieve bootloader version bootloaderVersion = BOOTLOADER_VERSION_REGISTER; - - // 32Khz XTAL - NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk); - NRF_CLOCK->TASKS_LFCLKSTART = 1UL; - - // Set up RTC1 as tick timer - NVIC_DisableIRQ(RTC1_IRQn); - NRF_RTC1->EVTENCLR = RTC_EVTEN_COMPARE0_Msk; - NRF_RTC1->INTENCLR = RTC_INTENSET_COMPARE0_Msk; - NRF_RTC1->TASKS_STOP = 1; - NRF_RTC1->TASKS_CLEAR = 1; - - ticks_ms = 0; - - NRF_RTC1->PRESCALER = HAL_RTC_COUNTER_PRESCALER; - NRF_RTC1->INTENSET = RTC_INTENSET_TICK_Msk; - NRF_RTC1->TASKS_START = 1; - NRF_RTC1->EVTENSET = RTC_EVTEN_OVRFLW_Msk; - NVIC_SetPriority(RTC1_IRQn, 0xf); // lowest priority - NVIC_EnableIRQ(RTC1_IRQn); -} - -void RTC1_IRQHandler(void) -{ - // Clear event - NRF_RTC1->EVENTS_TICK = 0; - volatile uint32_t dummy = NRF_RTC1->EVENTS_TICK; - (void) dummy; - - // Tick correction - uint32_t systick_counter = NRF_RTC1->COUNTER; - uint32_t diff = (systick_counter - ticks_ms) & portNRF_RTC_MAXTICKS; - ticks_ms += diff; } // Check the status of the two buttons on CircuitPlayground Express. If both are diff --git a/ports/nrf/boards/pca10056/board.c b/ports/nrf/boards/pca10056/board.c index 8ca87759b..5ad81c21d 100644 --- a/ports/nrf/boards/pca10056/board.c +++ b/ports/nrf/boards/pca10056/board.c @@ -31,49 +31,8 @@ #include "boards/board.h" -volatile uint32_t ticks_ms = 0; +void board_init(void) { -#define HAL_LFCLK_FREQ (32768UL) -#define HAL_RTC_FREQ (1024UL) -#define HAL_RTC_COUNTER_PRESCALER ((HAL_LFCLK_FREQ/HAL_RTC_FREQ)-1) - -/* Maximum RTC ticks */ -#define portNRF_RTC_MAXTICKS ((1U<<24)-1U) - -void board_init(void) -{ - // 32Khz XTAL - NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk); - NRF_CLOCK->TASKS_LFCLKSTART = 1UL; - - // Set up RTC1 as tick timer - NVIC_DisableIRQ(RTC1_IRQn); - NRF_RTC1->EVTENCLR = RTC_EVTEN_COMPARE0_Msk; - NRF_RTC1->INTENCLR = RTC_INTENSET_COMPARE0_Msk; - NRF_RTC1->TASKS_STOP = 1; - NRF_RTC1->TASKS_CLEAR = 1; - - ticks_ms = 0; - - NRF_RTC1->PRESCALER = HAL_RTC_COUNTER_PRESCALER; - NRF_RTC1->INTENSET = RTC_INTENSET_TICK_Msk; - NRF_RTC1->TASKS_START = 1; - NRF_RTC1->EVTENSET = RTC_EVTEN_OVRFLW_Msk; - NVIC_SetPriority(RTC1_IRQn, 0xf); // lowest priority - NVIC_EnableIRQ(RTC1_IRQn); -} - -void RTC1_IRQHandler(void) -{ - // Clear event - NRF_RTC1->EVENTS_TICK = 0; - volatile uint32_t dummy = NRF_RTC1->EVENTS_TICK; - (void) dummy; - // - //// Tick correction - uint32_t systick_counter = NRF_RTC1->COUNTER; - uint32_t diff = (systick_counter - ticks_ms) & portNRF_RTC_MAXTICKS; - ticks_ms += diff; } bool board_requests_safe_mode(void) { diff --git a/ports/nrf/boards/pca10056/examples/buttons.py b/ports/nrf/boards/pca10056/examples/buttons.py new file mode 100644 index 000000000..9f4a7cfd4 --- /dev/null +++ b/ports/nrf/boards/pca10056/examples/buttons.py @@ -0,0 +1,26 @@ +import board +import digitalio +import gamepad +import time + +pad = gamepad.GamePad( + digitalio.DigitalInOut(board.PA11), + digitalio.DigitalInOut(board.PA12), + digitalio.DigitalInOut(board.PA24), + digitalio.DigitalInOut(board.PA25), +) + +prev_buttons = 0 + +while True: + buttons = pad.get_pressed() + + if buttons != prev_buttons: + for i in range(0, 4): + bit = (1 << i) + if (buttons & bit) != (prev_buttons & bit): + print('Button %d %s' % (i + 1, 'pressed' if buttons & bit else 'released')) + + prev_buttons = buttons + + time.sleep(0.1) diff --git a/ports/nrf/common-hal/time/__init__.c b/ports/nrf/common-hal/time/__init__.c index dc29e2d6d..ec77354a9 100644 --- a/ports/nrf/common-hal/time/__init__.c +++ b/ports/nrf/common-hal/time/__init__.c @@ -27,7 +27,7 @@ #include "py/mphal.h" #include "shared-bindings/time/__init__.h" -#include "boards/board.h" +#include "tick.h" inline uint64_t common_hal_time_monotonic() { return ticks_ms; diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index a02ebd3f1..63fe5e3b4 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -181,6 +181,9 @@ #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) #define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0) +// Scan gamepad every 32ms +#define CIRCUITPY_GAMEPAD_TICKS 0x1f + // if sdk is in use, import configuration #if BLUETOOTH_SD #include "bluetooth_conf.h" @@ -223,6 +226,7 @@ extern const struct _mp_obj_module_t random_module; extern const struct _mp_obj_module_t storage_module; extern const struct _mp_obj_module_t time_module; extern const struct _mp_obj_module_t supervisor_module; +extern const struct _mp_obj_module_t gamepad_module; extern const struct _mp_obj_module_t pyb_module; extern const struct _mp_obj_module_t machine_module; @@ -269,6 +273,7 @@ extern const struct _mp_obj_module_t ble_module; { MP_OBJ_NEW_QSTR (MP_QSTR_random ), (mp_obj_t)&random_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_storage ), (mp_obj_t)&storage_module },\ { MP_OBJ_NEW_QSTR (MP_QSTR_supervisor ), (mp_obj_t)&supervisor_module }, \ + { MP_OBJ_NEW_QSTR (MP_QSTR_gamepad ), (mp_obj_t)&gamepad_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_time ), (mp_obj_t)&time_module }, \ { MP_ROM_QSTR (MP_QSTR_pyb ), MP_ROM_PTR(&pyb_module) }, \ { MP_ROM_QSTR (MP_QSTR_utime ), MP_ROM_PTR(&mp_module_utime) }, \ diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index 4ac9c08e0..c72ed7cc3 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -28,16 +28,18 @@ #include "supervisor/port.h" #include "boards/board.h" +#include "shared-module/gamepad/__init__.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/pulseio/PWMOut.h" +#include "tick.h" safe_mode_t port_init(void) { board_init(); -#if 0 // Configure millisecond timer initialization. tick_init(); +#if 0 #ifdef CIRCUITPY_CANARY_WORD // Run in safe mode if the canary is corrupt. if (_ezero != CIRCUITPY_CANARY_WORD) { @@ -54,6 +56,10 @@ safe_mode_t port_init(void) { } void reset_port(void) { + #ifdef CIRCUITPY_GAMEPAD_TICKS + gamepad_reset(); + #endif + pwmout_reset(); reset_all_pins(); } diff --git a/ports/nrf/tick.c b/ports/nrf/tick.c new file mode 100644 index 000000000..fccc8181d --- /dev/null +++ b/ports/nrf/tick.c @@ -0,0 +1,81 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "tick.h" + +#include "supervisor/shared/autoreload.h" +#include "shared-module/gamepad/__init__.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "nrf.h" + +// Global millisecond tick count +volatile uint64_t ticks_ms = 0; + +void SysTick_Handler(void) { + // SysTick interrupt handler called when the SysTick timer reaches zero + // (every millisecond). + ticks_ms += 1; + + #ifdef CIRCUITPY_AUTORELOAD_DELAY_MS + autoreload_tick(); + #endif + #ifdef CIRCUITPY_GAMEPAD_TICKS + if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) { + gamepad_tick(); + } + #endif +} + +void tick_init() { + uint32_t ticks_per_ms = common_hal_mcu_processor_get_frequency() / 1000; + SysTick_Config(ticks_per_ms); +// NVIC_EnableIRQ(SysTick_IRQn); +} + +void tick_delay(uint32_t us) { + uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; + uint32_t us_between_ticks = SysTick->VAL / ticks_per_us; + uint64_t start_ms = ticks_ms; + while (us > 1000) { + while (ticks_ms == start_ms) {} + us -= us_between_ticks; + start_ms = ticks_ms; + us_between_ticks = 1000; + } + while (SysTick->VAL > ((us_between_ticks - us) * ticks_per_us)) {} +} + +// us counts down! +void current_tick(uint64_t* ms, uint32_t* us_until_ms) { + uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; + *ms = ticks_ms; + *us_until_ms = SysTick->VAL / ticks_per_us; +} + +void wait_until(uint64_t ms, uint32_t us_until_ms) { + uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; + while(ticks_ms <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {} +} diff --git a/ports/nrf/tick.h b/ports/nrf/tick.h new file mode 100644 index 000000000..73f17d703 --- /dev/null +++ b/ports/nrf/tick.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_NRF_TICK_H +#define MICROPY_INCLUDED_NRF_TICK_H + +#include "mpconfigport.h" + +#include <stdint.h> + +extern volatile uint64_t ticks_ms; + +extern struct timer_descriptor ms_timer; + +void tick_init(void); + +void tick_delay(uint32_t us); + +void current_tick(uint64_t* ms, uint32_t* us_until_ms); +// Do not call this with interrupts disabled because it may be waiting for +// ticks_ms to increment. +void wait_until(uint64_t ms, uint32_t us_until_ms); + +#endif // MICROPY_INCLUDED_NRF_TICK_H diff --git a/shared-bindings/index.rst b/shared-bindings/index.rst index d1261dcd2..1813d5699 100644 --- a/shared-bindings/index.rst +++ b/shared-bindings/index.rst @@ -27,7 +27,7 @@ Module Supported Ports `board` **All Supported** `busio` **All Supported** `digitalio` **All Supported** -`gamepad` **SAMD Express** +`gamepad` **SAMD Express, nRF** `math` **All Supported** `microcontroller` **All Supported** `multiterminal` **ESP8266** |
