nrf/bluetooth: Add support for nimble based bluetooth.

Signed-off-by: Andrew Leech <andrew@alelec.net>
pull/8318/merge^2
Andrew Leech 2024-03-20 15:38:48 +11:00
rodzic 2e1cd87f10
commit d319fde1cd
22 zmienionych plików z 790 dodań i 45 usunięć

Wyświetl plik

@ -9,7 +9,9 @@
#include "modlog/modlog.h"
#include "log_common/log_common.h"
#define MICROPY_PY_BLUETOOTH_DIAGNOSTIC_LOGGING (1)
#ifndef MICROPY_PY_BLUETOOTH_DIAGNOSTIC_LOGGING
#define MICROPY_PY_BLUETOOTH_DIAGNOSTIC_LOGGING (0)
#endif
#if MICROPY_PY_BLUETOOTH_DIAGNOSTIC_LOGGING
#define DFLT_LOG_DEBUG(...) MODLOG_DEBUG(4, __VA_ARGS__)

Wyświetl plik

@ -519,24 +519,30 @@ static int central_gap_event_cb(struct ble_gap_event *event, void *arg) {
// On ports such as ESP32 where we only implement the bindings, then
// the port must provide these functions.
// But for STM32 / Unix-H4, we provide a default implementation of the
// For STM32 / Unix-H4, we provide a default implementation of the
// port-specific functionality.
// TODO: In the future if a port ever needs to customise these functions
// then investigate using MP_WEAK or splitting them out to another .c file.
#if !MICROPY_BLUETOOTH_NIMBLE_CONTROLLER
#include "transport/uart/ble_hci_uart.h"
#endif
void mp_bluetooth_nimble_port_hci_init(void) {
DEBUG_printf("mp_bluetooth_nimble_port_hci_init (nimble default)\n");
#if MYNEWT_VAL_BLE_HCI_TRANSPORT_UART
// This calls mp_bluetooth_hci_uart_init (via ble_hci_uart_init --> hal_uart_config --> mp_bluetooth_hci_uart_init).
ble_hci_uart_init();
#endif
mp_bluetooth_hci_controller_init();
}
void mp_bluetooth_nimble_port_hci_deinit(void) {
DEBUG_printf("mp_bluetooth_nimble_port_hci_deinit (nimble default)\n");
mp_bluetooth_hci_controller_deinit();
#if MYNEWT_VAL_BLE_HCI_TRANSPORT_UART
mp_bluetooth_hci_uart_deinit();
#endif
}
void mp_bluetooth_nimble_port_start(void) {
@ -600,10 +606,6 @@ int mp_bluetooth_init(void) {
MP_STATE_PORT(bluetooth_nimble_memory) = NULL;
#endif
// Allow port (ESP32) to override NimBLE's HCI init.
// Otherwise default implementation above calls ble_hci_uart_init().
mp_bluetooth_nimble_port_hci_init();
// Static initialization is complete, can start processing events.
mp_bluetooth_nimble_ble_state = MP_BLUETOOTH_NIMBLE_BLE_STATE_WAITING_FOR_SYNC;
@ -611,6 +613,10 @@ int mp_bluetooth_init(void) {
DEBUG_printf("mp_bluetooth_init: nimble_port_init\n");
nimble_port_init();
// Allow port (ESP32) to override NimBLE's HCI init.
// Otherwise default implementation above calls ble_hci_uart_init().
mp_bluetooth_nimble_port_hci_init();
ble_hs_cfg.reset_cb = reset_cb;
ble_hs_cfg.sync_cb = sync_cb;
ble_hs_cfg.gatts_register_cb = gatts_register_cb;

Wyświetl plik

@ -86,7 +86,6 @@ SRC_THIRDPARTY_C += $(addprefix $(NIMBLE_LIB_DIR)/, \
ble_uuid.c \
) \
nimble/host/util/src/addr.c \
nimble/transport/uart/src/ble_hci_uart.c \
$(addprefix porting/nimble/src/, \
endian.c \
mem.c \
@ -100,7 +99,6 @@ SRC_THIRDPARTY_C += $(addprefix $(NIMBLE_LIB_DIR)/, \
SRC_THIRDPARTY_C += $(addprefix $(NIMBLE_EXTMOD_DIR)/, \
nimble/nimble_npl_os.c \
hal/hal_uart.c \
)
INC += -I$(TOP)/$(NIMBLE_EXTMOD_DIR)
@ -112,11 +110,60 @@ INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/host/services/gatt/include
INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/host/store/ram/include
INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/host/util/include
INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/include
INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/transport/uart/include
INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/porting/nimble/include
$(BUILD)/$(NIMBLE_LIB_DIR)/%.o: CFLAGS += -Wno-maybe-uninitialized -Wno-pointer-arith -Wno-unused-but-set-variable -Wno-format -Wno-sign-compare -Wno-old-style-declaration
endif
ifeq ($(MICROPY_BLUETOOTH_NIMBLE_CONTROLLER),1)
# Include controller layer to run entire stack on-chip
CFLAGS_EXTMOD += -DMICROPY_BLUETOOTH_NIMBLE_CONTROLLER=1
INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/controller/include
SRC_THIRDPARTY_C += $(addprefix $(NIMBLE_LIB_DIR)/, \
$(addprefix nimble/controller/src/, \
ble_ll.c \
ble_ll_adv.c \
ble_ll_conn.c \
ble_ll_conn_hci.c \
ble_ll_ctrl.c \
ble_ll_dtm.c \
ble_ll_hci.c \
ble_ll_hci_ev.c \
ble_ll_iso.c \
ble_ll_rand.c \
ble_ll_resolv.c \
ble_ll_rfmgmt.c \
ble_ll_scan.c \
ble_ll_sched.c \
ble_ll_supp_cmd.c \
ble_ll_sync.c \
ble_ll_trace.c \
ble_ll_utils.c \
ble_ll_whitelist.c \
) \
)
SRC_THIRDPARTY_C += $(addprefix $(NIMBLE_LIB_DIR)/, \
$(addprefix porting/nimble/src/, \
hal_timer.c \
os_cputime.c \
os_cputime_pwr2.c \
) \
)
SRC_THIRDPARTY_C += $(NIMBLE_LIB_DIR)/nimble/transport/ram/src/ble_hci_ram.c
INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/transport/ram/include
else # !MICROPY_BLUETOOTH_NIMBLE_CONTROLLER
# External controller being used
INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/transport/uart/include
SRC_THIRDPARTY_C += $(addprefix $(NIMBLE_EXTMOD_DIR)/, \
hal/hal_uart.c \
)
SRC_THIRDPARTY_C += $(NIMBLE_LIB_DIR)/nimble/transport/uart/src/ble_hci_uart.c
endif
endif

Wyświetl plik

@ -30,6 +30,8 @@
#include "nimble/ble.h"
#include "nimble/nimble_npl.h"
#include "extmod/nimble/hal/hal_uart.h"
#include "os/os_cputime.h"
#include "hal/hal_timer.h"
#include "extmod/modbluetooth.h"
#include "extmod/nimble/modbluetooth_nimble.h"
@ -44,7 +46,7 @@
#define DEBUG_TIME_printf(...) // printf(__VA_ARGS__)
#define DEBUG_CRIT_printf(...) // printf(__VA_ARGS__)
bool ble_npl_os_started(void) {
MP_WEAK bool ble_npl_os_started(void) {
DEBUG_OS_printf("ble_npl_os_started\n");
return true;
}
@ -175,6 +177,24 @@ int nimble_sprintf(char *str, const char *fmt, ...) {
return 0;
}
// Function to implement `strncat()` function in C
char* strncat(char* destination, const char* source, size_t num)
{
// make `ptr` point to the end of the destination string
char* ptr = destination + strlen(destination);
// Appends characters of the source to the destination string
while (*source != '\0' && num--) {
*ptr++ = *source++;
}
// null terminate destination string
*ptr = '\0';
// destination string is returned by standard `strncat()`
return destination;
}
/******************************************************************************/
// EVENTQ
@ -278,6 +298,61 @@ void ble_npl_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_event *ev) {
mp_bluetooth_hci_poll_now();
}
struct ble_npl_event *ble_npl_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo) {
if (tmo != BLE_NPL_TIME_FOREVER && tmo != 0) {
tmo += mp_hal_ticks_ms();
}
struct ble_npl_event *ev = NULL;
os_sr_t sr;
do {
ev = evq->head;
if (ev) {
OS_ENTER_CRITICAL(sr);
// Remove this event from the queue.
evq->head = ev->next;
if (ev->next) {
ev->next->prev = NULL;
ev->next = NULL;
}
ev->prev = NULL;
ev->pending = false;
// Stop searching and execute this event.
OS_EXIT_CRITICAL(sr);
break;
}
} while (tmo != 0 && (tmo == BLE_NPL_TIME_FOREVER || tmo < mp_hal_ticks_ms()));
return ev;
}
void ble_npl_event_run(struct ble_npl_event *ev) {
// Run the event handler.
DEBUG_EVENT_printf("ble_npl_event_run(%p)\n", ev);
ev->fn(ev);
}
inline bool ble_npl_event_is_queued(struct ble_npl_event *ev) {
return ev->pending;
}
void ble_npl_eventq_run(struct ble_npl_eventq *evq) {
printf("ble_npl_eventq_run\n");
assert(0);
}
void ble_npl_eventq_remove(struct ble_npl_eventq *evq, struct ble_npl_event *ev) {
DEBUG_EVENT_printf("ble_npl_eventq_remove(%p, %p (%p, %p))\n", evq, ev, ev->prev, ev->next);
os_sr_t sr;
OS_ENTER_CRITICAL(sr);
// Set the previous events next to this events next, so removing it from the chain
ev->prev->next = ev->next;
OS_EXIT_CRITICAL(sr);
}
void ble_npl_event_init(struct ble_npl_event *ev, ble_npl_event_fn *fn, void *arg) {
DEBUG_EVENT_printf("ble_npl_event_init(%p, %p, %p)\n", ev, fn, arg);
ev->fn = fn;
@ -473,7 +548,7 @@ void ble_npl_callout_set_arg(struct ble_npl_callout *c, void *arg) {
}
/******************************************************************************/
// TIME
// TIME (ticks in ms)
uint32_t ble_npl_time_get(void) {
DEBUG_TIME_printf("ble_npl_time_get -> %u\n", (uint)mp_hal_ticks_ms());

Wyświetl plik

@ -88,7 +88,9 @@ struct ble_npl_sem {
// --- Called by the MicroPython port -----------------------------------------
void mp_bluetooth_nimble_os_eventq_run_all(void);
void mp_bluetooth_nimble_eventq_run_all(struct ble_npl_eventq *eventq);
void mp_bluetooth_nimble_os_callout_process(void);
void mp_bluetooth_nimble_os_cputime_timer_poll(void);
// --- Must be provided by the MicroPython port -------------------------------

Wyświetl plik

@ -18,8 +18,13 @@ int nimble_sprintf(char *str, const char *fmt, ...);
#define sprintf(str, fmt, ...) nimble_sprintf(str, fmt, __VA_ARGS__)
#define MYNEWT_VAL(x) MYNEWT_VAL_ ## x
#define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val
#if MICROPY_PY_BLUETOOTH_DIAGNOSTIC_LOGGING
#define MYNEWT_VAL_LOG_LEVEL (0)
#else
#define MYNEWT_VAL_LOG_LEVEL (255)
#endif
/*** compiler/arm-none-eabi-m4 */
#define MYNEWT_VAL_HARDFLOAT (1)
@ -30,8 +35,13 @@ int nimble_sprintf(char *str, const char *fmt, ...);
#define MYNEWT_VAL_MSYS_1_BLOCK_SIZE (292)
#define MYNEWT_VAL_MSYS_2_BLOCK_COUNT (0)
#define MYNEWT_VAL_MSYS_2_BLOCK_SIZE (0)
#if MICROPY_BLUETOOTH_NIMBLE_CONTROLLER
#define MYNEWT_VAL_OS_CPUTIME_FREQ (32768)
#define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (5)
#else
#define MYNEWT_VAL_OS_CPUTIME_FREQ (1000000)
#define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0)
#endif
#define MYNEWT_VAL_OS_CTX_SW_STACK_CHECK (0)
#define MYNEWT_VAL_OS_CTX_SW_STACK_GUARD (4)
#define MYNEWT_VAL_OS_MAIN_STACK_SIZE (1024)
@ -40,6 +50,7 @@ int nimble_sprintf(char *str, const char *fmt, ...);
#define MYNEWT_VAL_OS_MEMPOOL_POISON (0)
/*** nimble */
#define MYNEWT_VAL_BLE_VERSION (52)
#define MYNEWT_VAL_BLE_EXT_ADV (0)
#define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31)
#define MYNEWT_VAL_BLE_MAX_CONNECTIONS (4)
@ -147,19 +158,143 @@ int nimble_sprintf(char *str, const char *fmt, ...);
#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO (0)
/* Overridden by targets/porting-nimble (defined by nimble/transport) */
#if MICROPY_BLUETOOTH_NIMBLE_CONTROLLER
#define NIMBLE_CFG_CONTROLLER (1)
#define MYNEWT_VAL_TIMER_5 (1)
#define MYNEWT_VAL_MCU_HFCLK_SOURCE_HFXO (1)
#ifndef MYNEWT_VAL_MCU_LFCLK_SOURCE__LFRC
#define MYNEWT_VAL_MCU_LFCLK_SOURCE__LFRC (0)
#endif
#ifndef MYNEWT_VAL_MCU_LFCLK_SOURCE__LFSYNTH
#define MYNEWT_VAL_MCU_LFCLK_SOURCE__LFSYNTH (0)
#endif
#ifndef MYNEWT_VAL_MCU_LFCLK_SOURCE__LFXO
#define MYNEWT_VAL_MCU_LFCLK_SOURCE__LFXO (1)
#endif
#ifndef MYNEWT_VAL_MCU_LFCLK_SOURCE
#define MYNEWT_VAL_MCU_LFCLK_SOURCE (1)
#endif
#ifndef MYNEWT_VAL_MCU_HFCLK_SOURCE__HFINT
#define MYNEWT_VAL_MCU_HFCLK_SOURCE__HFINT (0)
#endif
#ifndef MYNEWT_VAL_MCU_HFCLK_SOURCE__HFXO
#define MYNEWT_VAL_MCU_HFCLK_SOURCE__HFXO (0)
#endif
#ifndef MYNEWT_VAL_MCU_HFCLK_SOURCE
#define MYNEWT_VAL_MCU_HFCLK_SOURCE (1)
#endif
#ifndef MYNEWT_VAL_MCU_TARGET__nRF52810
#define MYNEWT_VAL_MCU_TARGET__nRF52810 (0)
#endif
#ifndef MYNEWT_VAL_MCU_TARGET__nRF52811
#define MYNEWT_VAL_MCU_TARGET__nRF52811 (0)
#endif
#ifndef MYNEWT_VAL_MCU_TARGET__nRF52832
#define MYNEWT_VAL_MCU_TARGET__nRF52832 (0)
#endif
#ifndef MYNEWT_VAL_MCU_TARGET__nRF52840
#define MYNEWT_VAL_MCU_TARGET__nRF52840 (1)
#endif
#ifndef MYNEWT_VAL_MCU_TARGET
#define MYNEWT_VAL_MCU_TARGET (1)
#endif
#ifndef MYNEWT_VAL_OS_TICKS_PER_SEC
#define MYNEWT_VAL_OS_TICKS_PER_SEC (128)
#endif
#define MYNEWT_VAL_BLE_HCI_TRANSPORT (1)
#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0)
#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0)
#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (0)
/*** nimble/controller */
#define MYNEWT_VAL_BLE_CONTROLLER (1)
#define MYNEWT_VAL_BLE_HW_WHITELIST_ENABLE (1)
#define MYNEWT_VAL_BLE_LL_SYSVIEW (0)
#define MYNEWT_VAL_BLE_LL_PRIO (0)
#define MYNEWT_VAL_BLE_LL_SCA (MYNEWT_VAL_BLE_LL_OUR_SCA)
#define MYNEWT_VAL_BLE_LL_TX_PWR_DBM (0)
#define MYNEWT_VAL_BLE_LL_NUM_COMP_PKT_ITVL_MS (2000)
#define MYNEWT_VAL_BLE_LL_MFRG_ID (0xFFFF)
#define MYNEWT_VAL_BLE_LL_NUM_SCAN_DUP_ADVS (8)
#define MYNEWT_VAL_BLE_LL_NUM_SCAN_RSP_ADVS (8)
#define MYNEWT_VAL_BLE_LL_WHITELIST_SIZE (8)
#define MYNEWT_VAL_BLE_LL_RESOLV_LIST_SIZE (4)
#define MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE (251)
#define MYNEWT_VAL_BLE_LL_SUPP_MAX_RX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE)
#define MYNEWT_VAL_BLE_LL_SUPP_MAX_TX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE)
#define MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES (27)
#define MYNEWT_VAL_BLE_LL_CONN_INIT_SLOTS (4)
#define MYNEWT_VAL_BLE_LL_CONN_INIT_MIN_WIN_OFFSET (0)
#define MYNEWT_VAL_BLE_LL_STRICT_CONN_SCHEDULING (0)
#define MYNEWT_VAL_BLE_LL_ADD_STRICT_SCHED_PERIODS (0)
#define MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD (3250)
#define MYNEWT_VAL_BLE_LL_RNG_BUFSIZE (32)
#define MYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME (MYNEWT_VAL_BLE_XTAL_SETTLE_TIME)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION (1)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ (1)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG (1)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_PING (MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_DATA_LEN_EXT (1)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY (1)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CSA2 (0)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY (0)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY (0)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV (MYNEWT_VAL_BLE_EXT_ADV)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV (MYNEWT_VAL_BLE_PERIODIC_ADV)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_CNT (MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_LIST_CNT (MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER (MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL (0)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_SCA_UPDATE (0)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ISO (MYNEWT_VAL_BLE_ISO)
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ISO_TEST (MYNEWT_VAL_BLE_ISO_TEST)
#define MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT (0)
#define MYNEWT_VAL_BLE_PUBLIC_DEV_ADDR ((uint8_t[6]){0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
#define MYNEWT_VAL_BLE_LL_DTM (BLE_LL_DIRECT_TEST_MODE)
#define MYNEWT_VAL_BLE_LL_DTM_EXTENSIONS (0)
#define MYNEWT_VAL_BLE_LL_VND_EVENT_ON_ASSERT (0)
#define MYNEWT_VAL_BLE_LL_SYSINIT_STAGE (250)
#define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_HCI_CMD (-1)
#define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_HCI_EV (-1)
#define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_SCHED_RUN (-1)
#define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_SCHED_ITEM_CB (-1)
#define MYNEWT_VAL_BLE_LL_SCHED_AUX_MAFS_DELAY (0)
#define MYNEWT_VAL_BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY (0)
#define MYNEWT_VAL_BLE_LL_SCHED_SCAN_AUX_PDU_LEN (41)
#define MYNEWT_VAL_BLE_LL_SCHED_SCAN_SYNC_PDU_LEN (32)
#define MYNEWT_VAL_BLE_LL_DIRECT_TEST_MODE (0)
#define MYNEWT_VAL_BLE_XTAL_SETTLE_TIME (0)
#define MYNEWT_VAL_BLE_LL_OUR_SCA (60)
#define MYNEWT_VAL_BLE_DEVICE (1)
#define MYNEWT_VAL_BLE_LP_CLOCK (1)
#define MYNEWT_VAL_BLE_NUM_COMP_PKT_RATE ((2 * OS_TICKS_PER_SEC))
#define MYNEWT_VAL_BLE_LL_MASTER_SCA (4)
/*** nimble/transport/ram */
#define MYNEWT_VAL_BLE_ACL_BUF_COUNT (4)
#define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255)
#if MYNEWT_VAL_BLE_EXT_ADV
#define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (257)
#else
#define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70)
#endif
#define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (2)
#define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8)
#else // ! MICROPY_BLUETOOTH_NIMBLE_CONTROLLER
#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0)
#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0)
#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0)
#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (1)
/*** nimble/transport/uart */
#define MYNEWT_VAL_BLE_ACL_BUF_COUNT (12)
#define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255)
#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12)
#define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70)
#define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (8)
#define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8)
/* Overridden by targets/porting-nimble (defined by nimble/transport/uart) */
#define MYNEWT_VAL_BLE_HCI_UART_BAUD (MICROPY_HW_BLE_UART_BAUDRATE)
#define MYNEWT_VAL_BLE_HCI_UART_DATA_BITS (8)
@ -168,6 +303,16 @@ int nimble_sprintf(char *str, const char *fmt, ...);
#define MYNEWT_VAL_BLE_HCI_UART_PORT (MICROPY_HW_BLE_UART_ID)
#define MYNEWT_VAL_BLE_HCI_UART_STOP_BITS (1)
/*** nimble/transport/uart */
#define MYNEWT_VAL_BLE_ACL_BUF_COUNT (12)
#define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255)
#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12)
#define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70)
#define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (8)
#define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8)
#endif
/* Required for code that uses BLE_HS_LOG */
#define MYNEWT_VAL_NEWT_FEATURE_LOGCFG (1)

Wyświetl plik

@ -22,6 +22,13 @@ SD_LOWER = $(shell echo $(SD) | tr '[:upper:]' '[:lower:]')
include boards/$(BOARD)/mpconfigboard.mk
ifeq ($(SD), )
ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),nrf51 nrf52))
# On nrf51 and nrf52 use modbluetooth & nimble by default unless SD is manually specified.
MICROPY_PY_BLUETOOTH ?= 1
MICROPY_BLUETOOTH_NIMBLE ?= 1
MICROPY_BLUETOOTH_NIMBLE_CONTROLLER ?= 1
endif
# If the build directory is not given, make it reflect the board name.
BUILD ?= build-$(BOARD)
include ../../py/mkenv.mk
@ -54,12 +61,11 @@ endif
QSTR_DEFS = qstrdefsport.h
# MicroPython feature configurations
ifeq ($(DEBUG), 0)
ifneq ($(DEBUG), 1)
MICROPY_ROM_TEXT_COMPRESSION ?= 1
endif
FROZEN_MANIFEST ?= modules/manifest.py
# include py core make definitions
include ../../py/py.mk
include ../../extmod/extmod.mk
@ -235,12 +241,41 @@ SRC_C += \
drivers/bluetooth/ble_uart.c \
$(wildcard $(BOARD_DIR)/*.c) \
ifeq ($(MICROPY_PY_BLUETOOTH),1)
ifneq ($(SD), )
$(error "MICROPY_PY_BLUETOOTH cannot be used at same time as SD")
endif
# NRF chips support directly running the entire stack, so enable the controller.
MICROPY_BLUETOOTH_NIMBLE_CONTROLLER=1
ifeq ($(MICROPY_BLUETOOTH_NIMBLE),1)
GIT_SUBMODULES += lib/mynewt-nimble
SRC_C += \
mpnimbleport.c \
mpbthciport.c
INC += -I$(TOP)/$(NIMBLE_LIB_DIR)/nimble/drivers/$(MCU_VARIANT)/include
SRC_LIB_C += \
$(NIMBLE_LIB_DIR)/nimble/drivers/$(MCU_VARIANT)/src/ble_hw.c \
$(NIMBLE_LIB_DIR)/nimble/drivers/$(MCU_VARIANT)/src/ble_phy.c
ifeq ($(MCU_VARIANT), nrf52)
SRC_LIB_C += $(NIMBLE_LIB_DIR)/nimble/drivers/$(MCU_VARIANT)/src/ble_phy_trace.c
endif
endif
endif
ifeq ($(MCU_SUB_VARIANT), nrf52840)
INC += -I./drivers/usb
INC += -I../../lib/tinyusb/src
# If SoftDevice is selected.
ifneq ($(SD), )
# For external tinyusb drivers to enable SoftDevice mode.
@ -273,6 +308,14 @@ DRIVERS_SRC_C += $(addprefix modules/,\
os/microbitfs.c \
board/modboard.c \
board/led.c \
music/modmusic.c \
music/musictunes.c \
nrf/modnrf.c \
nrf/flashbdev.c \
)
ifneq ($(SD), )
DRIVERS_SRC_C += $(addprefix modules/,\
ubluepy/modubluepy.c \
ubluepy/ubluepy_peripheral.c \
ubluepy/ubluepy_service.c \
@ -283,12 +326,9 @@ DRIVERS_SRC_C += $(addprefix modules/,\
ubluepy/ubluepy_descriptor.c \
ubluepy/ubluepy_scanner.c \
ubluepy/ubluepy_scan_entry.c \
music/modmusic.c \
music/musictunes.c \
ble/modble.c \
nrf/modnrf.c \
nrf/flashbdev.c \
)
endif
# Custom micropython startup file with smaller interrupt vector table
# than the file provided in nrfx.
@ -306,6 +346,7 @@ OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SYSTEM_C_SRC:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_LIB_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_C:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o))
OBJ += $(GEN_PINS_SRC:.c=.o)
$(BUILD)/$(OOFATFS_DIR)/ff.o: COPT += -Os
@ -446,8 +487,12 @@ nrfutil_dfu_sd: $(BUILD)/$(OUTPUT_FILENAME).hex
$(Q)nrfutil pkg generate --hw-version 52 --sd-req 0x00 --sd-id 0x00 --softdevice $(BUILD)/stripped_sd.hex $(BUILD)/stripped_sd.zip
$(Q)nrfutil dfu usb-serial -pkg $(BUILD)/stripped_sd.zip -p $(NRFUTIL_PORT) -t 0
nrfutil_dfu_deploy: $(BUILD)/$(OUTPUT_FILENAME).hex
$(BUILD)/$(OUTPUT_FILENAME)_dfu.zip: $(BUILD)/$(OUTPUT_FILENAME).hex
$(Q)nrfutil pkg generate --hw-version 52 --sd-req $(NRFUTIL_SD_REQ) --application-version 1 --application $(BUILD)/$(OUTPUT_FILENAME).hex $(BUILD)/$(OUTPUT_FILENAME)_dfu.zip
nrfutil_pkg: $(BUILD)/$(OUTPUT_FILENAME)_dfu.zip
nrfutil_dfu_deploy: nrfutil_pkg
$(Q)nrfutil dfu usb-serial -pkg $(BUILD)/$(OUTPUT_FILENAME)_dfu.zip -p $(NRFUTIL_PORT) -t 0
deploy: nrfutil_dfu_deploy

Wyświetl plik

@ -4,11 +4,19 @@ MCU_SUB_VARIANT = nrf51822
SOFTDEV_VERSION = 8.0.0
ifneq ($(SD),)
LD_FILES += boards/MICROBIT/custom_nrf51822_s110_microbit.ld
# If SD is used we need to reduce flash use by application
LD_FILES += boards/MICROBIT/nrf51822_smaller_fs.ld
FROZEN_MANIFEST ?=
else
MICROPY_VFS_LFS2 = 1
MICROPY_VFS_LFS2 = 0
else
ifneq ($(MICROPY_PY_BLUETOOTH),0)
# Otherwise if modbluetooth isn't disabled
# we can need to reduce flash usage a little.
LD_FILES += boards/MICROBIT/nrf51822_smaller_fs.ld
endif
endif
# Enable LFS2 if not disabled above.
MICROPY_VFS_LFS2 ?= 1
LD_FILES += boards/nrf51x22_256k_16k.ld
FLASHER = pyocd

Wyświetl plik

@ -1,7 +1,6 @@
MCU_SERIES = m4
MCU_VARIANT = nrf52
MCU_SUB_VARIANT = nrf52840
SOFTDEV_VERSION = 6.1.1
DFU ?= 1

Wyświetl plik

@ -31,6 +31,7 @@
#include "nrf_rng.h"
#include "drivers/rng.h"
#include "py/runtime.h"
#if BLUETOOTH_SD
#include "nrf_soc.h"
@ -38,8 +39,35 @@
#define BLUETOOTH_STACK_ENABLED() (ble_drv_stack_enabled())
#endif
#if MICROPY_PY_BLUETOOTH
#include "controller/ble_ll.h"
#include "extmod/modbluetooth.h"
#include "mpnimbleport.h"
// Will be set by ble_npl_hw_set_isr() during init
func nrf_ble_isr_rng = NULL;
void RNG_IRQHandler(void)
{
/*** nimble/drivers/nrf52/src/ble_hw.c */
if (nrf_ble_isr_rng != NULL) {
nrf_ble_isr_rng();
}
}
#endif
static inline uint32_t generate_hw_random(void) {
uint32_t retval = 0;
#if MICROPY_PY_BLUETOOTH
if (!mp_bluetooth_is_active()) {
// This is safe to re-init if we can't be sure it's already done.
ble_ll_rand_init();
}
ble_ll_rand_data_get((uint8_t *)&retval, 4);
#else
uint8_t * p_retval = (uint8_t *)&retval;
nrf_rng_event_clear(NRF_RNG, NRF_RNG_EVENT_VALRDY);
@ -55,7 +83,7 @@ static inline uint32_t generate_hw_random(void) {
}
nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_STOP);
#endif
return retval;
}

Wyświetl plik

@ -26,7 +26,7 @@
#include "py/mphal.h"
#if MICROPY_PY_MACHINE_SOFT_PWM
#if MICROPY_PY_TICKER
#include "ticker.h"
#include "nrfx_glue.h"
@ -166,4 +166,4 @@ void SlowTicker_IRQHandler(void)
}
}
#endif // MICROPY_PY_MACHINE_SOFT_PWM
#endif // MICROPY_PY_TICKER

Wyświetl plik

@ -55,6 +55,10 @@
#include "rtcounter.h"
#include "mphalport.h"
#if MICROPY_PY_BLUETOOTH
#include "extmod/modbluetooth.h"
#endif
#if MICROPY_PY_MACHINE_HW_PWM
#include "pwm.h"
#endif
@ -68,8 +72,11 @@
#include "ble_uart.h"
#endif
#if MICROPY_PY_MACHINE_SOFT_PWM
#if MICROPY_PY_TICKER
#include "ticker.h"
#endif
#if MICROPY_PY_MACHINE_SOFT_PWM
#include "softpwm.h"
#endif
@ -242,8 +249,11 @@ soft_reset:
ble_uart_init0();
#endif
#if MICROPY_PY_MACHINE_SOFT_PWM
#if MICROPY_PY_TICKER
ticker_init0();
#endif
#if MICROPY_PY_MACHINE_SOFT_PWM
softpwm_init0();
#endif
@ -254,8 +264,11 @@ soft_reset:
board_modules_init0();
#endif
#if MICROPY_PY_MACHINE_SOFT_PWM
#if MICROPY_PY_TICKER
ticker_start();
#endif
#if MICROPY_PY_MACHINE_SOFT_PWM
pwm_start();
#endif
@ -292,6 +305,10 @@ soft_reset:
pwm_deinit_all();
#endif
#if MICROPY_PY_BLUETOOTH
mp_bluetooth_deinit();
#endif
mp_deinit();
printf("MPY: soft reboot\n");

Wyświetl plik

@ -56,9 +56,13 @@ typedef struct _machine_rtc_obj_t {
} machine_rtc_obj_t;
static const nrfx_rtc_t machine_rtc_instances[] = {
#if NRFX_RTC0_ENABLED
NRFX_RTC_INSTANCE(0),
#endif
#if NRFX_RTC1_ENABLED
NRFX_RTC_INSTANCE(1),
#if defined(NRF52_SERIES)
#endif
#if NRFX_RTC2_ENABLED
NRFX_RTC_INSTANCE(2),
#endif
};

Wyświetl plik

@ -53,7 +53,7 @@ static mp_obj_t machine_timer_callbacks[] = {
static const machine_timer_obj_t machine_timer_obj[] = {
{{&machine_timer_type}, NRFX_TIMER_INSTANCE(0)},
#if MICROPY_PY_MACHINE_SOFT_PWM
#if MICROPY_PY_TICKER
{ },
#else
{{&machine_timer_type}, NRFX_TIMER_INSTANCE(1)},
@ -118,7 +118,7 @@ static mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args,
}
#endif
#if MICROPY_PY_MACHINE_SOFT_PWM
#if MICROPY_PY_TICKER
if (timer_id == 1) {
mp_raise_ValueError(MP_ERROR_TEXT("Timer reserved by ticker driver"));
}

Wyświetl plik

@ -0,0 +1,81 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Jim Mussared
* Copyright (c) 2020 Damien P. George
* Copyright (c) 2022 Andrew Leech
*
* 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/runtime.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#if MICROPY_PY_BLUETOOTH
#define DEBUG_printf(...) // mp_printf(&mp_plat_print, "mpbthciport.c: " __VA_ARGS__)
#include "mpbthciport.h"
#include "drivers/ticker.h"
#define BLUETOOTH_TICKER_SLOT 0
// // Prevent double-enqueuing of the scheduled task.
static volatile bool events_task_is_scheduled = false;
void mp_bluetooth_hci_init(void) {
/* Start regular background task to handle events */
events_task_is_scheduled = false;
set_ticker_callback(BLUETOOTH_TICKER_SLOT, mp_bluetooth_hci_poll_now, 0);
}
void mp_bluetooth_hci_deinit(void) {
clear_ticker_callback(BLUETOOTH_TICKER_SLOT);
events_task_is_scheduled = false;
}
// For synchronous mode, we run all BLE stack code inside a scheduled task.
// This task is scheduled periodically via a timer.
static mp_obj_t run_events_scheduled_task(mp_obj_t none_in) {
(void)none_in;
events_task_is_scheduled = false;
mp_bluetooth_hci_poll();
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(run_events_scheduled_task_obj, run_events_scheduled_task);
// Called periodically (ticker) to request that processing happens in the scheduler.
int32_t mp_bluetooth_hci_poll_now(void) {
// Return interval (128ms in 16us ticks) until next callback run
uint32_t next_tick = 128000 / 16;
if (!events_task_is_scheduled) {
events_task_is_scheduled = mp_sched_schedule(MP_OBJ_FROM_PTR(&run_events_scheduled_task_obj), mp_const_none);
if (!events_task_is_scheduled) {
// The schedule queue is full, set callback to try again soon (5ms).
next_tick = 5000 / 16;
}
}
return next_tick;
}
#endif // MICROPY_PY_BLUETOOTH

Wyświetl plik

@ -0,0 +1,42 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2021 Damien P. George
*
* 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_MPBTHCIPORT_H
#define MICROPY_INCLUDED_NRF_MPBTHCIPORT_H
// Initialise the HCI subsystem (should be called once, early on).
void mp_bluetooth_hci_init(void);
void mp_bluetooth_hci_deinit(void);
// Poll the HCI now.
int32_t mp_bluetooth_hci_poll_now(void);
// Must be provided by the stack bindings (e.g. mpnimbleport.c or mpbtstackport.c).
// Request new HCI data and pass to the stack, and run pending events/callouts.
// This is a low-level function and should not be called directly, use
// mp_bluetooth_hci_poll_now/mp_bluetooth_hci_poll_in_ms instead.
void mp_bluetooth_hci_poll(void);
#endif // MICROPY_INCLUDED_RP2_MPBTHCIPORT_H

Wyświetl plik

@ -31,8 +31,8 @@
// Set default feature levels for each processor
#if defined(NRF51822)
#if defined(BLUETOOTH_SD)
// If SoftDevice is used there is less flash/ram available for application
#if BLUETOOTH_SD || MICROPY_PY_BLUETOOTH
// If Bluetooth is used there is less flash/ram available for application
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_MINIMUM)
#else
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_CORE_FEATURES)
@ -160,6 +160,7 @@
#endif
#define MICROPY_PY_FUNCTION_ATTRS (1)
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
#define MICROPY_PY_BUILTINS_BYTEARRAY (1)
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
#define MICROPY_PY_BUILTINS_FROZENSET (1)
#define MICROPY_PY_BUILTINS_COMPILE (1)
@ -179,6 +180,9 @@
#define MICROPY_PY_MACHINE_BOOTLOADER (1)
#define MICROPY_PY_MACHINE_PULSE (0)
#define MICROPY_PY_MACHINE_SOFTI2C (MICROPY_PY_MACHINE_I2C)
#ifndef MICROPY_ENABLE_SCHEDULER
#define MICROPY_ENABLE_SCHEDULER (1)
#endif
#ifndef MICROPY_HW_LED_COUNT
#define MICROPY_HW_LED_COUNT (0)
@ -241,9 +245,22 @@
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0)
// if sdk is in use, import configuration and enable some core features
#define MICROPY_PY_TICKER (MICROPY_PY_MACHINE_SOFT_PWM || MICROPY_PY_BLUETOOTH)
#ifndef MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE
#define MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE (1)
#endif
#ifndef MICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS
#define MICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS (MICROPY_BLUETOOTH_NIMBLE)
#endif
#if BLUETOOTH_SD
#include "bluetooth_conf.h"
#endif
// if Bluetooth is in use ensure some core features are enabled.
#if BLUETOOTH_SD || MICROPY_PY_BLUETOOTH
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (1)
#define MICROPY_COMP_CONST (1)
#define MICROPY_COMP_CONST_FOLDING (1)
@ -348,6 +365,30 @@ long unsigned int rng_generate_random_word(void);
#ifndef MP_NEED_LOG2
#define MP_NEED_LOG2 (1)
// We have inlined IRQ functions for efficiency (they are generally
// 1 machine instruction).
//
// Note on IRQ state: you should not need to know the specific
// value of the state variable, but rather just pass the return
// value from disable_irq back to enable_irq. If you really need
// to know the machine-specific values, see irq.h.
#include <nrf.h>
static inline void enable_irq(mp_uint_t state) {
__set_PRIMASK(state);
}
static inline mp_uint_t disable_irq(void) {
mp_uint_t state = __get_PRIMASK();
__disable_irq();
return state;
}
#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
#endif
#ifndef MICROPY_BOARD_STARTUP

Wyświetl plik

@ -220,16 +220,19 @@ void mp_hal_stdout_tx_str(const char *str) {
void mp_hal_delay_us(mp_uint_t us) {
uint32_t now;
if (us == 0) {
MICROPY_EVENT_POLL_HOOK
return;
}
now = mp_hal_ticks_us();
while (mp_hal_ticks_us() - now < us) {
MICROPY_EVENT_POLL_HOOK
}
}
void mp_hal_delay_ms(mp_uint_t ms) {
uint32_t now;
if (ms == 0) {
MICROPY_EVENT_POLL_HOOK
return;
}
now = mp_hal_ticks_ms();

Wyświetl plik

@ -0,0 +1,155 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Jim Mussared
* Copyright (c) 2020 Damien P. George
* Copyright (c) 2022 Andrew Leech
*
* 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/runtime.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#include "led.h"
#if MICROPY_PY_BLUETOOTH && MICROPY_BLUETOOTH_NIMBLE
#define DEBUG_printf(...) // mp_printf(&mp_plat_print, "mpnimbleport.c: " __VA_ARGS__)
#include "mpbthciport.h"
#include "drivers/rng.h"
#include "nimble/nimble_npl.h"
#include "controller/ble_ll.h"
#include "controller/ble_ll_hci.h"
#include "nimble/controller/src/ble_ll_conn_priv.h"
#include "controller/ble_phy.h"
#include "nimble/ble_hci_trans.h"
#include "extmod/nimble/modbluetooth_nimble.h"
void mp_bluetooth_hci_controller_init(void) {
DEBUG_printf("mp_bluetooth_hci_controller_init\n");
// Init ble phy
// ref: nimble/controller/src/ble_ll.c:ble_ll_task()
ble_phy_init();
// Set output power to 1mW (0 dBm)
ble_phy_txpwr_set(MYNEWT_VAL(BLE_LL_TX_PWR_DBM));
// Register callback for transport
ble_hci_trans_cfg_ll(ble_ll_hci_cmd_rx, NULL, ble_ll_hci_acl_rx, NULL);
// Tell the host that we are ready to receive packets
ble_ll_hci_send_noop();
}
void mp_bluetooth_hci_controller_deinit(void) {
mp_bluetooth_hci_deinit();
}
// The global BLE controller LL data object
extern struct ble_ll_obj g_ble_ll_data;
static void run_controller_events() {
struct ble_npl_event *ev = ble_npl_eventq_get(&g_ble_ll_data.ll_evq, 0);
if (ev != NULL) {
ble_npl_event_run(ev);
}
}
// Get any pending data from the UART and send it to NimBLE's HCI buffers.
// Any further processing by NimBLE will be run via its event queue.
void mp_bluetooth_hci_poll(void) {
if (mp_bluetooth_nimble_ble_state >= MP_BLUETOOTH_NIMBLE_BLE_STATE_WAITING_FOR_SYNC) {
// DEBUG_printf("mp_bluetooth_hci_poll_uart %d\n", mp_bluetooth_nimble_ble_state);
// Handle any controller events first
run_controller_events();
// Run any timers.
mp_bluetooth_nimble_os_callout_process();
// Run any remaining events.
mp_bluetooth_nimble_os_eventq_run_all();
}
}
// --- Port-specific helpers for the generic NimBLE bindings. -----------------
void mp_bluetooth_nimble_hci_uart_wfi(void) {
#if defined(__WFI)
__WFI();
#endif
run_controller_events();
}
long jrand48(unsigned short xsubi[3]) {
ble_ll_rand_data_get((uint8_t *)xsubi, 4);
return *((long *)xsubi);
}
// The interrupt table (VTOR) on nrf port is not in sram so NVIC_SetVector() doesn't work.
// Capture the required interrupt handler callbacks used in the nimble controller here to run in
// the statically defined interrupt handler functions.
// ref: ports/nrf/drivers/rng.c
extern func nrf_ble_isr_rng;
static func nrf_ble_isr_phy = NULL;
static func nrf_ble_isr_rtc0 = NULL;
void RADIO_IRQHandler(void) {
if (nrf_ble_isr_phy != NULL) {
nrf_ble_isr_phy();
}
}
void RTC0_IRQHandler(void) {
if (nrf_ble_isr_rtc0 != NULL) {
nrf_ble_isr_rtc0();
}
}
void ble_npl_hw_set_isr(int irq_num, func irq_isr) {
switch (irq_num) {
case RNG_IRQn:
nrf_ble_isr_rng = irq_isr;
break;
case RADIO_IRQn:
nrf_ble_isr_phy = irq_isr;
break;
case RTC0_IRQn:
nrf_ble_isr_rtc0 = irq_isr;
break;
default:
// Unknown ISR
assert(0);
}
}
#endif // MICROPY_PY_BLUETOOTH && MICROPY_BLUETOOTH_NIMBLE

Wyświetl plik

@ -0,0 +1,42 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Andrew Leech
*
* 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_NIMBLE_PORT_H
#define MICROPY_INCLUDED_NRF_NIMBLE_PORT_H
typedef void (*func)(void);
// #define OS_CPUTIME_FREQ_PWR2
/*** src/micropython/lib/mynewt-nimble/nimble/drivers/nrf52/syscfg.yml */
#define MYNEWT_VAL_BLE_PHY_SYSVIEW (0)
#define MYNEWT_VAL_BLE_PHY_CODED_RX_IFS_EXTRA_MARGIN (0)
#define MYNEWT_VAL_BLE_PHY_DBG_TIME_TXRXEN_READY_PIN (-1)
#define MYNEWT_VAL_BLE_PHY_DBG_TIME_ADDRESS_END_PIN (-1)
#define MYNEWT_VAL_BLE_PHY_DBG_TIME_WFR_PIN (-1)
#define MYNEWT_VAL_BLE_PHY_NRF52840_ERRATA_164 (0)
#define MYNEWT_VAL_BLE_PHY_NRF52840_ERRATA_191 (1)
#endif // MICROPY_INCLUDED_NRF_NIMBLE_PORT_H

Wyświetl plik

@ -134,18 +134,21 @@
#define NRFX_SPIM_MISO_PULL_CFG 1
#define NRFX_RTC_ENABLED (MICROPY_PY_MACHINE_RTCOUNTER)
#if !MICROPY_BLUETOOTH_NIMBLE_CONTROLLER
#define NRFX_RTC0_ENABLED 1
#else
#define NRFX_RTC0_ENABLED 0
#endif
#define NRFX_RTC1_ENABLED 1
#define NRFX_RTC2_ENABLED (!NRF51) && (!NRF9160_XXAA)
#define NRFX_TIMER_ENABLED (MICROPY_PY_MACHINE_TIMER_NRF)
#define NRFX_TIMER0_ENABLED 1
#define NRFX_TIMER1_ENABLED (!MICROPY_PY_MACHINE_SOFT_PWM)
#define NRFX_TIMER1_ENABLED (!MICROPY_PY_TICKER)
#define NRFX_TIMER2_ENABLED 1
#define NRFX_TIMER3_ENABLED (!NRF51) && (!NRF9160_XXAA)
#define NRFX_TIMER4_ENABLED (!NRF51) && (!NRF9160_XXAA)
#define NRFX_PWM_ENABLED (!NRF51) && MICROPY_PY_MACHINE_HW_PWM
#define NRFX_PWM0_ENABLED 1
#define NRFX_PWM1_ENABLED 1