diff --git a/.gitmodules b/.gitmodules index 544815b3a3468..94317f0843d9d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -27,3 +27,6 @@ [submodule "lib/tinyusb"] path = lib/tinyusb url = https://github.com/hathach/tinyusb +[submodule "lib/nrfxlib"] + path = lib/nrfxlib + url = https://github.com/NordicPlayground/nrfxlib.git diff --git a/lib/nrfxlib b/lib/nrfxlib new file mode 160000 index 0000000000000..35120d32233dc --- /dev/null +++ b/lib/nrfxlib @@ -0,0 +1 @@ +Subproject commit 35120d32233dc354c89d8c62eaa6267093c7e35b diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index c02109a156225..c915f2e117bf0 100644 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -125,9 +125,13 @@ LIBS = \ ifeq ($(MCU_VARIANT), nrf52) LIBGCC_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) +LIBNFCTAG2_FILE_NAME = $(TOP)/lib/nrfxlib/nfc/lib/cortex-m4/hard-float/libnfct2t_nrf52.a LIBS += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc +LIBS += -L $(dir $(LIBNFCTAG2_FILE_NAME)) -lnfct2t_nrf52 +INC += -I./drivers/nfc +INC += -I$(TOP)/lib/nrfxlib/nfc/include SRC_LIB += $(addprefix lib/,\ libm/math.c \ @@ -150,6 +154,14 @@ SRC_LIB += $(addprefix lib/,\ libm/atan2f.c \ ) +SRC_NRFX += $(addprefix lib/nrfx/drivers/src/,\ + nrfx_nfct.c \ + ) + +DRIVERS_SRC_C += $(addprefix modules/,\ + machine/nfc.c \ + ) + endif SRC_LIB += $(addprefix lib/,\ diff --git a/ports/nrf/boards/pca10040/mpconfigboard.h b/ports/nrf/boards/pca10040/mpconfigboard.h index 82b74d9284916..6f8dffc17e133 100644 --- a/ports/nrf/boards/pca10040/mpconfigboard.h +++ b/ports/nrf/boards/pca10040/mpconfigboard.h @@ -37,6 +37,7 @@ #define MICROPY_PY_MACHINE_ADC (1) #define MICROPY_PY_MACHINE_TEMP (1) #define MICROPY_PY_RANDOM_HW_RNG (1) +#define MICROPY_PY_MACHINE_NFC (1) #define MICROPY_HW_HAS_LED (1) #define MICROPY_HW_LED_COUNT (4) diff --git a/ports/nrf/drivers/nfc/zephyr/types.h b/ports/nrf/drivers/nfc/zephyr/types.h new file mode 100644 index 0000000000000..d72c0f3b9a0dc --- /dev/null +++ b/ports/nrf/drivers/nfc/zephyr/types.h @@ -0,0 +1,2 @@ + +#define u8_t uint8_t diff --git a/ports/nrf/modules/machine/modmachine.c b/ports/nrf/modules/machine/modmachine.c index 841e136d0dbb1..2b0330ca6adfe 100644 --- a/ports/nrf/modules/machine/modmachine.c +++ b/ports/nrf/modules/machine/modmachine.c @@ -54,6 +54,9 @@ #if MICROPY_PY_MACHINE_RTCOUNTER #include "rtcounter.h" #endif +#if MICROPY_PY_MACHINE_NFC +#include "nfc.h" +#endif #define PYB_RESET_HARD (0) #define PYB_RESET_WDT (1) @@ -225,6 +228,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { #endif #if MICROPY_PY_MACHINE_TEMP { MP_ROM_QSTR(MP_QSTR_Temp), MP_ROM_PTR(&machine_temp_type) }, +#endif +#if MICROPY_PY_MACHINE_NFC + { MP_ROM_QSTR(MP_QSTR_NFC), MP_ROM_PTR(&machine_nfc_type) }, #endif { MP_ROM_QSTR(MP_QSTR_HARD_RESET), MP_ROM_INT(PYB_RESET_HARD) }, { MP_ROM_QSTR(MP_QSTR_WDT_RESET), MP_ROM_INT(PYB_RESET_WDT) }, diff --git a/ports/nrf/modules/machine/nfc.c b/ports/nrf/modules/machine/nfc.c new file mode 100644 index 0000000000000..6a1ae99b363f1 --- /dev/null +++ b/ports/nrf/modules/machine/nfc.c @@ -0,0 +1,142 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Glenn Ruben Bakke + * + * 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 "py/obj.h" + +#if MICROPY_PY_MACHINE_NFC + +#include "nfc.h" +#include "nfc_t2t_lib.h" +#include "nrfx_nfct.h" + +void nfc_callback(void * p_context, + enum nfc_t2t_event event, + const uint8_t * p_data, + size_t data_len) { + // For now empty. +} + +nrfx_err_t nfc_platform_setup(void) { + NRF_CLOCK->TASKS_HFCLKSTART = 1UL; + while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { + ; + } + return NRFX_SUCCESS; +} + +void nfc_platform_event_handler(nrfx_nfct_evt_t const *event) +{ + switch (event->evt_id) { + case NRFX_NFCT_EVT_FIELD_DETECTED: + nrfx_nfct_state_force(NRFX_NFCT_STATE_ACTIVATED); + break; + case NRFX_NFCT_EVT_FIELD_LOST: + break; + default: + break; + } +} + +typedef struct { + mp_obj_base_t base; +} machine_nfc_obj_t; + +/// \method __str__() +/// Return a string describing the NFC object. +STATIC void machine_nfc_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { + machine_nfc_obj_t *self = o; + (void)self; + + mp_printf(print, "NFC"); +} + +STATIC mp_obj_t machine_nfc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + machine_nfc_obj_t *self = m_new_obj(machine_nfc_obj_t); + + self->base.type = &machine_nfc_type; + + mp_int_t res = nfc_t2t_setup(nfc_callback, NULL); + + if (res == 0) { + return MP_OBJ_FROM_PTR(self); + } else { + m_free(self); + } + + return mp_const_none; +} + +/// \method start() +/// Start NFC emulation. +mp_obj_t machine_nfc_start(mp_obj_t self_in) { + machine_nfc_obj_t *self = self_in; + (void)self; + + mp_int_t res = nfc_t2t_emulation_start(); + + return mp_obj_new_int(res); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_machine_nfc_start_obj, machine_nfc_start); + +/// \method stop() +/// Stop NFC emulation. +mp_obj_t machine_nfc_stop(mp_obj_t self_in) { + machine_nfc_obj_t *self = self_in; + (void)self; + + mp_int_t res = nfc_t2t_emulation_stop(); + + return mp_obj_new_int(res); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_machine_nfc_stop_obj, machine_nfc_stop); + +/// \method payload_raw_set(bytes) +/// Set RAW payload data. +STATIC mp_obj_t machine_nfc_payload_raw_set(mp_obj_t self_in, mp_obj_t buf_in) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + + mp_int_t res = nfc_t2t_payload_raw_set(bufinfo.buf, bufinfo.len); + + return mp_obj_new_int(res); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_machine_nfc_payload_raw_set_obj, machine_nfc_payload_raw_set); + +STATIC const mp_rom_map_elem_t machine_nfc_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&mp_machine_nfc_start_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&mp_machine_nfc_stop_obj) }, + { MP_ROM_QSTR(MP_QSTR_payload_raw_set), MP_ROM_PTR(&mp_machine_nfc_payload_raw_set_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(machine_nfc_locals_dict, machine_nfc_locals_dict_table); + +const mp_obj_type_t machine_nfc_type = { + { &mp_type_type }, + .name = MP_QSTR_NFC, + .make_new = machine_nfc_make_new, + .locals_dict = (mp_obj_dict_t*)&machine_nfc_locals_dict, + .print = machine_nfc_print +}; + +#endif // MICROPY_PY_MACHINE_NFC diff --git a/ports/nrf/modules/machine/nfc.h b/ports/nrf/modules/machine/nfc.h new file mode 100644 index 0000000000000..653914216dde1 --- /dev/null +++ b/ports/nrf/modules/machine/nfc.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Glenn Ruben Bakke + * + * 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 MACHINE_NFC_H__ +#define MACHINE_NFC_H__ + +extern const mp_obj_type_t machine_nfc_type; + +#endif // MACHINE_NFC_H__ diff --git a/ports/nrf/modules/machine/timer.c b/ports/nrf/modules/machine/timer.c index 00a359118534a..3d8ceed7afd7a 100644 --- a/ports/nrf/modules/machine/timer.c +++ b/ports/nrf/modules/machine/timer.c @@ -61,8 +61,10 @@ STATIC const machine_timer_obj_t machine_timer_obj[] = { {{&machine_timer_type}, NRFX_TIMER_INSTANCE(2)}, #if defined(NRF52_SERIES) {{&machine_timer_type}, NRFX_TIMER_INSTANCE(3)}, +#if !defined(MICROPY_PY_MACHINE_NFC) {{&machine_timer_type}, NRFX_TIMER_INSTANCE(4)}, #endif +#endif }; void timer_init0(void) { diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index da9a03e1d03b5..cb6fceb42bb41 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -178,6 +178,10 @@ #define MICROPY_PY_RANDOM_HW_RNG (0) #endif +#ifndef MICROPY_PY_MACHINE_NFC +#define MICROPY_PY_MACHINE_NFC (0) +#endif + #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) #define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0) diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h index d8a7d521dae9d..dc78d346641ab 100644 --- a/ports/nrf/nrfx_config.h +++ b/ports/nrf/nrfx_config.h @@ -47,6 +47,14 @@ #define GPIO_COUNT 2 #endif +#if NRF52 + #define NRFX_NFCT_ENABLED 1 + #define NRFX_NFCT_CONFIG_IRQ_PRIORITY 6 +#else + #define NRFX_NFCT_ENABLED 0 +#endif + + #define NRFX_GPIOTE_ENABLED 1 #define NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1 #if NRF51