Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Juergen Marsch 2016-07-28 10:16:40 +02:00
commit a6ca3586be
16 changed files with 407 additions and 663 deletions

View File

@ -1,3 +1,13 @@
1v87 : Add support for compiling with float-abi=hard (even if it doesn't give us real-world benefits)
Add shortcut for quick execution of common call types
Fix BBC micro:bit save() regression from 1v86
Fix 'lock overflow' when calling methods with 'this' bound (fix #870, fix #885)
Fix jsvStringIteratorGetCharOrMinusOne for zero-length strings
Allow tab-completion straight after '.'
Make sure execution stops for native functions if there's an error when parsing arguments
NRF5x: remove setName and add functionality to setAdvertising, along with advertising interval
NRF5x: allow raw advertising data in setAdvertising
1v86 : Compile Telnet server into linux by default, Add '--telnet' command-line option to enable it
Fix lock 'leak' in Telnet when Telnet is turned off
Add Telnet serial device to allow redirection

View File

@ -67,7 +67,7 @@
# # GENDIR=/home/mydir/mygendir
# SETDEFINES=FileDefines # settings which are called after definitions for board are done
# # SETDEFINES=/home/mydir/myDefines
# UNSUPPORTEDMAKE=FileUnsu# Adds additional files from unsupported sources(means not supported by Gordon) to actual make
# UNSUPPORTEDMAKE=FileUnsu# Adds additional files from unsupported sources(means not supported by Gordon) to actual make
# # UNSUPPORTEDMAKE=/home/mydir/unsupportedCommands
# PROJECTNAME=myBigProject# Sets projectname
# BLACKLIST=fileBlacklist # Removes javascript commands given in a file from compilation and therefore from project defined firmware
@ -497,7 +497,6 @@ USE_GRAPHICS=1
USE_FILESYSTEM=1
USE_CRYPTO=1
#USE_TLS=1
DEFINES += -DBOARD_PCA10040 # remove
else ifdef LPC1768
EMBEDDED=1
@ -674,7 +673,7 @@ USE_HASHLIB=1
USE_GRAPHICS=1
USE_CRYPTO=1
USE_TLS=1
USE_TELNET=1
USE_TELNET=1
#USE_LCD_SDL=1
ifdef MACOSX
@ -689,7 +688,7 @@ endif
endif
endif
#set or reset defines like USE_GRAPHIC from an external file to customize firmware
#set or reset defines like USE_GRAPHIC from an external file to customize firmware
ifdef SETDEFINES
include $(SETDEFINES)
endif
@ -879,11 +878,11 @@ INCLUDE += -I$(ROOT)/libs/math
WRAPPERSOURCES += libs/math/jswrap_math.c
ifeq ($(FAMILY),ESP8266)
# special ESP8266 maths lib that doesn't go into RAM
LIBS += -lmirom
LIBS += -lmirom
LDFLAGS += -L$(ROOT)/targets/esp8266
else
# everything else uses normal maths lib
LIBS += -lm
LIBS += -lm
endif
endif
@ -1092,7 +1091,7 @@ libs/crypto/mbedtls/library/cipher_wrap.c \
libs/crypto/mbedtls/library/md.c \
libs/crypto/mbedtls/library/md_wrap.c \
libs/crypto/mbedtls/library/oid.c \
libs/crypto/mbedtls/library/pkcs5.c
libs/crypto/mbedtls/library/pkcs5.c
endif
endif
@ -1179,6 +1178,10 @@ endif #STM32F3
ifeq ($(FAMILY), STM32F4)
ARCHFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp
# The archflags below use the STM32F4's FPU for 32 bit floats, and pass doubles as 64 bit
# Thing is, we don't use 'float', and only use doubles so this is basically useless to us (and increases code size)
# ARCHFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4 -mabi=aapcs -mfloat-abi=hard -mfpu=fpv4-sp-d16
ARM=1
DEFINES += -DSTM32F4
ifdef WICED_XXX
@ -1287,7 +1290,7 @@ ifeq ($(FAMILY), NRF51)
NRF5X=1
NRF5X_SDK_PATH=$(ROOT)/targetlibs/nrf5x/nrf5_sdk
# ARCHFLAGS are shared by both CFLAGS and LDFLAGS.
ARCHFLAGS = -mcpu=cortex-m0 -mthumb -mabi=aapcs -mfloat-abi=soft # Use nRF51 makefiles provided in SDK as reference.
@ -1309,7 +1312,7 @@ ifeq ($(FAMILY), NRF51)
NRF_BOOTLOADER = $(ROOT)/targetlibs/nrf5x/nrf5_singlebank_bl_hex/nrf51_s130_singlebank_bl.hex
NFR_BL_START_ADDR = 0x3C000
NRF_BOOTLOADER_SETTINGS = $(ROOT)/targetlibs/nrf5x/nrf5_singlebank_bl_hex/bootloader_settings_nrf51.hex # This file writes 0x3FC00 with 0x01 so we can flash the application with the bootloader.
endif
endif # FAMILY == NRF51
@ -1320,11 +1323,8 @@ ifeq ($(FAMILY), NRF52)
NRF5X_SDK_PATH=$(ROOT)/targetlibs/nrf5x/nrf5_sdk
# ARCHFLAGS are shared by both CFLAGS and LDFLAGS.
ARCHFLAGS = -mcpu=cortex-m4 -mthumb -mfloat-abi=softfp -mlittle-endian -mfpu=fpv4-sp-d16 # compile flags as used for Pico
# Below are the flags used by nRF52 makefiles. This breaks the argument packing done by jsnative.c on newer GCC versions
# Compile with 'DEBUG=1 NRF52832DK=1 make', and check whether you get warnings at startup
#ARCHFLAGS = -mcpu=cortex-m4 -mthumb -mabi=aapcs -mfloat-abi=hard -mfpu=fpv4-sp-d16
ARCHFLAGS = -mcpu=cortex-m4 -mthumb -mabi=aapcs -mfloat-abi=hard -mfpu=fpv4-sp-d16
# nRF52 specific.
INCLUDE += -I$(NRF5X_SDK_PATH)/../nrf52_config
INCLUDE += -I$(NRF5X_SDK_PATH)/components/softdevice/s132/headers
@ -1348,10 +1348,6 @@ endif #FAMILY == NRF52
ifdef NFC
# FIXME TODO SUPER NASTY - For some reason, NFC is a binary blob, and it's compiled with VFP argument passing
# This breaks passing of floats in Espruino, but we have to do it anyway just to build :(
ARCHFLAGS = -mcpu=cortex-m4 -mthumb -mabi=aapcs -mfloat-abi=hard -mfpu=fpv4-sp-d16
# --------------------------
DEFINES += -DUSE_NFC
INCLUDE += -I$(NRF5X_SDK_PATH)/components/drivers_nrf/clock
INCLUDE += -I$(NRF5X_SDK_PATH)/components/nfc/t2t_lib
@ -1448,12 +1444,12 @@ ifdef NRF5X
# Just try and get rid of the compile warnings.
CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-parameter -fomit-frame-pointer #this is for device manager in nordic sdk
DEFINES += -DBLUETOOTH
DEFINES += -DBLUETOOTH -D$(BOARD)
ARM = 1
ARM_HAS_OWN_CMSIS = 1 # Nordic uses its own CMSIS files in its SDK, these are up-to-date.
INCLUDE += -I$(ROOT)/targetlibs/nrf5x -I$(NRF5X_SDK_PATH)
TEMPLATE_PATH = $(ROOT)/targetlibs/nrf5x/nrf5x_linkers # This is where the common linker for both nRF51 & nRF52 is stored.
LDFLAGS += -L$(TEMPLATE_PATH)
@ -1490,6 +1486,7 @@ ifdef NRF5X
INCLUDE += -I$(NRF5X_SDK_PATH)/components/libraries/trace
INCLUDE += -I$(NRF5X_SDK_PATH)/components/softdevice/common/softdevice_handler
INCLUDE += -I$(NRF5X_SDK_PATH)/components/drivers_nrf/twi_master
INCLUDE += -I$(NRF5X_SDK_PATH)/components/drivers_nrf/hal/nrf_pwm
TARGETSOURCES += \
$(NRF5X_SDK_PATH)/components/libraries/util/app_error.c \
@ -1511,7 +1508,7 @@ ifdef NRF5X
$(NRF5X_SDK_PATH)/components/softdevice/common/softdevice_handler/softdevice_handler.c \
$(NRF5X_SDK_PATH)/components/drivers_nrf/hal/nrf_nvmc.c \
$(NRF5X_SDK_PATH)/components/drivers_nrf/twi_master/nrf_drv_twi.c \
$(NRF5X_SDK_PATH)/components/drivers_nrf/hal/nrf_adc.c
$(NRF5X_SDK_PATH)/components/drivers_nrf/hal/nrf_adc.c
# $(NRF5X_SDK_PATH)/components/libraries/util/nrf_log.c
ifdef USE_BOOTLOADER
@ -1673,7 +1670,7 @@ else ifdef EFM32
LDFLAGS += $(OPTIMIZEFLAGS) $(ARCHFLAGS)
LDFLAGS += -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
else
LDFLAGS += $(OPTIMIZEFLAGS) $(ARCHFLAGS)
LDFLAGS += $(OPTIMIZEFLAGS) $(ARCHFLAGS)
endif
ifdef EMBEDDED
@ -1725,7 +1722,7 @@ ESPTOOL ?= $(ESP8266_SDK_ROOT)/esptool/esptool.py
INCLUDE += -I$(ESP8266_SDK_ROOT)/include -I$(ROOT)/targets/esp8266
endif # ESP8266
# Adds additional files from unsupported sources(means not supported by Gordon) to actual make
# Adds additional files from unsupported sources(means not supported by Gordon) to actual make
ifdef UNSUPPORTEDMAKE
include $(UNSUPPORTEDMAKE)
endif
@ -1764,7 +1761,7 @@ ifdef USE_NET
# hack to ensure that Pico/etc have all possible firmware configs listed
$(Q)python scripts/build_board_json.py $(WRAPPERSOURCES) $(DEFINES) -DUSE_WIZNET=1 -DUSE_CC3000=1 -B$(BOARD)
else
$(Q)python scripts/build_board_json.py $(WRAPPERSOURCES) $(DEFINES) -B$(BOARD)
$(Q)python scripts/build_board_json.py $(WRAPPERSOURCES) $(DEFINES) -B$(BOARD)
endif
@ -1793,7 +1790,7 @@ $(PLATFORM_CONFIG_FILE): boards/$(BOARD).py scripts/build_platform_config.py
$(Q)python scripts/build_platform_config.py $(BOARD) $(HEADERFILENAME)
# skips compiling and linking, if NO_COMPILE is defined
# Generation of temporary files and setting of wrappersources is already done this moment
# Generation of temporary files and setting of wrappersources is already done this moment
ifndef NO_COMPILE
compile=$(CC) $(CFLAGS) $< -o $@
@ -1871,7 +1868,7 @@ ifdef USE_CRYPTO
$(Q)$(OBJCOPY) --rename-section .rodata=.irom0.text libs/crypto/mbedtls/library/sha1.o
$(Q)$(OBJCOPY) --rename-section .rodata=.irom0.text libs/crypto/mbedtls/library/sha256.o
$(Q)$(OBJCOPY) --rename-section .rodata=.irom0.text libs/crypto/mbedtls/library/sha512.o
endif
endif
$(Q)$(LD) $(OPTIMIZEFLAGS) -nostdlib -Wl,--no-check-sections -Wl,-static -r -o $@ $(OBJS)
$(Q)$(OBJCOPY) --rename-section .text=.irom0.text --rename-section .literal=.irom0.literal $@

View File

@ -38,7 +38,7 @@ chip = {
'package' : "QFN48",
'ram' : 16,
'flash' : 256,
'speed' : 96,
'speed' : 16,
'usart' : 1,
'spi' : 1,
'i2c' : 1,
@ -49,8 +49,8 @@ chip = {
'saved_code' : {
'address' : ((256 - 3) * 1024),
'page_size' : 1024,
'pages' : 0,
'flash_available' : (256 - 108 - 16) # total flash pages - softdevice - bootloader
'pages' : 3,
'flash_available' : (256 - 108 - 3) # total flash pages - softdevice - saved code
}
};

View File

@ -60,10 +60,9 @@ bool nfcEnabled = false;
APP_RAM_BASE_CENTRAL_LINKS_##CENTRAL_LINK_COUNT##_PERIPH_LINKS_##PERIPHERAL_LINK_COUNT##_SEC_COUNT_##CENTRAL_LINK_COUNT##_MID_BW
#define IDEAL_RAM_START_ADDRESS(C_LINK_CNT, P_LINK_CNT) IDEAL_RAM_START_ADDRESS_INTERN(C_LINK_CNT, P_LINK_CNT)
#define DEVICE_NAME "Espruino "PC_BOARD_ID /**< Name of device. Will be included in the advertising data. */
#define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service (vendor specific). */
#define APP_ADV_INTERVAL 600 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 375ms). */
#define APP_DEFAULT_ADV_INTERVAL MSEC_TO_UNITS(375, UNIT_0_625_MS) /**< The advertising interval (in units of 0.625 ms). */
#define APP_ADV_TIMEOUT_IN_SECONDS 180 /**< The advertising timeout (in units of seconds). */
#define SCAN_INTERVAL 0x00A0 /**< Scan interval in units of 0.625 millisecond. 100ms */
@ -96,8 +95,6 @@ bool nfcEnabled = false;
#endif
#define BLE_HANDLE_MAX 0xFFFF /**< Max handle value in BLE. */
#define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
static ble_nus_t m_nus; /**< Structure to identify the Nordic UART Service. */
static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
#if CENTRAL_LINK_COUNT>0
@ -111,6 +108,8 @@ static ble_dfu_t m_dfus;
static dm_application_instance_t m_app_handle; /**< Application identifier allocated by device manager */
#endif
uint16_t advertising_interval = APP_DEFAULT_ADV_INTERVAL;
typedef enum {
BLE_NONE = 0,
@ -215,9 +214,19 @@ Called when an NFC field is no longer detected
* @details
*/
void ble_app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name) {
jsiConsolePrintf("NRF ERROR 0x%x at %s:%d\n", error_code, p_file_name, line_num);
#ifdef LED1_PININDEX
jshPinOutput(LED1_PININDEX, LED1_ONSTATE);
#endif
#ifdef LED2_PININDEX
jshPinOutput(LED2_PININDEX, LED2_ONSTATE);
#endif
#ifdef LED3_PININDEX
jshPinOutput(LED3_PININDEX, LED3_ONSTATE);
#endif
jsiConsolePrintf("NRF ERROR 0x%x at %s:%d\n", error_code, p_file_name?p_file_name:"?", line_num);
jsiConsolePrint("REBOOTING.\n");
jshTransmitFlush();
jshDelayMicroseconds(1000000);
NVIC_SystemReset();
}
@ -232,22 +241,38 @@ void ble_app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t
* @param[in] line_num Line number of the failing ASSERT call.
* @param[in] p_file_name File name of the failing ASSERT call.
*/
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
{
ble_app_error_handler(DEAD_BEEF, line_num, p_file_name);
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name) {
ble_app_error_handler(0xDEADBEEF, line_num, p_file_name);
}
#ifdef USE_BOOTLOADER
/**@brief Function for stopping advertising.
*/
static void advertising_stop(void)
{
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) {
ble_app_error_handler(id, pc, 0);
}
void advertising_start(void) {
uint32_t err_code = 0;
// Actually start advertising
ble_gap_adv_params_t adv_params;
memset(&adv_params, 0, sizeof(adv_params));
adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;
adv_params.p_peer_addr = NULL;
adv_params.fp = BLE_GAP_ADV_FP_ANY;
adv_params.p_whitelist = NULL;
adv_params.timeout = APP_ADV_TIMEOUT_IN_SECONDS;
adv_params.interval = advertising_interval;
err_code = sd_ble_gap_adv_start(&adv_params);
APP_ERROR_CHECK(err_code);
}
static void advertising_stop(void) {
uint32_t err_code;
err_code = sd_ble_gap_adv_stop();
APP_ERROR_CHECK(err_code);
}
#ifdef USE_BOOTLOADER
/**@brief Function for loading application-specific context after establishing a secure connection.
*
@ -343,11 +368,28 @@ static void gap_params_init(void)
ble_gap_conn_params_t gap_conn_params;
ble_gap_conn_sec_mode_t sec_mode;
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
char deviceName[BLE_GAP_DEVNAME_MAX_LEN];
#ifdef PUCKJS
strcpy(deviceName,"Puck.js");
#else
strcpy(deviceName,"Espruino "PC_BOARD_ID);
#endif
size_t len = strlen(deviceName);
#ifdef PUCKJS
// append last 2 bytes of MAC address to name
uint32_t addr = NRF_FICR->DEVICEADDR[0];
deviceName[len++] = ' ';
deviceName[len++] = itoch((addr>>12)&15);
deviceName[len++] = itoch((addr>>8)&15);
deviceName[len++] = itoch((addr>>4)&15);
deviceName[len++] = itoch((addr)&15);
// not null terminated
#endif
err_code = sd_ble_gap_device_name_set(&sec_mode,
(const uint8_t *) DEVICE_NAME,
strlen(DEVICE_NAME));
(const uint8_t *)deviceName,
len);
APP_ERROR_CHECK(err_code);
memset(&gap_conn_params, 0, sizeof(gap_conn_params));
@ -589,22 +631,6 @@ void bleQueueEventAndUnLock(const char *name, JsVar *data) {
jsvUnLock2(nrf, data);
}
void jswrap_nrf_bluetooth_startAdvertise(void) {
uint32_t err_code = 0;
// Actually start advertising
ble_gap_adv_params_t adv_params;
memset(&adv_params, 0, sizeof(adv_params));
adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;
adv_params.p_peer_addr = NULL;
adv_params.fp = BLE_GAP_ADV_FP_ANY;
adv_params.p_whitelist = NULL;
adv_params.timeout = APP_ADV_TIMEOUT_IN_SECONDS;
adv_params.interval = APP_ADV_INTERVAL;
err_code = sd_ble_gap_adv_start(&adv_params);
APP_ERROR_CHECK(err_code);
}
/// Get the correct event name for a BLE write event to a characteristic (eventName should be 12 chars long)
void ble_handle_to_write_event_name(char *eventName, uint16_t handle) {
strcpy(eventName, BLE_WRITE_EVENT);
@ -623,7 +649,7 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
switch (p_ble_evt->header.evt_id) {
case BLE_GAP_EVT_TIMEOUT:
// the timeout for sd_ble_gap_adv_start expired - kick it off again
jswrap_nrf_bluetooth_startAdvertise();
advertising_start();
break;
case BLE_GAP_EVT_CONNECTED:
@ -654,7 +680,7 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
m_conn_handle = BLE_CONN_HANDLE_INVALID;
if (!jsiIsConsoleDeviceForced()) jsiSetConsoleDevice(DEFAULT_CONSOLE_DEVICE, 0);
// restart advertising after disconnection
jswrap_nrf_bluetooth_startAdvertise();
advertising_start();
jshHadEvent();
break;
@ -822,6 +848,7 @@ static void sys_evt_dispatch(uint32_t sys_evt)
#ifdef USE_NFC
/// Sigh - NFC has lots of these, so we need to define it to build
void log_uart_printf(const char * format_msg, ...) {
jsiConsolePrintf("NFC: %s\n", format_msg);
}
/**
@ -928,7 +955,7 @@ static void advertising_init(void)
ble_adv_modes_config_t options = {0};
options.ble_adv_fast_enabled = BLE_ADV_FAST_ENABLED;
options.ble_adv_fast_interval = APP_ADV_INTERVAL;
options.ble_adv_fast_interval = advertising_interval;
options.ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS;
err_code = ble_advertising_init(&advdata, &scanrsp, &options, NULL, NULL);
@ -991,9 +1018,9 @@ static void device_manager_init(bool erase_bonds)
"type": "class",
"class" : "NRF"
}
The NRF class is for controlling functionality of the Nordic nRF51/nRF52 chips. Currently these are only used in the [BBC micro:bit](/MicroBit).
The NRF class is for controlling functionality of the Nordic nRF51/nRF52 chips. Currently these only used in [Puck.js](http://puck-js.com) and the [BBC micro:bit](/MicroBit).
The main part of this is control of Bluetooth Smart - both searching for devices, and changing advertising data.
The main part of this is control of Bluetooth Low Energy - both searching for devices, and changing advertising data.
*/
/*JSON{
"type" : "object",
@ -1003,6 +1030,7 @@ The main part of this is control of Bluetooth Smart - both searching for devices
}
The Bluetooth Serial port - used when data is sent or received over Bluetooth Smart on nRF51/nRF52 chips.
*/
void jswrap_nrf_bluetooth_init(void) {
// Initialize.
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
@ -1021,40 +1049,6 @@ void jswrap_nrf_bluetooth_init(void) {
jswrap_nrf_bluetooth_wake();
}
/*JSON{
"type" : "staticmethod",
"class" : "NRF",
"name" : "setName",
"generate" : "jswrap_nrf_bluetooth_setName",
"params" : [
["name","JsVar","The name to advertise as"]
]
}
Set the Name that will appear when another device searches
for Bluetooth devices.
**Note:** This clears any advertising data that was set - you'll
need to call `NRF.setAdvertising({...})` after to restore the data
if you had something set previously.
*/
void jswrap_nrf_bluetooth_setName(JsVar *name) {
uint32_t err_code;
ble_gap_conn_sec_mode_t sec_mode;
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
JSV_GET_AS_CHAR_ARRAY(namePtr, nameLen, name);
if (!namePtr) return;
err_code = sd_ble_gap_device_name_set(&sec_mode,
(const uint8_t *)namePtr,
nameLen);
if (err_code)
jsExceptionHere(JSET_ERROR, "Got BLE error code %d", err_code);
jswrap_nrf_bluetooth_setAdvertising(0);
}
/*JSON{
"type" : "staticmethod",
"class" : "NRF",
@ -1088,7 +1082,7 @@ Enable Bluetooth communications (they are enabled by default)
*/
void jswrap_nrf_bluetooth_wake(void) {
// NRF_RADIO->TASKS_DISABLE = (0UL); // BUG: This was causing a hardfault.
jswrap_nrf_bluetooth_startAdvertise();
advertising_start();
}
/*JSON{
@ -1135,12 +1129,13 @@ JsVarFloat jswrap_nrf_bluetooth_getBattery(void) {
"name" : "setAdvertising",
"generate" : "jswrap_nrf_bluetooth_setAdvertising",
"params" : [
["data","JsVar","The data to advertise as an object - see below for more info"]
["data","JsVar","The data to advertise as an object - see below for more info"],
["options","JsVar","An optional object of options"]
]
}
Change the data that Espruino advertises.
Data is of the form `{ UUID : data_as_byte_array }`. The UUID should be a [Bluetooth Service ID](https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx).
Data can be of the form `{ UUID : data_as_byte_array }`. The UUID should be a [Bluetooth Service ID](https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx).
For example to return battery level at 95%, do:
@ -1162,13 +1157,100 @@ setInterval(function() {
**Note:** Currently only standardised bluetooth UUIDs are allowed (see the
list above).
You can also supply the raw advertising data in an array. For example to advertise as an Eddystone beacon:
```
NRF.setAdvertising([0x03, // Length of Service List
0x03, // Param: Service List
0xAA, 0xFE, // Eddystone ID
0x13, // Length of Service Data
0x16, // Service Data
0xAA, 0xFE, // Eddystone ID
0x10, // Frame type: URL
0xF8, // Power
0x03, // https://
'g','o','o','.','g','l','/','B','3','J','0','O','c'],
{interval:100});
```
`options` is an object, which can contain:
```
{
name: "Hello" // The name of the device
showName: true/false // include full name, or nothing
discoverable: true/false // general discoverable, or limited - default is limited
interval: 600 // Advertising interval in msec, between 20 and 10000
}` to avoid adding the Nordic UART service
```
*/
void jswrap_nrf_bluetooth_setAdvertising(JsVar *data) {
void jswrap_nrf_bluetooth_setAdvertising(JsVar *data, JsVar *options) {
uint32_t err_code;
ble_advdata_t advdata;
setup_advdata(&advdata);
bool bleChanged;
if (jsvIsObject(data)) {
if (jsvIsObject(options)) {
JsVar *v;
v = jsvObjectGetChild(options, "showName", 0);
if (v) advdata.name_type = jsvGetBoolAndUnLock(v) ?
BLE_ADVDATA_FULL_NAME :
BLE_ADVDATA_NO_NAME;
v = jsvObjectGetChild(options, "discoverable", 0);
if (v) advdata.flags = jsvGetBoolAndUnLock(v) ?
BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE :
BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
v = jsvObjectGetChild(options, "interval", 0);
if (v) {
uint16_t new_advertising_interval = MSEC_TO_UNITS(jsvGetIntegerAndUnLock(v), UNIT_0_625_MS);
if (new_advertising_interval<0x0020) new_advertising_interval=0x0020;
if (new_advertising_interval>0x4000) new_advertising_interval=0x4000;
if (new_advertising_interval != advertising_interval) {
advertising_interval = new_advertising_interval;
bleChanged = true;
}
}
v = jsvObjectGetChild(options, "name", 0);
if (v) {
JSV_GET_AS_CHAR_ARRAY(namePtr, nameLen, v);
if (namePtr) {
ble_gap_conn_sec_mode_t sec_mode;
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
err_code = sd_ble_gap_device_name_set(&sec_mode,
(const uint8_t *)namePtr,
nameLen);
if (err_code)
jsExceptionHere(JSET_ERROR, "Got BLE error code %d", err_code);
bleChanged = true;
}
jsvUnLock(v);
}
} else if (!jsvIsUndefined(options)) {
jsExceptionHere(JSET_TYPEERROR, "Expecting 'options' to be object or undefined, got %t", options);
return;
}
if (jsvIsArray(data)) {
// raw data...
JSV_GET_AS_CHAR_ARRAY(dPtr, dLen, data);
if (!dPtr) {
jsExceptionHere(JSET_TYPEERROR, "Unable to convert data argument to an array");
return;
}
if (bleChanged)
advertising_stop();
err_code = sd_ble_gap_adv_data_set(dPtr, dLen, NULL, 0);
if (err_code)
jsExceptionHere(JSET_ERROR, "Got BLE error code %d", err_code);
if (bleChanged)
advertising_start();
return; // we're done here now
} else if (jsvIsObject(data)) {
ble_advdata_service_data_t *service_data = (ble_advdata_service_data_t*)alloca(jsvGetChildren(data)*sizeof(ble_advdata_service_data_t));
int n = 0;
JsvObjectIterator it;
@ -1189,11 +1271,16 @@ void jswrap_nrf_bluetooth_setAdvertising(JsVar *data) {
advdata.p_service_data_array = service_data;
} else if (!jsvIsUndefined(data)) {
jsExceptionHere(JSET_TYPEERROR, "Expecting object or undefined, got %t", data);
return;
}
if (bleChanged)
advertising_stop();
err_code = ble_advdata_set(&advdata, NULL);
if (err_code)
jsExceptionHere(JSET_ERROR, "Got BLE error code %d", err_code);
if (bleChanged)
advertising_start();
}

View File

@ -20,12 +20,11 @@
// public static methods.
void jswrap_nrf_bluetooth_init(void);
void jswrap_nrf_bluetooth_setName(JsVar *name);
void jswrap_nrf_bluetooth_sleep(void); // maybe these should return err_code?
void jswrap_nrf_bluetooth_wake(void);
JsVarFloat jswrap_nrf_bluetooth_getBattery(void);
void jswrap_nrf_bluetooth_setAdvertising(JsVar *data);
void jswrap_nrf_bluetooth_setAdvertising(JsVar *data, JsVar *options);
void jswrap_nrf_bluetooth_setServices(JsVar *data);
void jswrap_nrf_bluetooth_setScan(JsVar *callback);
void jswrap_nrf_bluetooth_setTxPower(JsVarInt pwr);

View File

@ -1,6 +1,5 @@
^\./archives
^\./targets/stm32f
^\./targets/stm32l
^\./targetlibs
^\./targets/libmbed
^\./libs/fat_sd
^\./libs/math

View File

@ -761,7 +761,7 @@ void jsiSemiInit(bool autoLoad) {
" "JS_VERSION" Copyright 2016 G.Williams\n"
// Point out about donations - but don't bug people
// who bought boards that helped Espruino
#if !defined(PICO) && !defined(ESPRUINOBOARD) && !defined(ESPRUINOWIFI)
#if !defined(PICO) && !defined(ESPRUINOBOARD) && !defined(ESPRUINOWIFI) && !defined(PUCKJS)
"\n"
"Espruino is Open Source. Our work is supported\n"
"only by sales of official boards and donations:\n"
@ -1187,22 +1187,26 @@ void jsiTabComplete() {
}
jslKill();
jslSetLex(oldLex);
if (!data.partial) {
jsvUnLock(object);
if (!object && !data.partial) {
return;
}
data.partialLen = jsvGetStringLength(data.partial);
size_t actualPartialLen = inputCursorPos + 1 - partialStart;
if (actualPartialLen > data.partialLen) {
// we had a token but were past the end of it when asked
// to autocomplete ---> no token
jsvUnLock(data.partial);
return;
} else if (actualPartialLen < data.partialLen) {
JsVar *v = jsvNewFromStringVar(data.partial, 0, actualPartialLen);
jsvUnLock(data.partial);
data.partial = v;
data.partialLen = actualPartialLen;
if (data.partial) {
data.partialLen = jsvGetStringLength(data.partial);
size_t actualPartialLen = inputCursorPos + 1 - partialStart;
if (actualPartialLen > data.partialLen) {
// we had a token but were past the end of it when asked
// to autocomplete ---> no token
jsvUnLock(data.partial);
return;
} else if (actualPartialLen < data.partialLen) {
JsVar *v = jsvNewFromStringVar(data.partial, 0, actualPartialLen);
jsvUnLock(data.partial);
data.partial = v;
data.partialLen = actualPartialLen;
}
} else {
data.partial = jsvNewFromEmptyString();
data.partialLen = 0;
}
// If we had the name of an object here, try and look it up

View File

@ -21,7 +21,7 @@
#define MAX_ARGS 12
#if defined(__i386__) || defined(__x86_64__)
#define USE_X86_CDECL // cdecl on x86 puts FP args elsewhere!
#define USE_SEPARATE_DOUBLES // cdecl on x86 puts FP args elsewhere!
#endif
#if defined(__WORDSIZE) && __WORDSIZE == 64
@ -41,14 +41,38 @@
#endif
#endif
#ifdef __ARM_PCS_VFP
#define USE_FLOAT_RETURN_FIX
#define USE_SEPARATE_DOUBLES
#endif
/** Call a function with the given argument specifiers */
JsVar *jsnCallFunction(void *function, JsnArgumentType argumentSpecifier, JsVar *thisParam, JsVar **paramData, int paramCount) {
#ifndef SAVE_ON_FLASH
// Handle common call types quickly:
// ------- void(void)
if (argumentSpecifier==JSWAT_VOID) {
((void (*)())function)();
return 0;
}
// ------- JsVar*(void)
if (argumentSpecifier==JSWAT_JSVAR) {
return ((JsVar *(*)())function)();
}
// ------- void('this')
if (argumentSpecifier==(JSWAT_VOID | JSWAT_THIS_ARG)) {
((void (*)(JsVar *))function)(thisParam);
return 0;
}
#endif
// Now do it the hard way...
JsnArgumentType returnType = (JsnArgumentType)(argumentSpecifier&JSWAT_MASK);
JsVar *argsArray = 0; // if JSWAT_ARGUMENT_ARRAY is ever used (note it'll only ever be used once)
int paramNumber = 0; // how many parameters we have
int argCount = 0;
size_t argData[MAX_ARGS];
#ifdef USE_X86_CDECL
#ifdef USE_SEPARATE_DOUBLES
int doubleCount = 0;
JsVarFloat doubleData[MAX_ARGS];
#endif
@ -113,7 +137,7 @@ JsVar *jsnCallFunction(void *function, JsnArgumentType argumentSpecifier, JsVar
break;
case JSWAT_JSVARFLOAT: { // 64 bit float
JsVarFloat f = jsvGetFloat(param);
#ifdef USE_X86_CDECL
#ifdef USE_SEPARATE_DOUBLES
doubleData[doubleCount++] = f;
#else
uint64_t i = *(uint64_t*)&f;
@ -151,17 +175,20 @@ JsVar *jsnCallFunction(void *function, JsnArgumentType argumentSpecifier, JsVar
// When args<=4 on ARM, everything is passed in registers (so we try and do this case first)
if (argCount<=4) {
#ifdef USE_X86_CDECL
#ifdef USE_SEPARATE_DOUBLES
assert(doubleCount<=4);
if (doubleCount) {
// We are passing doubles
if (returnType==JSWAT_JSVARFLOAT) {
// On x86, doubles are returned in a floating point unit register
JsVarFloat f = ((JsVarFloat (*)(size_t,size_t,size_t,size_t,JsVarFloat,JsVarFloat,JsVarFloat,JsVarFloat))function)(argData[0],argData[1],argData[2],argData[3],doubleData[0],doubleData[1],doubleData[2],doubleData[3]);
result = *(uint64_t *)&f;
} else {
#ifdef USE_64BIT
if (JSWAT_IS_64BIT(returnType))
result = ((uint64_t (*)(size_t,size_t,size_t,size_t,JsVarFloat,JsVarFloat,JsVarFloat,JsVarFloat))function)(argData[0],argData[1],argData[2],argData[3],doubleData[0],doubleData[1],doubleData[2],doubleData[3]);
else
#endif
result = ((uint32_t (*)(size_t,size_t,size_t,size_t,JsVarFloat,JsVarFloat,JsVarFloat,JsVarFloat))function)(argData[0],argData[1],argData[2],argData[3],doubleData[0],doubleData[1],doubleData[2],doubleData[3]);
}
} else if (returnType==JSWAT_JSVARFLOAT) {
@ -183,7 +210,7 @@ JsVar *jsnCallFunction(void *function, JsnArgumentType argumentSpecifier, JsVar
result = ((uint32_t (*)(size_t,size_t,size_t,size_t))function)(argData[0],argData[1],argData[2],argData[3]);
}
} else { // else it gets tricky...
#ifdef USE_X86_CDECL
#ifdef USE_SEPARATE_DOUBLES
assert(doubleCount==0);
if (returnType==JSWAT_JSVARFLOAT) {
// On x86, doubles are returned in a floating point unit register

View File

@ -533,7 +533,7 @@ NO_INLINE JsVar *jspeFunctionCall(JsVar *function, JsVar *functionName, JsVar *t
// Now, if we're parsing add the rest of the arguments
int allocatedArgCount = boundArgs;
if (isParsing) {
while (!JSP_SHOULDNT_PARSE && lex->tk!=')' && lex->tk!=LEX_EOF) {
while (!JSP_HAS_ERROR && lex->tk!=')' && lex->tk!=LEX_EOF) {
if ((unsigned)argCount>=argPtrSize) {
// allocate more space on stack
unsigned int newArgPtrSize = argPtrSize?argPtrSize*4:16;
@ -572,10 +572,9 @@ NO_INLINE JsVar *jspeFunctionCall(JsVar *function, JsVar *functionName, JsVar *t
if (nativePtr) {
if (nativePtr && !JSP_HAS_ERROR) {
returnVar = jsnCallFunction(nativePtr, function->varData.native.argTypes, thisVar, argPtr, argCount);
} else {
assert(0); // in case something went horribly wrong
returnVar = 0;
}
@ -684,8 +683,10 @@ NO_INLINE JsVar *jspeFunctionCall(JsVar *function, JsVar *functionName, JsVar *t
if (jsvIsStringEqual(param, JSPARSE_FUNCTION_SCOPE_NAME)) functionScope = jsvSkipName(param);
else if (jsvIsStringEqual(param, JSPARSE_FUNCTION_CODE_NAME)) functionCode = jsvSkipName(param);
else if (jsvIsStringEqual(param, JSPARSE_FUNCTION_NAME_NAME)) functionInternalName = jsvSkipName(param);
else if (jsvIsStringEqual(param, JSPARSE_FUNCTION_THIS_NAME)) thisVar = jsvSkipName(param);
else if (jsvIsStringEqual(param, JSPARSE_FUNCTION_LINENUMBER_NAME)) functionLineNumber = (uint16_t)jsvGetIntegerAndUnLock(jsvSkipName(param));
else if (jsvIsStringEqual(param, JSPARSE_FUNCTION_THIS_NAME)) {
jsvUnLock(thisVar);
thisVar = jsvSkipName(param);
} else if (jsvIsStringEqual(param, JSPARSE_FUNCTION_LINENUMBER_NAME)) functionLineNumber = (uint16_t)jsvGetIntegerAndUnLock(jsvSkipName(param));
else if (jsvIsFunctionParameter(param)) {
JsVar *paramName = jsvCopy(param);
// paramName is already a name (it's a function parameter)

View File

@ -56,7 +56,7 @@ static ALWAYS_INLINE char jsvStringIteratorGetChar(JsvStringIterator *it) {
/// Gets the current (>=0) character (or -1)
static ALWAYS_INLINE int jsvStringIteratorGetCharOrMinusOne(JsvStringIterator *it) {
if (!it->ptr) return -1;
if (!it->ptr || it->charIdx>=it->charsInVar) return -1;
return (int)(unsigned char)READ_FLASH_UINT8(&it->ptr[it->charIdx]);
}

View File

@ -28,6 +28,9 @@
/* CLOCK */
#define CLOCK_ENABLED 0
// CLOCK_ENABLED is for enabling the clock driver in the SDK
// Seems not to be needed is using SoftDevice?
// http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v11.0.0%2Fhardware_driver_clock.html&cp=4_0_0_2_1
#if (CLOCK_ENABLED == 1)
#define CLOCK_CONFIG_XTAL_FREQ NRF_CLOCK_XTALFREQ_Default

View File

@ -28,6 +28,9 @@
/* CLOCK */
#define CLOCK_ENABLED 0
// CLOCK_ENABLED is for enabling the clock driver in the SDK
// Seems not to be needed is using SoftDevice?
// http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v11.0.0%2Fhardware_driver_clock.html&cp=4_0_0_2_1
#if (CLOCK_ENABLED == 1)
#define CLOCK_CONFIG_XTAL_FREQ NRF_CLOCK_XTALFREQ_Default

View File

@ -1,464 +0,0 @@
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
#ifndef NRF_DRV_CONFIG_H
#define NRF_DRV_CONFIG_H
/**
* Provide a non-zero value here in applications that need to use several
* peripherals with the same ID that are sharing certain resources
* (for example, SPI0 and TWI0). Obviously, such peripherals cannot be used
* simultaneously. Therefore, this definition allows to initialize the driver
* for another peripheral from a given group only after the previously used one
* is uninitialized. Normally, this is not possible, because interrupt handlers
* are implemented in individual drivers.
* This functionality requires a more complicated interrupt handling and driver
* initialization, hence it is not always desirable to use it.
*/
#define PERIPHERAL_RESOURCE_SHARING_ENABLED 0
/* CLOCK */
#define CLOCK_ENABLED 0
#if (CLOCK_ENABLED == 1)
#define CLOCK_CONFIG_XTAL_FREQ NRF_CLOCK_XTALFREQ_Default
#define CLOCK_CONFIG_LF_SRC NRF_CLOCK_LFCLK_Xtal
#define CLOCK_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#endif
/* GPIOTE */
#define GPIOTE_ENABLED 0
#if (GPIOTE_ENABLED == 1)
#define GPIOTE_CONFIG_USE_SWI_EGU false
#define GPIOTE_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1
#endif
/* TIMER */
#define TIMER0_ENABLED 0
#if (TIMER0_ENABLED == 1)
#define TIMER0_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz
#define TIMER0_CONFIG_MODE TIMER_MODE_MODE_Timer
#define TIMER0_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_32Bit
#define TIMER0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define TIMER0_INSTANCE_INDEX 0
#endif
#define TIMER1_ENABLED 0
#if (TIMER1_ENABLED == 1)
#define TIMER1_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz
#define TIMER1_CONFIG_MODE TIMER_MODE_MODE_Timer
#define TIMER1_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit
#define TIMER1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define TIMER1_INSTANCE_INDEX (TIMER0_ENABLED)
#endif
#define TIMER2_ENABLED 0
#if (TIMER2_ENABLED == 1)
#define TIMER2_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz
#define TIMER2_CONFIG_MODE TIMER_MODE_MODE_Timer
#define TIMER2_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit
#define TIMER2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define TIMER2_INSTANCE_INDEX (TIMER1_ENABLED+TIMER0_ENABLED)
#endif
#define TIMER3_ENABLED 0
#if (TIMER3_ENABLED == 1)
#define TIMER3_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz
#define TIMER3_CONFIG_MODE TIMER_MODE_MODE_Timer
#define TIMER3_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit
#define TIMER3_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define TIMER3_INSTANCE_INDEX (TIMER2_ENABLED+TIMER1_ENABLED+TIMER0_ENABLED)
#endif
#define TIMER4_ENABLED 0
#if (TIMER4_ENABLED == 1)
#define TIMER4_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz
#define TIMER4_CONFIG_MODE TIMER_MODE_MODE_Timer
#define TIMER4_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit
#define TIMER4_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define TIMER4_INSTANCE_INDEX (TIMER3_ENABLED+TIMER2_ENABLED+TIMER1_ENABLED+TIMER0_ENABLED)
#endif
#define TIMER_COUNT (TIMER0_ENABLED + TIMER1_ENABLED + TIMER2_ENABLED + TIMER3_ENABLED + TIMER4_ENABLED)
/* RTC */
#define RTC0_ENABLED 0
#if (RTC0_ENABLED == 1)
#define RTC0_CONFIG_FREQUENCY 32678
#define RTC0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define RTC0_CONFIG_RELIABLE false
#define RTC0_INSTANCE_INDEX 0
#endif
#define RTC1_ENABLED 0
#if (RTC1_ENABLED == 1)
#define RTC1_CONFIG_FREQUENCY 32768
#define RTC1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define RTC1_CONFIG_RELIABLE false
#define RTC1_INSTANCE_INDEX (RTC0_ENABLED)
#endif
#define RTC2_ENABLED 0
#if (RTC2_ENABLED == 1)
#define RTC2_CONFIG_FREQUENCY 32768
#define RTC2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define RTC2_CONFIG_RELIABLE false
#define RTC2_INSTANCE_INDEX (RTC0_ENABLED+RTC1_ENABLED)
#endif
#define RTC_COUNT (RTC0_ENABLED+RTC1_ENABLED+RTC2_ENABLED)
#define NRF_MAXIMUM_LATENCY_US 2000
/* RNG */
#define RNG_ENABLED 0
#if (RNG_ENABLED == 1)
#define RNG_CONFIG_ERROR_CORRECTION true
#define RNG_CONFIG_POOL_SIZE 8
#define RNG_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#endif
/* PWM */
#define PWM0_ENABLED 0
#if (PWM0_ENABLED == 1)
#define PWM0_CONFIG_OUT0_PIN 2
#define PWM0_CONFIG_OUT1_PIN 3
#define PWM0_CONFIG_OUT2_PIN 4
#define PWM0_CONFIG_OUT3_PIN 5
#define PWM0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define PWM0_CONFIG_BASE_CLOCK NRF_PWM_CLK_1MHz
#define PWM0_CONFIG_COUNT_MODE NRF_PWM_MODE_UP
#define PWM0_CONFIG_TOP_VALUE 1000
#define PWM0_CONFIG_LOAD_MODE NRF_PWM_LOAD_COMMON
#define PWM0_CONFIG_STEP_MODE NRF_PWM_STEP_AUTO
#define PWM0_INSTANCE_INDEX 0
#endif
#define PWM1_ENABLED 0
#if (PWM1_ENABLED == 1)
#define PWM1_CONFIG_OUT0_PIN 2
#define PWM1_CONFIG_OUT1_PIN 3
#define PWM1_CONFIG_OUT2_PIN 4
#define PWM1_CONFIG_OUT3_PIN 5
#define PWM1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define PWM1_CONFIG_BASE_CLOCK NRF_PWM_CLK_1MHz
#define PWM1_CONFIG_COUNT_MODE NRF_PWM_MODE_UP
#define PWM1_CONFIG_TOP_VALUE 1000
#define PWM1_CONFIG_LOAD_MODE NRF_PWM_LOAD_COMMON
#define PWM1_CONFIG_STEP_MODE NRF_PWM_STEP_AUTO
#define PWM1_INSTANCE_INDEX (PWM0_ENABLED)
#endif
#define PWM2_ENABLED 0
#if (PWM2_ENABLED == 1)
#define PWM2_CONFIG_OUT0_PIN 2
#define PWM2_CONFIG_OUT1_PIN 3
#define PWM2_CONFIG_OUT2_PIN 4
#define PWM2_CONFIG_OUT3_PIN 5
#define PWM2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define PWM2_CONFIG_BASE_CLOCK NRF_PWM_CLK_1MHz
#define PWM2_CONFIG_COUNT_MODE NRF_PWM_MODE_UP
#define PWM2_CONFIG_TOP_VALUE 1000
#define PWM2_CONFIG_LOAD_MODE NRF_PWM_LOAD_COMMON
#define PWM2_CONFIG_STEP_MODE NRF_PWM_STEP_AUTO
#define PWM2_INSTANCE_INDEX (PWM0_ENABLED + PWM1_ENABLED)
#endif
#define PWM_COUNT (PWM0_ENABLED + PWM1_ENABLED + PWM2_ENABLED)
/* SPI */
#define SPI0_ENABLED 0
#if (SPI0_ENABLED == 1)
#define SPI0_USE_EASY_DMA 0
#define SPI0_CONFIG_SCK_PIN 2
#define SPI0_CONFIG_MOSI_PIN 3
#define SPI0_CONFIG_MISO_PIN 4
#define SPI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define SPI0_INSTANCE_INDEX 0
#endif
#define SPI1_ENABLED 0
#if (SPI1_ENABLED == 1)
#define SPI1_USE_EASY_DMA 0
#define SPI1_CONFIG_SCK_PIN 2
#define SPI1_CONFIG_MOSI_PIN 3
#define SPI1_CONFIG_MISO_PIN 4
#define SPI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define SPI1_INSTANCE_INDEX (SPI0_ENABLED)
#endif
#define SPI2_ENABLED 0
#if (SPI2_ENABLED == 1)
#define SPI2_USE_EASY_DMA 0
#define SPI2_CONFIG_SCK_PIN 2
#define SPI2_CONFIG_MOSI_PIN 3
#define SPI2_CONFIG_MISO_PIN 4
#define SPI2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define SPI2_INSTANCE_INDEX (SPI0_ENABLED + SPI1_ENABLED)
#endif
#define SPI_COUNT (SPI0_ENABLED + SPI1_ENABLED + SPI2_ENABLED)
/* SPIS */
#define SPIS0_ENABLED 0
#if (SPIS0_ENABLED == 1)
#define SPIS0_CONFIG_SCK_PIN 2
#define SPIS0_CONFIG_MOSI_PIN 3
#define SPIS0_CONFIG_MISO_PIN 4
#define SPIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define SPIS0_INSTANCE_INDEX 0
#endif
#define SPIS1_ENABLED 0
#if (SPIS1_ENABLED == 1)
#define SPIS1_CONFIG_SCK_PIN 2
#define SPIS1_CONFIG_MOSI_PIN 3
#define SPIS1_CONFIG_MISO_PIN 4
#define SPIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define SPIS1_INSTANCE_INDEX SPIS0_ENABLED
#endif
#define SPIS2_ENABLED 0
#if (SPIS2_ENABLED == 1)
#define SPIS2_CONFIG_SCK_PIN 2
#define SPIS2_CONFIG_MOSI_PIN 3
#define SPIS2_CONFIG_MISO_PIN 4
#define SPIS2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define SPIS2_INSTANCE_INDEX (SPIS0_ENABLED + SPIS1_ENABLED)
#endif
#define SPIS_COUNT (SPIS0_ENABLED + SPIS1_ENABLED + SPIS2_ENABLED)
/* UART */
#define UART0_ENABLED 0
#if (UART0_ENABLED == 1)
#define UART0_CONFIG_HWFC NRF_UART_HWFC_DISABLED
#define UART0_CONFIG_PARITY NRF_UART_PARITY_EXCLUDED
#define UART0_CONFIG_BAUDRATE NRF_UART_BAUDRATE_115200
#define UART0_CONFIG_PSEL_TXD 0
#define UART0_CONFIG_PSEL_RXD 0
#define UART0_CONFIG_PSEL_CTS 0
#define UART0_CONFIG_PSEL_RTS 0
#define UART0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#ifdef NRF52
#define UART0_CONFIG_USE_EASY_DMA false
//Compile time flag
#define UART_EASY_DMA_SUPPORT 1
#define UART_LEGACY_SUPPORT 1
#endif //NRF52
#endif
#define TWI0_ENABLED 0
#if (TWI0_ENABLED == 1)
#define TWI0_USE_EASY_DMA 0
#define TWI0_CONFIG_FREQUENCY NRF_TWI_FREQ_100K
#define TWI0_CONFIG_SCL 0
#define TWI0_CONFIG_SDA 1
#define TWI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define TWI0_INSTANCE_INDEX 0
#endif
#define TWI1_ENABLED 0
#if (TWI1_ENABLED == 1)
#define TWI1_USE_EASY_DMA 0
#define TWI1_CONFIG_FREQUENCY NRF_TWI_FREQ_100K
#define TWI1_CONFIG_SCL 0
#define TWI1_CONFIG_SDA 1
#define TWI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define TWI1_INSTANCE_INDEX (TWI0_ENABLED)
#endif
#define TWI_COUNT (TWI0_ENABLED + TWI1_ENABLED)
/* TWIS */
#define TWIS0_ENABLED 0
#if (TWIS0_ENABLED == 1)
#define TWIS0_CONFIG_ADDR0 0
#define TWIS0_CONFIG_ADDR1 0 /* 0: Disabled */
#define TWIS0_CONFIG_SCL 0
#define TWIS0_CONFIG_SDA 1
#define TWIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define TWIS0_INSTANCE_INDEX 0
#endif
#define TWIS1_ENABLED 0
#if (TWIS1_ENABLED == 1)
#define TWIS1_CONFIG_ADDR0 0
#define TWIS1_CONFIG_ADDR1 0 /* 0: Disabled */
#define TWIS1_CONFIG_SCL 0
#define TWIS1_CONFIG_SDA 1
#define TWIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define TWIS1_INSTANCE_INDEX (TWIS0_ENABLED)
#endif
#define TWIS_COUNT (TWIS0_ENABLED + TWIS1_ENABLED)
/* For more documentation see nrf_drv_twis.h file */
#define TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0
/* For more documentation see nrf_drv_twis.h file */
#define TWIS_NO_SYNC_MODE 0
/* QDEC */
#define QDEC_ENABLED 0
#if (QDEC_ENABLED == 1)
#define QDEC_CONFIG_REPORTPER NRF_QDEC_REPORTPER_10
#define QDEC_CONFIG_SAMPLEPER NRF_QDEC_SAMPLEPER_16384us
#define QDEC_CONFIG_PIO_A 1
#define QDEC_CONFIG_PIO_B 2
#define QDEC_CONFIG_PIO_LED 3
#define QDEC_CONFIG_LEDPRE 511
#define QDEC_CONFIG_LEDPOL NRF_QDEC_LEPOL_ACTIVE_HIGH
#define QDEC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define QDEC_CONFIG_DBFEN false
#define QDEC_CONFIG_SAMPLE_INTEN false
#endif
/* ADC */
#define ADC_ENABLED 0
#if (ADC_ENABLED == 1)
#define ADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#endif
/* SAADC */
#define SAADC_ENABLED 0
#if (SAADC_ENABLED == 1)
#define SAADC_CONFIG_RESOLUTION NRF_SAADC_RESOLUTION_10BIT
#define SAADC_CONFIG_OVERSAMPLE NRF_SAADC_OVERSAMPLE_DISABLED
#define SAADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#endif
/* PDM */
#define PDM_ENABLED 0
#if (PDM_ENABLED == 1)
#define PDM_CONFIG_MODE NRF_PDM_MODE_MONO
#define PDM_CONFIG_EDGE NRF_PDM_EDGE_LEFTFALLING
#define PDM_CONFIG_CLOCK_FREQ NRF_PDM_FREQ_1032K
#define PDM_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#endif
/* COMP */
#define COMP_ENABLED 0
#if (COMP_ENABLED == 1)
#define COMP_CONFIG_REF NRF_COMP_REF_Int1V8
#define COMP_CONFIG_MAIN_MODE NRF_COMP_MAIN_MODE_SE
#define COMP_CONFIG_SPEED_MODE NRF_COMP_SP_MODE_High
#define COMP_CONFIG_HYST NRF_COMP_HYST_NoHyst
#define COMP_CONFIG_ISOURCE NRF_COMP_ISOURCE_Off
#define COMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define COMP_CONFIG_INPUT NRF_COMP_INPUT_0
#endif
/* LPCOMP */
#define LPCOMP_ENABLED 0
#if (LPCOMP_ENABLED == 1)
#define LPCOMP_CONFIG_REFERENCE NRF_LPCOMP_REF_SUPPLY_4_8
#define LPCOMP_CONFIG_DETECTION NRF_LPCOMP_DETECT_DOWN
#define LPCOMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define LPCOMP_CONFIG_INPUT NRF_LPCOMP_INPUT_0
#endif
/* WDT */
#define WDT_ENABLED 0
#if (WDT_ENABLED == 1)
#define WDT_CONFIG_BEHAVIOUR NRF_WDT_BEHAVIOUR_RUN_SLEEP
#define WDT_CONFIG_RELOAD_VALUE 2000
#define WDT_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH
#endif
/* SWI EGU */
#ifdef NRF52
#define EGU_ENABLED 0
#endif
/* I2S */
#define I2S_ENABLED 0
#if (I2S_ENABLED == 1)
#define I2S_CONFIG_SCK_PIN 22
#define I2S_CONFIG_LRCK_PIN 23
#define I2S_CONFIG_MCK_PIN NRF_DRV_I2S_PIN_NOT_USED
#define I2S_CONFIG_SDOUT_PIN 24
#define I2S_CONFIG_SDIN_PIN 25
#define I2S_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH
#define I2S_CONFIG_MASTER NRF_I2S_MODE_MASTER
#define I2S_CONFIG_FORMAT NRF_I2S_FORMAT_I2S
#define I2S_CONFIG_ALIGN NRF_I2S_ALIGN_LEFT
#define I2S_CONFIG_SWIDTH NRF_I2S_SWIDTH_16BIT
#define I2S_CONFIG_CHANNELS NRF_I2S_CHANNELS_STEREO
#define I2S_CONFIG_MCK_SETUP NRF_I2S_MCK_32MDIV8
#define I2S_CONFIG_RATIO NRF_I2S_RATIO_256X
#endif
#include "nrf_drv_config_validation.h"
#endif // NRF_DRV_CONFIG_H

View File

@ -37,9 +37,11 @@
#include "nrf_timer.h"
#include "app_uart.h"
#include "nrf_drv_uart.h"
#include "nrf_delay.h"
#ifdef NRF52
#include "nrf_saadc.h"
#include "nrf_pwm.h"
#else
#include "nrf_adc.h"
#endif
@ -69,6 +71,10 @@ volatile bool hadEvent = false; // set if we've had an event we need to deal wit
bool uartIsSending = false;
bool uartInitialised = false;
JshPinFunction pinStates[JSH_PIN_COUNT];
/// Called when we have had an event that means we should execute JS
void jshHadEvent() {
hadEvent = true;
@ -87,29 +93,33 @@ void sys_evt_handler(uint32_t sys_evt) {
}
}
unsigned int getNRFBaud(int baud) {
switch (baud) {
case 1200: return UART_BAUDRATE_BAUDRATE_Baud1200;
case 2400: return UART_BAUDRATE_BAUDRATE_Baud2400;
case 4800: return UART_BAUDRATE_BAUDRATE_Baud4800;
case 9600: return UART_BAUDRATE_BAUDRATE_Baud9600;
case 14400: return UART_BAUDRATE_BAUDRATE_Baud14400;
case 19200: return UART_BAUDRATE_BAUDRATE_Baud19200;
case 28800: return UART_BAUDRATE_BAUDRATE_Baud28800;
case 38400: return UART_BAUDRATE_BAUDRATE_Baud38400;
case 57600: return UART_BAUDRATE_BAUDRATE_Baud57600;
case 76800: return UART_BAUDRATE_BAUDRATE_Baud76800;
case 115200: return UART_BAUDRATE_BAUDRATE_Baud115200;
case 230400: return UART_BAUDRATE_BAUDRATE_Baud230400;
case 250000: return UART_BAUDRATE_BAUDRATE_Baud250000;
case 460800: return UART_BAUDRATE_BAUDRATE_Baud460800;
case 921600: return UART_BAUDRATE_BAUDRATE_Baud921600;
case 1000000: return UART_BAUDRATE_BAUDRATE_Baud1M;
default: return 0; // error
static NO_INLINE void jshPinSetFunction_int(JshPinFunction func, uint32_t pin) {
JshPinFunction fType = func&JSH_MASK_TYPE;
JshPinFunction fInfo = func&JSH_MASK_INFO;
switch (fType) {
case JSH_NOTHING: break;
#ifdef NRF52
case JSH_TIMER1: NRF_PWM0->PSEL.OUT[fInfo>>JSH_SHIFT_INFO] = pin; break;
case JSH_TIMER2: NRF_PWM1->PSEL.OUT[fInfo>>JSH_SHIFT_INFO] = pin; break;
case JSH_TIMER3: NRF_PWM2->PSEL.OUT[fInfo>>JSH_SHIFT_INFO] = pin; break;
// FIXME: if no pins are active on the given PWM now, turn it off
#endif
case JSH_USART1: if (fInfo==JSH_USART_RX) NRF_UART0->PSELRXD = pin;
else NRF_UART0->PSELTXD = pin; break;
default: assert(0);
}
}
static NO_INLINE void jshPinSetFunction(Pin pin, JshPinFunction func) {
if (pinStates[pin]==func) return;
// disconnect existing peripheral (if there was one)
if (pinStates[pin])
jshPinSetFunction_int(pinStates[pin], 0xFFFFFFFF);
// connect new peripheral
pinStates[pin] = func;
jshPinSetFunction_int(pinStates[pin], pinInfo[pin].pin);
}
#ifdef BLUETOOTH
APP_TIMER_DEF(m_wakeup_timer_id);
@ -240,8 +250,7 @@ void jshDelayMicroseconds(int microsec) {
if (microsec <= 0) {
return;
}
nrf_utils_delay_us((uint32_t) microsec);
nrf_delay_us((uint32_t)microsec);
}
void jshPinSetValue(Pin pin, bool value) {
@ -254,6 +263,8 @@ bool jshPinGetValue(Pin pin) {
// Set the pin state
void jshPinSetState(Pin pin, JshPinState state) {
// If this was set to be some kind of AF (USART, etc), reset it.
jshPinSetFunction(pin, JSH_NOTHING);
/* Make sure we kill software PWM if we set the pin state
* after we've started it */
if (BITFIELD_GET(jshPinSoftPWM, pin)) {
@ -313,7 +324,7 @@ void jshPinSetState(Pin pin, JshPinState state) {
/** Get the pin state (only accurate for simple IO - won't return JSHPINSTATE_USART_OUT for instance).
* Note that you should use JSHPINSTATE_MASK as other flags may have been added */
JshPinState jshPinGetState(Pin pin) {
return (JshPinState) nrf_utils_gpio_pin_get_state((uint32_t)pinInfo[pin].pin);
return 0; // FIXME need to get able to get pin state!
}
#ifdef NRF52
@ -426,14 +437,89 @@ int jshPinAnalogFast(Pin pin) {
JshPinFunction jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq, JshAnalogOutputFlags flags) {
/* we set the bit field here so that if the user changes the pin state
* later on, we can get rid of the IRQs */
if (!jshGetPinStateIsManual(pin)) {
BITFIELD_SET(jshPinSoftPWM, pin, 0);
jshPinSetState(pin, JSHPINSTATE_GPIO_OUT);
#ifdef NRF52
if (flags & JSAOF_FORCE_SOFTWARE) {
#endif
if (!jshGetPinStateIsManual(pin)) {
BITFIELD_SET(jshPinSoftPWM, pin, 0);
jshPinSetState(pin, JSHPINSTATE_GPIO_OUT);
}
BITFIELD_SET(jshPinSoftPWM, pin, 1);
if (freq<=0) freq=50;
jstPinPWM(freq, value, pin);
return JSH_NOTHING;
#ifdef NRF52
}
BITFIELD_SET(jshPinSoftPWM, pin, 1);
if (freq<=0) freq=50;
jstPinPWM(freq, value, pin);
return JSH_NOTHING;
JshPinFunction func = JSH_TIMER1 | JSH_TIMER_CH1;
// FIXME: Search for free timers to use (based on freq as well)
NRF_PWM_Type *pwm;
if ((func&JSH_MASK_TYPE) == JSH_TIMER1) pwm = NRF_PWM0;
else if ((func&JSH_MASK_TYPE) == JSH_TIMER2) pwm = NRF_PWM1;
else if ((func&JSH_MASK_TYPE) == JSH_TIMER3) pwm = NRF_PWM2;
else { assert(0); return 0; };
jshPinSetState(pin, JSHPINSTATE_GPIO_OUT);
jshPinSetFunction(pin, func);
nrf_pwm_enable(pwm);
nrf_pwm_clk_t clk;
if (freq<=0) freq = 1000;
int counter = (int)(16000000.0 / freq);
if (counter<32768) {
clk = NRF_PWM_CLK_16MHz;
if (counter<1) counter=1;
} else if (counter < (32768<<1)) {
clk = NRF_PWM_CLK_8MHz;
counter >>= 1;
} else if (counter < (32768<<2)) {
clk = NRF_PWM_CLK_4MHz;
counter >>= 2;
} else if (counter < (32768<<3)) {
clk = NRF_PWM_CLK_2MHz;
counter >>= 3;
} else if (counter < (32768<<4)) {
clk = NRF_PWM_CLK_1MHz;
counter >>= 4;
} else if (counter < (32768<<5)) {
clk = NRF_PWM_CLK_500kHz;
counter >>= 5;
} else if (counter < (32768<<6)) {
clk = NRF_PWM_CLK_250kHz;
counter >>= 6;
} else {
clk = NRF_PWM_CLK_125kHz;
counter >>= 7;
if (counter>32767) counter = 32767;
// Warn that we're out of range?
}
nrf_pwm_configure(pwm,
clk, NRF_PWM_MODE_UP, counter /* top value - 15 bits, not 16! */);
nrf_pwm_decoder_set(pwm,
NRF_PWM_LOAD_INDIVIDUAL, // allow all 4 channels to be used
NRF_PWM_STEP_TRIGGERED); // Only step on NEXTSTEP task
/*nrf_pwm_shorts_set(pwm, 0);
nrf_pwm_int_set(pwm, 0);
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_LOOPSDONE);
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND0);
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND1);
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_STOPPED);
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_STOPPED);*/
static uint16_t pwmValues[4];
pwmValues[func >> JSH_SHIFT_INFO] = counter - (uint16_t)(value*counter);
nrf_pwm_loop_set(pwm, PWM_LOOP_CNT_Disabled);
nrf_pwm_seq_ptr_set( pwm, 0, pwmValues);
nrf_pwm_seq_cnt_set( pwm, 0, 4);
nrf_pwm_seq_refresh_set( pwm, 0, 0);
nrf_pwm_seq_end_delay_set(pwm, 0, 0);
nrf_pwm_task_trigger(pwm, NRF_PWM_TASK_SEQSTART0);
// nrf_pwm_disable(pwm);
return func;
#endif
} // if freq<=0, the default is used
void jshPinPulse(Pin pin, bool pulsePolarity, JsVarFloat pulseTime) {
@ -551,7 +637,7 @@ void jshUSARTSetup(IOEventFlags device, JshUSARTInfo *inf) {
if (device != EV_SERIAL1)
return;
int baud = getNRFBaud(inf->baudRate);
int baud = nrf_utils_get_baud_enum(inf->baudRate);
if (baud==0)
return jsError("Invalid baud rate %d", inf->baudRate);
if (!jshIsPinValid(inf->pinRX) || !jshIsPinValid(inf->pinTX))
@ -567,6 +653,9 @@ void jshUSARTSetup(IOEventFlags device, JshUSARTInfo *inf) {
inf->parity!=0, // TODO: ODD or EVEN parity?
baud
};
// APP_UART_INIT will set pins, but this ensures we know so can reset state later
jshPinSetFunction(inf->pinRX, JSH_USART1|JSH_USART_RX);
jshPinSetFunction(inf->pinTX, JSH_USART1|JSH_USART_TX);
APP_UART_INIT(&comm_params,
uart0_event_handle,

View File

@ -18,21 +18,30 @@
#include "nrf.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "app_uart.h"
#include "nrf_error.h"
#include "nrf_nvmc.h"
uint32_t nrf_utils_gpio_pin_get_state(uint32_t pin)
{
/*uint32_t pin_register;
pin_register = NRF_GPIO->PIN_CNF[pin];*/
return (uint32_t) 0;
}
void nrf_utils_delay_us(uint32_t microsec)
{
nrf_delay_us(microsec);
unsigned int nrf_utils_get_baud_enum(int baud) {
switch (baud) {
case 1200: return UART_BAUDRATE_BAUDRATE_Baud1200;
case 2400: return UART_BAUDRATE_BAUDRATE_Baud2400;
case 4800: return UART_BAUDRATE_BAUDRATE_Baud4800;
case 9600: return UART_BAUDRATE_BAUDRATE_Baud9600;
case 14400: return UART_BAUDRATE_BAUDRATE_Baud14400;
case 19200: return UART_BAUDRATE_BAUDRATE_Baud19200;
case 28800: return UART_BAUDRATE_BAUDRATE_Baud28800;
case 38400: return UART_BAUDRATE_BAUDRATE_Baud38400;
case 57600: return UART_BAUDRATE_BAUDRATE_Baud57600;
case 76800: return UART_BAUDRATE_BAUDRATE_Baud76800;
case 115200: return UART_BAUDRATE_BAUDRATE_Baud115200;
case 230400: return UART_BAUDRATE_BAUDRATE_Baud230400;
case 250000: return UART_BAUDRATE_BAUDRATE_Baud250000;
case 460800: return UART_BAUDRATE_BAUDRATE_Baud460800;
case 921600: return UART_BAUDRATE_BAUDRATE_Baud921600;
case 1000000: return UART_BAUDRATE_BAUDRATE_Baud1M;
default: return 0; // error
}
}
// Configure the low frequency clock to use the external 32.768 kHz crystal as a source. Start this clock.
@ -95,16 +104,3 @@ uint8_t nrf_utils_get_random_number()
return rand_num;
}
void nrf_utils_app_uart_put(uint8_t character) {
while (app_uart_put(character) != NRF_SUCCESS);
}
void print_string_to_terminal(uint8_t * debug_string, uint32_t len)
{
int i;
for (i = 0; i < len; i++)
{
nrf_utils_app_uart_put((char) debug_string[i]);
}
}

View File

@ -20,10 +20,7 @@
#include <stdint.h>
/// Functions for configuring and setting GPIOS.
uint32_t nrf_utils_gpio_pin_get_state(uint32_t pin);
void nrf_utils_delay_us(uint32_t microsec);
unsigned int nrf_utils_get_baud_enum(int baud);
// Configure the low frequency clock to use the external 32.768 kHz crystal as a source & start.
void nrf_utils_lfclk_config_and_start(void);
@ -31,10 +28,6 @@ void nrf_utils_lfclk_config_and_start(void);
int nrf_utils_get_device_id(uint8_t * device_id, int maxChars);
uint8_t nrf_utils_get_random_number(void);
void nrf_utils_app_uart_put(uint8_t character);
void print_string_to_terminal(uint8_t * debug_string, uint32_t len);
#endif // NRF5X_UTILS_H__
/** @} */