[nrf52840] update platform drivers and libraries (#2608)

Signed-off-by: Robert Lubos <[email protected]>
This commit is contained in:
Robert Lubos
2018-03-12 18:24:12 +00:00
committed by Jonathan Hui
parent 2559e03b55
commit 6d98377a1a
237 changed files with 145887 additions and 49511 deletions
+95 -26
View File
@@ -34,6 +34,10 @@ lib_LIBRARIES
libopenthread-nrf52840-softdevice-sdk.a \
$(NULL)
# Do not enable -pedantic-errors for nRF52840 driver library
override CFLAGS := $(filter-out -pedantic-errors,$(CFLAGS))
override CXXFLAGS := $(filter-out -pedantic-errors,$(CXXFLAGS))
COMMONCPPFLAGS = \
-DCONFIG_GPIO_AS_PINRESET \
-DNRF52840_XXAA \
@@ -45,7 +49,6 @@ COMMONCPPFLAGS
-I$(srcdir) \
-I$(top_srcdir)/third_party/NordicSemiconductor \
-I$(top_srcdir)/third_party/NordicSemiconductor/cmsis \
-I$(top_srcdir)/third_party/NordicSemiconductor/device \
-I$(top_srcdir)/third_party/NordicSemiconductor/dependencies \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common \
@@ -55,13 +58,21 @@ COMMONCPPFLAGS
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/power \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/systick \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/usbd \
-I$(top_srcdir)/third_party/NordicSemiconductor/hal \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/atfifo \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/atomic \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/config \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc \
-I$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/acm \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk \
-I$(top_srcdir)/third_party/NordicSemiconductor/nrfx/soc \
-I$(top_srcdir)/third_party/NordicSemiconductor/segger_rtt \
-I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/headers \
$(NULL)
PLATFORM_COMMON_SOURCES = \
@@ -144,19 +155,24 @@ RADIO_DRIVER_SOURCES
NORDICSEMI_SOURCES = \
@top_builddir@/third_party/NordicSemiconductor/dependencies/app_util_platform.c \
@top_builddir@/third_party/NordicSemiconductor/device/gcc_startup_nrf52840.S \
@top_builddir@/third_party/NordicSemiconductor/device/system_nrf52840.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/common/nrf_drv_common.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/clock/nrf_drv_clock.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/power/nrf_drv_power.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/systick/nrf_drv_systick.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd.c \
@top_builddir@/third_party/NordicSemiconductor/hal/nrf_nvmc.c \
@top_builddir@/third_party/NordicSemiconductor/libraries/app_error/app_error.c \
@top_builddir@/third_party/NordicSemiconductor/libraries/app_error/app_error_weak.c \
@top_builddir@/third_party/NordicSemiconductor/libraries/atfifo/nrf_atfifo.c \
@top_builddir@/third_party/NordicSemiconductor/libraries/atomic/nrf_atomic.c \
@top_builddir@/third_party/NordicSemiconductor/libraries/usb/app_usbd.c \
@top_builddir@/third_party/NordicSemiconductor/libraries/usb/app_usbd_core.c \
@top_builddir@/third_party/NordicSemiconductor/libraries/usb/app_usbd_string_desc.c \
@top_builddir@/third_party/NordicSemiconductor/libraries/usb/app_usbd_serial_num.c \
@top_builddir@/third_party/NordicSemiconductor/libraries/usb/class/cdc/acm/app_usbd_cdc_acm.c \
@top_builddir@/third_party/NordicSemiconductor/nrfx/drivers/src/nrfx_clock.c \
@top_builddir@/third_party/NordicSemiconductor/nrfx/drivers/src/nrfx_power.c \
@top_builddir@/third_party/NordicSemiconductor/nrfx/drivers/src/nrfx_systick.c \
@top_builddir@/third_party/NordicSemiconductor/nrfx/hal/nrf_nvmc.c \
@top_builddir@/third_party/NordicSemiconductor/nrfx/mdk/gcc_startup_nrf52840.S \
@top_builddir@/third_party/NordicSemiconductor/nrfx/mdk/system_nrf52840.c \
@top_builddir@/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT.c \
$(NULL)
@@ -203,15 +219,32 @@ noinst_HEADERS
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmFunc.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmInstr.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmSimd.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/compiler_abstraction.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf51_to_nrf52.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf51_to_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf52_to_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf52840_bitfields.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf52840_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/system_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/app_util_platform.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/app_util.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/apply_old_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nordic_common.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_assert.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_error.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log_instance.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_log.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrf_section.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrfx_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrfx_glue.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/nrfx_log.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_common.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_errors.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_macros.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_os.h \
$(top_srcdir)/third_party/NordicSemiconductor/dependencies/sdk_resources.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock/nrf_drv_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/common/nrf_drv_common.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/power/nrf_drv_power.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/systick/nrf_drv_systick.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd_errata.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/usbd/nrf_drv_usbd.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.h \
@@ -240,18 +273,54 @@ noinst_HEADERS
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_assert.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_gpio.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_gpiote.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_egu.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_nvmc.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_ppi.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_rng.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_uart.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error/app_error_weak.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error/app_error.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/atfifo/nrf_atfifo_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/atfifo/nrf_atfifo.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/atomic/nrf_atomic_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/atomic/nrf_atomic.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_class_base.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_core.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_descriptor.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_langid.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_request.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_serial_num.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_string_desc.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/app_usbd.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/app_usbd_cdc_desc.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/app_usbd_cdc_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/acm/app_usbd_cdc_acm_internal.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/class/cdc/acm/app_usbd_cdc_acm.h \
$(top_srcdir)/third_party/NordicSemiconductor/libraries/usb/config/app_usbd_string_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/nrfx_common.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/nrfx_errors.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_power_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_power.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/drivers/include/nrfx_systick.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_gpio.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_gpiote.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_egu.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_nvmc.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_ppi.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_power.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_rng.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_uart.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/hal/nrf_usbd.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/compiler_abstraction.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf51_to_nrf52.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf51_to_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52_to_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52840_bitfields.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/nrf52840_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/nrfx/mdk/system_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT.h \
@top_builddir@/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT_Conf.h \
$(top_srcdir)/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT_Conf.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_err.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_gap.h \
+1 -1
View File
@@ -30,7 +30,7 @@
#include <openthread/config.h>
#include <openthread/platform/misc.h>
#include <device/nrf.h>
#include <nrf.h>
#include "platform-nrf5.h"
@@ -35,9 +35,9 @@
#ifndef PLATFORM_CONFIG_H_
#define PLATFORM_CONFIG_H_
#include "device/nrf.h"
#include "nrf.h"
#include "nrf_peripherals.h"
#include "drivers/clock/nrf_drv_clock.h"
#include "hal/nrf_peripherals.h"
#include "hal/nrf_radio.h"
#include "hal/nrf_uart.h"
+1 -1
View File
@@ -38,8 +38,8 @@
#include <openthread/platform/logging.h>
#include "platform-nrf5.h"
#include <device/nrf.h>
#include <drivers/clock/nrf_drv_clock.h>
#include <nrf.h>
#include <openthread/config.h>
+1 -1
View File
@@ -50,7 +50,7 @@
#include "platform-nrf5.h"
#include "platform.h"
#include <device/nrf.h>
#include <nrf.h>
#include <nrf_802154.h>
#include <openthread-core-config.h>
+18 -60
View File
@@ -56,6 +56,7 @@
#include "drivers/clock/nrf_drv_clock.h"
#include "drivers/power/nrf_drv_power.h"
#include "libraries/usb/app_usbd.h"
#include "libraries/usb/app_usbd_serial_num.h"
#include "libraries/usb/class/cdc/acm/app_usbd_cdc_acm.h"
#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
@@ -69,19 +70,14 @@ static void cdcAcmUserEventHandler(app_usbd_class_inst_t const *aInstance, app_u
#define CDC_ACM_DATA_EPIN NRF_DRV_USBD_EPIN1
#define CDC_ACM_DATA_EPOUT NRF_DRV_USBD_EPOUT1
#define SERIAL_NUMBER_STRING_SIZE 16
#define CDC_ACM_INTERFACES_CONFIG() \
APP_USBD_CDC_ACM_CONFIG(CDC_ACM_COMM_INTERFACE, CDC_ACM_COMM_EPIN, CDC_ACM_DATA_INTERFACE, CDC_ACM_DATA_EPIN, \
CDC_ACM_DATA_EPOUT)
static const uint8_t sCdcAcmClassDescriptors[] = {APP_USBD_CDC_ACM_DEFAULT_DESC(CDC_ACM_COMM_INTERFACE,
CDC_ACM_COMM_EPIN,
CDC_ACM_DATA_INTERFACE,
CDC_ACM_DATA_EPIN,
CDC_ACM_DATA_EPOUT)};
APP_USBD_CDC_ACM_GLOBAL_DEF(sAppCdcAcm, CDC_ACM_INTERFACES_CONFIG(), cdcAcmUserEventHandler, sCdcAcmClassDescriptors);
APP_USBD_CDC_ACM_GLOBAL_DEF(sAppCdcAcm,
cdcAcmUserEventHandler,
CDC_ACM_COMM_INTERFACE,
CDC_ACM_DATA_INTERFACE,
CDC_ACM_COMM_EPIN,
CDC_ACM_DATA_EPIN,
CDC_ACM_DATA_EPOUT,
APP_USBD_CDC_COMM_PROTOCOL_AT_V250);
// Rx buffer length must by multiple of NRF_DRV_USBD_EPSIZE.
static char sRxBuffer[NRF_DRV_USBD_EPSIZE * ((UART_RX_BUFFER_SIZE + NRF_DRV_USBD_EPSIZE - 1) / NRF_DRV_USBD_EPSIZE)];
@@ -101,26 +97,6 @@ static struct
volatile bool mReceiveDone;
} sUsbState;
uint16_t gExternSerialNumber[SERIAL_NUMBER_STRING_SIZE + 1];
static void serialNumberStringCreate(void)
{
gExternSerialNumber[0] = (uint16_t)APP_USBD_DESCRIPTOR_STRING << 8 | sizeof(gExternSerialNumber);
uint32_t deviceIdHi = NRF_FICR->DEVICEID[1];
uint32_t deviceIdLo = NRF_FICR->DEVICEID[0];
uint64_t deviceId = (((uint64_t)deviceIdHi) << 32) | deviceIdLo;
for (size_t i = 1; i < SERIAL_NUMBER_STRING_SIZE + 1; ++i)
{
char tmp[2];
snprintf(tmp, sizeof(tmp), "%x", (unsigned int)(deviceId & 0xF));
gExternSerialNumber[i] = tmp[0];
deviceId >>= 4;
}
}
static void cdcAcmUserEventHandler(app_usbd_class_inst_t const *aCdcAcmInstance, app_usbd_cdc_acm_user_event_t aEvent)
{
app_usbd_cdc_acm_t const *cdcAcmClass = app_usbd_cdc_acm_class_get(aCdcAcmInstance);
@@ -129,7 +105,7 @@ static void cdcAcmUserEventHandler(app_usbd_class_inst_t const *aCdcAcmInstance,
{
case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
// Setup first transfer.
(void)app_usbd_cdc_acm_read(&sAppCdcAcm, sRxBuffer, sizeof(sRxBuffer));
(void)app_usbd_cdc_acm_read_any(&sAppCdcAcm, sRxBuffer, sizeof(sRxBuffer));
sUsbState.mOpenTimestamp = otPlatAlarmMilliGetNow();
break;
@@ -159,32 +135,23 @@ static void usbdUserEventHandler(app_usbd_event_type_t aEvent)
app_usbd_disable();
break;
default:
break;
}
}
static void powerUsbEventHandler(nrf_drv_power_usb_evt_t aEvent)
{
switch (aEvent)
{
case NRF_DRV_POWER_USB_EVT_DETECTED:
case APP_USBD_EVT_POWER_DETECTED:
// Workaround for missing port open event.
sAppCdcAcm.specific.p_data->ctx.line_state = 0;
sUsbState.mConnected = true;
break;
case NRF_DRV_POWER_USB_EVT_REMOVED:
case APP_USBD_EVT_POWER_REMOVED:
sUsbState.mConnected = false;
break;
case NRF_DRV_POWER_USB_EVT_READY:
case APP_USBD_EVT_POWER_READY:
sUsbState.mReadyToStart = true;
break;
default:
assert(false);
break;
}
}
@@ -265,7 +232,7 @@ static void processReceive(void)
}
// Setup next transfer.
if (app_usbd_cdc_acm_read(&sAppCdcAcm, sRxBuffer, sizeof(sRxBuffer)) == NRF_SUCCESS)
if (app_usbd_cdc_acm_read_any(&sAppCdcAcm, sRxBuffer, sizeof(sRxBuffer)) == NRF_SUCCESS)
{
sUsbState.mReceiveDone = false;
}
@@ -297,25 +264,20 @@ static void processTransmit(void)
void nrf5UartInit(void)
{
static const nrf_drv_power_usbevt_config_t powerConfig = {.handler = powerUsbEventHandler};
static const app_usbd_config_t usbdConfig = {.ev_state_proc = usbdUserEventHandler};
memset((void *)&sUsbState, 0, sizeof(sUsbState));
serialNumberStringCreate();
app_usbd_serial_num_generate();
ret_code_t ret = nrf_drv_power_init(NULL);
assert(ret == NRF_SUCCESS);
ret = app_usbd_init(&usbdConfig);
ret_code_t ret = app_usbd_init(&usbdConfig);
assert(ret == NRF_SUCCESS);
app_usbd_class_inst_t const *cdcAcmInstance = app_usbd_cdc_acm_class_inst_get(&sAppCdcAcm);
ret = app_usbd_class_append(cdcAcmInstance);
assert(ret == NRF_SUCCESS);
ret = nrf_drv_power_usbevt_init(&powerConfig);
ret = app_usbd_power_events_enable();
assert(ret == NRF_SUCCESS);
}
@@ -334,12 +296,8 @@ void nrf5UartDeinit(void)
app_usbd_disable();
}
nrf_drv_power_usbevt_uninit();
app_usbd_class_remove_all();
app_usbd_uninit();
nrf_drv_power_uninit();
}
void nrf5UartProcess(void)
+1 -2
View File
@@ -5,9 +5,8 @@ in process of building the OpenThread's nRF52840 platform.
Directory consists of following folders:
- /cmsis - Core Peripheral Access Layer Headers files
- /dependencies - Dependencies for drivers and libraries from nrf5 SDK
- /device - MDK for the nRF52840 chip
- /drivers - Drivers for the nRF52840 that are used in the platform
- /hal - Hardware Access Layer for the nRF52840 chip
- /libraries - Libraries for the nRF52840 chip
- /nrfx - Standalone drivers for peripherals present in Nordic SoCs (https://github.com/NordicSemiconductor/nrfx)
- /segger_rtt - Library for the RTT communication
- /softdevice - SoftDevice s140 headers
File diff suppressed because it is too large Load Diff
+68 -70
View File
@@ -37,7 +37,7 @@
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* ########################### Core Function Access ########################### */
@@ -56,8 +56,8 @@
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return (__regControl);
register uint32_t __regControl __ASM("control");
return(__regControl);
}
@@ -68,8 +68,8 @@ __STATIC_INLINE uint32_t __get_CONTROL(void)
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
register uint32_t __regControl __ASM("control");
__regControl = control;
}
@@ -80,8 +80,8 @@ __STATIC_INLINE void __set_CONTROL(uint32_t control)
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return (__regIPSR);
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
@@ -92,8 +92,8 @@ __STATIC_INLINE uint32_t __get_IPSR(void)
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return (__regAPSR);
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
@@ -104,8 +104,8 @@ __STATIC_INLINE uint32_t __get_APSR(void)
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return (__regXPSR);
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
@@ -116,8 +116,8 @@ __STATIC_INLINE uint32_t __get_xPSR(void)
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return (__regProcessStackPointer);
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
@@ -128,8 +128,8 @@ __STATIC_INLINE uint32_t __get_PSP(void)
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
@@ -140,8 +140,8 @@ __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return (__regMainStackPointer);
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
@@ -152,8 +152,8 @@ __STATIC_INLINE uint32_t __get_MSP(void)
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
@@ -164,8 +164,8 @@ __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return (__regPriMask);
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
@@ -176,8 +176,8 @@ __STATIC_INLINE uint32_t __get_PRIMASK(void)
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
@@ -206,8 +206,8 @@ __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return (__regBasePri);
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
@@ -218,8 +218,8 @@ __STATIC_INLINE uint32_t __get_BASEPRI(void)
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xFFU);
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xFFU);
}
@@ -231,8 +231,8 @@ __STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
*/
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
{
register uint32_t __regBasePriMax __ASM("basepri_max");
__regBasePriMax = (basePri & 0xFFU);
register uint32_t __regBasePriMax __ASM("basepri_max");
__regBasePriMax = (basePri & 0xFFU);
}
@@ -243,8 +243,8 @@ __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return (__regFaultMask);
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
@@ -255,8 +255,8 @@ __STATIC_INLINE uint32_t __get_FAULTMASK(void)
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
@@ -272,10 +272,10 @@ __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
register uint32_t __regfpscr __ASM("fpscr");
return (__regfpscr);
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return (0U);
return(0U);
#endif
}
@@ -288,8 +288,8 @@ __STATIC_INLINE uint32_t __get_FPSCR(void)
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
@@ -387,8 +387,8 @@ __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
rev16 r0, r0
bx lr
}
#endif
@@ -401,8 +401,8 @@ __attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(u
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
revsh r0, r0
bx lr
}
#endif
@@ -434,24 +434,22 @@ __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(in
\return Reversed value
*/
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
#define __RBIT __rbit
#define __RBIT __rbit
#else
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
uint32_t result;
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value; value >>= 1U)
{
result <<= 1U;
result |= value & 1U;
s--;
}
result <<= s; /* shift when v's highest bits are zero */
return (result);
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value; value >>= 1U)
{
result <<= 1U;
result |= value & 1U;
s--;
}
result <<= s; /* shift when v's highest bits are zero */
return(result);
}
#endif
@@ -474,9 +472,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
\return value of type uint8_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
#else
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
#endif
@@ -487,9 +485,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
\return value of type uint16_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
#else
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
#endif
@@ -500,9 +498,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
\return value of type uint32_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
#else
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
#endif
@@ -515,9 +513,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXB(value, ptr) __strex(value, ptr)
#define __STREXB(value, ptr) __strex(value, ptr)
#else
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
@@ -530,9 +528,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXH(value, ptr) __strex(value, ptr)
#define __STREXH(value, ptr) __strex(value, ptr)
#else
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
@@ -545,9 +543,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXW(value, ptr) __strex(value, ptr)
#define __STREXW(value, ptr) __strex(value, ptr)
#else
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
@@ -588,8 +586,8 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
rrx r0, r0
bx lr
}
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+13 -14
View File
@@ -31,11 +31,10 @@
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMFUNC_H
@@ -50,35 +49,35 @@
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#include <cmsis_csm.h>
#endif
+13 -13
View File
@@ -33,9 +33,9 @@
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMINSTR_H
@@ -50,35 +50,35 @@
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#include <cmsis_csm.h>
#endif
+14 -14
View File
@@ -33,16 +33,16 @@
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMSIMD_H
#define __CORE_CMSIMD_H
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif
@@ -54,35 +54,35 @@ extern "C" {
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#include <cmsis_csm.h>
#endif
+178 -34
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -59,25 +59,75 @@
#ifdef __cplusplus
extern "C" {
#endif
/**
* @cond (NODOX)
*/
/*lint -save -e27 -e10 -e19 */
#if defined (__LINT__)
#define STACK_BASE 0x1F000 // Arbitrary value.
#define STACK_TOP 0x20000 // Arbitrary value.
//lint -save -e27 -e10 -e19
#if defined ( __CC_ARM ) && !defined (__LINT__)
#elif defined ( __CC_ARM )
extern char STACK$$Base;
extern char STACK$$Length;
#define STACK_BASE &STACK$$Base
#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&STACK$$Length))
#elif defined ( __ICCARM__ )
extern char CSTACK$$Base;
extern char CSTACK$$Length;
#define STACK_BASE &CSTACK$$Base
#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&CSTACK$$Length))
#elif defined ( __GNUC__ )
extern uint32_t __StackTop;
extern uint32_t __StackLimit;
#define STACK_BASE &__StackLimit
#define STACK_TOP &__StackTop
#endif
//lint -restore
/* These macros are valid only when absolute placement is used for the application
* image. The macros are not compile time symbols. They cannot be used as a
* constant expression, for example, inside a static assert or linker script
* at-placement. */
#if defined (__LINT__)
#define CODE_START (0) // Arbitrary value.
#define CODE_END (0x1000) // Arbitrary value.
#define CODE_SIZE (0x1000) // Arbitrary value.
#elif defined ( __CC_ARM )
extern char Image$$ER_IROM1$$Base;
extern char Image$$ER_IROM1$$Length;
extern char Image$$ER_IROM1$$Limit;
#define CODE_START ((uint32_t)&Image$$ER_IROM1$$Base)
#define CODE_END ((uint32_t)&Image$$ER_IROM1$$Limit)
#define CODE_SIZE ((uint32_t)&Image$$ER_IROM1$$Length)
#elif defined ( __ICCARM__ )
extern void * __vector_table;
extern char RO_END$$Base;
#define CODE_START ((uint32_t)&__vector_table)
#define CODE_END ((uint32_t)&RO_END$$Base)
#define CODE_SIZE (CODE_END - CODE_START)
#elif defined(__SES_ARM)
extern uint32_t * _vectors;
extern uint32_t __FLASH_segment_used_end__;
#define CODE_START ((uint32_t)&_vectors)
#define CODE_END ((uint32_t)&__FLASH_segment_used_end__)
#define CODE_SIZE (CODE_END - CODE_START)
#elif defined ( __GNUC__ )
extern uint32_t __isr_vector;
extern uint32_t __etext;
#define CODE_START ((uint32_t)&__isr_vector)
#define CODE_END ((uint32_t)&__etext)
#define CODE_SIZE (CODE_END - CODE_START)
#endif
/** @}
* @endcond
*/
/* lint -restore */
enum
{
@@ -86,6 +136,51 @@ enum
UNIT_10_MS = 10000 /**< Number of microseconds in 10 milliseconds. */
};
/**
* @brief Counts number of bits required for the given value
*
* The macro technically searches for the highest bit set.
* For value 0 it returns 0.
*
* @param val Value to be processed
*
* @return Number of bits required for the given value
*/
//lint -emacro(572,VBITS)
#define VBITS(val) VBITS_32(val)
/**
* @def VBITS_1
* @brief Internal macro used by @ref VBITS */
/**
* @def VBITS_2
* @brief Internal macro used by @ref VBITS */
/**
* @def VBITS_4
* @brief Internal macro used by @ref VBITS */
/**
* @def VBITS_8
* @brief Internal macro used by @ref VBITS */
/**
* @def VBITS_16
* @brief Internal macro used by @ref VBITS */
/**
* @def VBITS_32
* @brief Internal macro used by @ref VBITS */
#define VBITS_1( v) ((((v) & (0x0001U << 0)) != 0) ? 1U : 0U)
#define VBITS_2( v) ((((v) & (0x0001U << 1)) != 0) ? VBITS_1 ((v) >> 1) + 1 : VBITS_1 (v))
#define VBITS_4( v) ((((v) & (0x0003U << 2)) != 0) ? VBITS_2 ((v) >> 2) + 2 : VBITS_2 (v))
#define VBITS_8( v) ((((v) & (0x000fU << 4)) != 0) ? VBITS_4 ((v) >> 4) + 4 : VBITS_4 (v))
#define VBITS_16(v) ((((v) & (0x00ffU << 8)) != 0) ? VBITS_8 ((v) >> 8) + 8 : VBITS_8 (v))
#define VBITS_32(v) ((((v) & (0xffffU << 16)) != 0) ? VBITS_16((v) >> 16) + 16 : VBITS_16(v))
/*Segger embedded studio originally has offsetof macro which cannot be used in macros (like STATIC_ASSERT).
This redefinition is to allow using that. */
#if defined(__SES_ARM) && defined(__GNUC__)
#undef offsetof
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
#endif
/**@brief Implementation specific macro for delayed macro expansion used in string concatenation
*
@@ -105,35 +200,50 @@ enum
#define STRING_CONCATENATE(lhs, rhs) STRING_CONCATENATE_IMPL(lhs, rhs)
// Disable lint-warnings/errors for STATIC_ASSERT
//lint -emacro(10, STATIC_ASSERT)
//lint -emacro(15, STATIC_ASSERT)
//lint -emacro(18, STATIC_ASSERT)
//lint -emacro(19, STATIC_ASSERT)
//lint -emacro(30, STATIC_ASSERT)
//lint -emacro(37, STATIC_ASSERT)
//lint -emacro(42, STATIC_ASSERT)
//lint -emacro(26, STATIC_ASSERT)
//lint -emacro(102,STATIC_ASSERT)
//lint -emacro(533,STATIC_ASSERT)
//lint -emacro(534,STATIC_ASSERT)
//lint -emacro(132,STATIC_ASSERT)
//lint -emacro(414,STATIC_ASSERT)
//lint -emacro(578,STATIC_ASSERT)
//lint -emacro(628,STATIC_ASSERT)
//lint -emacro(648,STATIC_ASSERT)
//lint -emacro(830,STATIC_ASSERT)
#ifndef __LINT__
/**@brief Macro for doing static (i.e. compile time) assertion.
*
* @note If the EXPR isn't resolvable, then the error message won't be shown.
* @note The output of STATIC_ASSERT will be different across different compilers.
*
* @param[in] EXPR Constant expression to be verified.
* @hideinitializer
*/
#define STATIC_ASSERT(EXPR) \
extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(EXPR)])]
#ifdef __GNUC__
#define STATIC_ASSERT_SIMPLE(EXPR) _Static_assert(EXPR, "unspecified message")
#define STATIC_ASSERT_MSG(EXPR, MSG) _Static_assert(EXPR, MSG)
#endif
#ifdef __CC_ARM
#define STATIC_ASSERT_SIMPLE(EXPR) extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(EXPR)])]
#define STATIC_ASSERT_MSG(EXPR, MSG) extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(EXPR)])]
#endif
#ifdef __ICCARM__
#define STATIC_ASSERT_SIMPLE(EXPR) static_assert(EXPR, "unspecified message")
#define STATIC_ASSERT_MSG(EXPR, MSG) static_assert(EXPR, MSG)
#endif
#else // __LINT__
#define STATIC_ASSERT_SIMPLE(EXPR) extern char (*_ignore(void))
#define STATIC_ASSERT_MSG(EXPR, MSG) extern char (*_ignore(void))
#endif
#define _SELECT_ASSERT_FUNC(x, EXPR, MSG, ASSERT_MACRO) ASSERT_MACRO
/**
* @brief Static (i.e. compile time) assert macro.
*
* @note The output of STATIC_ASSERT can be different across compilers.
*
* Usage:
* STATIC_ASSERT(expression);
* STATIC_ASSERT(expression, message);
*
* @hideinitializer
*/
//lint -save -esym(???, STATIC_ASSERT)
#define STATIC_ASSERT(...) \
_SELECT_ASSERT_FUNC(x, ##__VA_ARGS__, \
STATIC_ASSERT_MSG(__VA_ARGS__), \
STATIC_ASSERT_SIMPLE(__VA_ARGS__))
//lint -restore
/**@brief Implementation details for NUM_VAR_ARGS */
@@ -275,7 +385,7 @@ typedef struct
*
* @return The aligned (increased) @p number.
*/
#define ALIGN_NUM(alignment, number) ((number - 1) + alignment - ((number - 1) % alignment))
#define ALIGN_NUM(alignment, number) (((number) - 1) + (alignment) - (((number) - 1) % (alignment)))
/**@brief Macro for getting first of 2 parameters.
*
@@ -839,6 +949,23 @@ static __INLINE uint8_t uint32_encode(uint32_t value, uint8_t * p_encoded_data)
return sizeof(uint32_t);
}
/**@brief Function for encoding a uint40 value.
*
* @param[in] value Value to be encoded.
* @param[out] p_encoded_data Buffer where the encoded data is to be written.
*
* @return Number of bytes written.
*/
static __INLINE uint8_t uint40_encode(uint64_t value, uint8_t * p_encoded_data)
{
p_encoded_data[0] = (uint8_t) ((value & 0x00000000FF) >> 0);
p_encoded_data[1] = (uint8_t) ((value & 0x000000FF00) >> 8);
p_encoded_data[2] = (uint8_t) ((value & 0x0000FF0000) >> 16);
p_encoded_data[3] = (uint8_t) ((value & 0x00FF000000) >> 24);
p_encoded_data[4] = (uint8_t) ((value & 0xFF00000000) >> 32);
return 5;
}
/**@brief Function for encoding a uint48 value.
*
* @param[in] value Value to be encoded.
@@ -938,6 +1065,8 @@ static __INLINE uint8_t uint16_big_encode(uint16_t value, uint8_t * p_encoded_da
return sizeof(uint16_t);
}
/*lint -esym(526, __rev) */
/*lint -esym(628, __rev) */
/**@brief Function for encoding a uint32 value in big-endian format.
*
* @param[in] value Value to be encoded.
@@ -951,6 +1080,21 @@ static __INLINE uint8_t uint32_big_encode(uint32_t value, uint8_t * p_encoded_da
return sizeof(uint32_t);
}
/**@brief Function for decoding a uint40 value.
*
* @param[in] p_encoded_data Buffer where the encoded data is stored.
*
* @return Decoded value. (uint64_t)
*/
static __INLINE uint64_t uint40_decode(const uint8_t * p_encoded_data)
{
return ( (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) |
(((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) |
(((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) |
(((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24) |
(((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32 ));
}
/**@brief Function for decoding a uint48 value.
*
* @param[in] p_encoded_data Buffer where the encoded data is stored.
@@ -1030,6 +1174,7 @@ static __INLINE bool is_word_aligned(void const* p)
return (((uintptr_t)p & 0x03) == 0);
}
/*lint -e{568, 685} */
/**
* @brief Function for checking if provided address is located in stack space.
*
@@ -1050,7 +1195,6 @@ static __INLINE bool is_address_from_stack(void * ptr)
}
}
#ifdef __cplusplus
}
#endif
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2014 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -71,6 +71,7 @@ void app_util_critical_region_enter(uint8_t *p_nested)
/* return value can be safely ignored */
(void) sd_nvic_critical_region_enter(p_nested);
#else
(void)p_nested;
app_util_disable_irq();
#endif
}
@@ -85,6 +86,7 @@ void app_util_critical_region_exit(uint8_t nested)
/* return value can be safely ignored */
(void) sd_nvic_critical_region_exit(nested);
#else
(void)nested;
app_util_enable_irq();
#endif
}
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2014 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -122,7 +122,7 @@ typedef enum
/**@brief Macro for setting a breakpoint.
*/
#if defined(__GNUC__)
#define NRF_BREAKPOINT __builtin_trap()
#define NRF_BREAKPOINT __asm__("BKPT 0");
#else
#define NRF_BREAKPOINT __BKPT(0)
#endif
@@ -155,6 +155,20 @@ typedef enum
#define PACKED_STRUCT __packed struct
#endif
#if defined ( __CC_ARM )
#define PRAGMA_OPTIMIZATION_FORCE_START _Pragma ("push") \
_Pragma ("O3")
#define PRAGMA_OPTIMIZATION_FORCE_END _Pragma ("pop")
#elif defined ( __GNUC__ )
#define PRAGMA_OPTIMIZATION_FORCE_START _Pragma("GCC push_options") \
_Pragma ("GCC optimize (\"Os\")")
#define PRAGMA_OPTIMIZATION_FORCE_END _Pragma ("GCC pop_options")
#elif defined (__ICCARM__)
#define PRAGMA_OPTIMIZATION_FORCE_START _Pragma ("optimize=high z")
#define PRAGMA_OPTIMIZATION_FORCE_END
#endif
void app_util_critical_region_enter (uint8_t *p_nested);
void app_util_critical_region_exit (uint8_t nested);
@@ -197,12 +211,14 @@ void app_util_critical_region_exit (uint8_t nested);
/**@brief Macro to enable anonymous unions from a certain point in the code.
*/
#if defined(__CC_ARM)
#define ANON_UNIONS_ENABLE _Pragma("push") \
_Pragma("anon_unions")
#define ANON_UNIONS_ENABLE _Pragma("push") \
_Pragma("anon_unions") \
struct semicolon_swallower
#elif defined(__ICCARM__)
#define ANON_UNIONS_ENABLE _Pragma("language=extended")
#define ANON_UNIONS_ENABLE _Pragma("language=extended") \
struct semicolon_swallower
#else
#define ANON_UNIONS_ENABLE
#define ANON_UNIONS_ENABLE struct semicolon_swallower
// No action will be taken.
// For GCC anonymous unions are enabled by default.
#endif
@@ -211,12 +227,13 @@ void app_util_critical_region_exit (uint8_t nested);
* @note Call only after first calling @ref ANON_UNIONS_ENABLE.
*/
#if defined(__CC_ARM)
#define ANON_UNIONS_DISABLE _Pragma("pop")
#define ANON_UNIONS_DISABLE _Pragma("pop") \
struct semicolon_swallower
#elif defined(__ICCARM__)
#define ANON_UNIONS_DISABLE
#define ANON_UNIONS_DISABLE struct semicolon_swallower
// for IAR leave anonymous unions enabled
#else
#define ANON_UNIONS_DISABLE
#define ANON_UNIONS_DISABLE struct semicolon_swallower
// No action will be taken.
// For GCC anonymous unions are enabled by default.
#endif
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2008 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2008 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -1,52 +1,52 @@
/* Copyright (c) 2016, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/** @file
* @brief Utilities for verifying program logic
*/
#ifndef NRF_ASSERT_H_
#define NRF_ASSERT_H_
#ifdef __cplusplus
extern "C" {
#endif
#define ASSERT(expr) \
if (!(expr)) \
{ \
while(1); \
}
#ifdef __cplusplus
}
#endif
#endif /* NRF_ASSERT_H_ */
/* Copyright (c) 2016, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/** @file
* @brief Utilities for verifying program logic
*/
#ifndef NRF_ASSERT_H_
#define NRF_ASSERT_H_
#ifdef __cplusplus
extern "C" {
#endif
#define ASSERT(expr) \
if (!(expr)) \
{ \
while(1); \
}
#ifdef __cplusplus
}
#endif
#endif /* NRF_ASSERT_H_ */
-268
View File
@@ -1,268 +0,0 @@
/**
* Copyright (c) 2011 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _NRF_DELAY_H
#define _NRF_DELAY_H
#include "nrf.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CLOCK_FREQ_16MHz (16000000UL)
#ifdef NRF52_SERIES
#define CPU_FREQ_64MHz
#endif
/**
* @brief Function for delaying execution for number of microseconds.
*
* @note NRF52 has instruction cache and because of that delay is not precise.
*
* @param number_of_us
*
*/
/*lint -e{438, 522, 40, 10, 563} */
__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us);
/**
* @brief Function for delaying execution for number of miliseconds.
*
* @note NRF52 has instruction cache and because of that delay is not precise.
*
* @note Function internally calls @ref nrf_delay_us so the maximum delay is the
* same as in case of @ref nrf_delay_us, approx. 71 minutes.
*
* @param number_of_ms
*
*/
/*lint -e{438, 522, 40, 10, 563} */
__STATIC_INLINE void nrf_delay_ms(uint32_t number_of_ms);
#if defined ( __CC_ARM )
__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us)
{
if (!number_of_us)
return;
__asm
{
loop:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CMP SystemCoreClock, CLOCK_FREQ_16MHz
BEQ cond
NOP
#ifdef CPU_FREQ_64MHz
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
#endif //CPU_FREQ_64MHz
cond:
SUBS number_of_us, #1
BNE loop
}
}
#elif defined ( _WIN32 ) || defined ( __unix ) || defined( __APPLE__ )
#ifndef CUSTOM_NRF_DELAY_US
__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us)
{}
#endif
#elif defined ( __GNUC__ ) || ( __ICCARM__ )
__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us)
{
const uint32_t clock16MHz = CLOCK_FREQ_16MHz;
if (number_of_us)
{
__ASM volatile (
#if ( defined(__GNUC__) && (__CORTEX_M == (0x00U) ) )
".syntax unified\n"
#endif
"1:\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" CMP %[SystemCoreClock], %[clock16MHz]\n"
" BEQ.N 2f\n"
" NOP\n"
#ifdef CPU_FREQ_64MHz
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
" NOP\n"
#endif //CPU_FREQ_64MHz
"2:\n"
" SUBS %[number_of_us], %[number_of_us], #1\n"
" BNE.N 1b\n"
#if ( defined(__GNUC__) && (__CORTEX_M == (0x00U) ) )
".syntax divided\n"
#endif
#if ( __CORTEX_M == (0x00U) )
// The SUBS instruction in Cortex-M0 is available only in 16-bit encoding,
// hence it requires a "lo" register (r0-r7) as an operand.
: [number_of_us] "=l" (number_of_us)
#else
: [number_of_us] "=r" (number_of_us)
#endif
: [SystemCoreClock] "r" (SystemCoreClock),
[clock16MHz] "r" (clock16MHz),
"[number_of_us]" (number_of_us)
);
}
}
#endif
__STATIC_INLINE void nrf_delay_ms(uint32_t number_of_ms)
{
nrf_delay_us(1000*number_of_ms);
}
#ifdef __cplusplus
}
#endif
#endif
+13 -5
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -38,6 +38,16 @@
*
*/
/* Header guard */
#ifndef SOFTDEVICE_PRESENT
/**
@defgroup nrf_error Global Error Codes
@{
@brief Global Error definitions
*/
#ifndef NRF_ERROR_H__
#define NRF_ERROR_H__
@@ -45,8 +55,6 @@
extern "C" {
#endif
/// @cond Make doxygen skip this file
/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions
* @{ */
#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base
@@ -74,14 +82,14 @@ extern "C" {
#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address
#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy
#ifdef __cplusplus
}
#endif
#endif // NRF_ERROR_H__
/// @endcond
/**
@}
*/
#endif // SOFTDEVICE_PRESENT
+91 -34
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -71,6 +71,12 @@ extern "C" {
#define NRF_LOG_LEVEL NRF_LOG_DEFAULT_LEVEL
#endif
/** @brief Initial severity if filtering is enabled.
*/
#ifndef NRF_LOG_INITIAL_LEVEL
#define NRF_LOG_INITIAL_LEVEL NRF_LOG_LEVEL
#endif
#include "nrf_log_internal.h"
@@ -107,14 +113,54 @@ extern "C" {
#define NRF_LOG_INFO(...) NRF_LOG_INTERNAL_INFO( __VA_ARGS__)
#define NRF_LOG_DEBUG(...) NRF_LOG_INTERNAL_DEBUG( __VA_ARGS__)
/** @def NRF_LOG_INST_ERROR
* @brief Macro for logging error messages for a given module instance. It takes a printf-like, formatted
* string with up to seven arguments.
*
* @param p_inst Pointer to the instance with logging support.
*
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*/
/** @def NRF_LOG_INST_WARNING
* @brief Macro for logging error messages for a given module instance. It takes a printf-like, formatted
* string with up to seven arguments.
*
* @param p_inst Pointer to the instance with logging support.
*
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*/
/** @def NRF_LOG_INST_INFO
* @brief Macro for logging error messages for a given module instance. It takes a printf-like, formatted
* string with up to seven arguments.
*
* @param p_inst Pointer to the instance with logging support.
*
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*/
/** @def NRF_LOG_INST_DEBUG
* @brief Macro for logging error messages for given module instance. It takes a printf-like, formatted
* string with up to seven arguments.
*
* @param p_inst Pointer to the instance with logging support.
*
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*/
#define NRF_LOG_INST_ERROR(p_inst,...) NRF_LOG_INTERNAL_INST_ERROR(p_inst,__VA_ARGS__)
#define NRF_LOG_INST_WARNING(p_inst,...) NRF_LOG_INTERNAL_INST_WARNING(p_inst,__VA_ARGS__)
#define NRF_LOG_INST_INFO(p_inst,...) NRF_LOG_INTERNAL_INST_INFO(p_inst, __VA_ARGS__)
#define NRF_LOG_INST_DEBUG(p_inst,...) NRF_LOG_INTERNAL_INST_DEBUG(p_inst, __VA_ARGS__)
/**
* @brief A macro for logging a formatted string without any prefix or timestamp.
* @brief Macro for logging a formatted string without any prefix or timestamp.
*/
#define NRF_LOG_RAW_INFO(...) NRF_LOG_INTERNAL_RAW_INFO( __VA_ARGS__)
/** @def NRF_LOG_HEXDUMP_ERROR
* @brief Macro for logging raw bytes.
* @details It is compiled in only if @ref NRF_LOG_LEVEL includes error logs.
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*
* @param p_data Pointer to data.
* @param len Data length in bytes.
@@ -145,20 +191,51 @@ extern "C" {
#define NRF_LOG_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len)
#define NRF_LOG_HEXDUMP_DEBUG(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len)
/** @def NRF_LOG_HEXDUMP_INST_ERROR
* @brief Macro for logging raw bytes for a specific module instance.
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*
* @param p_inst Pointer to the instance with logging support.
* @param p_data Pointer to data.
* @param len Data length in bytes.
*/
/** @def NRF_LOG_HEXDUMP_INST_WARNING
* @brief Macro for logging raw bytes for a specific module instance.
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*
* @param p_inst Pointer to the instance with logging support.
* @param p_data Pointer to data.
* @param len Data length in bytes.
*/
/** @def NRF_LOG_HEXDUMP_INST_INFO
* @brief Macro for logging raw bytes for a specific module instance.
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*
* @param p_inst Pointer to the instance with logging support.
* @param p_data Pointer to data.
* @param len Data length in bytes.
*/
/** @def NRF_LOG_HEXDUMP_INST_DEBUG
* @brief Macro for logging raw bytes for a specific module instance.
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*
* @param p_inst Pointer to the instance with logging support.
* @param p_data Pointer to data.
* @param len Data length in bytes.
*/
#define NRF_LOG_HEXDUMP_INST_ERROR(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_ERROR(p_inst, p_data, len)
#define NRF_LOG_HEXDUMP_INST_WARNING(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_WARNING(p_inst, p_data, len)
#define NRF_LOG_HEXDUMP_INST_INFO(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_INFO(p_inst, p_data, len)
#define NRF_LOG_HEXDUMP_INST_DEBUG(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_DEBUG(p_inst, p_data, len)
/**
* @brief Macro for logging hexdump without any prefix or timestamp.
*/
#define NRF_LOG_RAW_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len)
/**
* @brief A macro for blocking reading from bidirectional backend used for logging.
*
* Macro call is blocking and returns when single byte is received.
*/
#define NRF_LOG_GETCHAR() NRF_LOG_INTERNAL_GETCHAR()
/**
* @brief A macro for copying a string to internal logger buffer if logs are deferred.
* @brief Macro for copying a string to internal logger buffer if logs are deferred.
*
* @param _str String.
*/
@@ -182,7 +259,7 @@ uint32_t nrf_log_push(char * const p_str);
/**
* @brief Macro to be used in a formatted string to a pass float number to the log.
*
* Macro should be used in formatted string instead of the %f specifier together with
* Use this macro in a formatted string instead of the %f specifier together with
* @ref NRF_LOG_FLOAT macro.
* Example: NRF_LOG_INFO("My float number" NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(f)))
*/
@@ -197,33 +274,13 @@ uint32_t nrf_log_push(char * const p_str);
: (int32_t)(val) - (val))*100)
/**
* @def NRF_LOG_MODULE_REGISTER
* @brief Macro for registering an independent module.
*
* Registration creates set of dynamic (RAM) and constant variables associated with the module.
*/
#if NRF_LOG_ENABLED
#define NRF_LOG_MODULE_REGISTER() NRF_LOG_INTERNAL_MODULE_REGISTER()
#ifdef UNIT_TEST
#define _CONST
#define COMPILED_LOG_LEVEL 4
#else
#define _CONST const
#define COMPILED_LOG_LEVEL NRF_LOG_LEVEL
#endif
#define NRF_LOG_MODULE_REGISTER() \
NRF_SECTION_ITEM_REGISTER(log_const_data, \
_CONST nrf_log_module_const_data_t NRF_LOG_MODULE_DATA_CONST) = { \
.p_module_name = STRINGIFY(NRF_LOG_MODULE_NAME), \
.info_color_id = NRF_LOG_INFO_COLOR, \
.debug_color_id = NRF_LOG_DEBUG_COLOR, \
.compiled_lvl = COMPILED_LOG_LEVEL, \
}; \
NRF_SECTION_ITEM_REGISTER(log_dynamic_data, \
nrf_log_module_dynamic_data_t NRF_LOG_MODULE_DATA_DYNAMIC)
#else
#define NRF_LOG_MODULE_REGISTER() /*lint -save -e19*/ /*lint -restore*/
#endif
#ifdef __cplusplus
}
@@ -0,0 +1,135 @@
/**
* Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_LOG_INSTANCE_H
#define NRF_LOG_INSTANCE_H
#include "sdk_config.h"
#include "nrf_section.h"
#include "nrf_log_types.h"
#include <stdint.h>
/*
* For GCC, sections are sorted in the group by the linker. For IAR and KEIL, it is assumed that linker will sort
* dynamic and const section in the same order (but in different locations). Proper message formatting
* is based on that assumption.
*/
#if defined(__GNUC__)
#define NRF_LOG_DYNAMIC_SECTION_NAME(_module_name) CONCAT_2(log_dynamic_data_,_module_name)
#define NRF_LOG_CONST_SECTION_NAME(_module_name) CONCAT_2(log_const_data_,_module_name)
#else
#define NRF_LOG_DYNAMIC_SECTION_NAME(_module_name) log_dynamic_data
#define NRF_LOG_CONST_SECTION_NAME(_module_name) log_const_data
#endif
#define NRF_LOG_ITEM_DATA(_name) CONCAT_3(m_nrf_log_,_name,_logs_data)
#define NRF_LOG_ITEM_DATA_DYNAMIC(_name) CONCAT_2(NRF_LOG_ITEM_DATA(_name),_dynamic)
#define NRF_LOG_ITEM_DATA_CONST(_name) CONCAT_2(NRF_LOG_ITEM_DATA(_name),_const)
#ifdef UNIT_TEST
#define _CONST
#else
#define _CONST const
#endif
#if NRF_LOG_FILTERS_ENABLED
#define NRF_LOG_DYNAMIC_STRUCT_NAME nrf_log_module_dynamic_data_t
#else
#define NRF_LOG_DYNAMIC_STRUCT_NAME nrf_log_module_reduced_dynamic_data_t
#endif
#define NRF_LOG_INTERNAL_ITEM_REGISTER( \
_name, _str_name, _info_color, _debug_color, _initial_lvl, _compiled_lvl) \
NRF_SECTION_ITEM_REGISTER(NRF_LOG_CONST_SECTION_NAME(_name), \
_CONST nrf_log_module_const_data_t NRF_LOG_ITEM_DATA_CONST(_name)) = { \
.p_module_name = _str_name, \
.info_color_id = _info_color, \
.debug_color_id = _debug_color, \
.compiled_lvl = (nrf_log_severity_t)_compiled_lvl, \
.initial_lvl = (nrf_log_severity_t)_initial_lvl, \
}; \
NRF_SECTION_ITEM_REGISTER(NRF_LOG_DYNAMIC_SECTION_NAME(_name), \
NRF_LOG_DYNAMIC_STRUCT_NAME NRF_LOG_ITEM_DATA_DYNAMIC(_name))
/**@file
*
* @defgroup nrf_log_instance Macros for logging on instance level
* @{
* @ingroup nrf_log
*
* @brief Macros for logging on instance level
*/
/** @def NRF_LOG_INSTANCE_PTR_DECLARE
* @brief Macro for declaring a logger instance pointer in the module stucture.
*/
/** @def NRF_LOG_INSTANCE_REGISTER
* @brief Macro for creating an independent module instance.
*
* Module instance provides filtering of logs on instance level instead of module level.
*/
/** @def NRF_LOG_INSTANCE_PTR_INIT
* @brief Macro for initializing a pointer to the logger instance.
*/
/** @} */
#if NRF_LOG_ENABLED
#define NRF_LOG_INSTANCE_PTR_DECLARE(_p_name) NRF_LOG_DYNAMIC_STRUCT_NAME * _p_name;
#define NRF_LOG_INSTANCE_REGISTER( \
_module_name, _inst_name, _info_color, _debug_color, _initial_lvl, _compiled_lvl) \
NRF_LOG_INTERNAL_ITEM_REGISTER(CONCAT_3(_module_name,_,_inst_name), \
STRINGIFY(_module_name._inst_name), \
_info_color, \
_debug_color, \
_initial_lvl, \
_compiled_lvl)
#define NRF_LOG_INSTANCE_PTR_INIT(_p_name, _module_name, _inst_name) \
._p_name = &NRF_LOG_ITEM_DATA_DYNAMIC(CONCAT_3(_module_name,_,_inst_name)),
#else
#define NRF_LOG_INSTANCE_PTR_DECLARE(_p_name)
#define NRF_LOG_INSTANCE_REGISTER(_module_name, _inst_name, info_color, debug_color, _initial_lvl, compiled_lvl)
#define NRF_LOG_INSTANCE_PTR_INIT(_p_name, _module_name, _inst_name)
#endif
#endif //NRF_LOG_INSTANCE_H
+125 -131
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -45,6 +45,8 @@
#include "app_util.h"
#include <stdint.h>
#include <stdbool.h>
#include "nrf_log_instance.h"
#include "nrf_log_types.h"
#ifndef NRF_LOG_ERROR_COLOR
#define NRF_LOG_ERROR_COLOR NRF_LOG_COLOR_DEFAULT
@@ -87,36 +89,30 @@
#define NRF_LOG_MODULE_NAME app
#endif
#define NRF_LOG_LEVEL_ERROR 1UL
#define NRF_LOG_LEVEL_WARNING 2UL
#define NRF_LOG_LEVEL_INFO 3UL
#define NRF_LOG_LEVEL_DEBUG 4UL
#define NRF_LOG_LEVEL_INTERNAL 5UL
#define NRF_LOG_LEVEL_BITS 3
#define NRF_LOG_LEVEL_MASK ((1UL << NRF_LOG_LEVEL_BITS) - 1)
#define NRF_LOG_RAW_POS 4U
#define NRF_LOG_RAW (1UL << NRF_LOG_RAW_POS)
#define NRF_LOG_MODULE_ID_BITS 16
#define NRF_LOG_MODULE_ID_POS 16
#define NRF_LOG_LEVEL_INFO_RAW (NRF_LOG_RAW | NRF_LOG_LEVEL_INFO)
#define NRF_LOG_MAX_NUM_OF_ARGS 6
#define NRF_LOG_MODULE_DATA CONCAT_3(m_nrf_log_,NRF_LOG_MODULE_NAME,_logs_data)
#define NRF_LOG_MODULE_DATA_DYNAMIC CONCAT_2(NRF_LOG_MODULE_DATA,_dynamic)
#define NRF_LOG_MODULE_DATA_CONST CONCAT_2(NRF_LOG_MODULE_DATA,_const)
#if NRF_LOG_FILTERS_ENABLED && NRF_LOG_ENABLED
#define NRF_LOG_FILTER NRF_LOG_MODULE_DATA_DYNAMIC.filter
#define NRF_LOG_FILTER NRF_LOG_ITEM_DATA_DYNAMIC(NRF_LOG_MODULE_NAME).filter
#define NRF_LOG_INST_FILTER(p_inst) (p_inst)->filter
#else
#undef NRF_LOG_FILTER
#define NRF_LOG_FILTER NRF_LOG_LEVEL_DEBUG
#define NRF_LOG_FILTER NRF_LOG_SEVERITY_DEBUG
#define NRF_LOG_INST_FILTER(p_inst) NRF_LOG_SEVERITY_DEBUG
#endif
#if NRF_LOG_ENABLED
#define NRF_LOG_MODULE_ID NRF_LOG_MODULE_DATA_DYNAMIC.module_id
#define NRF_LOG_MODULE_ID NRF_LOG_ITEM_DATA_DYNAMIC(NRF_LOG_MODULE_NAME).module_id
#define NRF_LOG_INST_ID(p_inst) (p_inst)->module_id
#else
#define NRF_LOG_MODULE_ID 0
#define NRF_LOG_MODULE_ID 0
#define NRF_LOG_INST_ID(p_inst) 0
#endif
@@ -162,9 +158,10 @@
(void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3); (void)(_arg4)
#define LOG_INTERNAL_6(_type, _str, _arg0, _arg1, _arg2, _arg3, _arg4, _arg5) \
(void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3); (void)(_arg4); (void)(_arg5)
#endif //NRF_LOG_ENABLED && (NRF_LOG_DEFAULT_LEVEL >= NRF_LOG_LEVEL_ERROR)
#endif //NRF_LOG_ENABLED
#define LOG_SEVERITY_MOD_ID(severity) ((severity) | NRF_LOG_MODULE_ID << NRF_LOG_MODULE_ID_POS)
#define LOG_SEVERITY_INST_ID(severity,p_inst) ((severity) | NRF_LOG_INST_ID(p_inst) << NRF_LOG_MODULE_ID_POS)
#if NRF_LOG_ENABLED
#define LOG_HEXDUMP(_severity, _p_data, _length) \
@@ -174,132 +171,125 @@
(void)(_severity); (void)(_p_data); (void)_length
#endif
#define NRF_LOG_INTERNAL_ERROR(...) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_ERROR) && \
(NRF_LOG_LEVEL_ERROR <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_ERROR) \
{ \
LOG_INTERNAL(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_ERROR), __VA_ARGS__); \
} \
}
#define NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_ERROR) && \
(NRF_LOG_LEVEL_ERROR <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_ERROR) \
{ \
LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_ERROR), \
(p_data), (len)); \
} \
#define NRF_LOG_INTERNAL_INST(level, level_id, p_inst, ...) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
(level <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_INST_FILTER(p_inst) >= level) \
{ \
LOG_INTERNAL(LOG_SEVERITY_INST_ID(level_id, p_inst), __VA_ARGS__); \
} \
}
#define NRF_LOG_INTERNAL_WARNING(...) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_WARNING) && \
(NRF_LOG_LEVEL_WARNING <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_WARNING) \
{ \
LOG_INTERNAL(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_WARNING), __VA_ARGS__); \
} \
#define NRF_LOG_INTERNAL_MODULE(level, level_id, ...) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
(level <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_FILTER >= level) \
{ \
LOG_INTERNAL(LOG_SEVERITY_MOD_ID(level_id), __VA_ARGS__); \
} \
}
#define NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_WARNING) && \
(NRF_LOG_LEVEL_WARNING <= NRF_LOG_DEFAULT_LEVEL)) \
#define NRF_LOG_INTERNAL_HEXDUMP_INST(level, level_id, p_inst, p_data, len) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
(level <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_WARNING) \
if (NRF_LOG_INST_FILTER(p_inst) >= level) \
{ \
LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_WARNING, \
LOG_HEXDUMP(LOG_SEVERITY_INST_ID(level_id, p_inst), \
(p_data), (len)); \
} \
}
#define NRF_LOG_INTERNAL_INFO(...) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \
(NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \
#define NRF_LOG_INTERNAL_HEXDUMP_MODULE(level, level_id, p_data, len) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
(level <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_INFO) \
if (NRF_LOG_FILTER >= level) \
{ \
LOG_INTERNAL(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_INFO), __VA_ARGS__); \
} \
}
#define NRF_LOG_INTERNAL_RAW_INFO(...) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \
(NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_INFO) \
{ \
LOG_INTERNAL(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_INFO | NRF_LOG_RAW), \
__VA_ARGS__); \
} \
}
#define NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \
(NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_INFO) \
{ \
LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_INFO), \
LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(level_id), \
(p_data), (len)); \
} \
}
#define NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \
(NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_INFO) \
{ \
LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_INFO_RAW), \
(p_data), (len)); \
} \
}
#define NRF_LOG_INTERNAL_INST_ERROR(p_inst, ...) \
NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR, p_inst, __VA_ARGS__)
#define NRF_LOG_INTERNAL_DEBUG(...) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_DEBUG) && \
(NRF_LOG_LEVEL_DEBUG <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_DEBUG) \
{ \
LOG_INTERNAL(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_DEBUG), __VA_ARGS__); \
} \
}
#define NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_DEBUG) && \
(NRF_LOG_LEVEL_DEBUG <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_DEBUG) \
{ \
LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_DEBUG), \
(p_data), (len)); \
} \
}
#define NRF_LOG_INTERNAL_ERROR(...) \
NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR,__VA_ARGS__)
#if NRF_MODULE_ENABLED(NRF_LOG)
#define NRF_LOG_INTERNAL_GETCHAR() nrf_log_getchar()
#define NRF_LOG_INTERNAL_HEXDUMP_INST_ERROR(p_inst, p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR, p_inst, p_data, len)
#define NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR, p_data, len)
#define NRF_LOG_INTERNAL_INST_WARNING(p_inst, ...) \
NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING, p_inst, __VA_ARGS__)
#define NRF_LOG_INTERNAL_WARNING(...) \
NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING,__VA_ARGS__)
#define NRF_LOG_INTERNAL_HEXDUMP_INST_WARNING(p_inst, p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING, p_inst, p_data, len)
#define NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING, p_data, len)
#define NRF_LOG_INTERNAL_INST_INFO(p_inst, ...) \
NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, p_inst, __VA_ARGS__)
#define NRF_LOG_INTERNAL_INFO(...) \
NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, __VA_ARGS__)
#define NRF_LOG_INTERNAL_HEXDUMP_INST_INFO(p_inst, p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, p_inst, p_data, len)
#define NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, p_data, len)
#define NRF_LOG_INTERNAL_RAW_INFO(...) \
NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO_RAW, __VA_ARGS__)
#define NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO_RAW, p_data, len)
#define NRF_LOG_INTERNAL_INST_DEBUG(p_inst, ...) \
NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, p_inst, __VA_ARGS__)
#define NRF_LOG_INTERNAL_DEBUG(...) \
NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, __VA_ARGS__)
#define NRF_LOG_INTERNAL_HEXDUMP_INST_DEBUG(p_inst, p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, p_inst, p_data, len)
#define NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, p_data, len)
#if NRF_LOG_ENABLED
#ifdef UNIT_TEST
#define COMPILED_LOG_LEVEL 4
#else
#define NRF_LOG_INTERNAL_GETCHAR() (void)
#define COMPILED_LOG_LEVEL NRF_LOG_LEVEL
#endif
typedef struct
{
uint16_t module_id;
uint16_t order_idx;
uint32_t filter;
uint32_t filter_lvls;
} nrf_log_module_dynamic_data_t;
typedef struct
{
const char * p_module_name;
uint8_t info_color_id;
uint8_t debug_color_id;
uint8_t compiled_lvl;
} nrf_log_module_const_data_t;
#define NRF_LOG_INTERNAL_MODULE_REGISTER() \
NRF_LOG_INTERNAL_ITEM_REGISTER(NRF_LOG_MODULE_NAME, \
STRINGIFY(NRF_LOG_MODULE_NAME), \
NRF_LOG_INFO_COLOR, \
NRF_LOG_DEBUG_COLOR, \
NRF_LOG_INITIAL_LEVEL, \
COMPILED_LOG_LEVEL)
extern nrf_log_module_dynamic_data_t NRF_LOG_MODULE_DATA_DYNAMIC;
#else
#define NRF_LOG_INTERNAL_MODULE_REGISTER() /*lint -save -e19*/ /*lint -restore*/
#endif
extern NRF_LOG_DYNAMIC_STRUCT_NAME NRF_LOG_ITEM_DATA_DYNAMIC(NRF_LOG_MODULE_NAME);
/**
* Set of macros for encoding and decoding header for log entries.
@@ -367,18 +357,19 @@ extern nrf_log_module_dynamic_data_t NRF_LOG_MODULE_DATA_DYNAMIC;
#define HEADER_TYPE_STD 1U
#define HEADER_TYPE_HEXDUMP 2U
#define HEADER_TYPE_PUSHED 0U
#define HEADER_TYPE_INVALID 3U
typedef struct
{
uint32_t type : 2;
uint32_t raw : 1;
uint32_t in_progress: 1;
uint32_t data : 29;
} nrf_log_generic_header_t;
typedef struct
{
uint32_t type : 2;
uint32_t raw : 1;
uint32_t in_progress: 1;
uint32_t severity : 3;
uint32_t nargs : 4;
uint32_t addr : 22;
@@ -387,7 +378,7 @@ typedef struct
typedef struct
{
uint32_t type : 2;
uint32_t raw : 1;
uint32_t in_progress: 1;
uint32_t severity : 3;
uint32_t offset : 10;
uint32_t reserved : 6;
@@ -403,15 +394,18 @@ typedef struct
uint32_t len : 10;
} nrf_log_pushed_header_t;
typedef union
{
nrf_log_generic_header_t generic;
nrf_log_std_header_t std;
nrf_log_hexdump_header_t hexdump;
nrf_log_pushed_header_t pushed;
uint32_t raw;
} nrf_log_main_header_t;
typedef struct
{
union {
nrf_log_generic_header_t generic;
nrf_log_std_header_t std;
nrf_log_hexdump_header_t hexdump;
nrf_log_pushed_header_t pushed;
uint32_t raw;
} base;
nrf_log_main_header_t base;
uint32_t module_id;
uint32_t timestamp;
} nrf_log_header_t;
@@ -0,0 +1,97 @@
/**
* Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_LOG_TYPES_H
#define NRF_LOG_TYPES_H
#include <stdint.h>
/**
* @brief Logger severity levels.
*/
typedef enum
{
NRF_LOG_SEVERITY_NONE,
NRF_LOG_SEVERITY_ERROR,
NRF_LOG_SEVERITY_WARNING,
NRF_LOG_SEVERITY_INFO,
NRF_LOG_SEVERITY_DEBUG,
NRF_LOG_SEVERITY_INFO_RAW, /* Artificial level to pass information about skipping string postprocessing.*/
} nrf_log_severity_t;
/**
* @brief Structure holding dynamic data associated with a module or instance if filtering is enabled (@ref NRF_LOG_FILTERS_ENABLED).
*
* See @ref NRF_LOG_MODULE_REGISTER and @ref NRF_LOG_INSTANCE_REGISTER.
*/
typedef struct
{
uint16_t module_id; ///< Module ID assigned during initialization.
uint16_t order_idx; ///< Ordered index of the module (used for auto-completion).
uint32_t filter; ///< Current highest severity level accepted (redundant to @ref nrf_log_module_dynamic_data_t::filter_lvls, used for optimization)
uint32_t filter_lvls; ///< Current severity levels for each backend (3 bits per backend).
} nrf_log_module_dynamic_data_t;
/**
* @brief Structure holding dynamic data associated with a module or instance if filtering is disabled (@ref NRF_LOG_FILTERS_ENABLED).
*
* See @ref NRF_LOG_MODULE_REGISTER and @ref NRF_LOG_INSTANCE_REGISTER.
*/
typedef struct
{
uint16_t module_id; ///< Module ID assigned during initialization.
uint16_t padding; ///< Padding to fit in word.
} nrf_log_module_reduced_dynamic_data_t;
/**
* @brief Structure holding constant data associated with a module or instance.
*
* See @ref NRF_LOG_MODULE_REGISTER and @ref NRF_LOG_INSTANCE_REGISTER.
*/
typedef struct
{
const char * p_module_name; ///< Module or instance name.
uint8_t info_color_id; ///< Color code of info messages.
uint8_t debug_color_id; ///< Color code of debug messages.
nrf_log_severity_t compiled_lvl; ///< Compiled highest severity level.
nrf_log_severity_t initial_lvl; ///< Severity level for given module or instance set on backend initialization.
} nrf_log_module_const_data_t;
#endif //NRF_LOG_TYPES_H
+1 -1
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -0,0 +1,47 @@
/**
* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_CONFIG_H__
#define NRFX_CONFIG_H__
// TODO - temporary redirection
#include <sdk_config.h>
#endif // NRFX_CONFIG_H__
+268
View File
@@ -0,0 +1,268 @@
/**
* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_GLUE_H__
#define NRFX_GLUE_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_glue nrfx_glue.h
* @{
* @ingroup nrfx
*
* @brief This file contains macros that should be implemented according to
* the needs of the host environment into which @em nrfx is integrated.
*/
#include <apply_old_config.h>
#include <soc/nrfx_irqs.h>
//------------------------------------------------------------------------------
#include <nrf_assert.h>
/**
* @brief Macro for placing a runtime assertion.
*
* @param expression Expression to evaluate.
*/
#define NRFX_ASSERT(expression) ASSERT(expression)
#include <app_util.h>
/**
* @brief Macro for placing a compile time assertion.
*
* @param expression Expression to evaluate.
*/
#define NRFX_STATIC_ASSERT(expression) STATIC_ASSERT(expression)
//------------------------------------------------------------------------------
#ifdef NRF51
#ifdef SOFTDEVICE_PRESENT
#define INTERRUPT_PRIORITY_IS_VALID(pri) (((pri) == 1) || ((pri) == 3))
#else
#define INTERRUPT_PRIORITY_IS_VALID(pri) ((pri) < 4)
#endif //SOFTDEVICE_PRESENT
#else
#ifdef SOFTDEVICE_PRESENT
#define INTERRUPT_PRIORITY_IS_VALID(pri) ((((pri) > 1) && ((pri) < 4)) || \
(((pri) > 4) && ((pri) < 8)))
#else
#define INTERRUPT_PRIORITY_IS_VALID(pri) ((pri) < 8)
#endif //SOFTDEVICE_PRESENT
#endif //NRF52
/**
* @brief Macro for setting the priority of a specific IRQ.
*
* @param irq_number IRQ number.
* @param priority Priority to set.
*/
#define NRFX_IRQ_PRIORITY_SET(irq_number, priority) \
_NRFX_IRQ_PRIORITY_SET(irq_number, priority)
static inline void _NRFX_IRQ_PRIORITY_SET(IRQn_Type irq_number,
uint8_t priority)
{
ASSERT(INTERRUPT_PRIORITY_IS_VALID(priority));
NVIC_SetPriority(irq_number, priority);
}
/**
* @brief Macro for enabling a specific IRQ.
*
* @param irq_number IRQ number.
*/
#define NRFX_IRQ_ENABLE(irq_number) _NRFX_IRQ_ENABLE(irq_number)
static inline void _NRFX_IRQ_ENABLE(IRQn_Type irq_number)
{
NVIC_ClearPendingIRQ(irq_number);
NVIC_EnableIRQ(irq_number);
}
/**
* @brief Macro for checking if a specific IRQ is enabled.
*
* @param irq_number IRQ number.
*
* @retval true If the IRQ is enabled.
* @retval false Otherwise.
*/
#define NRFX_IRQ_IS_ENABLED(irq_number) _NRFX_IRQ_IS_ENABLED(irq_number)
static inline bool _NRFX_IRQ_IS_ENABLED(IRQn_Type irq_number)
{
return 0 != (NVIC->ISER[irq_number / 32] & (1UL << (irq_number % 32)));
}
/**
* @brief Macro for disabling a specific IRQ.
*
* @param irq_number IRQ number.
*/
#define NRFX_IRQ_DISABLE(irq_number) _NRFX_IRQ_DISABLE(irq_number)
static inline void _NRFX_IRQ_DISABLE(IRQn_Type irq_number)
{
NVIC_DisableIRQ(irq_number);
}
/**
* @brief Macro for setting a specific IRQ as pending.
*
* @param irq_number IRQ number.
*/
#define NRFX_IRQ_PENDING_SET(irq_number) _NRFX_IRQ_PENDING_SET(irq_number)
static inline void _NRFX_IRQ_PENDING_SET(IRQn_Type irq_number)
{
NVIC_SetPendingIRQ(irq_number);
}
/**
* @brief Macro for clearing the pending status of a specific IRQ.
*
* @param irq_number IRQ number.
*/
#define NRFX_IRQ_PENDING_CLEAR(irq_number) _NRFX_IRQ_PENDING_CLEAR(irq_number)
static inline void _NRFX_IRQ_PENDING_CLEAR(IRQn_Type irq_number)
{
NVIC_ClearPendingIRQ(irq_number);
}
/**
* @brief Macro for checking the pending status of a specific IRQ.
*
* @retval true If the IRQ is pending.
* @retval false Otherwise.
*/
#define NRFX_IRQ_IS_PENDING(irq_number) _NRFX_IRQ_IS_PENDING(irq_number)
static inline bool _NRFX_IRQ_IS_PENDING(IRQn_Type irq_number)
{
return (NVIC_GetPendingIRQ(irq_number) == 1);
}
#include <nordic_common.h>
#include <app_util_platform.h>
/**
* @brief Macro for entering into a critical section.
*/
#define NRFX_CRITICAL_SECTION_ENTER() CRITICAL_REGION_ENTER()
/**
* @brief Macro for exiting from a critical section.
*/
#define NRFX_CRITICAL_SECTION_EXIT() CRITICAL_REGION_EXIT()
//------------------------------------------------------------------------------
/**
* @brief When set to a non-zero value, this macro specifies that
* @ref nrfx_coredep_delay_us uses a precise DWT-based solution.
* A compilation error is generated if the DWT unit is not present
* in the SoC used.
*/
#define NRFX_DELAY_DWT_BASED 0
#include <soc/nrfx_coredep.h>
#define NRFX_DELAY_US(us_time) nrfx_coredep_delay_us(us_time)
//------------------------------------------------------------------------------
#include <sdk_errors.h>
/**
* @brief When set to a non-zero value, this macro specifies that the
* @ref nrfx_error_codes and the @ref ret_code_t type itself are defined
* in a customized way and the default definitions from @c <nrfx_error.h>
* should not be used.
*/
#define NRFX_CUSTOM_ERROR_CODES 1
typedef ret_code_t nrfx_err_t;
#define NRFX_SUCCESS NRF_SUCCESS
#define NRFX_ERROR_INTERNAL NRF_ERROR_INTERNAL
#define NRFX_ERROR_NO_MEM NRF_ERROR_NO_MEM
#define NRFX_ERROR_NOT_SUPPORTED NRF_ERROR_NOT_SUPPORTED
#define NRFX_ERROR_INVALID_PARAM NRF_ERROR_INVALID_PARAM
#define NRFX_ERROR_INVALID_STATE NRF_ERROR_INVALID_STATE
#define NRFX_ERROR_INVALID_LENGTH NRF_ERROR_INVALID_LENGTH
#define NRFX_ERROR_TIMEOUT NRF_ERROR_TIMEOUT
#define NRFX_ERROR_FORBIDDEN NRF_ERROR_FORBIDDEN
#define NRFX_ERROR_NULL NRF_ERROR_NULL
#define NRFX_ERROR_INVALID_ADDR NRF_ERROR_INVALID_ADDR
#define NRFX_ERROR_BUSY NRF_ERROR_BUSY
#define NRFX_ERROR_ALREADY_INITIALIZED NRF_ERROR_MODULE_ALREADY_INITIALIZED
#define NRFX_ERROR_DRV_TWI_ERR_OVERRUN NRF_ERROR_DRV_TWI_ERR_OVERRUN
#define NRFX_ERROR_DRV_TWI_ERR_ANACK NRF_ERROR_DRV_TWI_ERR_ANACK
#define NRFX_ERROR_DRV_TWI_ERR_DNACK NRF_ERROR_DRV_TWI_ERR_DNACK
//------------------------------------------------------------------------------
#include <sdk_resources.h>
/**
* @brief Bitmask defining PPI channels reserved to be used outside of nrfx.
*/
#define NRFX_PPI_CHANNELS_USED NRF_PPI_CHANNELS_USED
/**
* @brief Bitmask defining PPI groups reserved to be used outside of nrfx.
*/
#define NRFX_PPI_GROUPS_USED NRF_PPI_GROUPS_USED
/**
* @brief Bitmask defining SWI instances reserved to be used outside of nrfx.
*/
#define NRFX_SWI_USED NRF_SWI_USED
/**
* @brief Bitmask defining TIMER instances reserved to be used outside of nrfx.
*/
#define NRFX_TIMERS_USED NRF_TIMERS_USED
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRFX_GLUE_H__
+152
View File
@@ -0,0 +1,152 @@
/**
* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_LOG_H__
#define NRFX_LOG_H__
#ifdef __cplusplus
extern "C" {
#endif
#if defined(NRFX_LOG_MODULE)
#define NRF_LOG_MODULE_NAME NRFX_LOG_MODULE
#define NRFX_CONFIG_ENTRY(x) CONCAT_3(NRFX_, NRFX_LOG_MODULE, x)
#if NRFX_CHECK(NRFX_CONFIG_ENTRY(_CONFIG_LOG_ENABLED))
#define NRF_LOG_LEVEL NRFX_CONFIG_ENTRY(_CONFIG_LOG_LEVEL)
#define NRF_LOG_INFO_COLOR NRFX_CONFIG_ENTRY(_CONFIG_INFO_COLOR)
#define NRF_LOG_DEBUG_COLOR NRFX_CONFIG_ENTRY(_CONFIG_DEBUG_COLOR)
#else
#define NRF_LOG_LEVEL 0
#endif
#endif // defined(NRFX_LOG_MODULE)
#include <nrf_log.h>
#if defined(NRFX_LOG_MODULE)
NRF_LOG_MODULE_REGISTER();
#endif
#define TEST_MACRO_INFO(...) NRF_LOG_INFO(__VA_ARGS__)
/**
* @defgroup nrfx_log nrfx_log.h
* @{
* @ingroup nrfx
*
* @brief This file contains macros that should be implemented according to
* the needs of the host environment into which @em nrfx is integrated.
*/
/**
* @brief Macro for logging a message with the severity level ERROR.
*/
#define NRFX_LOG_ERROR(...) NRF_LOG_ERROR(__VA_ARGS__)
/**
* @brief Macro for logging a message with the severity level WARNING.
*/
#define NRFX_LOG_WARNING(...) NRF_LOG_WARNING(__VA_ARGS__)
/**
* @brief Macro for logging a message with the severity level INFO.
*/
#define NRFX_LOG_INFO(...) TEST_MACRO_INFO(__VA_ARGS__)
/**
* @brief Macro for logging a message with the severity level DEBUG.
*/
#define NRFX_LOG_DEBUG(...) NRF_LOG_DEBUG(__VA_ARGS__)
/**
* @brief Macro for logging a memory dump with the severity level ERROR.
*
* @param[in] p_memory Pointer to the memory region to be dumped.
* @param[in] length Length of the memory region in bytes.
*/
#define NRFX_LOG_HEXDUMP_ERROR(p_memory, length) \
NRF_LOG_HEXDUMP_ERROR(p_memory, length)
/**
* @brief Macro for logging a memory dump with the severity level WARNING.
*
* @param[in] p_memory Pointer to the memory region to be dumped.
* @param[in] length Length of the memory region in bytes.
*/
#define NRFX_LOG_HEXDUMP_WARNING(p_memory, length) \
NRF_LOG_HEXDUMP_WARNING(p_memory, length)
/**
* @brief Macro for logging a memory dump with the severity level INFO.
*
* @param[in] p_memory Pointer to the memory region to be dumped.
* @param[in] length Length of the memory region in bytes.
*/
#define NRFX_LOG_HEXDUMP_INFO(p_memory, length) \
NRF_LOG_HEXDUMP_INFO(p_memory, length)
/**
* @brief Macro for logging a memory dump with the severity level DEBUG.
*
* @param[in] p_memory Pointer to the memory region to be dumped.
* @param[in] length Length of the memory region in bytes.
*/
#define NRFX_LOG_HEXDUMP_DEBUG(p_memory, length) \
NRF_LOG_HEXDUMP_DEBUG(p_memory, length)
/**
* @brief Macro for getting the textual representation of a given error code.
*
* @param[in] error_code Error code.
*
* @return String containing the textual representation of the error code.
*/
#define NRFX_LOG_ERROR_STRING_GET(error_code) \
NRF_LOG_ERROR_STRING_GET(error_code)
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRFX_LOG_H__
+1 -1
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2013 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
+157 -70
View File
@@ -54,27 +54,71 @@
#define APP_USBD_DEVICE_VER_MINOR 0
#endif
// <e> APP_USBD_EVENT_QUEUE_ENABLE - Enable event queue
// <q> APP_USBD_CONFIG_SELF_POWERED - Self powered
#ifndef APP_USBD_CONFIG_SELF_POWERED
#define APP_USBD_CONFIG_SELF_POWERED 1
#endif
// <q> APP_USBD_CONFIG_POWER_EVENTS_PROCESS - Process power events
// <i> Enable processing power events in USB event handler.
#ifndef APP_USBD_CONFIG_POWER_EVENTS_PROCESS
#define APP_USBD_CONFIG_POWER_EVENTS_PROCESS 1
#endif
// <e> APP_USBD_CONFIG_EVENT_QUEUE_ENABLE - Enable event queue
// <i> This is the default configuration when all the events are placed into internal queue.
// <i> Disable it when external queue is used like app_scheduler or if you wish to process all events inside interrupts.
// <i> Processing all events from the interrupt level adds requirement not to call any functions that modifies the USBD library state from the context higher than USB interrupt context.
// <i> Functions that modify USBD state are functions for sleep, wakeup, start, stop, enable and disable.
//==========================================================
#ifndef APP_USBD_EVENT_QUEUE_ENABLE
#define APP_USBD_EVENT_QUEUE_ENABLE 1
#ifndef APP_USBD_CONFIG_EVENT_QUEUE_ENABLE
#define APP_USBD_CONFIG_EVENT_QUEUE_ENABLE 1
#endif
// <o> APP_USBD_EVENT_QUEUE_SIZE - The size of event queue <16-64>
// <o> APP_USBD_CONFIG_EVENT_QUEUE_SIZE - The size of event queue <16-64>
// <i> The size of the queue for the events that would be processed in the main loop.
#ifndef APP_USBD_EVENT_QUEUE_SIZE
#define APP_USBD_EVENT_QUEUE_SIZE 32
#ifndef APP_USBD_CONFIG_EVENT_QUEUE_SIZE
#define APP_USBD_CONFIG_EVENT_QUEUE_SIZE 32
#endif
// <o> APP_USBD_CONFIG_SOF_HANDLING_MODE - Change SOF events handling mode.
// <i> Normal queue - SOF events are pushed normally into event queue.
// <i> Compress queue - SOF events are counted and binded with other events or executed when queue is empty.
// <i> This prevents queue from filling with SOF events.
// <i> Interrupt - SOF events are processed in interrupt.
// <0=> Normal queue
// <1=> Compress queue
// <2=> Interrupt
#ifndef APP_USBD_CONFIG_SOF_HANDLING_MODE
#define APP_USBD_CONFIG_SOF_HANDLING_MODE 1
#endif
// </e>
// <q> APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE - Provide a function that generates timestamps for logs based on the current SOF
// <i> The function app_usbd_sof_timestamp_get will be implemented if the logger is enabled.
// <i> Use it when initializing the logger.
// <i> SOF processing will be always enabled when this configuration parameter is active.
// <i> Notice that this option is configured outside of APP_USBD_CONFIG_LOG_ENABLED.
// <i> This means that it will work even if the logging in this very module is disabled.
#ifndef APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE
#define APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE 0
#endif
// <e> APP_USBD_CONFIG_LOG_ENABLED - Enable logging in the module
//==========================================================
#ifndef APP_USBD_CONFIG_LOG_ENABLED
@@ -85,6 +129,113 @@
// </e>
// <e> USBD_ENABLED - nrf_drv_usbd - USB driver
//==========================================================
#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
#ifndef USBD_ENABLED
#define USBD_ENABLED 1
#endif
#else // USB_CDC_AS_SERIAL_TRANSPORT == 1
#ifndef USBD_ENABLED
#define USBD_ENABLED 0
#endif
#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
// <o> USBD_CONFIG_IRQ_PRIORITY - Interrupt priority
// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest)
// <1=> 1
// <2=> 2
// <3=> 3
// <4=> 4
// <5=> 5
// <6=> 6
// <7=> 7
#ifndef USBD_CONFIG_IRQ_PRIORITY
#define USBD_CONFIG_IRQ_PRIORITY 7
#endif
// <o> USBD_CONFIG_DMASCHEDULER_MODE - USBD SMA scheduler working scheme
// <0=> Prioritized access
// <1=> Round Robin
#ifndef USBD_CONFIG_DMASCHEDULER_MODE
#define USBD_CONFIG_DMASCHEDULER_MODE 0
#endif
// </e>
// <h> app_usbd_cdc_acm - USB CDC ACM class
//==========================================================
// <q> APP_USBD_CDC_ACM_ENABLED - app_usbd_cdc_acm - USB CDC ACM class
#ifndef APP_USBD_CDC_ACM_ENABLED
#define APP_USBD_CDC_ACM_ENABLED 1
#endif
// </h>
//==========================================================
// <h> nrf_log - Logging
//==========================================================
// <e> NRF_LOG_ENABLED - Logging module for nRF5 SDK
//==========================================================
#ifndef NRF_LOG_ENABLED
#define NRF_LOG_ENABLED 0
#endif
// </e>
// </h>
// <h> segger_rtt - SEGGER RTT
//==========================================================
// <o> SEGGER_RTT_CONFIG_BUFFER_SIZE_UP - Size of upstream buffer.
// <i> Note that either @ref NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE
// <i> or this value is actually used. It depends on which one is bigger.
#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 512
#endif
// <o> SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS - Size of upstream buffer.
#ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS
#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2
#endif
// <o> SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN - Size of upstream buffer.
#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16
#endif
// <o> SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS - Size of upstream buffer.
#ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS
#define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2
#endif
// <o> SEGGER_RTT_CONFIG_DEFAULT_MODE - RTT behavior if the buffer is full.
// <i> The following modes are supported:
// <i> - SKIP - Do not block, output nothing.
// <i> - TRIM - Do not block, output as much as fits.
// <i> - BLOCK - Wait until there is space in the buffer.
// <0=> SKIP
// <1=> TRIM
// <2=> BLOCK_IF_FIFO_FULL
#ifndef SEGGER_RTT_CONFIG_DEFAULT_MODE
#define SEGGER_RTT_CONFIG_DEFAULT_MODE 0
#endif
// </h>
//==========================================================
// <e> CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver
//==========================================================
#ifndef CLOCK_ENABLED
@@ -189,68 +340,4 @@
#endif
#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
// <e> USBD_ENABLED - nrf_drv_usbd - USB driver
//==========================================================
#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
#ifndef USBD_ENABLED
#define USBD_ENABLED 1
#endif
#else // USB_CDC_AS_SERIAL_TRANSPORT == 1
#ifndef USBD_ENABLED
#define USBD_ENABLED 0
#endif
#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
// <o> USBD_CONFIG_IRQ_PRIORITY - Interrupt priority
// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest)
// <1=> 1
// <2=> 2
// <3=> 3
// <4=> 4
// <5=> 5
// <6=> 6
// <7=> 7
#ifndef USBD_CONFIG_IRQ_PRIORITY
#define USBD_CONFIG_IRQ_PRIORITY 7
#endif
// <o> NRF_DRV_USBD_DMASCHEDULER_MODE - USBD SMA scheduler working scheme
// <0=> Prioritized access
// <1=> Round Robin
#ifndef NRF_DRV_USBD_DMASCHEDULER_MODE
#define NRF_DRV_USBD_DMASCHEDULER_MODE 0
#endif
// </e>
// <h> app_usbd_cdc_acm - USB CDC ACM class
//==========================================================
// <q> APP_USBD_CLASS_CDC_ACM_ENABLED - Enabling USBD CDC ACM Class library
#ifndef APP_USBD_CLASS_CDC_ACM_ENABLED
#define APP_USBD_CLASS_CDC_ACM_ENABLED 1
#endif
// </h>
//==========================================================
// <h> nrf_log - Logging
//==========================================================
// <e> NRF_LOG_ENABLED - Logging module for nRF5 SDK
//==========================================================
#ifndef NRF_LOG_ENABLED
#define NRF_LOG_ENABLED 0
#endif
// </e>
// </h>
#endif //SDK_CONFIG_H
+32 -17
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2013 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -71,7 +71,6 @@
#include <stdint.h>
#include "nrf_error.h"
#include "sdk_config.h"
#ifdef __cplusplus
extern "C" {
@@ -89,9 +88,11 @@ extern "C" {
* @defgroup sdk_module_codes Codes reserved as identification for module where the error occurred.
* @{
*/
#define NRF_ERROR_MEMORY_MANAGER_ERR_BASE (0x8100)
#define NRF_ERROR_PERIPH_DRIVERS_ERR_BASE (0x8200)
#define NRF_ERROR_GAZELLE_ERR_BASE (0x8300)
#define NRF_ERROR_MEMORY_MANAGER_ERR_BASE (0x8100) /**< Base address for Memory Manager related errors. */
#define NRF_ERROR_PERIPH_DRIVERS_ERR_BASE (0x8200) /**< Base address for Peripheral drivers related errors. */
#define NRF_ERROR_GAZELLE_ERR_BASE (0x8300) /**< Base address for Gazelle related errors. */
#define NRF_ERROR_BLE_IPSP_ERR_BASE (0x8400) /**< Base address for BLE IPSP related errors. */
#define NRF_ERROR_CRYPTO_ERR_BASE (0x8500) /**< Base address for crypto related errors. */
/** @} */
@@ -108,15 +109,16 @@ extern "C" {
* @defgroup sdk_common_errors Codes reserved as identification for common errors.
* @{
*/
#define NRF_ERROR_MODULE_NOT_INITIALZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0000)
#define NRF_ERROR_MUTEX_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0001)
#define NRF_ERROR_MUTEX_LOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0002)
#define NRF_ERROR_MUTEX_UNLOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0003)
#define NRF_ERROR_MUTEX_COND_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0004)
#define NRF_ERROR_MODULE_ALREADY_INITIALIZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0005)
#define NRF_ERROR_STORAGE_FULL (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0006)
#define NRF_ERROR_API_NOT_IMPLEMENTED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0010)
#define NRF_ERROR_FEATURE_NOT_ENABLED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0011)
#define NRF_ERROR_MODULE_NOT_INITIALZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0000) ///< Module not initialized
#define NRF_ERROR_MUTEX_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0001) ///< Mutex initialization failed
#define NRF_ERROR_MUTEX_LOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0002) ///< Mutex lock failed
#define NRF_ERROR_MUTEX_UNLOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0003) ///< Mutex unlock failed
#define NRF_ERROR_MUTEX_COND_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0004) ///< Mutex conditional initialization failed
#define NRF_ERROR_MODULE_ALREADY_INITIALIZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0005) ///< Module already initialized
#define NRF_ERROR_STORAGE_FULL (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0006) ///< Storage full
#define NRF_ERROR_API_NOT_IMPLEMENTED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0010) ///< API not implemented
#define NRF_ERROR_FEATURE_NOT_ENABLED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0011) ///< Feature not enabled
#define NRF_ERROR_IO_PENDING (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0012) ///< Input/Output pending
/** @} */
@@ -124,11 +126,24 @@ extern "C" {
* @defgroup drv_specific_errors Error / status codes specific to drivers.
* @{
*/
#define NRF_ERROR_DRV_TWI_ERR_OVERRUN (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0000)
#define NRF_ERROR_DRV_TWI_ERR_ANACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0001)
#define NRF_ERROR_DRV_TWI_ERR_DNACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0002)
#define NRF_ERROR_DRV_TWI_ERR_OVERRUN (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0000)
#define NRF_ERROR_DRV_TWI_ERR_ANACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0001)
#define NRF_ERROR_DRV_TWI_ERR_DNACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0002)
/** @} */
/**
* @defgroup ble_ipsp_errors IPSP codes
* @brief Error and status codes specific to IPSP.
* @{
*/
#define NRF_ERROR_BLE_IPSP_RX_PKT_TRUNCATED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0000)
#define NRF_ERROR_BLE_IPSP_CHANNEL_ALREADY_EXISTS (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0001)
#define NRF_ERROR_BLE_IPSP_LINK_DISCONNECTED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0002)
#define NRF_ERROR_BLE_IPSP_PEER_REJECTED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0003)
/* @} */
/**
* @brief API Result.
*
+52 -28
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2013 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -49,11 +49,51 @@
#ifndef SDK_MACROS_H__
#define SDK_MACROS_H__
#include "nrf_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
/**@brief Macro for parameter checking.
*
* If @p _cond evaluates to true, does nothing. Otherwise,
* if @p _module ## _PARAM_CHECK_DISABLED is @e not set (default), prints an error message
* if @p _printfn is provided, and returns from the calling function context with code @p _err.
* If @p _module ## _PARAM_CHECK_DISABLED is set, behaves like the ASSERT macro.
*
* Parameter checking implemented using this macro can be optionally turned off for release code.
* Only disable runtime parameter checks if size if a major concern.
*
* @param _module The module name.
* @param _cond The condition to be evaluated.
* @param _err The error to be returned.
* @param _printfn A printf-compatible function used to log the error.
* Leave empty if no logging is needed.
*
* @hideinitializer
*/
/*lint -esym(666, NRF_PARAM_CHECK*) : Expression with side effects passed to macro */
#define NRF_PARAM_CHECK(_module, _cond, _err, _printfn) \
do \
{ \
if ((_cond)) \
{ \
/* Do nothing. */ \
} \
else if (!(_module ## _PARAM_CHECK_DISABLED)) \
{ \
_printfn("%s check failed in %s() with value 0x%x.", #_cond, __func__, _err); \
return (_err); \
} \
else \
{ \
ASSERT((_cond)); \
} \
} while (0);
/**@brief Macro for verifying statement to be true. It will cause the exterior function to return
* err_code if the statement is not true.
*
@@ -109,15 +149,19 @@ do \
/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior
* function to return err_code if the err_code is not @ref NRF_SUCCESS.
* function to return error code of statement if it is not @ref NRF_SUCCESS.
*
* @param[in] err_code The error code to check.
* @param[in] statement Statement to check against NRF_SUCCESS.
*/
#ifdef DISABLE_PARAM_CHECK
#define VERIFY_SUCCESS()
#else
#define VERIFY_SUCCESS(err_code) VERIFY_TRUE((err_code) == NRF_SUCCESS, (err_code))
#endif /* DISABLE_PARAM_CHECK */
#define VERIFY_SUCCESS(statement) \
do \
{ \
uint32_t _err_code = (uint32_t) (statement); \
if (_err_code != NRF_SUCCESS) \
{ \
return _err_code; \
} \
} while(0)
/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior
@@ -125,11 +169,7 @@ do \
*
* @param[in] err_code The error code to check.
*/
#ifdef DISABLE_PARAM_CHECK
#define VERIFY_SUCCESS_VOID()
#else
#define VERIFY_SUCCESS_VOID(err_code) VERIFY_TRUE_VOID((err_code) == NRF_SUCCESS)
#endif /* DISABLE_PARAM_CHECK */
/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
@@ -138,11 +178,7 @@ do \
* @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED
* should be true if the module is initialized, false if not.
*/
#ifdef DISABLE_PARAM_CHECK
#define VERIFY_MODULE_INITIALIZED()
#else
#define VERIFY_MODULE_INITIALIZED() VERIFY_TRUE((MODULE_INITIALIZED), NRF_ERROR_INVALID_STATE)
#endif /* DISABLE_PARAM_CHECK */
/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
@@ -151,11 +187,7 @@ do \
* @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED
* should be true if the module is initialized, false if not.
*/
#ifdef DISABLE_PARAM_CHECK
#define VERIFY_MODULE_INITIALIZED_VOID()
#else
#define VERIFY_MODULE_INITIALIZED_VOID() VERIFY_TRUE_VOID((MODULE_INITIALIZED))
#endif /* DISABLE_PARAM_CHECK */
/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
@@ -163,11 +195,7 @@ do \
*
* @param[in] param The variable to check if is NULL.
*/
#ifdef DISABLE_PARAM_CHECK
#define VERIFY_PARAM_NOT_NULL()
#else
#define VERIFY_PARAM_NOT_NULL(param) VERIFY_FALSE(((param) == NULL), NRF_ERROR_NULL)
#endif /* DISABLE_PARAM_CHECK */
/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
@@ -175,11 +203,7 @@ do \
*
* @param[in] param The variable to check if is NULL.
*/
#ifdef DISABLE_PARAM_CHECK
#define VERIFY_PARAM_NOT_NULL_VOID()
#else
#define VERIFY_PARAM_NOT_NULL_VOID(param) VERIFY_FALSE_VOID(((param) == NULL))
#endif /* DISABLE_PARAM_CHECK */
/** @} */
+1 -1
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2013 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -0,0 +1,86 @@
/**
* Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/** @file
* @brief Definition file for resource usage by SoftDevice, ESB and Gazell.
*/
#ifndef SDK_RESOURCES_H__
#define SDK_RESOURCES_H__
#ifdef __cplusplus
extern "C" {
#endif
#if defined(SOFTDEVICE_PRESENT) || defined (BLE_STACK_SUPPORT_REQD) || defined (ANT_STACK_SUPPORT_REQD)
#include "nrf_sd_def.h"
#else
#define SD_PPI_RESTRICTED 0uL /**< 1 if PPI peripheral is restricted, 0 otherwise. */
#define SD_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */
#define SD_PPI_GROUPS_USED 0uL /**< PPI groups utilized by SotfDevice (not available to th spplication). */
#define SD_TIMERS_USED 0uL /**< Timers used by SoftDevice. */
#define SD_SWI_USED 0uL /**< Software interrupts used by SoftDevice. */
#endif
#ifdef GAZELL_PRESENT
#include "nrf_gzll_resources.h"
#else
#define GZLL_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by Gazell (not available to th spplication). */
#define GZLL_TIMERS_USED 0uL /**< Timers used by Gazell. */
#define GZLL_SWI_USED 0uL /**< Software interrupts used by Gazell */
#endif
#ifdef ESB_PRESENT
#include "nrf_esb_resources.h"
#else
#define ESB_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by ESB (not available to th spplication). */
#define ESB_TIMERS_USED 0uL /**< Timers used by ESB. */
#define ESB_SWI_USED 0uL /**< Software interrupts used by ESB */
#endif
#define NRF_PPI_CHANNELS_USED (SD_PPI_CHANNELS_USED | GZLL_PPI_CHANNELS_USED | ESB_PPI_CHANNELS_USED)
#define NRF_PPI_GROUPS_USED (SD_PPI_GROUPS_USED)
#define NRF_SWI_USED (SD_SWI_USED | GZLL_SWI_USED | ESB_SWI_USED)
#define NRF_TIMERS_USED (SD_TIMERS_USED | GZLL_TIMERS_USED | ESB_TIMERS_USED)
#ifdef __cplusplus
}
#endif
#endif // SDK_RESOURCES_H__
@@ -1,144 +0,0 @@
/* Copyright (c) 2016, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _COMPILER_ABSTRACTION_H
#define _COMPILER_ABSTRACTION_H
/*lint ++flb "Enter library region" */
#if defined ( __CC_ARM )
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE __inline
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __ALIGN
#define __ALIGN(n) __align(n)
#endif
#ifndef __PACKED
#define __PACKED __packed
#endif
#define GET_SP() __current_sp()
#elif defined ( __ICCARM__ )
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __ALIGN
#define STRING_PRAGMA(x) _Pragma(#x)
#define __ALIGN(n) STRING_PRAGMA(data_alignment = n)
#endif
#ifndef __PACKED
#define __PACKED __packed
#endif
#define GET_SP() __get_SP()
#elif defined ( __GNUC__ )
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __ALIGN
#define __ALIGN(n) __attribute__((aligned(n)))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#define GET_SP() gcc_current_sp()
static inline unsigned int gcc_current_sp(void)
{
register unsigned sp __ASM("sp");
return sp;
}
#elif defined ( __TASKING__ )
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __ALIGN
#define __ALIGN(n) __align(n)
#endif
/* Not defined for TASKING. */
#ifndef __PACKED
#define __PACKED
#endif
#define GET_SP() __get_MSP()
#endif
/*lint --flb "Leave library region" */
#endif
@@ -1,538 +0,0 @@
/* Copyright (c) 2013 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
.syntax unified
.arch armv7e-m
#ifdef __STARTUP_CONFIG
#include "startup_config.h"
#endif
.section .stack
.align 3
#if defined(__STARTUP_CONFIG)
.equ Stack_Size, __STARTUP_CONFIG_STACK_SIZE
#elif defined(__STACK_SIZE)
.equ Stack_Size, __STACK_SIZE
#else
.equ Stack_Size, 8192
#endif
.globl __StackTop
.globl __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
#if defined(__STARTUP_CONFIG)
.equ Heap_Size, __STARTUP_CONFIG_HEAP_SIZE
#elif defined(__HEAP_SIZE)
.equ Heap_Size, __HEAP_SIZE
#else
.equ Heap_Size, 8192
#endif
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
.if Heap_Size
.space Heap_Size
.endif
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.section .isr_vector
.align 2
.globl __isr_vector
__isr_vector:
.long __StackTop /* Top of Stack */
.long Reset_Handler
.long NMI_Handler
.long HardFault_Handler
.long MemoryManagement_Handler
.long BusFault_Handler
.long UsageFault_Handler
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long SVC_Handler
.long DebugMon_Handler
.long 0 /*Reserved */
.long PendSV_Handler
.long SysTick_Handler
/* External Interrupts */
.long POWER_CLOCK_IRQHandler
.long RADIO_IRQHandler
.long UARTE0_UART0_IRQHandler
.long SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler
.long SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler
.long NFCT_IRQHandler
.long GPIOTE_IRQHandler
.long SAADC_IRQHandler
.long TIMER0_IRQHandler
.long TIMER1_IRQHandler
.long TIMER2_IRQHandler
.long RTC0_IRQHandler
.long TEMP_IRQHandler
.long RNG_IRQHandler
.long ECB_IRQHandler
.long CCM_AAR_IRQHandler
.long WDT_IRQHandler
.long RTC1_IRQHandler
.long QDEC_IRQHandler
.long COMP_LPCOMP_IRQHandler
.long SWI0_EGU0_IRQHandler
.long SWI1_EGU1_IRQHandler
.long SWI2_EGU2_IRQHandler
.long SWI3_EGU3_IRQHandler
.long SWI4_EGU4_IRQHandler
.long SWI5_EGU5_IRQHandler
.long TIMER3_IRQHandler
.long TIMER4_IRQHandler
.long PWM0_IRQHandler
.long PDM_IRQHandler
.long 0 /*Reserved */
.long 0 /*Reserved */
.long MWU_IRQHandler
.long PWM1_IRQHandler
.long PWM2_IRQHandler
.long SPIM2_SPIS2_SPI2_IRQHandler
.long RTC2_IRQHandler
.long I2S_IRQHandler
.long FPU_IRQHandler
.long USBD_IRQHandler
.long UARTE1_IRQHandler
.long QSPI_IRQHandler
.long CRYPTOCELL_IRQHandler
.long SPIM3_IRQHandler
.long 0 /*Reserved */
.long PWM3_IRQHandler
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.size __isr_vector, . - __isr_vector
/* Reset Handler */
.text
.thumb
.thumb_func
.align 1
.globl Reset_Handler
.type Reset_Handler, % function
Reset_Handler:
/* Loop to copy data from read only memory to RAM.
* The ranges of copy from/to are specified by following symbols:
* __etext: LMA of start of the section to copy from. Usually end of text
* __data_start__: VMA of start of the section to copy to.
* __bss_start__: VMA of end of the section to copy to. Normally __data_end__ is used, but by using __bss_start__
* the user can add their own initialized data section before BSS section with the INTERT AFTER command.
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r1, = __etext
ldr r2, = __data_start__
ldr r3, = __bss_start__
subs r3, r2
ble .L_loop1_done
.L_loop1:
subs r3, #4
ldr r0, [r1, r3]
str r0, [r2, r3]
bgt .L_loop1
.L_loop1_done:
/* This part of work usually is done in C library startup code. Otherwise,
* define __STARTUP_CLEAR_BSS to enable it in this startup. This section
* clears the RAM where BSS data is located.
*
* The BSS section is specified by following symbols
* __bss_start__: start of the BSS section.
* __bss_end__: end of the BSS section.
*
* All addresses must be aligned to 4 bytes boundary.
*/
#ifdef __STARTUP_CLEAR_BSS
ldr r1, = __bss_start__
ldr r2, = __bss_end__
movs r0, 0
subs r2, r1
ble .L_loop3_done
.L_loop3:
subs r2, #4
str r0, [r1, r2]
bgt .L_loop3
.L_loop3_done:
#endif /* __STARTUP_CLEAR_BSS */
/* Execute SystemInit function. */
bl SystemInit
/* Call _start function provided by libraries.
* If those libraries are not accessible, define __START as your entry point.
*/
#ifndef __START
#define __START _start
#endif
bl __START
.pool
.size Reset_Handler, . - Reset_Handler
.section ".text"
/* Dummy Exception Handlers (infinite loops which can be modified) */
.weak NMI_Handler
.type NMI_Handler, % function
NMI_Handler:
b .
.size NMI_Handler, . - NMI_Handler
.weak HardFault_Handler
.type HardFault_Handler, % function
HardFault_Handler:
b .
.size HardFault_Handler, . - HardFault_Handler
.weak MemoryManagement_Handler
.type MemoryManagement_Handler, % function
MemoryManagement_Handler:
b .
.size MemoryManagement_Handler, . - MemoryManagement_Handler
.weak BusFault_Handler
.type BusFault_Handler, % function
BusFault_Handler:
b .
.size BusFault_Handler, . - BusFault_Handler
.weak UsageFault_Handler
.type UsageFault_Handler, % function
UsageFault_Handler:
b .
.size UsageFault_Handler, . - UsageFault_Handler
.weak SVC_Handler
.type SVC_Handler, % function
SVC_Handler:
b .
.size SVC_Handler, . - SVC_Handler
.weak DebugMon_Handler
.type DebugMon_Handler, % function
DebugMon_Handler:
b .
.size DebugMon_Handler, . - DebugMon_Handler
.weak PendSV_Handler
.type PendSV_Handler, % function
PendSV_Handler:
b .
.size PendSV_Handler, . - PendSV_Handler
.weak SysTick_Handler
.type SysTick_Handler, % function
SysTick_Handler:
b .
.size SysTick_Handler, . - SysTick_Handler
/* IRQ Handlers */
.globl Default_Handler
.type Default_Handler, % function
Default_Handler:
b .
.size Default_Handler, . - Default_Handler
.macro IRQ handler
.weak \handler
.set \handler, Default_Handler
.endm
IRQ POWER_CLOCK_IRQHandler
IRQ RADIO_IRQHandler
IRQ UARTE0_UART0_IRQHandler
IRQ SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler
IRQ SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler
IRQ NFCT_IRQHandler
IRQ GPIOTE_IRQHandler
IRQ SAADC_IRQHandler
IRQ TIMER0_IRQHandler
IRQ TIMER1_IRQHandler
IRQ TIMER2_IRQHandler
IRQ RTC0_IRQHandler
IRQ TEMP_IRQHandler
IRQ RNG_IRQHandler
IRQ ECB_IRQHandler
IRQ CCM_AAR_IRQHandler
IRQ WDT_IRQHandler
IRQ RTC1_IRQHandler
IRQ QDEC_IRQHandler
IRQ COMP_LPCOMP_IRQHandler
IRQ SWI0_EGU0_IRQHandler
IRQ SWI1_EGU1_IRQHandler
IRQ SWI2_EGU2_IRQHandler
IRQ SWI3_EGU3_IRQHandler
IRQ SWI4_EGU4_IRQHandler
IRQ SWI5_EGU5_IRQHandler
IRQ TIMER3_IRQHandler
IRQ TIMER4_IRQHandler
IRQ PWM0_IRQHandler
IRQ PDM_IRQHandler
IRQ MWU_IRQHandler
IRQ PWM1_IRQHandler
IRQ PWM2_IRQHandler
IRQ SPIM2_SPIS2_SPI2_IRQHandler
IRQ RTC2_IRQHandler
IRQ I2S_IRQHandler
IRQ FPU_IRQHandler
IRQ USBD_IRQHandler
IRQ UARTE1_IRQHandler
IRQ QSPI_IRQHandler
IRQ CRYPTOCELL_IRQHandler
IRQ SPIM3_IRQHandler
IRQ PWM3_IRQHandler
.end
-84
View File
@@ -1,84 +0,0 @@
/* Copyright (c) 2016, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_H
#define NRF_H
/* MDK version */
#define MDK_MAJOR_VERSION 8
#define MDK_MINOR_VERSION 11
#define MDK_MICRO_VERSION 1
/* Redefine "old" too-generic name NRF52 to NRF52832_XXAA to keep backwards compatibility. */
#if defined (NRF52)
#ifndef NRF52832_XXAA
#define NRF52832_XXAA
#endif
#endif
/* Define NRF52_SERIES for common use in nRF52 series devices. */
#if defined (NRF52832_XXAA) || defined (NRF52840_XXAA)
#define NRF52_SERIES
#endif
#if defined(_WIN32)
/* Do not include nrf specific files when building for PC host */
#elif defined(__unix)
/* Do not include nrf specific files when building for PC host */
#elif defined(__APPLE__)
/* Do not include nrf specific files when building for PC host */
#else
/* Device selection for device includes. */
#if defined (NRF51)
#include "nrf51.h"
#include "nrf51_bitfields.h"
#include "nrf51_deprecated.h"
#elif defined (NRF52840_XXAA)
#include "nrf52840.h"
#include "nrf52840_bitfields.h"
#include "nrf51_to_nrf52840.h"
#include "nrf52_to_nrf52840.h"
#elif defined (NRF52832_XXAA)
#include "nrf52.h"
#include "nrf52_bitfields.h"
#include "nrf51_to_nrf52.h"
#include "nrf52_name_change.h"
#else
#error "Device must be defined. See nrf.h."
#endif /* NRF51, NRF52832_XXAA, NRF52840_XXAA */
#include "compiler_abstraction.h"
#endif /* _WIN32 || __unix || __APPLE__ */
#endif /* NRF_H */
-248
View File
@@ -1,248 +0,0 @@
/* Copyright (c) 2012 ARM LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of ARM nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdint.h>
#include <stdbool.h>
#include "nrf.h"
#include "system_nrf52840.h"
/*lint ++flb "Enter library region" */
#define __SYSTEM_CLOCK_64M (64000000UL)
static bool errata_36(void);
static bool errata_98(void);
static bool errata_103(void);
static bool errata_115(void);
static bool errata_120(void);
#if defined ( __CC_ARM )
uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
#elif defined ( __ICCARM__ )
__root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M;
#elif defined ( __GNUC__ )
uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
#endif
void SystemCoreClockUpdate(void)
{
SystemCoreClock = __SYSTEM_CLOCK_64M;
}
void SystemInit(void)
{
/* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document
for your device located at https://infocenter.nordicsemi.com/ */
if (errata_36())
{
NRF_CLOCK->EVENTS_DONE = 0;
NRF_CLOCK->EVENTS_CTTO = 0;
NRF_CLOCK->CTIV = 0;
}
/* Workaround for Errata 98 "NFCT: Not able to communicate with the peer" found at the Errata document
for your device located at https://infocenter.nordicsemi.com/ */
if (errata_98())
{
*(volatile uint32_t *)0x4000568Cul = 0x00038148ul;
}
/* Workaround for Errata 103 "CCM: Wrong reset value of CCM MAXPACKETSIZE" found at the Errata document
for your device located at https://infocenter.nordicsemi.com/ */
if (errata_103())
{
NRF_CCM->MAXPACKETSIZE = 0xFBul;
}
/* Workaround for Errata 115 "RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document
for your device located at https://infocenter.nordicsemi.com/ */
if (errata_115())
{
*(volatile uint32_t *)0x40000EE4 = (*(volatile uint32_t *)0x40000EE4 & 0xFFFFFFF0) | (*
(uint32_t *)0x10000258 & 0x0000000F);
}
/* Workaround for Errata 120 "QSPI: Data read or written is corrupted" found at the Errata document
for your device located at https://infocenter.nordicsemi.com/ */
if (errata_120())
{
*(volatile uint32_t *)0x40029640ul = 0x200ul;
}
/* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
* compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
* operations are not used in your code. */
#if (__FPU_USED == 1)
SCB->CPACR |= (3UL << 20) | (3UL << 22);
__DSB();
__ISB();
#endif
/* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined,
two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as
normal GPIOs. */
#if defined (CONFIG_NFCT_PINS_AS_GPIOS)
if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos))
{
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {}
NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {}
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {}
NVIC_SystemReset();
}
#endif
/* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not
defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be
reserved for PinReset and not available as normal GPIO. */
#if defined (CONFIG_GPIO_AS_PINRESET)
if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected <<
UICR_PSELRESET_CONNECT_Pos)) ||
((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected <<
UICR_PSELRESET_CONNECT_Pos)))
{
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {}
NRF_UICR->PSELRESET[0] = 18;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {}
NRF_UICR->PSELRESET[1] = 18;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {}
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {}
NVIC_SystemReset();
}
#endif
/* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
Specification to see which one). */
#if defined (ENABLE_SWO)
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos;
NRF_P1->PIN_CNF[0] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect <<
GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
#endif
/* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
Specification to see which ones). */
#if defined (ENABLE_TRACE)
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos;
NRF_P0->PIN_CNF[7] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect <<
GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
NRF_P1->PIN_CNF[0] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect <<
GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
NRF_P0->PIN_CNF[12] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect <<
GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
NRF_P0->PIN_CNF[11] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect <<
GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
NRF_P1->PIN_CNF[9] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect <<
GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
#endif
SystemCoreClockUpdate();
}
static bool errata_36(void)
{
if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul))
{
return true;
}
return false;
}
static bool errata_98(void)
{
if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul))
{
return true;
}
return false;
}
static bool errata_103(void)
{
if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul))
{
return true;
}
return false;
}
static bool errata_115(void)
{
if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul))
{
return true;
}
return false;
}
static bool errata_120(void)
{
if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul))
{
return true;
}
return false;
}
/*lint --flb "Leave library region" */
@@ -1,69 +0,0 @@
/* Copyright (c) 2012 ARM LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of ARM nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef SYSTEM_NRF52840_H
#define SYSTEM_NRF52840_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit(void);
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate(void);
#ifdef __cplusplus
}
#endif
#endif /* SYSTEM_NRF52840_H */
+63 -94
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -37,36 +37,28 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "sdk_common.h"
#include <nordic_common.h>
#include "nrf_drv_clock.h"
#if NRF_MODULE_ENABLED(CLOCK)
#include "nrf_drv_clock.h"
#include "nrf_error.h"
#include "app_util_platform.h"
#ifdef SOFTDEVICE_PRESENT
#include "nrf_sdh.h"
#include "nrf_sdh_soc.h"
#endif
#define NRF_LOG_MODULE_NAME clock
#if CLOCK_CONFIG_LOG_ENABLED
#define NRF_LOG_LEVEL CLOCK_CONFIG_LOG_LEVEL
#define NRF_LOG_INFO_COLOR CLOCK_CONFIG_INFO_COLOR
#define NRF_LOG_DEBUG_COLOR CLOCK_CONFIG_DEBUG_COLOR
#define EVT_TO_STR(event) (event == NRF_CLOCK_EVENT_HFCLKSTARTED ? "NRF_CLOCK_EVENT_HFCLKSTARTED" : \
(event == NRF_CLOCK_EVENT_LFCLKSTARTED ? "NRF_CLOCK_EVENT_LFCLKSTARTED" : \
(event == NRF_CLOCK_EVENT_DONE ? "NRF_CLOCK_EVENT_DONE" : \
(event == NRF_CLOCK_EVENT_CTTO ? "NRF_CLOCK_EVENT_CTTO" : "UNKNOWN EVENT"))))
#else //CLOCK_CONFIG_LOG_ENABLED
#define EVT_TO_STR(event) ""
#define NRF_LOG_LEVEL 0
#endif //CLOCK_CONFIG_LOG_ENABLED
#include "nrf_log.h"
NRF_LOG_MODULE_REGISTER();
/* Validate configuration */
INTERRUPT_PRIORITY_VALIDATION(CLOCK_CONFIG_IRQ_PRIORITY);
#define EVT_TO_STR(event) \
(event == NRF_CLOCK_EVENT_HFCLKSTARTED ? "NRF_CLOCK_EVENT_HFCLKSTARTED" : \
(event == NRF_CLOCK_EVENT_LFCLKSTARTED ? "NRF_CLOCK_EVENT_LFCLKSTARTED" : \
(event == NRF_CLOCK_EVENT_DONE ? "NRF_CLOCK_EVENT_DONE" : \
(event == NRF_CLOCK_EVENT_CTTO ? "NRF_CLOCK_EVENT_CTTO" : \
"UNKNOWN EVENT"))))
/*lint -save -e652 */
#define NRF_CLOCK_LFCLK_RC CLOCK_LFCLKSRC_SRC_RC
@@ -107,22 +99,12 @@ typedef struct
static nrf_drv_clock_cb_t m_clock_cb;
static void clock_irq_handler(nrfx_clock_evt_type_t evt);
/**@brief Function for starting LFCLK. This function will return immediately without waiting for start.
*/
static void lfclk_start(void)
{
nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED);
nrf_clock_int_enable(NRF_CLOCK_INT_LF_STARTED_MASK);
nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART);
}
/**@brief Function for stopping LFCLK and calibration (if it was set up).
*/
static void lfclk_stop(void)
{
#if CALIBRATION_SUPPORT
(void)nrf_drv_clock_calibration_abort();
nrfx_clock_calibration_timer_stop();
#endif
#ifdef SOFTDEVICE_PRESENT
@@ -132,9 +114,7 @@ static void lfclk_stop(void)
ASSERT(!nrf_sdh_is_enabled());
#endif // SOFTDEVICE_PRESENT
nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTOP);
while (nrf_clock_lf_is_running())
{}
nrfx_clock_lfclk_stop();
m_clock_cb.lfclk_on = false;
}
@@ -148,9 +128,7 @@ static void hfclk_start(void)
}
#endif // SOFTDEVICE_PRESENT
nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED);
nrf_clock_int_enable(NRF_CLOCK_INT_HF_STARTED_MASK);
nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART);
nrfx_clock_hfclk_start();
}
static void hfclk_stop(void)
@@ -159,13 +137,12 @@ static void hfclk_stop(void)
if (nrf_sdh_is_enabled())
{
(void)sd_clock_hfclk_release();
m_clock_cb.hfclk_on = false;
return;
}
#endif // SOFTDEVICE_PRESENT
nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP);
while (nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY))
{}
nrfx_clock_hfclk_stop();
m_clock_cb.hfclk_on = false;
}
@@ -187,12 +164,12 @@ ret_code_t nrf_drv_clock_init(void)
m_clock_cb.hfclk_requests = 0;
m_clock_cb.p_lf_head = NULL;
m_clock_cb.lfclk_requests = 0;
nrf_drv_common_power_clock_irq_init();
err_code = nrfx_clock_init(clock_irq_handler);
#ifdef SOFTDEVICE_PRESENT
if (!nrf_sdh_is_enabled())
#endif
{
nrf_clock_lf_src_set((nrf_clock_lfclk_t)CLOCK_CONFIG_LF_SRC);
nrfx_clock_enable();
}
#if CALIBRATION_SUPPORT
@@ -203,24 +180,20 @@ ret_code_t nrf_drv_clock_init(void)
}
NRF_LOG_INFO("Function: %s, error code: %s.",
(uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
(uint32_t)__func__,
(uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
return err_code;
}
void nrf_drv_clock_uninit(void)
{
ASSERT(m_clock_cb.module_initialized);
nrf_drv_common_clock_irq_disable();
nrf_clock_int_disable(0xFFFFFFFF);
lfclk_stop();
hfclk_stop();
m_clock_cb.module_initialized = false;
NRF_LOG_INFO("Uninitialized.");
nrfx_clock_disable();
nrfx_clock_uninit();
}
static void item_enqueue(nrf_drv_clock_handler_item_t ** p_head,
nrf_drv_clock_handler_item_t * p_item)
nrf_drv_clock_handler_item_t * p_item)
{
nrf_drv_clock_handler_item_t * p_next = *p_head;
while (p_next)
@@ -270,7 +243,7 @@ void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t * p_handler_item)
}
if (m_clock_cb.lfclk_requests == 0)
{
lfclk_start();
nrfx_clock_lfclk_start();
}
++(m_clock_cb.lfclk_requests);
CRITICAL_REGION_EXIT();
@@ -304,7 +277,7 @@ bool nrf_drv_clock_lfclk_is_running(void)
}
#endif // SOFTDEVICE_PRESENT
return nrf_clock_lf_is_running();
return nrfx_clock_lfclk_is_running();
}
void nrf_drv_clock_hfclk_request(nrf_drv_clock_handler_item_t * p_handler_item)
@@ -367,7 +340,7 @@ bool nrf_drv_clock_hfclk_is_running(void)
}
#endif // SOFTDEVICE_PRESENT
return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY);
return nrfx_clock_hfclk_is_running();
}
#if CALIBRATION_SUPPORT
@@ -384,10 +357,11 @@ static void clock_calibration_hf_started(nrf_drv_clock_evt_type_t event)
}
else
{
nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE);
nrf_clock_int_enable(NRF_CLOCK_INT_DONE_MASK);
m_clock_cb.cal_state = CAL_STATE_CAL;
nrf_clock_task_trigger(NRF_CLOCK_TASK_CAL);
ASSERT(event == NRF_DRV_CLOCK_EVT_HFCLK_STARTED);
if (nrfx_clock_calibration_start() != NRFX_SUCCESS)
{
ASSERT(false);
}
}
}
#endif // CALIBRATION_SUPPORT
@@ -413,21 +387,24 @@ ret_code_t nrf_drv_clock_calibration_start(uint8_t interval, nrf_drv_clock_event
else
{
m_clock_cb.cal_state = CAL_STATE_CT;
nrf_clock_cal_timer_timeout_set(interval);
nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO);
nrf_clock_int_enable(NRF_CLOCK_INT_CTTO_MASK);
nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTART);
nrfx_clock_calibration_timer_start(interval);
}
}
else
{
err_code = NRF_ERROR_BUSY;
}
NRF_LOG_WARNING("Function: %s, error code: %s.", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
NRF_LOG_WARNING("Function: %s, error code: %s.",
(uint32_t)__func__,
(uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
return err_code;
#else
UNUSED_PARAMETER(interval);
UNUSED_PARAMETER(handler);
err_code = NRF_ERROR_FORBIDDEN;
NRF_LOG_WARNING("Function: %s, error code: %s.", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
NRF_LOG_WARNING("Function: %s, error code: %s.",
(uint32_t)__func__,
(uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
return err_code;
#endif // CALIBRATION_SUPPORT
}
@@ -440,8 +417,7 @@ ret_code_t nrf_drv_clock_calibration_abort(void)
switch (m_clock_cb.cal_state)
{
case CAL_STATE_CT:
nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK);
nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTOP);
nrfx_clock_calibration_timer_stop();
m_clock_cb.cal_state = CAL_STATE_IDLE;
if (m_clock_cb.cal_done_handler)
{
@@ -458,11 +434,15 @@ ret_code_t nrf_drv_clock_calibration_abort(void)
}
CRITICAL_REGION_EXIT();
NRF_LOG_INFO("Function: %s, error code: %s.", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
NRF_LOG_INFO("Function: %s, error code: %s.",
(uint32_t)__func__,
(uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
return err_code;
#else
err_code = NRF_ERROR_FORBIDDEN;
NRF_LOG_WARNING("Function: %s, error code: %s.", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
NRF_LOG_WARNING("Function: %s, error code: %s.",
(uint32_t)__func__,
(uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
return err_code;
#endif // CALIBRATION_SUPPORT
}
@@ -473,11 +453,16 @@ ret_code_t nrf_drv_clock_is_calibrating(bool * p_is_calibrating)
#if CALIBRATION_SUPPORT
ASSERT(m_clock_cb.module_initialized);
*p_is_calibrating = (m_clock_cb.cal_state != CAL_STATE_IDLE);
NRF_LOG_INFO("Function: %s, error code: %s.", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
NRF_LOG_INFO("Function: %s, error code: %s.",
(uint32_t)__func__,
(uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
return err_code;
#else
UNUSED_PARAMETER(p_is_calibrating);
err_code = NRF_ERROR_FORBIDDEN;
NRF_LOG_WARNING("Function: %s, error code: %s.", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
NRF_LOG_WARNING("Function: %s, error code: %s.",
(uint32_t)__func__,
(uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
return err_code;
#endif // CALIBRATION_SUPPORT
}
@@ -506,42 +491,26 @@ __STATIC_INLINE void clock_clk_started_notify(nrf_drv_clock_evt_type_t evt_type)
}
}
#if NRF_DRV_COMMON_POWER_CLOCK_ISR
void nrf_drv_clock_onIRQ(void)
#else
void POWER_CLOCK_IRQHandler(void)
#endif
static void clock_irq_handler(nrfx_clock_evt_type_t evt)
{
if (nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED))
if (evt == NRFX_CLOCK_EVT_HFCLK_STARTED)
{
nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED);
NRF_LOG_DEBUG("Event: %s.", (uint32_t)EVT_TO_STR(NRF_CLOCK_EVENT_HFCLKSTARTED));
nrf_clock_int_disable(NRF_CLOCK_INT_HF_STARTED_MASK);
m_clock_cb.hfclk_on = true;
clock_clk_started_notify(NRF_DRV_CLOCK_EVT_HFCLK_STARTED);
}
if (nrf_clock_event_check(NRF_CLOCK_EVENT_LFCLKSTARTED))
if (evt == NRFX_CLOCK_EVT_LFCLK_STARTED)
{
nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED);
NRF_LOG_DEBUG("Event: %s.", (uint32_t)EVT_TO_STR(NRF_CLOCK_EVENT_LFCLKSTARTED));
nrf_clock_int_disable(NRF_CLOCK_INT_LF_STARTED_MASK);
m_clock_cb.lfclk_on = true;
clock_clk_started_notify(NRF_DRV_CLOCK_EVT_LFCLK_STARTED);
}
#if CALIBRATION_SUPPORT
if (nrf_clock_event_check(NRF_CLOCK_EVENT_CTTO))
if (evt == NRFX_CLOCK_EVT_CTTO)
{
nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO);
NRF_LOG_DEBUG("Event: %s.", (uint32_t)EVT_TO_STR(NRF_CLOCK_EVENT_CTTO));
nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK);
nrf_drv_clock_hfclk_request(&m_clock_cb.cal_hfclk_started_handler_item);
}
if (nrf_clock_event_check(NRF_CLOCK_EVENT_DONE))
if (evt == NRFX_CLOCK_EVT_CAL_DONE)
{
nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE);
NRF_LOG_DEBUG("Event: %s.", (uint32_t)EVT_TO_STR(NRF_CLOCK_EVENT_DONE));
nrf_clock_int_disable(NRF_CLOCK_INT_DONE_MASK);
nrf_drv_clock_hfclk_release();
bool aborted = (m_clock_cb.cal_state == CAL_STATE_ABORT);
m_clock_cb.cal_state = CAL_STATE_IDLE;
@@ -565,10 +534,10 @@ static void soc_evt_handler(uint32_t evt_id, void * p_context)
{
if (evt_id == NRF_EVT_HFCLKSTARTED)
{
m_clock_cb.hfclk_on = true;
clock_clk_started_notify(NRF_DRV_CLOCK_EVT_HFCLK_STARTED);
}
}
NRF_SDH_SOC_OBSERVER(m_soc_evt_observer, CLOCK_CONFIG_SOC_OBSERVER_PRIO, soc_evt_handler, NULL);
/**
@@ -601,7 +570,7 @@ static void sd_state_evt_handler(nrf_sdh_state_evt_t state, void * p_context)
case NRF_SDH_EVT_STATE_DISABLED:
/* Reinit interrupts */
ASSERT(m_clock_cb.module_initialized);
nrf_drv_common_irq_enable(POWER_CLOCK_IRQn, CLOCK_CONFIG_IRQ_PRIORITY);
nrfx_clock_enable();
/* SD leaves LFCLK enabled - disable it if it is no longer required. */
nrf_drv_clock_lfclk_release();
+53 -41
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -40,30 +40,18 @@
#ifndef NRF_DRV_CLOCK_H__
#define NRF_DRV_CLOCK_H__
#include <stdbool.h>
#include <stdint.h>
#include "sdk_errors.h"
#include "nrf_assert.h"
#include "nrf_clock.h"
#include "sdk_config.h"
#include "nrf_drv_common.h"
#include <nrfx_clock.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
*
* @addtogroup nrf_clock Clock HAL and driver
* @ingroup nrf_drivers
* @brief Clock APIs.
* @details The clock HAL provides basic APIs for accessing the registers of the clock.
* The clock driver provides APIs on a higher level.
*
* @defgroup nrf_drv_clock Clock driver
* @defgroup nrf_drv_clock Clock driver - legacy layer
* @{
* @ingroup nrf_clock
* @brief Driver for managing the low-frequency clock (LFCLK) and the high-frequency clock (HFCLK).
*
* @brief Layer providing compatibility with the former API.
*/
/**
@@ -96,9 +84,6 @@ struct nrf_drv_clock_handler_item_s
/**
* @brief Function for checking if driver is already initialized
*
* This function is used to check whatever common POWER_CLOCK common interrupt
* should be disabled or not if @ref nrf_drv_power tries to disable the interrupt.
*
* @retval true Driver is initialized
* @retval false Driver is uninitialized
*/
@@ -109,8 +94,8 @@ bool nrf_drv_clock_init_check(void);
*
* After initialization, the module is in power off state (clocks are not requested).
*
* @retval NRF_SUCCESS If the procedure was successful.
* @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED If the driver was already initialized.
* @retval NRF_SUCCESS If the procedure was successful.
* @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED If the driver was already initialized.
*/
ret_code_t nrf_drv_clock_init(void);
@@ -155,7 +140,7 @@ void nrf_drv_clock_lfclk_release(void);
/**
* @brief Function for checking the LFCLK state.
*
* @retval true If the LFCLK is running.
* @retval true If the LFCLK is running.
* @retval false If the LFCLK is not running.
*/
bool nrf_drv_clock_lfclk_is_running(void);
@@ -209,13 +194,13 @@ bool nrf_drv_clock_hfclk_is_running(void);
* - Requesting the high-accuracy HFCLK
* - Hardware-supported calibration
*
* @param[in] delay Time after which the calibration will be started (in 0.25 s units).
* @param[in] handler NULL or user function to be called when calibration is completed or aborted.
* @param[in] delay Time after which the calibration will be started (in 0.25 s units).
* @param[in] handler NULL or user function to be called when calibration is completed or aborted.
*
* @retval NRF_SUCCESS If the procedure was successful.
* @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator.
* @retval NRF_ERROR_INVALID_STATE If the low-frequency clock is off.
* @retval NRF_ERROR_BUSY If calibration is in progress.
* @retval NRF_SUCCESS If the procedure was successful.
* @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator.
* @retval NRF_ERROR_INVALID_STATE If the low-frequency clock is off.
* @retval NRF_ERROR_BUSY If calibration is in progress.
*/
ret_code_t nrf_drv_clock_calibration_start(uint8_t delay, nrf_drv_clock_event_handler_t handler);
@@ -227,8 +212,8 @@ ret_code_t nrf_drv_clock_calibration_start(uint8_t delay, nrf_drv_clock_event_ha
* aborted calibration is completed. @ref nrf_drv_clock_is_calibrating can also be used to check
* if the system is calibrating.
*
* @retval NRF_SUCCESS If the procedure was successful.
* @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator.
* @retval NRF_SUCCESS If the procedure was successful.
* @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator.
*/
ret_code_t nrf_drv_clock_calibration_abort(void);
@@ -238,28 +223,57 @@ ret_code_t nrf_drv_clock_calibration_abort(void);
* This function indicates that the system is
* in calibration if it is in any of the calibration process phases (see @ref nrf_drv_clock_calibration_start).
*
* @param[out] p_is_calibrating True if calibration is in progress, false if not.
* @param[out] p_is_calibrating True if calibration is in progress, false if not.
*
* @retval NRF_SUCCESS If the procedure was successful.
* @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator.
* @retval NRF_SUCCESS If the procedure was successful.
* @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator.
*/
ret_code_t nrf_drv_clock_is_calibrating(bool * p_is_calibrating);
/**@brief Function for returning a requested task address for the clock driver module.
*
* @param[in] task One of the peripheral tasks.
* @param[in] task One of the peripheral tasks.
*
* @return Task address.
* @return Task address.
*/
__STATIC_INLINE uint32_t nrf_drv_clock_ppi_task_addr(nrf_clock_task_t task);
/**@brief Function for returning a requested event address for the clock driver module.
*
* @param[in] event One of the peripheral events.
* @param[in] event One of the peripheral events.
*
* @return Event address.
* @return Event address.
*/
__STATIC_INLINE uint32_t nrf_drv_clock_ppi_event_addr(nrf_clock_event_t event);
#ifdef SOFTDEVICE_PRESENT
/**
* @brief Function called by the SoftDevice handler if an @ref NRF_SOC_EVTS event is received from the SoftDevice.
*
* @param[in] evt_id One of NRF_SOC_EVTS values.
*/
void nrf_drv_clock_on_soc_event(uint32_t evt_id);
/**
* @brief Function called by the SoftDevice handler when the SoftDevice has been enabled.
*
* This function is called just after the SoftDevice has been properly enabled.
* Its main purpose is to mark that LFCLK has been requested by SD.
*/
void nrf_drv_clock_on_sd_enable(void);
/**
* @brief Function called by the SoftDevice handler when the SoftDevice has been disabled.
*
* This function is called just after the SoftDevice has been properly disabled.
* It has two purposes:
* 1. Releases the LFCLK from the SD.
* 2. Reinitializes an interrupt after the SD releases POWER_CLOCK_IRQ.
*/
void nrf_drv_clock_on_sd_disable(void);
#endif
/**
*@}
**/
@@ -276,10 +290,8 @@ __STATIC_INLINE uint32_t nrf_drv_clock_ppi_event_addr(nrf_clock_event_t event)
}
#endif //SUPPRESS_INLINE_IMPLEMENTATION
/*lint --flb "Leave library region" */
#ifdef __cplusplus
}
#endif
#endif // NRF_CLOCK_H__
#endif // NRF_DRV_CLOCK_H__
@@ -1,297 +0,0 @@
/**
* Copyright (c) 2015 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stddef.h>
#include "nrf_drv_common.h"
#include "nrf_assert.h"
#include "app_util_platform.h"
#include "nrf_peripherals.h"
#if NRF_DRV_COMMON_POWER_CLOCK_ISR
#include "nrf_drv_power.h"
#include "nrf_drv_clock.h"
#endif
#ifdef SOFTDEVICE_PRESENT
#include "nrf_soc.h"
#endif
#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
#define NRF_LOG_MODULE_NAME common
#if COMMON_CONFIG_LOG_ENABLED
#define NRF_LOG_LEVEL COMMON_CONFIG_LOG_LEVEL
#define NRF_LOG_INFO_COLOR COMMON_CONFIG_INFO_COLOR
#define NRF_LOG_DEBUG_COLOR COMMON_CONFIG_DEBUG_COLOR
#else //COMMON_CONFIG_LOG_ENABLED
#define NRF_LOG_LEVEL 0
#endif //COMMON_CONFIG_LOG_ENABLED
#include "nrf_log.h"
NRF_LOG_MODULE_REGISTER();
typedef struct {
nrf_drv_irq_handler_t handler;
bool acquired;
} shared_resource_t;
// SPIM0, SPIS0, SPI0, TWIM0, TWIS0, TWI0
#if (NRF_MODULE_ENABLED(SPI0) || NRF_MODULE_ENABLED(SPIS0) || NRF_MODULE_ENABLED(TWI0) || NRF_MODULE_ENABLED(TWIS0))
#define SERIAL_BOX_0_IN_USE
// [this checking may need a different form in unit tests, hence macro]
#ifndef IS_SERIAL_BOX_0
#define IS_SERIAL_BOX_0(p_per_base) (p_per_base == NRF_SPI0)
#endif
static shared_resource_t m_serial_box_0 = { .acquired = false };
void SPI0_TWI0_IRQHandler(void)
{
ASSERT(m_serial_box_0.handler);
m_serial_box_0.handler();
}
#endif // (NRF_MODULE_ENABLED(SPI0) || NRF_MODULE_ENABLED(SPIS0) || NRF_MODULE_ENABLED(TWI0) || NRF_MODULE_ENABLED(TWIS0))
// SPIM1, SPIS1, SPI1, TWIM1, TWIS1, TWI1
#if (NRF_MODULE_ENABLED(SPI1) || NRF_MODULE_ENABLED(SPIS1) || NRF_MODULE_ENABLED(TWI1) || NRF_MODULE_ENABLED(TWIS1))
#define SERIAL_BOX_1_IN_USE
// [this checking may need a different form in unit tests, hence macro]
#ifndef IS_SERIAL_BOX_1
#define IS_SERIAL_BOX_1(p_per_base) (p_per_base == NRF_SPI1)
#endif
static shared_resource_t m_serial_box_1 = { .acquired = false };
#ifdef TWIM_PRESENT
void SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler(void)
#else
void SPI1_TWI1_IRQHandler(void)
#endif
{
ASSERT(m_serial_box_1.handler);
m_serial_box_1.handler();
}
#endif // (NRF_MODULE_ENABLED(SPI1) || NRF_MODULE_ENABLED(SPIS1) || NRF_MODULE_ENABLED(TWI1) || NRF_MODULE_ENABLED(TWIS1))
// SPIM2, SPIS2, SPI2
#if (NRF_MODULE_ENABLED(SPI2) || NRF_MODULE_ENABLED(SPIS2))
#define SERIAL_BOX_2_IN_USE
// [this checking may need a different form in unit tests, hence macro]
#ifndef IS_SERIAL_BOX_2
#define IS_SERIAL_BOX_2(p_per_base) (p_per_base == NRF_SPI2)
#endif
static shared_resource_t m_serial_box_2 = { .acquired = false };
void SPIM2_SPIS2_SPI2_IRQHandler(void)
{
ASSERT(m_serial_box_2.handler);
m_serial_box_2.handler();
}
#endif // (NRF_MODULE_ENABLED(SPI2) || NRF_MODULE_ENABLED(SPIS2))
// COMP, LPCOMP
#if (NRF_MODULE_ENABLED(COMP) || NRF_MODULE_ENABLED(LPCOMP))
#define COMP_LPCOMP_IN_USE
#ifndef IS_COMP_LPCOMP
#define IS_COMP_LPCOMP(p_per_base) ((p_per_base) == NRF_LPCOMP)
#endif
static shared_resource_t m_comp_lpcomp = { .acquired = false };
void LPCOMP_IRQHandler(void)
{
ASSERT(m_comp_lpcomp.handler);
m_comp_lpcomp.handler();
}
#endif // (NRF_MODULE_ENABLED(COMP) || NRF_MODULE_ENABLED(LPCOMP))
#if defined(SERIAL_BOX_0_IN_USE) || \
defined(SERIAL_BOX_1_IN_USE) || \
defined(SERIAL_BOX_2_IN_USE) || \
defined(COMP_LPCOMP_IN_USE)
static ret_code_t acquire_shared_resource(shared_resource_t * p_resource,
nrf_drv_irq_handler_t handler)
{
ret_code_t err_code;
bool busy = false;
CRITICAL_REGION_ENTER();
if (p_resource->acquired)
{
busy = true;
}
else
{
p_resource->acquired = true;
}
CRITICAL_REGION_EXIT();
if (busy)
{
err_code = NRF_ERROR_BUSY;
NRF_LOG_WARNING("Function: %s, error code: %s.", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
return err_code;
}
p_resource->handler = handler;
err_code = NRF_SUCCESS;
NRF_LOG_INFO("Function: %s, error code: %s.", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
return err_code;
}
#endif
ret_code_t nrf_drv_common_per_res_acquire(void const * p_per_base,
nrf_drv_irq_handler_t handler)
{
#ifdef SERIAL_BOX_0_IN_USE
if (IS_SERIAL_BOX_0(p_per_base))
{
return acquire_shared_resource(&m_serial_box_0, handler);
}
#endif
#ifdef SERIAL_BOX_1_IN_USE
if (IS_SERIAL_BOX_1(p_per_base))
{
return acquire_shared_resource(&m_serial_box_1, handler);
}
#endif
#ifdef SERIAL_BOX_2_IN_USE
if (IS_SERIAL_BOX_2(p_per_base))
{
return acquire_shared_resource(&m_serial_box_2, handler);
}
#endif
#ifdef COMP_LPCOMP_IN_USE
if (IS_COMP_LPCOMP(p_per_base))
{
return acquire_shared_resource(&m_comp_lpcomp, handler);
}
#endif
ret_code_t err_code;
err_code = NRF_ERROR_INVALID_PARAM;
NRF_LOG_WARNING("Function: %s, error code: %s.", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
return err_code;
}
void nrf_drv_common_per_res_release(void const * p_per_base)
{
#ifdef SERIAL_BOX_0_IN_USE
if (IS_SERIAL_BOX_0(p_per_base))
{
m_serial_box_0.acquired = false;
}
else
#endif
#ifdef SERIAL_BOX_1_IN_USE
if (IS_SERIAL_BOX_1(p_per_base))
{
m_serial_box_1.acquired = false;
}
else
#endif
#ifdef SERIAL_BOX_2_IN_USE
if (IS_SERIAL_BOX_2(p_per_base))
{
m_serial_box_2.acquired = false;
}
else
#endif
#ifdef COMP_LPCOMP_IN_USE
if (IS_COMP_LPCOMP(p_per_base))
{
m_comp_lpcomp.acquired = false;
}
else
#endif
{}
}
#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
#if NRF_MODULE_ENABLED(POWER)
void nrf_drv_common_power_irq_disable(void)
{
#if NRF_DRV_COMMON_POWER_CLOCK_ISR
if (!nrf_drv_clock_init_check())
#endif
{
nrf_drv_common_irq_disable(POWER_CLOCK_IRQn);
}
}
#endif
#if NRF_MODULE_ENABLED(CLOCK)
void nrf_drv_common_clock_irq_disable(void)
{
#if NRF_DRV_COMMON_POWER_CLOCK_ISR
if (!nrf_drv_power_init_check())
#endif
{
nrf_drv_common_irq_disable(POWER_CLOCK_IRQn);
}
}
#endif
#if NRF_DRV_COMMON_POWER_CLOCK_ISR
void POWER_CLOCK_IRQHandler(void)
{
extern void nrf_drv_clock_onIRQ(void);
extern void nrf_drv_power_onIRQ(void);
nrf_drv_clock_onIRQ();
nrf_drv_power_onIRQ();
}
#endif // NRF_DRV_COMMON_POWER_CLOCK_ISR
void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority)
{
INTERRUPT_PRIORITY_ASSERT(priority);
NVIC_SetPriority(IRQn, priority);
NVIC_ClearPendingIRQ(IRQn);
NVIC_EnableIRQ(IRQn);
}
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2015 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -37,321 +37,27 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_DRV_COMMON_H__
#define NRF_DRV_COMMON_H__
#include <stdint.h>
#include <stdbool.h>
#include "nrf.h"
#include "sdk_errors.h"
#include "sdk_common.h"
#include "nrf_assert.h"
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef NRF51
#ifdef SOFTDEVICE_PRESENT
#define INTERRUPT_PRIORITY_IS_VALID(pri) (((pri) == 1) || ((pri) == 3))
#else
#define INTERRUPT_PRIORITY_IS_VALID(pri) ((pri) < 4)
#endif //SOFTDEVICE_PRESENT
#else
#ifdef SOFTDEVICE_PRESENT
#define INTERRUPT_PRIORITY_IS_VALID(pri) ((((pri) > 1) && ((pri) < 4)) || (((pri) > 5) && ((pri) < 8)))
#else
#define INTERRUPT_PRIORITY_IS_VALID(pri) ((pri) < 8)
#endif //SOFTDEVICE_PRESENT
#endif //NRF52
#define INTERRUPT_PRIORITY_VALIDATION(pri) STATIC_ASSERT(INTERRUPT_PRIORITY_IS_VALID((pri)))
#define INTERRUPT_PRIORITY_ASSERT(pri) ASSERT(INTERRUPT_PRIORITY_IS_VALID((pri)))
/**
* @defgroup nrf_drv_common Peripheral drivers common module
* @{
* @ingroup nrf_drivers
*/
/**
* @brief Offset of event registers in every peripheral instance.
*
* This is the offset where event registers start in every peripheral.
*/
#define NRF_DRV_COMMON_EVREGS_OFFSET 0x100U
/**
* @brief The flag that is set when POWER_CLOCK ISR is implemented in common module
*
* This flag means that the function POWER_CLOCK_IRQHandler is implemented in
* nrf_drv_common.c file. In the @c clock and @c power modules functions
* nrf_drv_clock_onIRQ nrf_drv_power_onIRQ should be implemented
* and they would be called from common implementation.
*
* None of the checking is done here.
* The implementation functions in @c clock and @c power are required to handle
* correctly the case when they are called without any event bit set.
*/
#define NRF_DRV_COMMON_POWER_CLOCK_ISR (NRF_MODULE_ENABLED(CLOCK) && NRF_MODULE_ENABLED(POWER))
/**
* @brief Driver state.
*/
typedef enum
{
NRF_DRV_STATE_UNINITIALIZED, /**< Uninitialized. */
NRF_DRV_STATE_INITIALIZED, /**< Initialized but powered off. */
NRF_DRV_STATE_POWERED_ON
} nrf_drv_state_t;
/**
* @brief Driver power state selection.
*/
typedef enum
{
NRF_DRV_PWR_CTRL_ON, /**< Power on request. */
NRF_DRV_PWR_CTRL_OFF /**< Power off request. */
} nrf_drv_pwr_ctrl_t;
/**
* @brief IRQ handler type.
*/
typedef void (*nrf_drv_irq_handler_t)(void);
#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
/**
* @brief Function for acquiring shared peripheral resources associated with
* the specified peripheral.
*
* Certain resources and registers are shared among peripherals that have
* the same ID (for example: SPI0, SPIM0, SPIS0, TWI0, TWIM0, and TWIS0).
* Only one of them can be utilized at a given time. This function reserves
* proper resources to be used by the specified peripheral.
* If PERIPHERAL_RESOURCE_SHARING_ENABLED is set to a non-zero value, IRQ
* handlers for peripherals that are sharing resources with others are
* implemented by the nrf_drv_common module instead of individual drivers.
* The drivers must then specify their interrupt handling routines and
* register them by using this function.
*
* @param[in] p_per_base Requested peripheral base pointer.
* @param[in] handler Interrupt handler to register. May be NULL
* if interrupts are not used for the peripheral.
*
* @retval NRF_SUCCESS If resources were acquired successfully.
* @retval NRF_ERROR_BUSY If resources were already acquired.
* @retval NRF_ERROR_INVALID_PARAM If the specified peripheral is not enabled
* or the peripheral does not share resources
* with other peripherals.
*/
ret_code_t nrf_drv_common_per_res_acquire(void const * p_per_base,
nrf_drv_irq_handler_t handler);
/**
* @brief Function for releasing shared resources reserved previously by
* @ref nrf_drv_common_per_res_acquire() for the specified peripheral.
*
* @param[in] p_per_base Requested peripheral base pointer.
*/
void nrf_drv_common_per_res_release(void const * p_per_base);
#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
/**
* @brief Function sets priority and enables NVIC interrupt
*
* @note Function checks if correct priority is used when softdevice is present
*
* @param[in] IRQn Interrupt id
* @param[in] priority Interrupt priority
*/
void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority);
#if NRF_MODULE_ENABLED(POWER)
/**
* @brief Disable power IRQ
*
* Power and clock peripheral uses the same IRQ.
* This function disables POWER_CLOCK IRQ only if CLOCK driver
* is uninitialized.
*
* @sa nrf_drv_common_power_clock_irq_init
*/
void nrf_drv_common_power_irq_disable(void);
#endif
#if NRF_MODULE_ENABLED(CLOCK)
/**
* @brief Disable clock IRQ
*
* Power and clock peripheral uses the same IRQ.
* This function disables POWER_CLOCK IRQ only if POWER driver
* is uninitialized.
*
* @sa nrf_drv_common_power_clock_irq_init
*/
void nrf_drv_common_clock_irq_disable(void);
#endif
/**
* @brief Check if interrupt is enabled
*
* Function that checks if selected interrupt is enabled.
*
* @param[in] IRQn Interrupt id
*
* @retval true Selected IRQ is enabled.
* @retval false Selected IRQ is disabled.
*/
__STATIC_INLINE bool nrf_drv_common_irq_enable_check(IRQn_Type IRQn);
/**
* @brief Function disables NVIC interrupt
*
* @param[in] IRQn Interrupt id
*/
__STATIC_INLINE void nrf_drv_common_irq_disable(IRQn_Type IRQn);
/**
* @brief Convert bit position to event code
*
* Function for converting the bit position in INTEN register to event code
* that is equivalent to the offset of the event register from the beginning
* of peripheral instance.
*
* For example the result of this function can be casted directly to
* the types like @ref nrf_twis_event_t or @ref nrf_rng_event_t
*
* @param bit Bit position in INTEN register
* @return Event code to be casted to the right enum type or to be used in functions like
* @ref nrf_rng_event_get
*
* @sa nrf_drv_event_to_bitpos
*/
__STATIC_INLINE uint32_t nrf_drv_bitpos_to_event(uint32_t bit);
/**
* @brief Convert event code to bit position
*
* This function can be used to get bit position in INTEN register from event code.
*
* @param event Event code that may be casted from enum values from types like
* @ref nrf_twis_event_t or @ref nrf_rng_event_t
* @return Bit position in INTEN register that corresponds to the given code.
*
* @sa nrf_drv_bitpos_to_event
*/
__STATIC_INLINE uint32_t nrf_drv_event_to_bitpos(uint32_t event);
/**
* @brief Get interrupt number connected with given instance
*
* Function returns interrupt number for a given instance of any peripheral.
* @param[in] pinst Pointer to peripheral registry
* @return Interrupt number
*/
__STATIC_INLINE IRQn_Type nrf_drv_get_IRQn(void const * const pinst);
#if NRF_MODULE_ENABLED(CLOCK) || NRF_MODULE_ENABLED(POWER)
/**
* @brief Enable and setup power clock IRQ
*
* This function would be called from @ref nrf_drv_clock and @ref nrf_drv_power
* to enable related interrupt.
* This function avoids multiple interrupt configuration.
*
* @note
* This function is aviable only if @ref nrf_drv_clock or @ref nrf_drv_power
* module is enabled.
*
* @note
* If both @ref nrf_drv_clock and @ref nrf_drv_power modules are enabled,
* during the compilation the check is made that
* @ref CLOCK_CONFIG_IRQ_PRIORITY equals @ref POWER_CONFIG_IRQ_PRIORITY.
*
* @sa nrf_drv_common_power_irq_disable
* @sa nrf_drv_common_clock_irq_disable
*/
__STATIC_INLINE void nrf_drv_common_power_clock_irq_init(void);
#endif
/**
* @brief Check if given object is in RAM
*
* Function for analyzing if given location is placed in RAM.
* This function is used to determine if we have address that can be supported by EasyDMA.
* @param[in] ptr Pointer to the object
* @retval true Object is located in RAM
* @retval false Object is not located in RAM
*/
__STATIC_INLINE bool nrf_drv_is_in_RAM(void const * const ptr);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE bool nrf_drv_common_irq_enable_check(IRQn_Type IRQn)
{
return 0 != (NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] &
(uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)));
}
__STATIC_INLINE void nrf_drv_common_irq_disable(IRQn_Type IRQn)
{
NVIC_DisableIRQ(IRQn);
}
__STATIC_INLINE uint32_t nrf_drv_bitpos_to_event(uint32_t bit)
{
return NRF_DRV_COMMON_EVREGS_OFFSET + bit * sizeof(uint32_t);
}
__STATIC_INLINE uint32_t nrf_drv_event_to_bitpos(uint32_t event)
{
return (event - NRF_DRV_COMMON_EVREGS_OFFSET) / sizeof(uint32_t);
}
__STATIC_INLINE IRQn_Type nrf_drv_get_IRQn(void const * const pinst)
{
uint8_t ret = (uint8_t)((uint32_t)pinst>>12U);
return (IRQn_Type) ret;
}
#if NRF_MODULE_ENABLED(CLOCK) || NRF_MODULE_ENABLED(POWER)
__STATIC_INLINE void nrf_drv_common_power_clock_irq_init(void)
{
if (!nrf_drv_common_irq_enable_check(POWER_CLOCK_IRQn))
{
nrf_drv_common_irq_enable(
POWER_CLOCK_IRQn,
#if NRF_DRV_COMMON_POWER_CLOCK_ISR
#if CLOCK_CONFIG_IRQ_PRIORITY != POWER_CONFIG_IRQ_PRIORITY
#error CLOCK_CONFIG_IRQ_PRIORITY and POWER_CONFIG_IRQ_PRIORITY have to be the same.
#endif
CLOCK_CONFIG_IRQ_PRIORITY
#elif NRF_MODULE_ENABLED(CLOCK)
CLOCK_CONFIG_IRQ_PRIORITY
#elif NRF_MODULE_ENABLED(POWER)
POWER_CONFIG_IRQ_PRIORITY
#endif
);
}
}
#endif
__STATIC_INLINE bool nrf_drv_is_in_RAM(void const * const ptr)
{
return ((((uintptr_t)ptr) & 0xE0000000u) == 0x20000000u);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
#define nrf_drv_irq_handler_t nrfx_irq_handler_t
#define nrf_drv_bitpos_to_event nrfx_bitpos_to_event
#define nrf_drv_event_to_bitpos nrfx_event_to_bitpos
#define nrf_drv_get_IRQn nrfx_get_irq_number
#define nrf_drv_is_in_RAM nrfx_is_in_ram
#ifdef __cplusplus
}
#endif
#endif // NRF_DRV_COMMON_H__
/** @} */
+150 -216
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2017 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -38,73 +38,26 @@
*
*/
#include "sdk_common.h"
#if NRF_MODULE_ENABLED(POWER)
#include "nrf_drv_power.h"
#include "nrf_assert.h"
#include "nordic_common.h"
#include "app_util_platform.h"
#include <nrf_drv_clock.h>
#ifdef SOFTDEVICE_PRESENT
#include "nrf_sdm.h"
#include "nrf_soc.h"
#include "nrf_sdh.h"
#include "nrf_sdh_soc.h"
#endif
/* Validate configuration */
INTERRUPT_PRIORITY_VALIDATION(POWER_CONFIG_IRQ_PRIORITY);
#include <app_util.h>
/**
* @internal
* @defgroup nrf_drv_power_internals POWER driver internals
* @ingroup nrf_drv_power
*
* Internal variables, auxiliary macros and functions of POWER driver.
* @{
*/
/**
* @brief Default configuration
*
* The structure with default configuration data.
* This structure would be used if configuration pointer given
* to the @ref nrf_drv_power_init is set to NULL.
*/
static const nrf_drv_power_config_t m_drv_power_config_default =
// The structure with default configuration data.
static const nrfx_power_config_t m_drv_power_config_default =
{
.dcdcen = POWER_CONFIG_DEFAULT_DCDCEN,
.dcdcen = NRFX_POWER_CONFIG_DEFAULT_DCDCEN,
#if NRF_POWER_HAS_VDDH
.dcdcenhv = POWER_CONFIG_DEFAULT_DCDCENHV,
.dcdcenhv = NRFX_POWER_CONFIG_DEFAULT_DCDCENHV,
#endif
};
/**
* @brief The initialization flag
*/
static bool m_initialized;
/**
* @brief The handler of power fail comparator warning event
*/
static nrf_drv_power_pofwarn_event_handler_t m_pofwarn_handler;
#if NRF_POWER_HAS_SLEEPEVT
/**
* @brief The handler of sleep event handler
*/
static nrf_drv_power_sleep_event_handler_t m_sleepevt_handler;
#endif
#if NRF_POWER_HAS_USBREG
/**
* @brief The handler of USB power events
*/
static nrf_drv_power_usb_event_handler_t m_usbevt_handler;
#endif
/** @} */
bool nrf_drv_power_init_check(void)
{
return m_initialized;
@@ -112,34 +65,28 @@ bool nrf_drv_power_init_check(void)
ret_code_t nrf_drv_power_init(nrf_drv_power_config_t const * p_config)
{
nrf_drv_power_config_t const * p_used_config;
if (m_initialized)
{
return NRF_ERROR_MODULE_ALREADY_INITIALIZED;
}
#ifdef SOFTDEVICE_PRESENT
if (nrf_sdh_is_enabled())
{
return NRF_ERROR_INVALID_STATE;
}
#endif
if (p_config == NULL)
{
p_config = &m_drv_power_config_default;
}
p_used_config = (p_config != NULL) ?
p_config : (&m_drv_power_config_default);
#if NRF_POWER_HAS_VDDH
nrf_power_dcdcen_vddh_set(p_used_config->dcdcenhv);
#endif
nrf_power_dcdcen_set(p_used_config->dcdcen);
nrf_drv_common_power_clock_irq_init();
m_initialized = true;
return NRF_SUCCESS;
ret_code_t err_code = nrfx_power_init(p_config);
if (err_code == NRFX_SUCCESS)
{
m_initialized = true;
}
return err_code;
}
void nrf_drv_power_uninit(void)
void nrf_drv_power_uninit()
{
ASSERT(m_initialized);
nrfx_power_uninit();
nrf_drv_power_pof_uninit();
#if NRF_POWER_HAS_SLEEPEVT
nrf_drv_power_sleepevt_uninit();
@@ -152,10 +99,8 @@ void nrf_drv_power_uninit(void)
ret_code_t nrf_drv_power_pof_init(nrf_drv_power_pofwarn_config_t const * p_config)
{
ASSERT(p_config != NULL);
nrf_drv_power_pof_uninit();
ret_code_t err_code = NRF_SUCCESS;
nrfx_power_pof_init(p_config);
#ifdef SOFTDEVICE_PRESENT
if (nrf_sdh_is_enabled())
{
@@ -176,7 +121,7 @@ ret_code_t nrf_drv_power_pof_init(nrf_drv_power_pofwarn_config_t const * p_confi
* the values taken by SD is different than the one in hardware
*/
uint8_t thr;
switch (p_config->thr)
switch(p_config->thr)
{
case NRF_POWER_POFTHR_V21:
thr = NRF_POWER_THRESHOLD_V21;
@@ -192,76 +137,51 @@ ret_code_t nrf_drv_power_pof_init(nrf_drv_power_pofwarn_config_t const * p_confi
break;
default:
/* Cannot configure */
nrfx_power_pof_uninit();
return NRF_ERROR_INVALID_STATE;
}
ASSERT(sd_power_pof_threshold_set(thr));
err_code = sd_power_pof_threshold_set(thr);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
}
err_code = sd_power_pof_enable(true);
}
else
#endif /* SOFTDEVICE_PRESENT */
{
nrf_power_pofcon_set(true, p_config->thr);
#if NRF_POWER_HAS_VDDH
nrf_power_pofcon_vddh_set(p_config->thrvddh);
#endif
nrfx_power_pof_enable(p_config);
}
if (p_config->handler != NULL)
{
m_pofwarn_handler = p_config->handler;
#ifdef SOFTDEVICE_PRESENT
if (nrf_sdh_is_enabled())
{
(void) sd_power_pof_enable(true);
}
else
#endif
{
nrf_power_int_enable(NRF_POWER_INT_POFWARN_MASK);
}
}
return NRF_SUCCESS;
return err_code;
}
void nrf_drv_power_pof_uninit(void)
void nrf_drv_power_pof_uninit()
{
#ifdef SOFTDEVICE_PRESENT
if (nrf_sdh_is_enabled())
{
(void) sd_power_pof_enable(false);
ret_code_t err_code = sd_power_pof_enable(false);
ASSERT(err_code == NRF_SUCCESS);
UNUSED_VARIABLE(err_code); //handle no-debug case
}
else
#endif
{
nrf_power_int_disable(NRF_POWER_INT_POFWARN_MASK);
nrfx_power_pof_disable();
}
m_pofwarn_handler = NULL;
nrfx_power_pof_uninit();
}
#if NRF_POWER_HAS_SLEEPEVT
ret_code_t nrf_drv_power_sleepevt_init(nrf_drv_power_sleepevt_config_t const * p_config)
{
ASSERT(p_config != NULL);
nrf_drv_power_sleepevt_uninit();
if (p_config->handler != NULL)
{
uint32_t enmask = 0;
m_sleepevt_handler = p_config->handler;
if (p_config->en_enter)
{
enmask |= NRF_POWER_INT_SLEEPENTER_MASK;
nrf_power_event_clear(NRF_POWER_EVENT_SLEEPENTER);
}
if (p_config->en_exit)
{
enmask |= NRF_POWER_INT_SLEEPEXIT_MASK;
nrf_power_event_clear(NRF_POWER_EVENT_SLEEPEXIT);
}
#ifdef SOFTDEVICE_PRESENT
if (nrf_sdh_is_enabled())
{
if (enmask != 0)
if ((p_config->en_enter) || (p_config->en_exit))
{
return NRF_ERROR_INVALID_STATE;
}
@@ -269,11 +189,10 @@ ret_code_t nrf_drv_power_sleepevt_init(nrf_drv_power_sleepevt_config_t const * p
else
#endif
{
nrf_power_int_enable(enmask);
nrfx_power_sleepevt_enable(p_config);
}
}
return NRF_SUCCESS;
return NRF_SUCCESS;
}
void nrf_drv_power_sleepevt_uninit(void)
@@ -286,35 +205,71 @@ void nrf_drv_power_sleepevt_uninit(void)
else
#endif
{
nrf_power_int_disable(
NRF_POWER_INT_SLEEPENTER_MASK |
NRF_POWER_INT_SLEEPEXIT_MASK);
nrfx_power_sleepevt_disable();
}
m_sleepevt_handler = NULL;
nrfx_power_sleepevt_uninit();
}
#endif /* NRF_POWER_HAS_SLEEPEVT */
#if NRF_POWER_HAS_USBREG
#ifdef SOFTDEVICE_PRESENT
static ret_code_t nrf_drv_power_sd_usbevt_enable(bool enable)
{
ret_code_t err_code;
err_code = sd_power_usbdetected_enable(enable);
ASSERT(err_code == NRF_SUCCESS);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
err_code = sd_power_usbpwrrdy_enable(enable);
ASSERT(err_code == NRF_SUCCESS);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
err_code = sd_power_usbremoved_enable(enable);
ASSERT(err_code == NRF_SUCCESS);
return err_code;
}
#endif // SOFTDEVICE_PRESENT
ret_code_t nrf_drv_power_usbevt_init(nrf_drv_power_usbevt_config_t const * p_config)
{
nrf_drv_power_usbevt_uninit();
if (p_config->handler != NULL)
{
m_usbevt_handler = p_config->handler;
nrfx_power_usbevt_init(p_config);
#ifdef SOFTDEVICE_PRESENT
if (nrf_sdh_is_enabled())
if (nrf_sdh_is_enabled())
{
ret_code_t err_code = nrf_drv_power_sd_usbevt_enable(true);
ASSERT(err_code == NRF_SUCCESS);
if (err_code != NRF_SUCCESS)
{
/** @todo Implement USB power events when SD support it */
return NRF_ERROR_INVALID_STATE;
return err_code;
}
else
uint32_t regstatus;
err_code = sd_power_usbregstatus_get(&regstatus);
ASSERT(err_code == NRF_SUCCESS);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
if (regstatus & POWER_USBREGSTATUS_VBUSDETECT_Msk)
{
nrfx_power_usb_event_handler_t usbevt_handler = nrfx_power_usb_handler_get();
ASSERT(usbevt_handler != NULL);
usbevt_handler(NRFX_POWER_USB_EVT_DETECTED);
}
}
else
#endif
{
nrf_power_int_enable(
NRF_POWER_INT_USBDETECTED_MASK |
NRF_POWER_INT_USBREMOVED_MASK |
NRF_POWER_INT_USBPWRRDY_MASK);
}
{
nrfx_power_usbevt_enable();
}
return NRF_SUCCESS;
}
@@ -322,86 +277,26 @@ ret_code_t nrf_drv_power_usbevt_init(nrf_drv_power_usbevt_config_t const * p_con
void nrf_drv_power_usbevt_uninit(void)
{
#ifdef SOFTDEVICE_PRESENT
CRITICAL_REGION_ENTER();
if (nrf_sdh_is_enabled())
{
/** @todo Implement USB power events when SD support it */
ret_code_t err_code = nrf_drv_power_sd_usbevt_enable(false);
ASSERT(err_code == NRF_SUCCESS);
UNUSED_VARIABLE(err_code);
}
else
#endif
{
nrf_power_int_disable(
NRF_POWER_INT_USBDETECTED_MASK |
NRF_POWER_INT_USBREMOVED_MASK |
NRF_POWER_INT_USBPWRRDY_MASK);
nrfx_power_usbevt_disable();
}
m_usbevt_handler = NULL;
#ifdef SOFTDEVICE_PRESENT
CRITICAL_REGION_EXIT();
#endif
nrfx_power_usbevt_uninit();
}
#endif /* NRF_POWER_HAS_USBREG */
/**
* @ingroup nrf_drv_power_internals
* @brief Interrupt handler
*
* POWER peripheral interrupt handler
*/
#if NRF_DRV_COMMON_POWER_CLOCK_ISR
void nrf_drv_power_onIRQ(void)
#else
void POWER_CLOCK_IRQHandler(void)
#endif
{
uint32_t enabled = nrf_power_int_enable_get();
if ((0 != (enabled & NRF_POWER_INT_POFWARN_MASK)) &&
nrf_power_event_get_and_clear(NRF_POWER_EVENT_POFWARN))
{
/* Cannot be null if event is enabled */
ASSERT(m_pofwarn_handler != NULL);
m_pofwarn_handler();
}
#if NRF_POWER_HAS_SLEEPEVT
if ((0 != (enabled & NRF_POWER_INT_SLEEPENTER_MASK)) &&
nrf_power_event_get_and_clear(NRF_POWER_EVENT_SLEEPENTER))
{
/* Cannot be null if event is enabled */
ASSERT(m_sleepevt_handler != NULL);
m_sleepevt_handler(NRF_DRV_POWER_SLEEP_EVT_ENTER);
}
if ((0 != (enabled & NRF_POWER_INT_SLEEPEXIT_MASK)) &&
nrf_power_event_get_and_clear(NRF_POWER_EVENT_SLEEPEXIT))
{
/* Cannot be null if event is enabled */
ASSERT(m_sleepevt_handler != NULL);
m_sleepevt_handler(NRF_DRV_POWER_SLEEP_EVT_EXIT);
}
#endif
#if NRF_POWER_HAS_USBREG
if ((0 != (enabled & NRF_POWER_INT_USBDETECTED_MASK)) &&
nrf_power_event_get_and_clear(NRF_POWER_EVENT_USBDETECTED))
{
/* Cannot be null if event is enabled */
ASSERT(m_usbevt_handler != NULL);
m_usbevt_handler(NRF_DRV_POWER_USB_EVT_DETECTED);
}
if ((0 != (enabled & NRF_POWER_INT_USBREMOVED_MASK)) &&
nrf_power_event_get_and_clear(NRF_POWER_EVENT_USBREMOVED))
{
/* Cannot be null if event is enabled */
ASSERT(m_usbevt_handler != NULL);
m_usbevt_handler(NRF_DRV_POWER_USB_EVT_REMOVED);
}
if ((0 != (enabled & NRF_POWER_INT_USBPWRRDY_MASK)) &&
nrf_power_event_get_and_clear(NRF_POWER_EVENT_USBPWRRDY))
{
/* Cannot be null if event is enabled */
ASSERT(m_usbevt_handler != NULL);
m_usbevt_handler(NRF_DRV_POWER_USB_EVT_READY);
}
#endif
}
#ifdef SOFTDEVICE_PRESENT
static void nrf_drv_power_sdh_soc_evt_handler(uint32_t evt_id, void * p_context);
static void nrf_drv_power_sdh_state_evt_handler(nrf_sdh_state_evt_t state, void * p_context);
@@ -418,34 +313,73 @@ static void nrf_drv_power_sdh_soc_evt_handler(uint32_t evt_id, void * p_context)
{
if (evt_id == NRF_EVT_POWER_FAILURE_WARNING)
{
nrfx_power_pofwarn_event_handler_t pofwarn_handler = nrfx_power_pof_handler_get();
/* Cannot be null if event is enabled */
ASSERT(m_pofwarn_handler != NULL);
m_pofwarn_handler();
ASSERT(pofwarn_handler != NULL);
pofwarn_handler();
}
#if NRF_POWER_HAS_USBREG
nrfx_power_usb_event_handler_t usbevt_handler = nrfx_power_usb_handler_get();
if (usbevt_handler != NULL)
{
switch (evt_id)
{
case NRF_EVT_POWER_USB_POWER_READY:
usbevt_handler(NRFX_POWER_USB_EVT_READY);
break;
case NRF_EVT_POWER_USB_DETECTED:
usbevt_handler(NRFX_POWER_USB_EVT_DETECTED);
break;
case NRF_EVT_POWER_USB_REMOVED:
usbevt_handler(NRFX_POWER_USB_EVT_REMOVED);
break;
default:
break;
}
}
#endif
}
static void nrf_drv_power_on_sd_enable(void)
{
ASSERT(m_initialized); /* This module has to be enabled first */
CRITICAL_REGION_ENTER();
if (m_pofwarn_handler != NULL)
if (nrfx_power_pof_handler_get() != NULL)
{
(void) sd_power_pof_enable(true);
ret_code_t err_code = sd_power_pof_enable(true);
ASSERT(err_code == NRF_SUCCESS);
UNUSED_VARIABLE(err_code); //handle no-debug case
}
CRITICAL_REGION_EXIT();
#if NRF_POWER_HAS_USBREG
if (nrfx_power_usb_handler_get() != NULL)
{
ret_code_t err_code = nrf_drv_power_sd_usbevt_enable(true);
ASSERT(err_code == NRF_SUCCESS);
UNUSED_VARIABLE(err_code); //handle no-debug case
}
#endif
}
static void nrf_drv_power_on_sd_disable(void)
{
/* Reinit interrupts */
ASSERT(m_initialized);
nrf_drv_common_irq_enable(POWER_CLOCK_IRQn, CLOCK_CONFIG_IRQ_PRIORITY);
if (m_pofwarn_handler != NULL)
NRFX_IRQ_PRIORITY_SET(POWER_CLOCK_IRQn, CLOCK_CONFIG_IRQ_PRIORITY);
NRFX_IRQ_ENABLE(POWER_CLOCK_IRQn);
if (nrfx_power_pof_handler_get() != NULL)
{
nrf_power_int_enable(NRF_POWER_INT_POFWARN_MASK);
}
#if NRF_POWER_HAS_USBREG
if (m_usbevt_handler != NULL)
if (nrfx_power_usb_handler_get() != NULL)
{
nrf_power_int_enable(
NRF_POWER_INT_USBDETECTED_MASK |
@@ -472,6 +406,6 @@ static void nrf_drv_power_sdh_state_evt_handler(nrf_sdh_state_evt_t state, void
}
}
#endif // SOFTDEVICE_PRESENT
#endif /* NRF_MODULE_ENABLED(POWER) */
#endif // SOFTDEVICE_PRESENT
+61 -200
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2017 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -41,189 +41,75 @@
#ifndef NRF_DRV_POWER_H__
#define NRF_DRV_POWER_H__
#include <stdbool.h>
#include <stdint.h>
#include "nrf_power.h"
#include "sdk_config.h"
#include "nrf_drv_common.h"
#include <nrfx_power.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_power Power HAL and driver
* @ingroup nrf_drivers
* @brief POWER peripheral APIs.
*
* The power peripheral HAL provides basic APIs for accessing
* the registers of the POWER peripheral.
* The POWER driver provides APIs on a higher level.
*/
/**
* @defgroup nrf_drv_power POWER driver
* @defgroup nrf_drv_power POWER driver - legacy layer
* @{
* @ingroup nrf_power
* @brief Driver for managing events and the state of POWER peripheral.
* @ingroup nrf_power
*
* @brief Layer providing compatibility with the former API.
*/
/**
* @brief Power mode possible configurations
*/
typedef enum
{
NRF_DRV_POWER_MODE_CONSTLAT, /**< Constant latency mode *///!< NRF_DRV_POWER_MODE_CONSTLAT
NRF_DRV_POWER_MODE_LOWPWR /**< Low power mode *///!< NRF_DRV_POWER_MODE_LOWPWR
}nrf_drv_power_mode_t;
#if NRF_POWER_HAS_SLEEPEVT
/**
* @brief Events from power system
*/
typedef enum
{
NRF_DRV_POWER_SLEEP_EVT_ENTER, /**< CPU entered WFI/WFE sleep
*
* Keep in mind that if this interrupt is enabled,
* it means that CPU was waken up just after WFI by this interrupt.
*/
NRF_DRV_POWER_SLEEP_EVT_EXIT /**< CPU exited WFI/WFE sleep */
}nrf_drv_power_sleep_evt_t;
#endif /* NRF_POWER_HAS_SLEEPEVT */
#if NRF_POWER_HAS_USBREG
/**
* @brief Events from USB power system
*/
typedef enum
{
NRF_DRV_POWER_USB_EVT_DETECTED, /**< USB power detected on the connector (plugged in). */
NRF_DRV_POWER_USB_EVT_REMOVED, /**< USB power removed from the connector. */
NRF_DRV_POWER_USB_EVT_READY /**< USB power regulator ready. */
}nrf_drv_power_usb_evt_t;
/**
* @brief USB power state
*
* The single enumerator that holds all data about current state of USB
* related POWER.
*
* Organized this way that higher power state has higher numeric value
*/
typedef enum
{
NRF_DRV_POWER_USB_STATE_DISCONNECTED, /**< No power on USB lines detected */
NRF_DRV_POWER_USB_STATE_CONNECTED, /**< The USB power is detected, but USB power regulator is not ready */
NRF_DRV_POWER_USB_STATE_READY /**< From the power point of view USB is ready for working */
}nrf_drv_power_usb_state_t;
#endif /* NRF_POWER_HAS_USBREG */
/**
* @name Callback types
*
* Defined types of callback functions
* @{
*/
/**
* @brief Event handler for power failure warning
*/
typedef void (*nrf_drv_power_pofwarn_event_handler_t)(void);
#if NRF_POWER_HAS_SLEEPEVT
/**
* @brief Event handler for entering/exiting sleep
*
* @param event Event type
*/
typedef void (*nrf_drv_power_sleep_event_handler_t)(nrf_drv_power_sleep_evt_t event);
/** @brief Type definition for forwarding the new implementation. */
typedef nrfx_power_config_t nrf_drv_power_config_t;
/** @brief Type definition for forwarding the new implementation. */
typedef nrfx_power_pofwarn_config_t nrf_drv_power_pofwarn_config_t;
#if NRF_POWER_HAS_SLEEPEVT || defined(__SDK_DOXYGEN__)
/** @brief Type definition for forwarding the new implementation. */
typedef nrfx_power_sleepevt_config_t nrf_drv_power_sleepevt_config_t;
#endif
#if NRF_POWER_HAS_USBREG || defined(__SDK_DOXYGEN__)
/** @brief Type definition for forwarding the new implementation. */
typedef nrfx_power_usbevt_config_t nrf_drv_power_usbevt_config_t;
#endif
#if NRF_POWER_HAS_USBREG
/**
* @brief Event handler for USB related power events
*
* @param event Event type
*/
typedef void (*nrf_drv_power_usb_event_handler_t)(nrf_drv_power_usb_evt_t event);
#endif
/** @} */
/** @brief Macro for forwarding the new implementation. */
#define NRF_DRV_POWER_MODE_CONSTLAT NRFX_POWER_MODE_CONSTLAT
/** @brief Macro for forwarding the new implementation. */
#define NRF_DRV_POWER_MODE_LOWPWR NRFX_POWER_MODE_LOWPWR
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_power_mode_t nrfx_power_mode_t
/** @brief Macro for forwarding the new implementation. */
#define NRF_DRV_POWER_SLEEP_EVT_ENTER NRFX_POWER_SLEEP_EVT_ENTER
/** @brief Macro for forwarding the new implementation. */
#define NRF_DRV_POWER_SLEEP_EVT_EXIT NRFX_POWER_SLEEP_EVT_EXIT
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_power_sleep_evt_t nrfx_power_sleep_evt_t
/** @brief Macro for forwarding the new implementation. */
#define NRF_DRV_POWER_USB_EVT_DETECTED NRFX_POWER_USB_EVT_DETECTED
/** @brief Macro for forwarding the new implementation. */
#define NRF_DRV_POWER_USB_EVT_REMOVED NRFX_POWER_USB_EVT_REMOVED
/** @brief Macro for forwarding the new implementation. */
#define NRF_DRV_POWER_USB_EVT_READY NRFX_POWER_USB_EVT_READY
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_power_usb_evt_t nrfx_power_usb_evt_t
/** @brief Macro for forwarding the new implementation. */
#define NRF_DRV_POWER_USB_STATE_DISCONNECTED NRFX_POWER_USB_STATE_DISCONNECTED
/** @brief Macro for forwarding the new implementation. */
#define NRF_DRV_POWER_USB_STATE_CONNECTED NRFX_POWER_USB_STATE_CONNECTED
/** @brief Macro for forwarding the new implementation. */
#define NRF_DRV_POWER_USB_STATE_READY NRFX_POWER_USB_STATE_READY
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_power_usb_state_t nrfx_power_usb_state_t
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_power_pofwarn_event_handler_t nrfx_power_pofwarn_event_handler_t
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_power_sleep_event_handler_t nrfx_power_sleep_event_handler_t
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_power_usb_event_handler_t nrfx_power_usb_event_handler_t
/**
* @brief General power configuration
*
* Parameters required to initialize power driver.
*/
typedef struct
{
/**
* @brief Enable main DCDC regulator
*
* This bit only informs the driver that elements for DCDC regulator
* are installed and regulator can be used.
* The regulator would be enabled or disabled automatically
* automatically by the hardware, basing on current power requirement.
*/
bool dcdcen:1;
#if NRF_POWER_HAS_VDDH
/**
* @brief Enable HV DCDC regulator
*
* This bit only informs the driver that elements for DCDC regulator
* are installed and regulator can be used.
* The regulator would be enabled or disabled automatically
* automatically by the hardware, basing on current power requirement.
*/
bool dcdcenhv: 1;
#endif
}nrf_drv_power_config_t;
/**
* @brief The configuration for power failure comparator
*
* Configuration used to enable and configure power failure comparator
*/
typedef struct
{
nrf_drv_power_pofwarn_event_handler_t handler; //!< Event handler
nrf_power_pof_thr_t thr; //!< Threshold for power failure detection
#if NRF_POWER_HAS_VDDH
nrf_power_pof_thrvddh_t thrvddh; //!< Threshold for power failure detection on VDDH pin
#endif
}nrf_drv_power_pofwarn_config_t;
#if NRF_POWER_HAS_SLEEPEVT
/**
* @brief The configuration of sleep event processing
*
* Configuration used to enable and configure sleep event handling
*/
typedef struct
{
nrf_drv_power_sleep_event_handler_t handler; //!< Event handler
bool en_enter:1; //!< Enable event on sleep entering
bool en_exit :1; //!< Enable event on sleep exiting
}nrf_drv_power_sleepevt_config_t;
#endif
#if NRF_POWER_HAS_USBREG
/**
* @brief The configuration of USB related power events
*
* Configuration used to enable and configure USB power event handling
*/
typedef struct
{
nrf_drv_power_usb_event_handler_t handler; //!< Event processing
}nrf_drv_power_usbevt_config_t;
#endif /* NRF_POWER_HAS_USBREG */
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_power_usbstatus_get nrfx_power_usbstatus_get
/**
* @brief Function for checking if driver is already initialized
*
* This function is used to check whatever common POWER_CLOCK common interrupt
* This function is used to check whether common POWER_CLOCK interrupt
* should be disabled or not if @ref nrf_drv_clock tries to disable the interrupt.
*
* @retval true Driver is initialized
@@ -279,7 +165,8 @@ ret_code_t nrf_drv_power_pof_init(nrf_drv_power_pofwarn_config_t const * p_confi
*/
void nrf_drv_power_pof_uninit(void);
#if NRF_POWER_HAS_SLEEPEVT
#if NRF_POWER_HAS_SLEEPEVT || defined(__SDK_DOXYGEN__)
/**
* @brief Initialize sleep entering and exiting events processing
*
@@ -306,9 +193,11 @@ ret_code_t nrf_drv_power_sleepevt_init(nrf_drv_power_sleepevt_config_t const * p
* @sa nrf_drv_power_sleepevt_init
*/
void nrf_drv_power_sleepevt_uninit(void);
#endif /* NRF_POWER_HAS_SLEEPEVT */
#if NRF_POWER_HAS_USBREG
#endif // NRF_POWER_HAS_SLEEPEVT || defined(__SDK_DOXYGEN__)
#if NRF_POWER_HAS_USBREG || defined(__SDK_DOXYGEN__)
/**
* @brief Initialize USB power event processing
*
@@ -332,40 +221,12 @@ ret_code_t nrf_drv_power_usbevt_init(nrf_drv_power_usbevt_config_t const * p_con
*/
void nrf_drv_power_usbevt_uninit(void);
/**
* @brief Get the status of USB power
*
* @return Current USB power status
*/
__STATIC_INLINE nrf_drv_power_usb_state_t nrf_drv_power_usbstatus_get(void);
#endif /* NRF_POWER_HAS_USBREG */
#endif // NRF_POWER_HAS_USBREG || defined(__SDK_DOXYGEN__)
/** @} */
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
#if NRF_POWER_HAS_USBREG
__STATIC_INLINE nrf_drv_power_usb_state_t nrf_drv_power_usbstatus_get(void)
{
uint32_t status = nrf_power_usbregstatus_get();
if (0 == (status & NRF_POWER_USBREGSTATUS_VBUSDETECT_MASK))
{
return NRF_DRV_POWER_USB_STATE_DISCONNECTED;
}
if (0 == (status & NRF_POWER_USBREGSTATUS_OUTPUTRDY_MASK))
{
return NRF_DRV_POWER_USB_STATE_CONNECTED;
}
return NRF_DRV_POWER_USB_STATE_READY;
}
#endif /* NRF_POWER_HAS_USBREG */
#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
#ifdef __cplusplus
}
#endif
#endif /* NRF_DRV_POWER_H__ */
#endif // NRF_DRV_POWER_H__
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -37,97 +37,44 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_DRV_SYSTICK_H__
#define NRF_DRV_SYSTICK_H__
#include <stdint.h>
#include <stdbool.h>
#include <nrfx_systick.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup nrf_systick SysTick HAL and driver
* @ingroup nrf_drivers
* @brief System Timer (SysTick) APIs
*
* The SysTick HAL provides basic APIs for accessing the registers of the system timer (SysTick).
* The SysTick driver provides APIs on a higher level.
*/
/**
* @defgroup nrf_drv_systick SysTick driver
* @defgroup nrf_drv_systick ARM(R) SysTick driver - legacy layer
* @{
* @ingroup nrf_systick
* @ingroup nrf_systick
*
* This library configures SysTick as a free-running timer.
* This timer is used to generate delays and pool for timeouts.
* Only relatively short timeouts are supported.
* The SysTick works on 64MHz and is 24-bits wide.
* It means that it overflows around 4 times per second and around 250&nbsp;ms
* would be the highest supported time in the library.
* But it would be really hard to detect if overflow was generated without
* using interrupts. For safely we would limit the maximum delay range by half.
* @brief Layer providing compatibility with the former API.
*/
/**
* @brief The value type that holds the SysTick state
*
* This variable is used to count the requested timeout.
* @sa nrf_drv_systick_get
*/
typedef struct {
uint32_t time; //!< Registered time value
}nrf_drv_systick_state_t;
/**
* @brief Configure and start the timer
*
* Function configures SysTick as a free-running timer without interrupt.
*/
void nrf_drv_systick_init(void);
/**
* @brief Get current SysTick state
*
* Function gets current state of the SysTick timer.
* It can be used to check time-out by @ref nrf_drv_systick_test.
*
* @param[out] p_state The pointer to the state variable to be filled
*/
void nrf_drv_systick_get(nrf_drv_systick_state_t * p_state);
/**
* @brief Test if specified time is up in relation to remembered state
*
* @param[in] p_state Remembered state set by @ref nrf_drv_systick_get
* @param[in] us Required time-out.
*
* @retval true If current time is higher than specified state plus given time-out.
* @retval false If current time is lower than specified state plus given time-out
*/
bool nrf_drv_systick_test(nrf_drv_systick_state_t const * p_state, uint32_t us);
/**
* @brief Blocking delay in CPU ticks
*
* @param[in] ticks Number of CPU ticks to delay.
*/
void nrf_drv_systick_delay_ticks(uint32_t ticks);
/**
* @brief Blocking delay in us
*
* @param[in] us Number of microseconds to delay.
*/
void nrf_drv_systick_delay_us(uint32_t us);
/**
* @brief Blocking delay in ms
*
* This delay function removes the limits of the highest possible delay value.
*
* @param[in] ms Number of milliseconds to delay.
*/
void nrf_drv_systick_delay_ms(uint32_t ms);
/** @brief Type definition for forwarding the new implementation. */
typedef nrfx_systick_state_t nrf_drv_systick_state_t;
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_systick_init nrfx_systick_init
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_systick_get nrfx_systick_get
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_systick_test nrfx_systick_test
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_systick_delay_ticks nrfx_systick_delay_ticks
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_systick_delay_us nrfx_systick_delay_us
/** @brief Macro for forwarding the new implementation. */
#define nrf_drv_systick_delay_ms nrfx_systick_delay_ms
/** @} */
#endif /* NRF_DRV_SYSTICK_H__ */
#ifdef __cplusplus
}
#endif
#endif // NRF_DRV_SYSTICK_H__
+249 -120
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -37,15 +37,12 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "sdk_common.h"
#if NRF_MODULE_ENABLED(USBD)
#include "sdk_config.h"
#if USBD_ENABLED
#include "nrf_drv_usbd.h"
#include "nrf.h"
#include "nordic_common.h"
#include "nrf_drv_common.h"
#include "nrf_atomic.h"
#include "nrf_delay.h"
#include "app_util_platform.h"
#include "nrf_drv_systick.h" /* Marker to delete when not required anymore: >> NRF_DRV_USBD_ERRATA_ENABLE << */
@@ -229,7 +226,7 @@ STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT7) == USBD_EPDATASTATUS_EPOUT7_Po
/**
* @brief Current driver state
*/
static nrf_drv_state_t m_drv_state = NRF_DRV_STATE_UNINITIALIZED;
static nrfx_drv_state_t m_drv_state = NRFX_DRV_STATE_UNINITIALIZED;
/**
* @brief Event handler for the library
@@ -490,11 +487,12 @@ bool nrf_drv_usbd_consumer(
nrf_drv_usbd_transfer_t * p_transfer = p_context;
ASSERT(ep_size >= data_size);
ASSERT((p_transfer->p_data.rx == NULL) ||
nrf_drv_is_in_RAM((const void*)(p_transfer->p_data.ptr)));
nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr)));
size_t size = p_transfer->size;
if (size < data_size)
{
NRF_LOG_DEBUG("consumer: buffer too small: r: %u, l: %u", data_size, size);
/* Buffer size to small */
p_next->size = 0;
p_next->p_data = p_transfer->p_data;
@@ -526,7 +524,7 @@ bool nrf_drv_usbd_feeder_ram(
size_t ep_size)
{
nrf_drv_usbd_transfer_t * p_transfer = p_context;
ASSERT(nrf_drv_is_in_RAM((const void*)(p_transfer->p_data.ptr)));
ASSERT(nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr)));
size_t tx_size = p_transfer->size;
if (tx_size > ep_size)
@@ -559,7 +557,7 @@ bool nrf_drv_usbd_feeder_ram_zlp(
size_t ep_size)
{
nrf_drv_usbd_transfer_t * p_transfer = p_context;
ASSERT(nrf_drv_is_in_RAM((const void*)(p_transfer->p_data.ptr)));
ASSERT(nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr)));
size_t tx_size = p_transfer->size;
if (tx_size > ep_size)
@@ -592,7 +590,7 @@ bool nrf_drv_usbd_feeder_flash(
size_t ep_size)
{
nrf_drv_usbd_transfer_t * p_transfer = p_context;
ASSERT(!nrf_drv_is_in_RAM((const void*)(p_transfer->p_data.ptr)));
ASSERT(!nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr)));
size_t tx_size = p_transfer->size;
void * p_buffer = nrf_drv_usbd_feeder_buffer_get();
@@ -630,7 +628,7 @@ bool nrf_drv_usbd_feeder_flash_zlp(
size_t ep_size)
{
nrf_drv_usbd_transfer_t * p_transfer = p_context;
ASSERT(!nrf_drv_is_in_RAM((const void*)(p_transfer->p_data.ptr)));
ASSERT(!nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr)));
size_t tx_size = p_transfer->size;
void * p_buffer = nrf_drv_usbd_feeder_buffer_get();
@@ -777,7 +775,7 @@ static inline void usbd_ep_abort(nrf_drv_usbd_ep_t ep)
if (NRF_USBD_EPOUT_CHECK(ep))
{
/* Host -> Device */
if ((~m_ep_dma_waiting) & (1U<<ep2bit(ep)))
if ((~m_ep_dma_waiting) & (1U << ep2bit(ep)))
{
/* If the bit in m_ep_dma_waiting in cleared - nothing would be
* processed inside transfer processing */
@@ -786,19 +784,19 @@ static inline void usbd_ep_abort(nrf_drv_usbd_ep_t ep)
else
{
p_state->handler.consumer = NULL;
m_ep_dma_waiting &= ~(1U<<ep2bit(ep));
m_ep_ready &= ~(1U<<ep2bit(ep));
m_ep_dma_waiting &= ~(1U << ep2bit(ep));
m_ep_ready &= ~(1U << ep2bit(ep));
}
/* Aborted */
p_state->status = NRF_USBD_EP_ABORTED;
}
else
{
if ((m_ep_dma_waiting | (~m_ep_ready)) & (1U<<ep2bit(ep)))
if ((m_ep_dma_waiting | (~m_ep_ready)) & (1U << ep2bit(ep)))
{
/* Device -> Host */
m_ep_dma_waiting &= ~(1U<<ep2bit(ep));
m_ep_ready |= 1U<<ep2bit(ep) ;
m_ep_dma_waiting &= ~(1U << ep2bit(ep));
m_ep_ready |= 1U << ep2bit(ep) ;
p_state->handler.feeder = NULL;
p_state->status = NRF_USBD_EP_ABORTED;
@@ -809,7 +807,7 @@ static inline void usbd_ep_abort(nrf_drv_usbd_ep_t ep)
CRITICAL_REGION_EXIT();
}
void usbd_drv_ep_abort(nrf_drv_usbd_ep_t ep)
void nrf_drv_usbd_ep_abort(nrf_drv_usbd_ep_t ep)
{
usbd_ep_abort(ep);
}
@@ -826,11 +824,14 @@ static void usbd_ep_abort_all(void)
while (0 != ep_waiting)
{
uint8_t bitpos = __CLZ(__RBIT(ep_waiting));
usbd_ep_abort(bit2ep(bitpos));
if(!NRF_USBD_EPISO_CHECK(bit2ep(bitpos)))
{
usbd_ep_abort(bit2ep(bitpos));
}
ep_waiting &= ~(1U << bitpos);
}
m_ep_ready = (((1U<<NRF_USBD_EPIN_CNT) - 1U) << USBD_EPIN_BITPOS_0);
m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << USBD_EPIN_BITPOS_0);
}
/**
@@ -855,7 +856,6 @@ static void ev_usbreset_handler(void)
{
m_bus_suspend = false;
m_last_setup_dir = NRF_DRV_USBD_EPOUT0;
usbd_ep_abort_all();
const nrf_drv_usbd_evt_t evt = {
.type = NRF_DRV_USBD_EVT_RESET
@@ -901,11 +901,16 @@ static inline void nrf_usbd_ep0in_dma_handler(void)
usbd_drv_ep_state_t * p_state = ep_state_access(ep);
if (NRF_USBD_EP_ABORTED == p_state->status)
{
/* Nothing to do - just ignore */
/* Clear transfer information just in case */
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
}
else if (p_state->handler.feeder == NULL)
{
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<<ep2bit(ep))));
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
}
else
{
/* Nothing to do */
}
}
@@ -930,11 +935,16 @@ static inline void nrf_usbd_epin_dma_handler(nrf_drv_usbd_ep_t ep)
usbd_drv_ep_state_t * p_state = ep_state_access(ep);
if (NRF_USBD_EP_ABORTED == p_state->status)
{
/* Nothing to do - just ignore */
/* Clear transfer information just in case */
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
}
else if (p_state->handler.feeder == NULL)
{
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<<ep2bit(ep))));
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
}
else
{
/* Nothing to do */
}
}
@@ -956,15 +966,20 @@ static inline void nrf_usbd_epiniso_dma_handler(nrf_drv_usbd_ep_t ep)
usbd_drv_ep_state_t * p_state = ep_state_access(ep);
if (NRF_USBD_EP_ABORTED == p_state->status)
{
/* Nothing to do - just ignore */
/* Clear transfer information just in case */
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
}
else if (p_state->handler.feeder == NULL)
{
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<<ep2bit(ep))));
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
/* Send event to the user - for an ISO IN endpoint, the whole transfer is finished in this moment */
NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK);
m_event_handler(&evt);
}
else
{
/* Nothing to do */
}
}
/**
@@ -982,18 +997,20 @@ static inline void nrf_usbd_ep0out_dma_handler(void)
usbd_drv_ep_state_t * p_state = ep_state_access(ep);
if (NRF_USBD_EP_ABORTED == p_state->status)
{
/* Nothing to do - just ignore */
/* Clear transfer information just in case */
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
}
else if (p_state->handler.consumer == NULL)
{
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<<ep2bit(ep))));
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
/* Send event to the user - for an OUT endpoint, the whole transfer is finished in this moment */
NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK);
m_event_handler(&evt);
return;
}
nrf_drv_usbd_setup_data_clear();
else
{
nrf_drv_usbd_setup_data_clear();
}
}
/**
@@ -1015,15 +1032,20 @@ static inline void nrf_usbd_epout_dma_handler(nrf_drv_usbd_ep_t ep)
usbd_drv_ep_state_t * p_state = ep_state_access(ep);
if (NRF_USBD_EP_ABORTED == p_state->status)
{
/* Nothing to do - just ignore */
/* Clear transfer information just in case */
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
}
else if (p_state->handler.consumer == NULL)
{
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<<ep2bit(ep))));
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
/* Send event to the user - for an OUT endpoint, the whole transfer is finished in this moment */
NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK);
m_event_handler(&evt);
}
else
{
/* Nothing to do */
}
#if NRF_DRV_USBD_EARLY_DMA_PROCESS
/* Speed up */
@@ -1054,11 +1076,15 @@ static inline void nrf_usbd_epoutiso_dma_handler(nrf_drv_usbd_ep_t ep)
}
else if (p_state->handler.consumer == NULL)
{
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<<ep2bit(ep))));
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
/* Send event to the user - for an OUT endpoint, the whole transfer is finished in this moment */
NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK);
m_event_handler(&evt);
}
else
{
/* Nothing to do */
}
}
@@ -1108,12 +1134,12 @@ static void usbd_ep_data_handler(nrf_drv_usbd_ep_t ep, uint8_t bitpos)
{
NRF_LOG_DEBUG("USBD event: EndpointData: %x", ep);
/* Mark endpoint ready for next DMA access */
m_ep_ready |= (1U<<bitpos);
m_ep_ready |= (1U << bitpos);
if (NRF_USBD_EPIN_CHECK(ep))
{
/* IN endpoint (Device -> Host) */
if (0 == (m_ep_dma_waiting & (1U<<bitpos)))
if (0 == (m_ep_dma_waiting & (1U << bitpos)))
{
NRF_LOG_DEBUG("USBD event: EndpointData: In finished");
/* No more data to be send - transmission finished */
@@ -1124,7 +1150,7 @@ static void usbd_ep_data_handler(nrf_drv_usbd_ep_t ep, uint8_t bitpos)
else
{
/* OUT endpoint (Host -> Device) */
if (0 == (m_ep_dma_waiting & (1U<<bitpos)))
if (0 == (m_ep_dma_waiting & (1U << bitpos)))
{
NRF_LOG_DEBUG("USBD event: EndpointData: Out waiting");
/* No buffer prepared - send event to the application */
@@ -1163,8 +1189,8 @@ static void ev_setup_handler(void)
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(
&m_ep_dma_waiting,
~((1U<<ep2bit(NRF_DRV_USBD_EPOUT0)) | (1U<<ep2bit(NRF_DRV_USBD_EPIN0)))));
m_ep_ready |= 1U<<ep2bit(NRF_DRV_USBD_EPIN0);
~((1U << ep2bit(NRF_DRV_USBD_EPOUT0)) | (1U << ep2bit(NRF_DRV_USBD_EPIN0)))));
m_ep_ready |= 1U << ep2bit(NRF_DRV_USBD_EPIN0);
const nrf_drv_usbd_evt_t evt = {
@@ -1222,9 +1248,9 @@ static void ev_epdata_handler(void)
if (nrf_drv_usbd_errata_104())
{
dataepstatus |= (m_simulated_dataepstatus &
~((1U<<USBD_EPOUT_BITPOS_0) | (1U<<USBD_EPIN_BITPOS_0)));
~((1U << USBD_EPOUT_BITPOS_0) | (1U << USBD_EPIN_BITPOS_0)));
m_simulated_dataepstatus &=
((1U<<USBD_EPOUT_BITPOS_0) | (1U<<USBD_EPIN_BITPOS_0));
((1U << USBD_EPOUT_BITPOS_0) | (1U << USBD_EPIN_BITPOS_0));
}
NRF_LOG_DEBUG("USBD event: EndpointEPStatus: %x", dataepstatus);
@@ -1244,13 +1270,6 @@ static void ev_epdata_handler(void)
}
}
static void ev_accessfault_handler(void)
{
/** @todo RK Currently do nothing about it.
* Implement it when accessfault would be better documented */
// ASSERT(0);
}
/**
* @brief Function to select the endpoint to start
*
@@ -1266,7 +1285,8 @@ static void ev_accessfault_handler(void)
*/
static uint8_t usbd_dma_scheduler_algorithm(uint32_t req)
{
/** @todo RK This is just simple algorithm for testing and should be updated */
/* Only prioritized scheduling mode is supported */
STATIC_ASSERT(USBD_CONFIG_DMASCHEDULER_MODE == NRF_DRV_USBD_DMASCHEDULER_PRIORITIZED);
return __CLZ(__RBIT(req));
}
@@ -1354,8 +1374,9 @@ static void usbd_dmareq_process(void)
}
else if (transfer.size < rx_size)
{
NRF_LOG_DEBUG("Endpoint %x overload (r: %u, e: %u)", ep, rx_size, transfer.size);
p_state->status = NRF_USBD_EP_OVERLOAD;
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<<pos)));
UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << pos)));
NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OVERLOAD);
m_event_handler(&evt);
/* This endpoint will not be transmitted now, repeat the loop */
@@ -1474,8 +1495,7 @@ static const nrf_drv_usbd_isr_t m_isr[] =
[USBD_INTEN_SOF_Pos ] = ev_sof_handler,
[USBD_INTEN_USBEVENT_Pos ] = ev_usbevent_handler,
[USBD_INTEN_EP0SETUP_Pos ] = ev_setup_handler,
[USBD_INTEN_EPDATA_Pos ] = ev_epdata_handler,
[USBD_INTEN_ACCESSFAULT_Pos] = ev_accessfault_handler
[USBD_INTEN_EPDATA_Pos ] = ev_epdata_handler
};
/**
@@ -1493,7 +1513,7 @@ void USBD_IRQHandler(void)
while (to_process)
{
uint8_t event_nr = __CLZ(__RBIT(to_process));
if (nrf_usbd_event_get_and_clear((nrf_usbd_event_t)nrf_drv_bitpos_to_event(event_nr)))
if (nrf_usbd_event_get_and_clear((nrf_usbd_event_t)nrfx_bitpos_to_event(event_nr)))
{
active |= 1UL << event_nr;
}
@@ -1532,7 +1552,7 @@ void USBD_IRQHandler(void)
if (0 != uii)
{
uint8_t rb;
m_simulated_dataepstatus |= ((uint32_t)uii)<<USBD_EPIN_BITPOS_0;
m_simulated_dataepstatus |= ((uint32_t)uii) << USBD_EPIN_BITPOS_0;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7A9;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = uii;
rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
@@ -1544,7 +1564,7 @@ void USBD_IRQHandler(void)
if (0 != uoi)
{
uint8_t rb;
m_simulated_dataepstatus |= ((uint32_t)uoi)<<USBD_EPOUT_BITPOS_0;
m_simulated_dataepstatus |= ((uint32_t)uoi) << USBD_EPOUT_BITPOS_0;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AA;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = uoi;
rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
@@ -1571,17 +1591,17 @@ void USBD_IRQHandler(void)
}
if (0 != (m_simulated_dataepstatus &
~((1U<<USBD_EPOUT_BITPOS_0) | (1U<<USBD_EPIN_BITPOS_0))))
~((1U << USBD_EPOUT_BITPOS_0) | (1U << USBD_EPIN_BITPOS_0))))
{
active |= enabled & NRF_USBD_INT_DATAEP_MASK;
}
if (0 != (m_simulated_dataepstatus &
((1U<<USBD_EPOUT_BITPOS_0) | (1U<<USBD_EPIN_BITPOS_0))))
((1U << USBD_EPOUT_BITPOS_0) | (1U << USBD_EPIN_BITPOS_0))))
{
if (0 != (enabled & NRF_USBD_INT_EP0DATADONE_MASK))
{
m_simulated_dataepstatus &=
~((1U<<USBD_EPOUT_BITPOS_0) | (1U<<USBD_EPIN_BITPOS_0));
~((1U << USBD_EPOUT_BITPOS_0) | (1U << USBD_EPIN_BITPOS_0));
active |= NRF_USBD_INT_EP0DATADONE_MASK;
}
}
@@ -1619,13 +1639,13 @@ ret_code_t nrf_drv_usbd_init(nrf_drv_usbd_event_handler_t const event_handler)
{
return NRF_ERROR_INVALID_PARAM;
}
if ( m_drv_state != NRF_DRV_STATE_UNINITIALIZED)
if ( m_drv_state != NRFX_DRV_STATE_UNINITIALIZED)
{
return NRF_ERROR_INVALID_STATE;
}
m_event_handler = event_handler;
m_drv_state = NRF_DRV_STATE_INITIALIZED;
m_drv_state = NRFX_DRV_STATE_INITIALIZED;
uint8_t n;
for (n=0; n<NRF_USBD_EPIN_CNT; ++n)
@@ -1654,22 +1674,55 @@ ret_code_t nrf_drv_usbd_init(nrf_drv_usbd_event_handler_t const event_handler)
ret_code_t nrf_drv_usbd_uninit(void)
{
if (m_drv_state != NRF_DRV_STATE_INITIALIZED)
if (m_drv_state != NRFX_DRV_STATE_INITIALIZED)
{
return NRF_ERROR_INVALID_STATE;
}
m_event_handler = NULL;
m_drv_state = NRF_DRV_STATE_UNINITIALIZED;
m_drv_state = NRFX_DRV_STATE_UNINITIALIZED;
return NRF_SUCCESS;
}
void nrf_drv_usbd_enable(void)
{
ASSERT(m_drv_state == NRF_DRV_STATE_INITIALIZED);
ASSERT(m_drv_state == NRFX_DRV_STATE_INITIALIZED);
/* Prepare for READY event receiving */
nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK);
if (nrf_drv_usbd_errata_187())
{
CRITICAL_REGION_ENTER();
if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
{
*((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
*((volatile uint32_t *)(0x4006ED14)) = 0x00000003;
*((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
}
else
{
*((volatile uint32_t *)(0x4006ED14)) = 0x00000003;
}
CRITICAL_REGION_EXIT();
}
if (nrf_drv_usbd_errata_171())
{
CRITICAL_REGION_ENTER();
if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
{
*((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
*((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
*((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
}
else
{
*((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
}
CRITICAL_REGION_EXIT();
}
/* Enable the peripheral */
nrf_usbd_enable();
/* Waiting for peripheral to enable, this should take a few us */
@@ -1678,6 +1731,39 @@ void nrf_drv_usbd_enable(void)
/* Empty loop */
}
nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK);
if (nrf_drv_usbd_errata_171())
{
CRITICAL_REGION_ENTER();
if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
{
*((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
*((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
*((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
}
else
{
*((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
}
CRITICAL_REGION_EXIT();
}
if (nrf_drv_usbd_errata_187())
{
CRITICAL_REGION_ENTER();
if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
{
*((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
*((volatile uint32_t *)(0x4006ED14)) = 0x00000000;
*((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
}
else
{
*((volatile uint32_t *)(0x4006ED14)) = 0x00000000;
}
CRITICAL_REGION_EXIT();
}
if (nrf_drv_usbd_errata_166())
{
@@ -1689,17 +1775,17 @@ void nrf_drv_usbd_enable(void)
nrf_usbd_isosplit_set(NRF_USBD_ISOSPLIT_Half);
m_ep_ready = (((1U<<NRF_USBD_EPIN_CNT) - 1U) << USBD_EPIN_BITPOS_0);
m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << USBD_EPIN_BITPOS_0);
m_ep_dma_waiting = 0;
m_dma_pending = 0;
m_last_setup_dir = NRF_DRV_USBD_EPOUT0;
m_drv_state = NRF_DRV_STATE_POWERED_ON;
m_drv_state = NRFX_DRV_STATE_POWERED_ON;
}
void nrf_drv_usbd_disable(void)
{
ASSERT(m_drv_state != NRF_DRV_STATE_UNINITIALIZED);
ASSERT(m_drv_state != NRFX_DRV_STATE_UNINITIALIZED);
/* Stop just in case */
nrf_drv_usbd_stop();
@@ -1708,12 +1794,12 @@ void nrf_drv_usbd_disable(void)
nrf_usbd_int_disable(nrf_usbd_int_enable_get());
nrf_usbd_disable();
m_dma_pending = 0;
m_drv_state = NRF_DRV_STATE_INITIALIZED;
m_drv_state = NRFX_DRV_STATE_INITIALIZED;
}
void nrf_drv_usbd_start(bool enable_sof)
{
ASSERT(m_drv_state == NRF_DRV_STATE_POWERED_ON);
ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON);
m_bus_suspend = false;
uint32_t ints_to_enable =
@@ -1724,8 +1810,7 @@ void nrf_drv_usbd_start(bool enable_sof)
NRF_USBD_INT_ENDEPOUT0_MASK |
NRF_USBD_INT_USBEVENT_MASK |
NRF_USBD_INT_EP0SETUP_MASK |
NRF_USBD_INT_DATAEP_MASK |
NRF_USBD_INT_ACCESSFAULT_MASK;
NRF_USBD_INT_DATAEP_MASK;
if (enable_sof || nrf_drv_usbd_errata_104())
{
@@ -1736,7 +1821,8 @@ void nrf_drv_usbd_start(bool enable_sof)
nrf_usbd_int_enable(ints_to_enable);
/* Enable interrupt globally */
nrf_drv_common_irq_enable(USBD_IRQn, USBD_CONFIG_IRQ_PRIORITY);
NRFX_IRQ_PRIORITY_SET(USBD_IRQn, USBD_CONFIG_IRQ_PRIORITY);
NRFX_IRQ_ENABLE(USBD_IRQn);
/* Enable pullups */
nrf_usbd_pullup_enable();
@@ -1744,9 +1830,9 @@ void nrf_drv_usbd_start(bool enable_sof)
void nrf_drv_usbd_stop(void)
{
ASSERT(m_drv_state == NRF_DRV_STATE_POWERED_ON);
ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON);
if (nrf_drv_common_irq_enable_check(USBD_IRQn))
if(NRFX_IRQ_IS_ENABLED(USBD_IRQn))
{
/* Abort transfers */
usbd_ep_abort_all();
@@ -1755,7 +1841,7 @@ void nrf_drv_usbd_stop(void)
nrf_usbd_pullup_disable();
/* Disable interrupt globally */
nrf_drv_common_irq_disable(USBD_IRQn);
NRFX_IRQ_DISABLE(USBD_IRQn);
/* Disable all interrupts */
nrf_usbd_int_disable(~0U);
@@ -1764,17 +1850,17 @@ void nrf_drv_usbd_stop(void)
bool nrf_drv_usbd_is_initialized(void)
{
return (m_drv_state >= NRF_DRV_STATE_INITIALIZED);
return (m_drv_state >= NRFX_DRV_STATE_INITIALIZED);
}
bool nrf_drv_usbd_is_enabled(void)
{
return (m_drv_state >= NRF_DRV_STATE_POWERED_ON);
return (m_drv_state >= NRFX_DRV_STATE_POWERED_ON);
}
bool nrf_drv_usbd_is_started(void)
{
return (nrf_drv_usbd_is_enabled() && nrf_drv_common_irq_enable_check(USBD_IRQn));
return (nrf_drv_usbd_is_enabled() && NRFX_IRQ_IS_ENABLED(USBD_IRQn));
}
bool nrf_drv_usbd_suspend(void)
@@ -1796,6 +1882,20 @@ bool nrf_drv_usbd_suspend(void)
else
{
suspended = true;
if (nrf_drv_usbd_errata_171())
{
if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
{
*((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
*((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
*((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
}
else
{
*((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
}
}
}
}
}
@@ -1813,6 +1913,21 @@ bool nrf_drv_usbd_wakeup_req(void)
{
nrf_usbd_lowpower_disable();
started = true;
if (nrf_drv_usbd_errata_171())
{
if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
{
*((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
*((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
*((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
}
else
{
*((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
}
}
}
CRITICAL_REGION_EXIT();
@@ -1865,36 +1980,53 @@ bool nrf_drv_usbd_ep_enable_check(nrf_drv_usbd_ep_t ep)
void nrf_drv_usbd_ep_enable(nrf_drv_usbd_ep_t ep)
{
nrf_usbd_ep_enable(ep_to_hal(ep));
nrf_usbd_int_enable(nrf_drv_usbd_ep_to_int(ep));
if ((NRF_USBD_EP_NR_GET(ep) != 0) && NRF_USBD_EPOUT_CHECK(ep))
if(nrf_usbd_ep_enable_check(ep))
{
return;
}
nrf_usbd_ep_enable(ep_to_hal(ep));
if ((NRF_USBD_EP_NR_GET(ep) != 0) && NRF_USBD_EPOUT_CHECK(ep) && (!NRF_USBD_EPISO_CHECK(ep)))
{
CRITICAL_REGION_ENTER();
m_ep_ready |= 1U<<ep2bit(ep);
usbd_drv_ep_state_t * p_state = ep_state_access(ep);
if (!NRF_USBD_EPISO_CHECK(ep))
{
ret_code_t ret;
NRF_DRV_USBD_TRANSFER_OUT(transfer, 0, 0);
ret = nrf_drv_usbd_ep_transfer(ep, &transfer);
ASSERT(ret == NRF_SUCCESS);
UNUSED_VARIABLE(ret);
}
p_state->status = NRF_USBD_EP_ABORTED;
nrf_drv_usbd_transfer_out_drop(ep);
m_ep_dma_waiting &= ~(1U << ep2bit(ep));
CRITICAL_REGION_EXIT();
}
}
void nrf_drv_usbd_ep_disable(nrf_drv_usbd_ep_t ep)
{
usbd_ep_abort(ep);
nrf_usbd_ep_disable(ep_to_hal(ep));
nrf_usbd_int_disable(nrf_drv_usbd_ep_to_int(ep));
}
void nrf_drv_usbd_ep_default_config(void)
{
nrf_usbd_int_disable(
NRF_USBD_INT_ENDEPIN1_MASK |
NRF_USBD_INT_ENDEPIN2_MASK |
NRF_USBD_INT_ENDEPIN3_MASK |
NRF_USBD_INT_ENDEPIN4_MASK |
NRF_USBD_INT_ENDEPIN5_MASK |
NRF_USBD_INT_ENDEPIN6_MASK |
NRF_USBD_INT_ENDEPIN7_MASK |
NRF_USBD_INT_ENDISOIN0_MASK |
NRF_USBD_INT_ENDEPOUT1_MASK |
NRF_USBD_INT_ENDEPOUT2_MASK |
NRF_USBD_INT_ENDEPOUT3_MASK |
NRF_USBD_INT_ENDEPOUT4_MASK |
NRF_USBD_INT_ENDEPOUT5_MASK |
NRF_USBD_INT_ENDEPOUT6_MASK |
NRF_USBD_INT_ENDEPOUT7_MASK |
NRF_USBD_INT_ENDISOOUT0_MASK
);
nrf_usbd_int_enable(NRF_USBD_INT_ENDEPIN0_MASK | NRF_USBD_INT_ENDEPOUT0_MASK);
nrf_usbd_ep_all_disable();
}
ret_code_t nrf_drv_usbd_ep_transfer(
nrf_drv_usbd_ep_t ep,
nrf_drv_usbd_transfer_t const * const p_transfer)
@@ -1922,14 +2054,6 @@ ret_code_t nrf_drv_usbd_ep_transfer(
NRF_LOG_DEBUG("USB driver: Transfer failed: EP is busy");
}
}
else if (nrf_usbd_ep_is_stall(ep))
{
ret = NRF_ERROR_FORBIDDEN;
if (NRF_USBD_FAILED_TRANSFERS_DEBUG && (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))))
{
NRF_LOG_DEBUG("USB driver: Transfer failed: EP is stalled");
}
}
else
{
usbd_drv_ep_state_t * p_state = ep_state_access(ep);
@@ -1938,7 +2062,7 @@ ret_code_t nrf_drv_usbd_ep_transfer(
if (NRF_USBD_EPIN_CHECK(ep))
{
p_context = m_ep_feeder_state + NRF_USBD_EP_NR_GET(ep);
if (nrf_drv_is_in_RAM(p_transfer->p_data.tx))
if (nrfx_is_in_ram(p_transfer->p_data.tx))
{
/* RAM */
if (0 == (p_transfer->flags & NRF_DRV_USBD_TRANSFER_ZLP_FLAG))
@@ -1998,7 +2122,7 @@ ret_code_t nrf_drv_usbd_ep_transfer(
else
{
p_context = m_ep_consumer_state + NRF_USBD_EP_NR_GET(ep);
ASSERT((p_transfer->p_data.rx == NULL) || (nrf_drv_is_in_RAM(p_transfer->p_data.rx)));
ASSERT((p_transfer->p_data.rx == NULL) || (nrfx_is_in_ram(p_transfer->p_data.rx)));
p_state->handler.consumer = nrf_drv_usbd_consumer;
}
*p_context = *p_transfer;
@@ -2041,14 +2165,6 @@ ret_code_t nrf_drv_usbd_ep_handled_transfer(
NRF_LOG_DEBUG("USB driver: Transfer failed: EP is busy");\
}
}
else if (nrf_usbd_ep_is_stall(ep))
{
ret = NRF_ERROR_FORBIDDEN;
if (NRF_USBD_FAILED_TRANSFERS_DEBUG && (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))))
{
NRF_LOG_DEBUG("USB driver: Transfer failed: EP is stalled");
}
}
else
{
/* Transfer can be configured now */
@@ -2114,6 +2230,11 @@ bool nrf_drv_usbd_ep_stall_check(nrf_drv_usbd_ep_t ep)
return nrf_usbd_ep_is_stall(ep_to_hal(ep));
}
void nrf_drv_usbd_ep_dtoggle_clear(nrf_drv_usbd_ep_t ep)
{
nrf_usbd_dtoggle_set(ep, NRF_USBD_DTOGGLE_DATA0);
}
void nrf_drv_usbd_setup_get(nrf_drv_usbd_setup_t * const p_setup)
{
memset(p_setup, 0, sizeof(nrf_drv_usbd_setup_t));
@@ -2163,17 +2284,25 @@ void nrf_drv_usbd_transfer_out_drop(nrf_drv_usbd_ep_t ep)
{
ASSERT(NRF_USBD_EPOUT_CHECK(ep));
if (m_ep_ready & (1U << ep2bit(ep)))
if (nrf_drv_usbd_errata_sizeepout_rw())
{
CRITICAL_REGION_ENTER();
m_ep_ready &= ~(1U << ep2bit(ep));
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7C5 + (2u * NRF_USBD_EP_NR_GET(ep));
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0;
UNUSED_VARIABLE(((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
CRITICAL_REGION_EXIT();
}
else
{
CRITICAL_REGION_ENTER();
m_ep_ready &= ~(1U << ep2bit(ep));
if (!NRF_USBD_EPISO_CHECK(ep))
{
ret_code_t ret;
NRF_DRV_USBD_TRANSFER_OUT(transfer, 0, 0);
ret = nrf_drv_usbd_ep_transfer(ep, &transfer);
ASSERT(ret == NRF_SUCCESS);
UNUSED_VARIABLE(ret);
nrf_usbd_epout_clear(ep);
}
CRITICAL_REGION_EXIT();
}
}
#endif // USBD_ENABLED
#endif // NRF_MODULE_ENABLED(USBD)
+24 -3
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -41,7 +41,6 @@
#ifndef NRF_DRV_USBD_H__
#define NRF_DRV_USBD_H__
#include "nrf_drv_common.h"
#include "sdk_errors.h"
#include "nrf_usbd.h"
#include <stdint.h>
@@ -49,6 +48,10 @@
#include "app_util.h"
#include "nrf_drv_usbd_errata.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_drv_usbd USB Device HAL and driver
* @ingroup nrf_drivers
@@ -712,6 +715,13 @@ void nrf_drv_usbd_ep_enable(nrf_drv_usbd_ep_t ep);
*/
void nrf_drv_usbd_ep_disable(nrf_drv_usbd_ep_t ep);
/**
* @brief Disable all endpoints except for EP0
*
* Disable all endpoints that can be disabled in USB device while it is still active.
*/
void nrf_drv_usbd_ep_default_config(void);
/**
* @brief Start sending data over endpoint
*
@@ -855,6 +865,13 @@ void nrf_drv_usbd_ep_stall_clear(nrf_drv_usbd_ep_t ep);
*/
bool nrf_drv_usbd_ep_stall_check(nrf_drv_usbd_ep_t ep);
/**
* @brief Clear current endpoint data toggle
*
* @param ep Endpoint number to clear
*/
void nrf_drv_usbd_ep_dtoggle_clear(nrf_drv_usbd_ep_t ep);
/**
* @brief Get parsed setup data
*
@@ -902,7 +919,7 @@ void nrf_drv_usbd_setup_stall(void);
* @endcode
* This function would check it again, but it makes it inside critical section.
*/
void usbd_drv_ep_abort(nrf_drv_usbd_ep_t ep);
void nrf_drv_usbd_ep_abort(nrf_drv_usbd_ep_t ep);
/**
* @brief Get the information about expected transfer SETUP data direction
@@ -921,5 +938,9 @@ nrf_drv_usbd_ep_t nrf_drv_usbd_last_setup_dir_get(void);
*/
void nrf_drv_usbd_transfer_out_drop(nrf_drv_usbd_ep_t ep);
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* NRF_DRV_USBD_H__ */
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2017 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -61,6 +61,43 @@
#define NRF_DRV_USBD_ERRATA_ENABLE 1
#endif
/**
* @brief Internal auxiliary function to check if the program is running on NRF52840 chip
* @retval true It is NRF52480 chip
* @retval false It is other chip
*/
static inline bool nrf_drv_usbd_errata_type_52840(void)
{
return ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 0x08) &&
(((*(uint32_t *)0xF0000FE4) & 0x0F) == 0x0));
}
/**
* @brief Internal auxiliary function to check if the program is running on first sample of
* NRF52840 chip
* @retval true It is NRF52480 chip and it is first sample version
* @retval false It is other chip
*/
static inline bool nrf_drv_usbd_errata_type_52840_proto1(void)
{
return ( nrf_drv_usbd_errata_type_52840() &&
( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x00 ) &&
( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) );
}
/**
* @brief Internal auxiliary function to check if the program is running on first final product of
* NRF52840 chip
* @retval true It is NRF52480 chip and it is first final product
* @retval false It is other chip
*/
static inline bool nrf_drv_usbd_errata_type_52840_fp1(void)
{
return ( nrf_drv_usbd_errata_type_52840() &&
( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x10 ) &&
( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) );
}
/**
* @brief Function to check if chip requires errata 104
*
@@ -69,7 +106,10 @@
* @retval true Errata should be implemented
* @retval false Errata should not be implemented
*/
static inline bool nrf_drv_usbd_errata_104(void);
static inline bool nrf_drv_usbd_errata_104(void)
{
return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_proto1();
}
/**
* @brief Function to check if chip requires errata 154
@@ -79,55 +119,62 @@ static inline bool nrf_drv_usbd_errata_104(void);
* @retval true Errata should be implemented
* @retval false Errata should not be implemented
*/
static inline bool nrf_drv_usbd_errata_154(void);
#if NRF_DRV_USBD_ERRATA_ENABLE
static inline bool nrf_drv_usbd_errata_type_52840(void)
{
return ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 0x08) && (((*(uint32_t *)0xF0000FE4) & 0x0F) == 0x0));
}
static inline bool nrf_drv_usbd_errata_type_52840_proto1(void)
{
return ( nrf_drv_usbd_errata_type_52840() &&
( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x00 ) &&
( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) );
}
static inline bool nrf_drv_usbd_errata_104(void)
{
return nrf_drv_usbd_errata_type_52840_proto1();
}
static inline bool nrf_drv_usbd_errata_154(void)
{
return nrf_drv_usbd_errata_type_52840_proto1();
return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_proto1();
}
/**
* @brief Function to check if chip requires errata 166
*
* Errata: ISO double buffering not functional
*
* @retval true Errata should be implemented
* @retval false Errata should not be implemented
*/
static inline bool nrf_drv_usbd_errata_166(void)
{
return true;
return NRF_DRV_USBD_ERRATA_ENABLE && true;
}
#else /* NRF_DRV_USBD_ERRATA_ENABLE */
static inline bool nrf_drv_usbd_errata_104(void)
/**
* @brief Function to check if chip requires errata 171
*
* Errata: USBD might not reach its active state.
*
* @retval true Errata should be implemented
* @retval false Errata should not be implemented
*/
static inline bool nrf_drv_usbd_errata_171(void)
{
return false;
return NRF_DRV_USBD_ERRATA_ENABLE && true;
}
static inline bool nrf_drv_usbd_errata_154(void)
/**
* @brief Function to check if chip requires errata 187
*
* Errata: USB cannot be enabled
*
* @retval true Errata should be implemented
* @retval false Errata should not be implemented
*/
static inline bool nrf_drv_usbd_errata_187(void)
{
return false;
return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_fp1();
}
static inline bool nrf_drv_usbd_errata_166(void)
/**
* @brief Function to check if chip requires errata ???
*
* Errata: SIZE.EPOUT not writable
*
* @retval true Errata should be implemented
* @retval false Errata should not be implemented
*/
static inline bool nrf_drv_usbd_errata_sizeepout_rw(void)
{
return false;
return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_proto1();
}
#endif /* NRF_DRV_USBD_ERRATA_ENABLE */
/** @} */
#endif /* NRF_DRV_USBD_ERRATA_H__ */
@@ -0,0 +1,125 @@
/**
* Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/** @file
*
* @defgroup app_error Common application error handler
* @{
* @ingroup app_common
*
* @brief Common application error handler.
*/
#include "nrf.h"
#include <stdio.h>
#include "app_error.h"
#include "nordic_common.h"
#include "sdk_errors.h"
/**@brief Function for error handling, which is called when an error has occurred.
*
* @warning This handler is an example only and does not fit a final product. You need to analyze
* how your product is supposed to react in case of error.
*
* @param[in] error_code Error code supplied to the handler.
* @param[in] line_num Line number where the handler is called.
* @param[in] p_file_name Pointer to the file name.
*/
void app_error_handler_bare(ret_code_t error_code)
{
error_info_t error_info =
{
.line_num = 0,
.p_file_name = NULL,
.err_code = error_code,
};
app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
UNUSED_VARIABLE(error_info);
}
void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info)
{
/* static error variables - in order to prevent removal by optimizers */
static volatile struct
{
uint32_t fault_id;
uint32_t pc;
uint32_t error_info;
assert_info_t * p_assert_info;
error_info_t * p_error_info;
ret_code_t err_code;
uint32_t line_num;
const uint8_t * p_file_name;
} m_error_data = {0};
// The following variable helps Keil keep the call stack visible, in addition, it can be set to
// 0 in the debugger to continue executing code after the error check.
volatile bool loop = true;
UNUSED_VARIABLE(loop);
m_error_data.fault_id = id;
m_error_data.pc = pc;
m_error_data.error_info = info;
switch (id)
{
case NRF_FAULT_ID_SDK_ASSERT:
m_error_data.p_assert_info = (assert_info_t *)info;
m_error_data.line_num = m_error_data.p_assert_info->line_num;
m_error_data.p_file_name = m_error_data.p_assert_info->p_file_name;
break;
case NRF_FAULT_ID_SDK_ERROR:
m_error_data.p_error_info = (error_info_t *)info;
m_error_data.err_code = m_error_data.p_error_info->err_code;
m_error_data.line_num = m_error_data.p_error_info->line_num;
m_error_data.p_file_name = m_error_data.p_error_info->p_file_name;
break;
}
UNUSED_VARIABLE(m_error_data);
// If printing is disrupted, remove the irq calls, or set the loop variable to 0 in the debugger.
__disable_irq();
while (loop);
__enable_irq();
}
@@ -1,239 +1,192 @@
/**
* Copyright (c) 2013 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/** @file
*
* @defgroup app_error Common application error handler
* @{
* @ingroup app_common
*
* @brief Common application error handler and macros for utilizing a common error handler.
*/
#ifndef APP_ERROR_H__
#define APP_ERROR_H__
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include "nrf.h"
#include "sdk_errors.h"
#include "nordic_common.h"
#include "app_error_weak.h"
#ifdef ANT_STACK_SUPPORT_REQD
#include "ant_error.h"
#endif // ANT_STACK_SUPPORT_REQD
#ifdef __cplusplus
extern "C" {
#endif
#define NRF_FAULT_ID_SDK_RANGE_START 0x00004000 /**< The start of the range of error IDs defined in the SDK. */
/**@defgroup APP_ERROR_FAULT_IDS Fault ID types
* @{ */
#define NRF_FAULT_ID_SDK_ERROR NRF_FAULT_ID_SDK_RANGE_START + 1 /**< An error stemming from a call to @ref APP_ERROR_CHECK or @ref APP_ERROR_CHECK_BOOL. The info parameter is a pointer to an @ref error_info_t variable. */
#define NRF_FAULT_ID_SDK_ASSERT NRF_FAULT_ID_SDK_RANGE_START + 2 /**< An error stemming from a call to ASSERT (nrf_assert.h). The info parameter is a pointer to an @ref assert_info_t variable. */
/**@} */
/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ERROR.
*/
typedef struct
{
uint16_t line_num; /**< The line number where the error occurred. */
uint8_t const * p_file_name; /**< The file in which the error occurred. */
uint32_t err_code; /**< The error code representing the error that occurred. */
} error_info_t;
/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ASSERT.
*/
typedef struct
{
uint16_t line_num; /**< The line number where the error occurred. */
uint8_t const * p_file_name; /**< The file in which the error occurred. */
} assert_info_t;
/**@brief Function for error handling, which is called when an error has occurred.
*
* @param[in] error_code Error code supplied to the handler.
* @param[in] line_num Line number where the handler is called.
* @param[in] p_file_name Pointer to the file name.
*/
void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name);
/**@brief Function for error handling, which is called when an error has occurred.
*
* @param[in] error_code Error code supplied to the handler.
*/
void app_error_handler_bare(ret_code_t error_code);
/**@brief Function for saving the parameters and entering an eternal loop, for debug purposes.
*
* @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
* @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
* unavailable.
* @param[in] info Optional additional information regarding the fault. Refer to each fault
* identifier for details.
*/
void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info);
/**@brief Function for printing all error info (using nrf_log).
*
* @details Nrf_log library must be initialized using NRF_LOG_INIT macro before calling
* this function.
*
* @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
* @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
* unavailable.
* @param[in] info Optional additional information regarding the fault. Refer to each fault
* identifier for details.
*/
static __INLINE void app_error_log(uint32_t id, uint32_t pc, uint32_t info)
{
switch (id)
{
case NRF_FAULT_ID_SDK_ASSERT:
//NRF_LOG_INFO(NRF_LOG_COLOR_RED "\r\n*** ASSERTION FAILED ***\r\n");
if (((assert_info_t *)(info))->p_file_name)
{
// NRF_LOG_INFO(NRF_LOG_COLOR_WHITE "Line Number: %u\r\n", (unsigned int) ((assert_info_t *)(info))->line_num);
//NRF_LOG_INFO("File Name: %s\r\n", ((assert_info_t *)(info))->p_file_name);
}
//NRF_LOG_INFO(NRF_LOG_COLOR_DEFAULT "\r\n");
break;
case NRF_FAULT_ID_SDK_ERROR:
//NRF_LOG_INFO(NRF_LOG_COLOR_RED "\r\n*** APPLICATION ERROR *** \r\n" NRF_LOG_COLOR_WHITE);
if (((error_info_t *)(info))->p_file_name)
{
//NRF_LOG_INFO("Line Number: %u\r\n", (unsigned int) ((error_info_t *)(info))->line_num);
//NRF_LOG_INFO("File Name: %s\r\n", ((error_info_t *)(info))->p_file_name);
}
//NRF_LOG_INFO("Error Code: 0x%X\r\n" NRF_LOG_COLOR_DEFAULT "\r\n", (unsigned int) ((error_info_t *)(info))->err_code);
break;
}
}
/**@brief Function for printing all error info (using printf).
*
* @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
* @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
* unavailable.
* @param[in] info Optional additional information regarding the fault. Refer to each fault
* identifier for details.
*/
//lint -save -e438
static __INLINE void app_error_print(uint32_t id, uint32_t pc, uint32_t info)
{
unsigned int tmp = id;
printf("app_error_print():\r\n");
printf("Fault identifier: 0x%X\r\n", tmp);
printf("Program counter: 0x%X\r\n", tmp = pc);
printf("Fault information: 0x%X\r\n", tmp = info);
switch (id)
{
case NRF_FAULT_ID_SDK_ASSERT:
printf("Line Number: %u\r\n", tmp = ((assert_info_t *)(info))->line_num);
printf("File Name: %s\r\n", ((assert_info_t *)(info))->p_file_name);
break;
case NRF_FAULT_ID_SDK_ERROR:
printf("Line Number: %u\r\n", tmp = ((error_info_t *)(info))->line_num);
printf("File Name: %s\r\n", ((error_info_t *)(info))->p_file_name);
printf("Error Code: 0x%X\r\n", tmp = ((error_info_t *)(info))->err_code);
break;
}
}
//lint -restore
/**@brief Macro for calling error handler function.
*
* @param[in] ERR_CODE Error code supplied to the error handler.
*/
#ifdef DEBUG
#define APP_ERROR_HANDLER(ERR_CODE) \
do \
{ \
app_error_handler((ERR_CODE), __LINE__, (uint8_t*) __FILE__); \
} while (0)
#else
#define APP_ERROR_HANDLER(ERR_CODE) \
do \
{ \
app_error_handler_bare((ERR_CODE)); \
} while (0)
#endif
/**@brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS.
*
* @param[in] ERR_CODE Error code supplied to the error handler.
*/
#define APP_ERROR_CHECK(ERR_CODE) \
do \
{ \
const uint32_t LOCAL_ERR_CODE = (ERR_CODE); \
if (LOCAL_ERR_CODE != NRF_SUCCESS) \
{ \
APP_ERROR_HANDLER(LOCAL_ERR_CODE); \
} \
} while (0)
/**@brief Macro for calling error handler function if supplied boolean value is false.
*
* @param[in] BOOLEAN_VALUE Boolean value to be evaluated.
*/
#define APP_ERROR_CHECK_BOOL(BOOLEAN_VALUE) \
do \
{ \
const uint32_t LOCAL_BOOLEAN_VALUE = (BOOLEAN_VALUE); \
if (!LOCAL_BOOLEAN_VALUE) \
{ \
APP_ERROR_HANDLER(0); \
} \
} while (0)
#ifdef __cplusplus
}
#endif
#endif // APP_ERROR_H__
/** @} */
/**
* Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/** @file
*
* @defgroup app_error Common application error handler
* @{
* @ingroup app_common
*
* @brief Common application error handler and macros for utilizing a common error handler.
*/
#ifndef APP_ERROR_H__
#define APP_ERROR_H__
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include "nrf.h"
#include "sdk_errors.h"
#include "nordic_common.h"
#include "app_error_weak.h"
#ifdef ANT_STACK_SUPPORT_REQD
#include "ant_error.h"
#endif // ANT_STACK_SUPPORT_REQD
#ifdef __cplusplus
extern "C" {
#endif
#define NRF_FAULT_ID_SDK_RANGE_START (0x00004000) /**< The start of the range of error IDs defined in the SDK. */
/**@defgroup APP_ERROR_FAULT_IDS Fault ID types
* @{ */
#define NRF_FAULT_ID_SDK_ERROR (NRF_FAULT_ID_SDK_RANGE_START + 1) /**< An error stemming from a call to @ref APP_ERROR_CHECK or @ref APP_ERROR_CHECK_BOOL. The info parameter is a pointer to an @ref error_info_t variable. */
#define NRF_FAULT_ID_SDK_ASSERT (NRF_FAULT_ID_SDK_RANGE_START + 2) /**< An error stemming from a call to ASSERT (nrf_assert.h). The info parameter is a pointer to an @ref assert_info_t variable. */
/**@} */
/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ERROR.
*/
typedef struct
{
uint32_t line_num; /**< The line number where the error occurred. */
uint8_t const * p_file_name; /**< The file in which the error occurred. */
uint32_t err_code; /**< The error code representing the error that occurred. */
} error_info_t;
/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ASSERT.
*/
typedef struct
{
uint16_t line_num; /**< The line number where the error occurred. */
uint8_t const * p_file_name; /**< The file in which the error occurred. */
} assert_info_t;
/**@brief Defines required by app_error_handler assembler intructions.
*/
#define APP_ERROR_ERROR_INFO_OFFSET_LINE_NUM (offsetof(error_info_t, line_num))
#define APP_ERROR_ERROR_INFO_OFFSET_P_FILE_NAME (offsetof(error_info_t, p_file_name))
#define APP_ERROR_ERROR_INFO_OFFSET_ERR_CODE (offsetof(error_info_t, err_code))
#define APP_ERROR_ERROR_INFO_SIZE (sizeof(error_info_t))
#define APP_ERROR_ERROR_INFO_SIZE_ALIGNED_8BYTE \
ALIGN_NUM(APP_ERROR_ERROR_INFO_SIZE, sizeof(uint64_t))
/**@brief Function for error handling, which is called when an error has occurred.
*
* @param[in] error_code Error code supplied to the handler.
* @param[in] line_num Line number where the handler is called.
* @param[in] p_file_name Pointer to the file name.
*/
void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name);
/**@brief Function for error handling, which is called when an error has occurred.
*
* @param[in] error_code Error code supplied to the handler.
*/
void app_error_handler_bare(ret_code_t error_code);
/**@brief Function for saving the parameters and entering an eternal loop, for debug purposes.
*
* @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
* @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
* unavailable.
* @param[in] info Optional additional information regarding the fault. Refer to each fault
* identifier for details.
*/
void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info);
/**@brief Function for logging details of error and flushing logs.
*
* @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
* @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
* unavailable.
* @param[in] info Optional additional information regarding the fault. Refer to each fault
* identifier for details.
*/
void app_error_log_handle(uint32_t id, uint32_t pc, uint32_t info);
/**@brief Macro for calling error handler function.
*
* @param[in] ERR_CODE Error code supplied to the error handler.
*/
#ifdef DEBUG
#define APP_ERROR_HANDLER(ERR_CODE) \
do \
{ \
app_error_handler((ERR_CODE), __LINE__, (uint8_t*) __FILE__); \
} while (0)
#else
#define APP_ERROR_HANDLER(ERR_CODE) \
do \
{ \
app_error_handler_bare((ERR_CODE)); \
} while (0)
#endif
/**@brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS.
*
* @param[in] ERR_CODE Error code supplied to the error handler.
*/
#define APP_ERROR_CHECK(ERR_CODE) \
do \
{ \
const uint32_t LOCAL_ERR_CODE = (ERR_CODE); \
if (LOCAL_ERR_CODE != NRF_SUCCESS) \
{ \
APP_ERROR_HANDLER(LOCAL_ERR_CODE); \
} \
} while (0)
/**@brief Macro for calling error handler function if supplied boolean value is false.
*
* @param[in] BOOLEAN_VALUE Boolean value to be evaluated.
*/
#define APP_ERROR_CHECK_BOOL(BOOLEAN_VALUE) \
do \
{ \
const uint32_t LOCAL_BOOLEAN_VALUE = (BOOLEAN_VALUE); \
if (!LOCAL_BOOLEAN_VALUE) \
{ \
APP_ERROR_HANDLER(0); \
} \
} while (0)
#ifdef __cplusplus
}
#endif
#endif // APP_ERROR_H__
/** @} */
@@ -0,0 +1,59 @@
/**
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "app_error.h"
#include <assert.h>
/*lint -save -e14 */
/**
* Function is implemented as weak so that it can be overwritten by custom application error handler
* when needed.
*/
__WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
{
(void)id;
(void)pc;
(void)info;
#ifndef DEBUG
NVIC_SystemReset();
#else
assert(false);
#endif // DEBUG
}
/*lint -restore */
@@ -1,85 +1,87 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef APP_ERROR_WEAK_H__
#define APP_ERROR_WEAK_H__
#ifdef __cplusplus
extern "C" {
#endif
/** @file
*
* @defgroup app_error Common application error handler
* @{
* @ingroup app_common
*
* @brief Common application error handler.
*/
/**@brief Callback function for errors, asserts, and faults.
*
* @details This function is called every time an error is raised in app_error, nrf_assert, or
* in the SoftDevice. Information about the error can be found in the @p info
* parameter.
*
* See also @ref nrf_fault_handler_t for more details.
*
* @note The function is implemented as weak so that it can be redefined by a custom error
* handler when needed.
*
* @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
* @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
* unavailable.
* @param[in] info Optional additional information regarding the fault. The value of the @p id
* parameter dictates how to interpret this parameter. Refer to the documentation
* for each fault identifier (@ref NRF_FAULT_IDS and @ref APP_ERROR_FAULT_IDS) for
* details about interpreting @p info.
*/
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info);
/** @} */
#ifdef __cplusplus
}
#endif
#endif // APP_ERROR_WEAK_H__
/**
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef APP_ERROR_WEAK_H__
#define APP_ERROR_WEAK_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @file
*
* @defgroup app_error Common application error handler
* @{
* @ingroup app_common
*
* @brief Common application error handler.
*/
/**@brief Callback function for errors, asserts, and faults.
*
* @details This function is called every time an error is raised in app_error, nrf_assert, or
* in the SoftDevice. Information about the error can be found in the @p info
* parameter.
*
* See also @ref nrf_fault_handler_t for more details.
*
* @note The function is implemented as weak so that it can be redefined by a custom error
* handler when needed.
*
* @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
* @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
* unavailable.
* @param[in] info Optional additional information regarding the fault. The value of the @p id
* parameter dictates how to interpret this parameter. Refer to the documentation
* for each fault identifier (@ref NRF_FAULT_IDS and @ref APP_ERROR_FAULT_IDS) for
* details about interpreting @p info.
*/
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info);
/** @} */
#ifdef __cplusplus
}
#endif
#endif // APP_ERROR_WEAK_H__
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2011 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2011 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -43,6 +43,15 @@
#include "nrf_atfifo.h"
#include "nrf_atfifo_internal.h"
#if NRF_ATFIFO_CONFIG_LOG_ENABLED
#define NRF_LOG_LEVEL NRF_ATFIFO_CONFIG_LOG_LEVEL
#define NRF_LOG_INIT_FILTER_LEVEL NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL
#define NRF_LOG_INFO_COLOR NRF_ATFIFO_CONFIG_INFO_COLOR
#define NRF_LOG_DEBUG_COLOR NRF_ATFIFO_CONFIG_DEBUG_COLOR
#else
#define NRF_LOG_LEVEL 0
#endif // NRF_ATFIFO_CONFIG_LOG_ENABLED
#include "nrf_log.h"
/* Unions testing */
STATIC_ASSERT(sizeof(nrf_atfifo_postag_t) == sizeof(uint32_t));
@@ -52,10 +61,12 @@ ret_code_t nrf_atfifo_init(nrf_atfifo_t * const p_fifo, void * p_buf, uint16_t b
{
if (NULL == p_buf)
{
NRF_LOG_INST_ERROR(p_fifo->p_log, "Initialization failed. p_buf == NULL");
return NRF_ERROR_NULL;
}
if (0 != (buf_size % item_size))
{
NRF_LOG_INST_ERROR(p_fifo->p_log, "Initialization failed. Buf_size not multiple of item_size");
return NRF_ERROR_INVALID_LENGTH;
}
@@ -65,6 +76,7 @@ ret_code_t nrf_atfifo_init(nrf_atfifo_t * const p_fifo, void * p_buf, uint16_t b
p_fifo->buf_size = buf_size;
p_fifo->item_size = item_size;
NRF_LOG_INST_INFO(p_fifo->p_log, "Initialized.");
return NRF_SUCCESS;
}
@@ -72,6 +84,7 @@ ret_code_t nrf_atfifo_init(nrf_atfifo_t * const p_fifo, void * p_buf, uint16_t b
ret_code_t nrf_atfifo_clear(nrf_atfifo_t * const p_fifo)
{
bool released = nrf_atfifo_space_clear(p_fifo);
NRF_LOG_INST_INFO(p_fifo->p_log, "Cleared result:%s", released ? "success" : "busy");
return released ? NRF_SUCCESS : NRF_ERROR_BUSY;
}
@@ -83,6 +96,7 @@ ret_code_t nrf_atfifo_alloc_put(nrf_atfifo_t * const p_fifo, void const * p_var,
void * p_data = nrf_atfifo_item_alloc(p_fifo, &context);
if (NULL == p_data)
{
NRF_LOG_INST_WARNING(p_fifo->p_log, "Copying in element (0x%08X) failed - no space.", p_var);
return NRF_ERROR_NO_MEM;
}
@@ -93,6 +107,7 @@ ret_code_t nrf_atfifo_alloc_put(nrf_atfifo_t * const p_fifo, void const * p_var,
{
*p_visible = visible;
}
NRF_LOG_INST_DEBUG(p_fifo->p_log, "Element (0x%08X) copied in.", p_var);
return NRF_SUCCESS;
}
@@ -101,8 +116,11 @@ void * nrf_atfifo_item_alloc(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t
{
if (nrf_atfifo_wspace_req(p_fifo, &(p_context->last_tail)))
{
return ((uint8_t*)(p_fifo->p_buf)) + p_context->last_tail.pos.wr;
void * p_item = ((uint8_t*)(p_fifo->p_buf)) + p_context->last_tail.pos.wr;
NRF_LOG_INST_DEBUG(p_fifo->p_log, "Allocated element (0x%08X).", p_item);
return p_item;
}
NRF_LOG_INST_WARNING(p_fifo->p_log, "Allocation failed - no space.");
return NULL;
}
@@ -111,9 +129,11 @@ bool nrf_atfifo_item_put(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t * p_
{
if ((p_context->last_tail.pos.wr) == (p_context->last_tail.pos.rd))
{
NRF_LOG_INST_DEBUG(p_fifo->p_log, "Put (uninterrupted)");
nrf_atfifo_wspace_close(p_fifo);
return true;
}
NRF_LOG_INST_DEBUG(p_fifo->p_log, "Put (interrupted!)");
return false;
}
@@ -125,6 +145,7 @@ ret_code_t nrf_atfifo_get_free(nrf_atfifo_t * const p_fifo, void * const p_var,
void const * p_s = nrf_atfifo_item_get(p_fifo, &context);
if (NULL == p_s)
{
NRF_LOG_INST_WARNING(p_fifo->p_log, "Copying out failed - no item in the FIFO.");
return NRF_ERROR_NOT_FOUND;
}
@@ -135,16 +156,20 @@ ret_code_t nrf_atfifo_get_free(nrf_atfifo_t * const p_fifo, void * const p_var,
{
*p_released = released;
}
NRF_LOG_INST_DEBUG(p_fifo->p_log, "Element (0x%08X) copied out.", p_var);
return NRF_SUCCESS;
}
void const * nrf_atfifo_item_get(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context)
void * nrf_atfifo_item_get(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context)
{
if (nrf_atfifo_rspace_req(p_fifo, &(p_context->last_head)))
{
return ((uint8_t*)(p_fifo->p_buf)) + p_context->last_head.pos.rd;
void * p_item = ((uint8_t*)(p_fifo->p_buf)) + p_context->last_head.pos.rd;
NRF_LOG_INST_DEBUG(p_fifo->p_log, "Get element: 0x%08X", p_item);
return p_item;
}
NRF_LOG_INST_WARNING(p_fifo->p_log, "Get failed - no item in the FIFO.");
return NULL;
}
@@ -153,8 +178,10 @@ bool nrf_atfifo_item_free(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p
{
if ((p_context->last_head.pos.wr) == (p_context->last_head.pos.rd))
{
NRF_LOG_INST_DEBUG(p_fifo->p_log, "Free (uninterrupted)");
nrf_atfifo_rspace_close(p_fifo);
return true;
}
NRF_LOG_INST_DEBUG(p_fifo->p_log, "Free (interrupted)");
return false;
}
+25 -11
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2011 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2011 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -41,10 +41,11 @@
#define NRF_ATFIFO_H__
#include <stdint.h>
#include "sdk_config.h"
#include "nordic_common.h"
#include "nrf_assert.h"
#include "sdk_errors.h"
#include "nrf_log_instance.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -134,11 +135,12 @@ typedef union nrf_atfifo_postag_u
*/
typedef struct nrf_atfifo_s
{
void * p_buf; //!< Pointer to the data buffer
nrf_atfifo_postag_t tail; //!< Read and write tail position tag
nrf_atfifo_postag_t head; //!< Read and write head position tag
uint16_t buf_size; //!< FIFO size in number of bytes (has to be divisible by @c item_size)
uint16_t item_size; //!< Size of a single FIFO item
void * p_buf; //!< Pointer to the data buffer
nrf_atfifo_postag_t tail; //!< Read and write tail position tag
nrf_atfifo_postag_t head; //!< Read and write head position tag
uint16_t buf_size; //!< FIFO size in number of bytes (has to be divisible by @c item_size)
uint16_t item_size; //!< Size of a single FIFO item
NRF_LOG_INSTANCE_PTR_DECLARE(p_log) //!< Pointer to instance of the logger object (Conditionally compiled).
}nrf_atfifo_t;
/**
@@ -164,6 +166,10 @@ typedef struct nrf_atfifo_rcontext_s
}nrf_atfifo_item_get_t;
/** @brief Name of the module used for logger messaging.
*/
#define NRF_ATFIFO_LOG_NAME atfifo
/**
* @defgroup nrf_atfifo_instmacros FIFO instance macros
*
@@ -228,9 +234,17 @@ typedef struct nrf_atfifo_rcontext_s
* @param[in] item_cnt Capacity of the created FIFO in maximum number of items that may be stored.
* The phisical size of the buffer will be 1 element bigger.
*/
#define NRF_ATFIFO_DEF(fifo_id, storage_type, item_cnt) \
static storage_type NRF_ATFIFO_BUF_NAME(fifo_id)[(item_cnt)+1]; \
static nrf_atfifo_t NRF_ATFIFO_INST_NAME(fifo_id); \
#define NRF_ATFIFO_DEF(fifo_id, storage_type, item_cnt) \
static storage_type NRF_ATFIFO_BUF_NAME(fifo_id)[(item_cnt)+1]; \
NRF_LOG_INSTANCE_REGISTER(NRF_ATFIFO_LOG_NAME, fifo_id, \
NRF_ATFIFO_CONFIG_INFO_COLOR, \
NRF_ATFIFO_CONFIG_DEBUG_COLOR, \
NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL, \
NRF_ATFIFO_CONFIG_LOG_LEVEL); \
static nrf_atfifo_t NRF_ATFIFO_INST_NAME(fifo_id) = { \
.p_buf = NULL, \
NRF_LOG_INSTANCE_PTR_INIT(p_log, NRF_ATFIFO_LOG_NAME, fifo_id) \
}; \
static nrf_atfifo_t * const fifo_id = &NRF_ATFIFO_INST_NAME(fifo_id)
/**
@@ -381,7 +395,7 @@ ret_code_t nrf_atfifo_get_free(nrf_atfifo_t * const p_fifo, void * const p_var,
*
* @return Pointer to data buffer or NULL if there is no data in the FIFO.
*/
void const * nrf_atfifo_item_get(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context);
void * nrf_atfifo_item_get(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context);
/**
* @brief Function for closing the reading operation.
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2011 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2011 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -1,495 +1,447 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**@file
*
* @defgroup nrf_atomic Atomic operations API
* @ingroup nrf_atfifo
* @{
*
* @brief @tagAPI52 This module implements C11 stdatomic.h simplified API.
At this point only Cortex-M3/M4 cores are supported (LDREX/STREX instructions).
* Atomic types are limited to @ref nrf_atomic_u32_t and @ref nrf_atomic_flag_t.
*/
#ifndef NRF_ATOMIC_H__
#define NRF_ATOMIC_H__
#include "sdk_common.h"
#ifndef NRF_ATOMIC_USE_BUILD_IN
#if (defined(__GNUC__) && defined(WIN32))
#define NRF_ATOMIC_USE_BUILD_IN 1
#else
#define NRF_ATOMIC_USE_BUILD_IN 0
#endif
#endif // NRF_ATOMIC_USE_BUILD_IN
#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U))
#define STREX_LDREX_PRESENT
#else
#include "app_util_platform.h"
#endif
/**
* @brief Atomic 32 bit unsigned type
* */
typedef volatile uint32_t nrf_atomic_u32_t;
/**
* @brief Atomic 1 bit flag type (technically 32 bit)
* */
typedef volatile uint32_t nrf_atomic_flag_t;
#if (NRF_ATOMIC_USE_BUILD_IN == 0) && defined(STREX_LDREX_PRESENT)
#include "nrf_atomic_internal.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Stores value to an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value to store
*
* @return Old value stored into atomic object
* */
static inline uint32_t nrf_atomic_u32_fetch_store(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_exchange_n(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data = value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
/**
* @brief Stores value to an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value to store
*
* @return New value stored into atomic object
* */
static inline uint32_t nrf_atomic_u32_store(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
__atomic_store_n(p_data, value, __ATOMIC_SEQ_CST);
return value;
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data = value;
CRITICAL_REGION_EXIT();
return value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
/**
* @brief Logical OR operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand OR operation
*
* @return Old value stored into atomic object
* */
static inline uint32_t nrf_atomic_u32_fetch_or(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_or(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data |= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
/**
* @brief Logical OR operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand OR operation
*
* @return New value stored into atomic object
* */
static inline uint32_t nrf_atomic_u32_or(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_or_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data |= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
/**
* @brief Logical AND operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand AND operation
*
* @return Old value stored into atomic object
* */
static inline uint32_t nrf_atomic_u32_fetch_and(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_and(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(and, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data &= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
/**
* @brief Logical AND operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand AND operation
*
* @return New value stored into atomic object
* */
static inline uint32_t nrf_atomic_u32_and(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_and_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(and, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data &= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
/**
* @brief Logical XOR operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand XOR operation
*
* @return Old value stored into atomic object
* */
static inline uint32_t nrf_atomic_u32_fetch_xor(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_xor(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data ^= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
/**
* @brief Logical XOR operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand XOR operation
*
* @return New value stored into atomic object
* */
static inline uint32_t nrf_atomic_u32_xor(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_xor_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data ^= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
/**
* @brief Arithmetic ADD operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand ADD operation
*
* @return Old value stored into atomic object
* */
static inline uint32_t nrf_atomic_u32_fetch_add(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_add(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(add, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data += value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
/**
* @brief Arithmetic ADD operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand ADD operation
*
* @return New value stored into atomic object
* */
static inline uint32_t nrf_atomic_u32_add(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_add_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(add, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data += value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
/**
* @brief Arithmetic SUB operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand SUB operation
*
* @return Old value stored into atomic object
* */
static inline uint32_t nrf_atomic_u32_fetch_sub(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_sub(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data -= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
/**
* @brief Arithmetic SUB operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand SUB operation
*
* @return New value stored into atomic object
* */
static inline uint32_t nrf_atomic_u32_sub(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_sub_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data -= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
/**************************************************************************************************/
/**
* @brief Logic one bit flag set operation on an atomic object
*
* @param[in] p_data Atomic flag memory pointer
*
* @return Old flag value
* */
static inline uint32_t nrf_atomic_flag_set_fetch(nrf_atomic_flag_t * p_data)
{
return nrf_atomic_u32_fetch_or(p_data, 1);
}
/**
* @brief Logic one bit flag set operation on an atomic object
*
* @param[in] p_data Atomic flag memory pointer
*
* @return New flag value
* */
static inline uint32_t nrf_atomic_flag_set(nrf_atomic_flag_t * p_data)
{
return nrf_atomic_u32_or(p_data, 1);
}
/**
* @brief Logic one bit flag clear operation on an atomic object
*
* @param[in] p_data Atomic flag memory pointer
*
* @return Old flag value
* */
static inline uint32_t nrf_atomic_flag_clear_fetch(nrf_atomic_flag_t * p_data)
{
return nrf_atomic_u32_fetch_and(p_data, 0);
}
/**
* @brief Logic one bit flag clear operation on an atomic object
*
* @param[in] p_data Atomic flag memory pointer
*
* @return New flag value
* */
static inline uint32_t nrf_atomic_flag_clear(nrf_atomic_flag_t * p_data)
{
return nrf_atomic_u32_and(p_data, 0);
}
#ifdef __cplusplus
}
#endif
#endif /* NRF_ATOMIC_H__ */
/** @} */
/**
* Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "nrf_atomic.h"
#ifndef NRF_ATOMIC_USE_BUILD_IN
#if (defined(__GNUC__) && defined(WIN32))
#define NRF_ATOMIC_USE_BUILD_IN 1
#else
#define NRF_ATOMIC_USE_BUILD_IN 0
#endif
#endif // NRF_ATOMIC_USE_BUILD_IN
#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U))
#define STREX_LDREX_PRESENT
#else
#include "app_util_platform.h"
#endif
#if (NRF_ATOMIC_USE_BUILD_IN == 0) && defined(STREX_LDREX_PRESENT)
#include "nrf_atomic_internal.h"
#endif
uint32_t nrf_atomic_u32_fetch_store(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_exchange_n(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data = value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_store(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
__atomic_store_n(p_data, value, __ATOMIC_SEQ_CST);
return value;
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data = value;
CRITICAL_REGION_EXIT();
return value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_fetch_or(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_or(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data |= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_or(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_or_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data |= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_fetch_and(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_and(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(and, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data &= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_and(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_and_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(and, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data &= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_fetch_xor(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_xor(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data ^= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_xor(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_xor_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data ^= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_fetch_add(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_add(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(add, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data += value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_add(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_add_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(add, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data += value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_fetch_sub(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_sub(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data -= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_sub(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_sub_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data -= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
bool nrf_atomic_u32_cmp_exch(nrf_atomic_u32_t * p_data,
uint32_t * p_expected,
uint32_t desired)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_compare_exchange(p_data,
p_expected,
&desired,
1,
__ATOMIC_SEQ_CST,
__ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
return nrf_atomic_internal_cmp_exch(p_data, p_expected, desired);
#else
CRITICAL_REGION_ENTER();
if(*p_data == *p_expected)
{
*p_data = desired;
return true;
}
else
{
*p_expected = *p_data;
return false;
}
CRITICAL_REGION_EXIT();
#endif
}
uint32_t nrf_atomic_u32_fetch_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
uint32_t expected = *p_data;
uint32_t new_val;
bool success;
do
{
if (expected >= value)
{
new_val = expected - value;
}
else
{
new_val = expected;
}
success = __atomic_compare_exchange(p_data,
&expected,
&new_val,
1,
__ATOMIC_SEQ_CST,
__ATOMIC_SEQ_CST);
} while(!success);
return expected;
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(sub_hs, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data -= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
uint32_t expected = *p_data;
uint32_t new_val;
bool success;
do
{
if (expected >= value)
{
new_val = expected - value;
}
else
{
new_val = expected;
}
success = __atomic_compare_exchange(p_data,
&expected,
&new_val,
1,
__ATOMIC_SEQ_CST,
__ATOMIC_SEQ_CST);
} while(!success);
return new_val;
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(sub_hs, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data -= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_flag_set_fetch(nrf_atomic_flag_t * p_data)
{
return nrf_atomic_u32_fetch_or(p_data, 1);
}
uint32_t nrf_atomic_flag_set(nrf_atomic_flag_t * p_data)
{
return nrf_atomic_u32_or(p_data, 1);
}
uint32_t nrf_atomic_flag_clear_fetch(nrf_atomic_flag_t * p_data)
{
return nrf_atomic_u32_fetch_and(p_data, 0);
}
uint32_t nrf_atomic_flag_clear(nrf_atomic_flag_t * p_data)
{
return nrf_atomic_u32_and(p_data, 0);
}
@@ -0,0 +1,274 @@
/**
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**@file
*
* @defgroup nrf_atomic Atomic operations API
* @ingroup app_common
* @{
*
* @brief @tagAPI52 This module implements C11 stdatomic.h simplified API.
At this point only Cortex-M3/M4 cores are supported (LDREX/STREX instructions).
* Atomic types are limited to @ref nrf_atomic_u32_t and @ref nrf_atomic_flag_t.
*/
#ifndef NRF_ATOMIC_H__
#define NRF_ATOMIC_H__
#include "sdk_common.h"
/**
* @brief Atomic 32 bit unsigned type
* */
typedef volatile uint32_t nrf_atomic_u32_t;
/**
* @brief Atomic 1 bit flag type (technically 32 bit)
* */
typedef volatile uint32_t nrf_atomic_flag_t;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Stores value to an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value to store
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_store(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Stores value to an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value to store
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_store(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Logical OR operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand OR operation
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_or(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Logical OR operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand OR operation
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_or(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Logical AND operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand AND operation
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_and(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Logical AND operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand AND operation
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_and(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Logical XOR operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand XOR operation
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_xor(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Logical XOR operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand XOR operation
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_xor(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Arithmetic ADD operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand ADD operation
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_add(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Arithmetic ADD operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand ADD operation
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_add(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Arithmetic SUB operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand SUB operation
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_sub(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Arithmetic SUB operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand SUB operation
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_sub(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief If value at pointer is equal to expected value, changes value at pointer to desired
*
* Atomically compares the value pointed to by p_data with the value pointed to by p_expected,
* and if those are equal, replaces the former with desired. Otherwise, loads the actual value
* pointed to by p_data into *p_expected.
*
* @param p_data Atomic memory pointer to test and modify.
* @param p_expected Pointer to test value.
* @param desired Value to be stored to atomic memory.
*
* @retval true *p_data was equal to *p_expected
* @retval false *p_data was not equal to *p_expected
*/
bool nrf_atomic_u32_cmp_exch(nrf_atomic_u32_t * p_data,
uint32_t * p_expected,
uint32_t desired);
/**
* @brief Arithmetic SUB operation on an atomic object performed if object >= value.
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand SUB operation
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Arithmetic SUB operation on an atomic object performed if object >= value.
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand SUB operation
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value);
/**************************************************************************************************/
/**
* @brief Logic one bit flag set operation on an atomic object
*
* @param[in] p_data Atomic flag memory pointer
*
* @return Old flag value
* */
uint32_t nrf_atomic_flag_set_fetch(nrf_atomic_flag_t * p_data);
/**
* @brief Logic one bit flag set operation on an atomic object
*
* @param[in] p_data Atomic flag memory pointer
*
* @return New flag value
* */
uint32_t nrf_atomic_flag_set(nrf_atomic_flag_t * p_data);
/**
* @brief Logic one bit flag clear operation on an atomic object
*
* @param[in] p_data Atomic flag memory pointer
*
* @return Old flag value
* */
uint32_t nrf_atomic_flag_clear_fetch(nrf_atomic_flag_t * p_data);
/**
* @brief Logic one bit flag clear operation on an atomic object
*
* @param[in] p_data Atomic flag memory pointer
*
* @return New flag value
* */
uint32_t nrf_atomic_flag_clear(nrf_atomic_flag_t * p_data);
#ifdef __cplusplus
}
#endif
#endif /* NRF_ATOMIC_H__ */
/** @} */
@@ -1,234 +1,343 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_ATOMIC_INTERNAL_H__
#define NRF_ATOMIC_INTERNAL_H__
#include "sdk_common.h"
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
*
* @defgroup nrf_atomic_internal Atomic operations internals
* @ingroup nrf_atomic
* @{
*
*/
/* Only Cortex M cores > 3 support LDREX/STREX instructions*/
#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)) == 0
#error "Unsupported core version"
#endif
#if defined ( __CC_ARM )
static __asm uint32_t nrf_atomic_internal_mov(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
/* The base standard provides for passing arguments in core registers (r0-r3) and on the stack.
* Registers r4 and r5 have to be saved on stack. Note that only even number of register push are
* allowed. This is a requirement of the Procedure Call Standard for the ARM Architecture [AAPCS].
* */
push {r4, r5}
mov r4, r0
loop_mov
ldrex r0, [r4]
mov r5, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_mov
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_orr(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_orr
ldrex r0, [r4]
orr r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_orr
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_and(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_and
ldrex r0, [r4]
and r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_and
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_eor(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_eor
ldrex r0, [r4]
eor r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_eor
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_add(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_add
ldrex r0, [r4]
add r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_add
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_sub(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_sub
ldrex r0, [r4]
sub r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_sub
str r5, [r2]
pop {r4, r5}
bx lr
}
#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \
old_val = nrf_atomic_internal_##asm_op(ptr, value, &new_val)
#elif defined ( __ICCARM__ ) || defined ( __GNUC__ )
/**
* @brief Atomic operation generic macro
* @param[in] asm_op operation: mov, orr, and, eor, add, sub
* @param[out] old_val atomic object output (uint32_t), value before operation
* @param[out] new_val atomic object output (uint32_t), value after operation
* @param[in] value atomic operation operand
* */
#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \
{ \
uint32_t str_res; \
__ASM volatile( \
"1: ldrex %["#old_val"], [%["#ptr"]]\n" \
NRF_ATOMIC_OP_##asm_op(new_val, old_val, value) \
" strex %[str_res], %["#new_val"], [%["#ptr"]]\n" \
" teq %[str_res], #0\n" \
" bne.n 1b" \
: \
[old_val]"=&r" (old_val), \
[new_val]"=&r" (new_val), \
[str_res]"=&r" (str_res) \
: \
[ptr]"r" (ptr), \
[value]"r" (value) \
: "cc"); \
UNUSED_PARAMETER(str_res); \
}
#define NRF_ATOMIC_OP_mov(new_val, old_val, value) "mov %["#new_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_orr(new_val, old_val, value) "orr %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_and(new_val, old_val, value) "and %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_eor(new_val, old_val, value) "eor %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_add(new_val, old_val, value) "add %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_sub(new_val, old_val, value) "sub %["#new_val"], %["#old_val"], %["#value"]\n"
#else
#error "Unsupported compiler"
#endif
#ifdef __cplusplus
}
#endif
#endif /* NRF_ATOMIC_INTERNAL_H__ */
/** @} */
/**
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_ATOMIC_INTERNAL_H__
#define NRF_ATOMIC_INTERNAL_H__
#include "sdk_common.h"
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
*
* @defgroup nrf_atomic_internal Atomic operations internals
* @ingroup nrf_atomic
* @{
*
*/
/* Only Cortex M cores > 3 support LDREX/STREX instructions*/
#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)) == 0
#error "Unsupported core version"
#endif
#if defined ( __CC_ARM )
static __asm uint32_t nrf_atomic_internal_mov(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
/* The base standard provides for passing arguments in core registers (r0-r3) and on the stack.
* Registers r4 and r5 have to be saved on stack. Note that only even number of register push are
* allowed. This is a requirement of the Procedure Call Standard for the ARM Architecture [AAPCS].
* */
push {r4, r5}
mov r4, r0
loop_mov
ldrex r0, [r4]
mov r5, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_mov
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_orr(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_orr
ldrex r0, [r4]
orr r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_orr
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_and(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_and
ldrex r0, [r4]
and r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_and
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_eor(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_eor
ldrex r0, [r4]
eor r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_eor
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_add(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_add
ldrex r0, [r4]
add r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_add
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_sub(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_sub
ldrex r0, [r4]
sub r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_sub
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm bool nrf_atomic_internal_cmp_exch(nrf_atomic_u32_t * p_data,
uint32_t * p_expected,
uint32_t value)
{
#define RET_REG r0
#define P_EXPC r1
#define VALUE r2
#define STR_RES r3
#define P_DATA r4
#define EXPC_VAL r5
#define ACT_VAL r6
push {r4-r6}
mov P_DATA, r0
mov RET_REG, #0
loop_cmp_exch
ldrex ACT_VAL, [P_DATA]
ldr EXPC_VAL, [P_EXPC]
cmp ACT_VAL, EXPC_VAL
ittee eq
strexeq STR_RES, VALUE, [P_DATA]
moveq RET_REG, #1
strexne STR_RES, ACT_VAL, [P_DATA]
strne ACT_VAL, [P_EXPC]
cmp STR_RES, #0
itt ne
movne RET_REG, #0
bne loop_cmp_exch
pop {r4-r6}
bx lr
#undef RET_REG
#undef P_EXPC
#undef VALUE
#undef STR_RES
#undef P_DATA
#undef EXPC_VAL
#undef ACT_VAL
}
static __asm uint32_t nrf_atomic_internal_sub_hs(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_sub_ge
ldrex r0, [r4]
cmp r0, r1
ite hs
subhs r5, r0, r1
movlo r5, r0
strex r3, r5, [r4]
cmp r3, #0
bne loop_sub_ge
str r5, [r2]
pop {r4, r5}
bx lr
}
#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \
old_val = nrf_atomic_internal_##asm_op(ptr, value, &new_val)
#elif defined ( __ICCARM__ ) || defined ( __GNUC__ )
/**
* @brief Atomic operation generic macro
* @param[in] asm_op operation: mov, orr, and, eor, add, sub
* @param[out] old_val atomic object output (uint32_t), value before operation
* @param[out] new_val atomic object output (uint32_t), value after operation
* @param[in] value atomic operation operand
* */
#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \
{ \
uint32_t str_res; \
__ASM volatile( \
"1: ldrex %["#old_val"], [%["#ptr"]]\n" \
NRF_ATOMIC_OP_##asm_op(new_val, old_val, value) \
" strex %[str_res], %["#new_val"], [%["#ptr"]]\n" \
" teq %[str_res], #0\n" \
" bne.n 1b" \
: \
[old_val]"=&r" (old_val), \
[new_val]"=&r" (new_val), \
[str_res]"=&r" (str_res) \
: \
[ptr]"r" (ptr), \
[value]"r" (value) \
: "cc"); \
UNUSED_PARAMETER(str_res); \
}
#define NRF_ATOMIC_OP_mov(new_val, old_val, value) "mov %["#new_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_orr(new_val, old_val, value) "orr %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_and(new_val, old_val, value) "and %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_eor(new_val, old_val, value) "eor %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_add(new_val, old_val, value) "add %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_sub(new_val, old_val, value) "sub %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_sub_hs(new_val, old_val, value) \
"cmp %["#old_val"], %["#value"]\n " \
"ite hs\n" \
"subhs %["#new_val"], %["#old_val"], %["#value"]\n" \
"movlo %["#new_val"], %["#old_val"]\n"
static inline bool nrf_atomic_internal_cmp_exch(nrf_atomic_u32_t * p_data,
uint32_t * p_expected,
uint32_t value)
{
bool res = false;
uint32_t str_res = 0;
uint32_t act_val = 0;
uint32_t exp_val = 0;
UNUSED_VARIABLE(str_res);
UNUSED_VARIABLE(act_val);
UNUSED_VARIABLE(exp_val);
__ASM volatile(
"1: ldrex %[act_val], [%[ptr]]\n"
" ldr %[exp_val], [%[expc]]\n"
" cmp %[act_val], %[exp_val]\n"
" ittee eq\n"
" strexeq %[str_res], %[value], [%[ptr]]\n"
" moveq %[res], #1\n"
" strexne %[str_res], %[act_val], [%[ptr]]\n"
" strne %[act_val], [%[expc]]\n"
" cmp %[str_res], #0\n"
" itt ne\n"
" movne %[res], #0\n"
" bne.n 1b"
:
[res] "=&r" (res),
[exp_val] "=&r" (exp_val),
[act_val] "=&r" (act_val),
[str_res] "=&r" (str_res)
:
"0" (res),
"1" (exp_val),
"2" (act_val),
[expc] "r" (p_expected),
[ptr] "r" (p_data),
[value] "r" (value)
: "cc");
return res;
}
#else
#error "Unsupported compiler"
#endif
#ifdef __cplusplus
}
#endif
#endif /* NRF_ATOMIC_INTERNAL_H__ */
/** @} */
File diff suppressed because it is too large Load Diff
+226 -44
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -41,14 +41,14 @@
#ifndef APP_USBD_H__
#define APP_USBD_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "nrf_drv_usbd.h"
#include "app_usbd_types.h"
#include "app_usbd_class_base.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup app_usbd USB Device high level library
* @ingroup app_common
@@ -60,11 +60,29 @@ extern "C" {
* @{
*/
/**
* @brief True if SOF timestamping is really provided.
*
* SOF timestamping is really provided if it was requested and if the logger is enabled.
*/
#if ((APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE) && (NRF_LOG_ENABLED))
#define APP_USBD_PROVIDE_SOF_TIMESTAMP 1
#else
#define APP_USBD_PROVIDE_SOF_TIMESTAMP 0
#endif
/**
* @brief SOF event handling modes.
*/
#define APP_USBD_SOF_HANDLING_NORMAL_QUEUE 0 //!< Push SOF events into event queue.
#define APP_USBD_SOF_HANDLING_COMPRESS_QUEUE 1 //!< Compress SOF events.
#define APP_USBD_SOF_HANDLING_INTERRUPT 2 //!< Handle SOF events in interrupt.
/**
* @brief Configuration passed to @ref app_usbd_init.
*/
typedef struct {
#if (!(APP_USBD_EVENT_QUEUE_ENABLE)) || defined(__SDK_DOXYGEN__)
#if (!(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)) || defined(__SDK_DOXYGEN__)
/**
* @brief User defined event handler.
*
@@ -76,12 +94,12 @@ typedef struct {
* @param p_event The event structure pointer.
*
* @note This field is available only when USB internal queue is disabled
* (see @ref APP_USBD_EVENT_QUEUE_ENABLE).
* (see @ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE).
*/
void (*ev_handler)(app_usbd_internal_evt_t const * const p_event);
#endif
#if (APP_USBD_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
/**
* @brief User defined event handler.
*
@@ -94,7 +112,7 @@ typedef struct {
* See @ref nrf_atfifo for more details.
*
* @note This field is available only when USBD internal queue is configured
* (see @ref APP_USBD_EVENT_QUEUE_ENABLE).
* (see @ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE).
*
* @note If is set to NULL no event would be called from interrupt.
* @note This function is called before event is processed.
@@ -110,7 +128,7 @@ typedef struct {
* This function is called while state event is processed.
*
* * @note This field is available only when USBD internal queue is configured
* (see @ref APP_USBD_EVENT_QUEUE_ENABLE).
* (see @ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE).
*
* @param event Event type.
* Only following events are sent into this function:
@@ -120,6 +138,7 @@ typedef struct {
* - APP_USBD_EVT_DRV_RESUME - It is also generated when remote wakeup is generated
* - APP_USBD_EVT_START
* - APP_USBD_EVT_STOP
* - APP_USBD_EVT_STATE_CHANGED
*/
void (*ev_state_proc)(app_usbd_event_type_t event);
@@ -134,6 +153,16 @@ typedef struct {
bool enable_sof;
} app_usbd_config_t;
#if (APP_USBD_PROVIDE_SOF_TIMESTAMP) || defined(__SDK_DOXYGEN__)
/**
* @brief Timestamp function for the logger.
*
* @return Current frame number taken directly from the last processed SOF.
*/
uint32_t app_usbd_sof_timestamp_get(void);
#endif
/**
* @brief USB library initialization.
*
@@ -154,6 +183,20 @@ ret_code_t app_usbd_init(app_usbd_config_t const * p_config);
*/
ret_code_t app_usbd_uninit(void);
#if (APP_USBD_CONFIG_POWER_EVENTS_PROCESS) || defined(__SDK_DOXYGEN__)
/**
* @brief Function to start USB related power events processing
*
* This function should be called after @ref app_usbd_init and after all the
* required classes were appended (@ref app_usbd_class_append).
*
* @retval NRF_SUCCESS Power events successfully initialized
* @retval NRF_ERROR_INVALID_STATE The state of the driver does not allow to enable
* the power events processing.
*/
ret_code_t app_usbd_power_events_enable(void);
#endif
/**
* @brief Enable USBD
*
@@ -176,7 +219,7 @@ void app_usbd_disable(void);
* @brief Request USBD to start
*
* The function sends start request to the event queue.
* If the queue is enabled (@ref APP_USBD_EVENT_QUEUE_ENABLE) it would be processed
* If the queue is enabled (@ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) it would be processed
* when the queue is processed.
* If queue is disabled it would be processed immediately inside this function.
* It means that if queue is disabled this function cannot be called from interrupt with priority
@@ -205,7 +248,7 @@ void app_usbd_start(void);
* @brief Stop USB to work
*
* The function sends stop request to the event queue.
* If the queue is enabled (@ref APP_USBD_EVENT_QUEUE_ENABLE) it would be processed
* If the queue is enabled (@ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) it would be processed
* when the queue is processed.
* If queue is disabled it would be processed immediately inside this function.
* It means that if queue is disabled this function cannot be called from interrupt with priority
@@ -244,6 +287,16 @@ void app_usbd_suspend_req(void);
*/
bool app_usbd_wakeup_req(void);
/**
* @brief Get information whether there is an active connection.
*
* Function to check if the communication with the bus is possible.
*
* @retval true The bus is active.
* @retval false There is no connection or bus is suspended.
*/
bool app_usbd_active_check(void);
/**
* @brief USBD event processor
*
@@ -252,7 +305,7 @@ bool app_usbd_wakeup_req(void);
void app_usbd_event_execute(app_usbd_internal_evt_t const * const p_event);
#if (APP_USBD_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
/**
* @brief Function that process events from the queue
*
@@ -400,49 +453,56 @@ ret_code_t app_usbd_class_rwu_unregister(app_usbd_class_inst_t const * const p_i
bool app_usbd_class_rwu_enabled_check(void);
/**
* @brief Function finds a given descriptor type in class descriptors payload
* @brief Find a specified descriptor
*
* @param[in] p_cinst Instance of a class
* @param[in] desc_type Descriptor type (@ref APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR)
* @param[in] desc_index Descriptor index (@ref APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR)
* @param[out] p_desc_len Descriptor length
* @param[in] p_cinst Class instance
* @param[in] desc_type Descriptor type @ref app_usbd_descriptor_t
* @param[in] desc_index Descriptor index
* @param[out] p_desc Pointer to escriptor
* @param[out] p_desc_len Length of descriptor
*
* @return Address of the descriptor (NULL if not found)
* @return Standard error code @ref ret_code_t
* @retval NRF_SUCCESS descriptor successfully found
* @retval NRF_ERROR_NOT_FOUND descriptor not found
* */
const void * app_usbd_class_descriptor_find(app_usbd_class_inst_t const * const p_cinst,
uint8_t desc_type,
uint8_t desc_index,
size_t * p_desc_len);
ret_code_t app_usbd_class_descriptor_find(app_usbd_class_inst_t const * const p_cinst,
uint8_t desc_type,
uint8_t desc_index,
uint8_t * p_desc,
size_t * p_desc_len);
/**
* @brief Standard interface request handle
* @brief Standard set interface request handle
*
* @param[in] p_setup_ev Setup event
* This function should be called when processing SET_INTERFACE request.
*
* @param[in] p_cinst Instance of a class
* @param[in] iface Interface number
*
* @return Standard error code
* */
ret_code_t app_usbd_interface_std_req_handle(app_usbd_setup_evt_t const * p_setup_ev);
/**
* @brief Standard endpoint request handle
*
* @param[in] p_setup_ev Setup event
*
* @return Standard error code
* @note Selected interface to reset has to be part of given class.
* In other case
* */
ret_code_t app_usbd_endpoint_std_req_handle(app_usbd_setup_evt_t const * p_setup_ev);
ret_code_t app_usbd_interface_ep_reset(app_usbd_class_inst_t const * const p_cinst,
uint8_t iface);
/**
* @brief Standard interface set request handle
* @brief Enable selected endpoint
*
* @param[in] p_cinst Instance of a class
* @param[in] p_setup_ev Setup event
* Selected endpoint is enabled and cleared.
*
* @return Standard error code
* */
ret_code_t app_usbd_req_std_set_interface(app_usbd_class_inst_t const * const p_cinst,
app_usbd_setup_evt_t const * const p_setup_ev);
* @param ep Endpoint number
*/
void app_usbd_ep_enable(nrf_drv_usbd_ep_t ep);
/**
* @brief Disable selected endpoint
*
* @param ep Endpoint number
*/
void app_usbd_ep_disable(nrf_drv_usbd_ep_t ep);
/**
* @name Iterate through classes lists
@@ -506,6 +566,21 @@ ret_code_t app_usbd_req_std_set_interface(app_usbd_class_inst_t const * const p_
}
/** @} */
/**
* @brief Search for selected interface
*
* Function searches for the given interface number and returns the class that contains it.
* Optionally it can return interface index inside class instance.
*
* @param[in] iface Interface number
* @param[out] p_iface_idx Pointer to a variable that would hold interface index inside returned
* class instance.
*
* @return Pointer to the class structure that cointain given interface or NULL if not found.
*/
app_usbd_class_inst_t const * app_usbd_iface_find(uint8_t iface, uint8_t * p_iface_idx);
/**
* @name Communicate with interfaces, endpoints and instances inside usbd library
*
@@ -516,12 +591,16 @@ ret_code_t app_usbd_req_std_set_interface(app_usbd_class_inst_t const * const p_
* @brief Call interface event handler
*
* Call event handler for selected interface.
* @param[in] iface Target interface number
* @param[in] p_event Event structure to send
* @param[in,out] p_class_inst Class instance that holds selected interface
* @param[in] iface_idx Index of the interface in class structure
* @param[in] p_event Event structure to be processed
*
* @return Operation status
*/
ret_code_t app_usbd_iface_call(uint8_t iface, app_usbd_complex_evt_t const * const p_event);
ret_code_t app_usbd_iface_call(
app_usbd_class_inst_t const * const p_class_inst,
uint8_t iface_idx,
app_usbd_complex_evt_t const * const p_event);
/**
* @brief Call endpoint event handler
@@ -554,6 +633,109 @@ ret_code_t app_usbd_req_std_set_interface(app_usbd_class_inst_t const * const p_
ret_code_t app_usbd_all_until_served_call(app_usbd_complex_evt_t const * const p_event);
/** @} */
/**
* @brief Endpoint transfer
*
* @param ep Endpoint number
* @param p_transfer Description of the transfer to be performed.
* The direction of the transfer is determined by the
* endpoint number.
*
* @retval NRF_ERROR_INVALID_STATE The state of the USB device does not allow
* data transfer on the endpoint.
* @return Values returned by @ref nrf_drv_usbd_ep_transfer
*
* @sa app_usbd_ep_handled_transfer
*/
ret_code_t app_usbd_ep_transfer(
nrf_drv_usbd_ep_t ep,
nrf_drv_usbd_transfer_t const * const p_transfer);
/**
* @brief Set up an endpoint handled transfer.
*
* Configures a transfer handled by the feedback function.
*
* @param ep Endpoint number.
* @param p_handler Function called when the next chunk of data is requested.
*
* @retval NRF_ERROR_INVALID_STATE The state of the USB device does not allow
* data transfer on the endpoint.
* @return Values returned by @ref nrf_drv_usbd_ep_handled_transfer.
*/
ret_code_t app_usbd_ep_handled_transfer(
nrf_drv_usbd_ep_t ep,
nrf_drv_usbd_handler_desc_t const * const p_handler);
/**
* @brief Select interface
*
* Select the given interface.
* This function calls class interface selection function or default
* interface selection function.
*
* After calling this function interface should be functional.
*
* @param[in,out] p_inst Instance of the class
* @param[in] iface_idx Index of the interface inside class structure
* @param[in] alternate Alternate setting that should be selected
*
* @return Standard Error code
*/
ret_code_t app_usbd_iface_select(
app_usbd_class_inst_t const * const p_inst,
uint8_t iface_idx,
uint8_t alternate);
/**
* @brief Deselect interface
*
* Disable the given interface.
* This function calls class interface deselection function or
* default interface selection function.
*
* After calling this function all the endpoints from the interface
* have to be disabled.
*
* @param[in,out] p_inst Instance of the class
* @param[in] iface_idx Index of the interface inside class structure
*/
void app_usbd_iface_deselect(
app_usbd_class_inst_t const * const p_inst,
uint8_t iface_idx);
/**
* @brief Get selected interface
*
* Function retieves currently selected interface.
* If the class contains @ref app_usbd_class_methods_t::iface_selection_get it is called.
* It it does not contain this function this function would return default, 0 value.
*
* @param[in] p_inst Instance of the class
* @param[in] iface_idx Index of the interface inside class structure
*
* @return Selected alternate interface setting
*/
uint8_t app_usbd_iface_selection_get(
app_usbd_class_inst_t const * const p_inst,
uint8_t iface_idx);
/**
* @brief Select alternate configuration 0 for all interfaces
*
* Auxiliary function that clears settings for all interfaces leaving them enabled.
*/
void app_usbd_all_iface_select_0(void);
/**
* @brief Deselect all interfaces
*
* Auxiliary function to disable all interfaces.
*/
void app_usbd_all_iface_deselect(void);
/** @} */
#ifdef __cplusplus
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -41,10 +41,6 @@
#ifndef APP_USBD_CLASS_BASE_H__
#define APP_USBD_CLASS_BASE_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
@@ -53,6 +49,10 @@ extern "C" {
#include "nrf_assert.h"
#include "app_util.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup app_usbd_class_base USBD Class Base module
* @ingroup app_usbd
@@ -95,6 +95,14 @@ typedef struct
app_usbd_class_inst_t const * p_sof_next; //!< Pointer to the next SOF event requiring instance
} app_usbd_class_data_t;
/**
* @brief Class descriptor context
*/
typedef struct
{
uint32_t line; //!< Number of line to resume writing descriptors from
} app_usbd_class_descriptor_ctx_t;
/**
* @brief Class interface function set
@@ -107,22 +115,102 @@ typedef struct {
* @param[in,out] p_inst Instance of the class
* @param[in] p_event Event to process
*
* @return Standard error code
*
* @note If given event is not supported by class, return @ref NRF_ERROR_NOT_SUPPORTED
*/
ret_code_t (* event_handler)(app_usbd_class_inst_t const * const p_inst,
app_usbd_complex_evt_t const * const p_event);
ret_code_t (* event_handler)(app_usbd_class_inst_t const * const p_inst,
app_usbd_complex_evt_t const * const p_event);
/**
* @brief Instance get descriptors
* @brief Instance feed descriptors
*
* The function used by every class instance.
* @param[in,out] p_inst Instance of the class
* @param[out] p_size Descriptor size
* Feeds whole descriptor of the instance
* @param[in] p_ctx Class descriptor context
* @param[in,out] p_inst Instance of the class
* @param[out] p_buff Buffer for descriptor
* @param[in] max_size Requested size of the descriptor
*
* @return Class descriptors start address
* @return True if not finished feeding the descriptor, false if done
*/
const void * (* get_descriptors)(app_usbd_class_inst_t const * const p_inst,
size_t * p_size);
bool (* feed_descriptors)(app_usbd_class_descriptor_ctx_t * p_ctx,
app_usbd_class_inst_t const * p_inst,
uint8_t * p_buff,
size_t max_size);
/**
* @brief Select interface
*
* Function called when class interface has to be selected.
*
* This function would be called for every interface when:
* - SET_INTERFACE command is processed by the default handler
* - SET_CONFIG(1) command is processed by the default handler
*
* @note Remember to disable all the endpoints that are not used
* in the selected configuration.
* @note If this function pointer is NULL default procedure would
* just enable all the interface endpoints and selecting
* alternate configurations other than 0 would generate error.
* @note Calling the function with alternate setting 0 has to always succeed.
*
* @param[in,out] p_inst Instance of the class
* @param[in] iface_idx Index of the interface inside class structure
* @param[in] alternate Alternate setting that should be selected
*
* @return Function has to return @ref NRF_SUCCESS when it has successfully proceed
* interface selection.
* If it returns @ref NRF_ERROR_NOT_SUPPORTED, default function would be used
* to proceed the request - just like there would be NULL pointer in this field.
* Any other kind of error would make library to STALL the request.
*/
ret_code_t (* iface_select)(app_usbd_class_inst_t const * const p_inst,
uint8_t iface_idx,
uint8_t alternate);
/**
* @brief Deselect interface
*
* Function called when the class interface has to be deselected.
*
* This function would be called for every interface when:
* - Library start internal event is processed by the default handler
* - RESET event is processed by the default handler
* - SET_ADDRESS is processed by the default handler
* - SET_CONFIG(0) is processed by the default handler
*
* @note Just after this function is called all the interface
* endpoints would be disabled.
* This function does not has to take care about it.
* @note If this function pointer is NULL default procedure would
* just disable all the interface endpoints.
*
* @param[in,out] p_inst Instance of the class
* @param[in] iface_idx Index of the interface inside class structure
*/
void (* iface_deselect)(app_usbd_class_inst_t const * const p_inst, uint8_t iface_idx);
/**
* @brief Get current interface
*
* Function called when class interface has to return its alternate settings
* in reaction on GET_INTERFACE command.
* It should be defined in a pair with @ref app_usbd_class_methods_t::iface_select.
*
* @param[in] p_inst Instance of the class
* @param[in] iface_idx Index of the interface inside class structure
*
* @return Current alternate setting of the selected interface.
*
* @note For the classes that support this function, when an interface that has not alternate
* configurations has been selected this function has to return 0 - default alternate setting.
*
* @note If this function pointer it NULL default procedure would return alternate interface
* value 0.
*/
uint8_t (* iface_selection_get)(app_usbd_class_inst_t const * const p_inst, uint8_t iface_idx);
} app_usbd_class_methods_t;
/**
@@ -588,6 +676,27 @@ static inline app_usbd_class_data_t * app_usbd_class_data_access(
} specific; \
} APP_USBD_CLASS_INSTANCE_TYPE(type_name)
/**
* @brief Same as @ref APP_USBD_CLASS_INSTANCE_TYPEDEF but for class with EP0 only.
*/
#define APP_USBD_CLASS_INSTANCE_NO_EP_TYPEDEF(type_name, interfaces_configs, class_config_dec) \
typedef union CONCAT_2(type_name, _u) \
{ \
app_usbd_class_inst_t base; \
struct \
{ \
APP_USBD_CLASS_DATA_TYPE(type_name) * p_data; \
app_usbd_class_methods_t const * p_class_methods; \
struct \
{ \
uint8_t cnt; \
app_usbd_class_iface_conf_t \
config[NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs))]; \
} iface; \
class_config_dec \
} specific; \
} APP_USBD_CLASS_INSTANCE_TYPE(type_name)
/**
* @brief Writable data structure declaration
*
@@ -637,6 +746,16 @@ static inline app_usbd_class_data_t * app_usbd_class_data_access(
APP_USBD_CLASS_DATA_TYPEDEF(type_name, class_data_dec); \
APP_USBD_CLASS_INSTANCE_TYPEDEF(type_name, interface_configs, class_config_dec)
/**
* @brief Same as @ref APP_USBD_CLASS_TYPEDEF but for class with EP0 only.
*/
#define APP_USBD_CLASS_NO_EP_TYPEDEF(type_name, \
interface_configs, \
class_config_dec, \
class_data_dec) \
APP_USBD_CLASS_DATA_TYPEDEF(type_name, class_data_dec); \
APP_USBD_CLASS_INSTANCE_NO_EP_TYPEDEF(type_name, interface_configs, class_config_dec)
/**
* @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF
*
@@ -675,6 +794,24 @@ static inline app_usbd_class_data_t * app_usbd_class_data_access(
} \
}
/**
* @brief Same as @ref APP_USBD_CLASS_INSTANCE_INITVAL but for class with EP0 only.
*/
#define APP_USBD_CLASS_INSTANCE_NO_EP_INITVAL(p_ram_data, \
class_methods, \
interfaces_configs, \
class_config_part) \
{ \
.specific = { \
.p_data = p_ram_data, \
.p_class_methods = class_methods, \
.iface = { \
.cnt = NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs)), \
.config = { APP_USBD_CLASS_IFACES_CONFIG_EXTRACT(interfaces_configs) } \
}, \
BRACKET_EXTRACT(class_config_part) \
} \
}
/**
* @brief Define the base class instance
@@ -684,7 +821,7 @@ static inline app_usbd_class_data_t * app_usbd_class_data_access(
* The tricky part is @c class_config_part.
* The configuration data here has to be placed inside brackets.
* Then any type of values can be used depending on the type used in @ref APP_USBD_CLASS_TYPEDEF.
* If instance does not have any specyfic data, use just empty bracket here.
* If instance does not has any specyfic data, use just empty bracket here.
* @code
* APP_USBD_CLASS_TYPEDEF(
* some_base_class,
@@ -792,6 +929,21 @@ static inline app_usbd_class_data_t * app_usbd_class_data_access(
interfaces_configs, \
class_config_part)
/**
* @brief Same as @ref APP_USBD_CLASS_INST_GLOBAL_DEF but for class with EP0 only.
*/
#define APP_USBD_CLASS_INST_NO_EP_GLOBAL_DEF(instance_name, \
type_name, \
class_methods, \
interfaces_configs, \
class_config_part) \
static APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(instance_name, _data); \
const APP_USBD_CLASS_INSTANCE_TYPE(type_name) instance_name = \
APP_USBD_CLASS_INSTANCE_NO_EP_INITVAL( \
&CONCAT_2(instance_name, _data), \
class_methods, \
interfaces_configs, \
class_config_part)
/**
* @brief Access class specific configuration
*
@@ -827,11 +979,96 @@ static inline app_usbd_class_data_t * app_usbd_class_data_access(
* but then we would totally lost type safety.
*
* A little more safe is to use pointer to base member of class instance.
* This would generate an error when used on any variable that have no base member
* This would generate an error when used on any variable that has no base member
* and would generate also error if this base member is wrong type.
*/
#define APP_USBD_CLASS_BASE_INSTANCE(p_inst) (&((p_inst)->base))
/*lint -emacro(142 438 616 646, APP_USBD_CLASS_DESCRIPTOR_INIT, APP_USBD_CLASS_DESCRIPTOR_BEGIN, APP_USBD_CLASS_DESCRIPTOR_YIELD, APP_USBD_CLASS_DESCRIPTOR_END, APP_USBD_CLASS_DESCRIPTOR_WRITE)*/
/**
* @brief Initialize class descriptor
*
* @param[in] p_ctx Class descriptor context
*/
#define APP_USBD_CLASS_DESCRIPTOR_INIT(p_ctx) \
(p_ctx)->line = 0;
/**
* @brief Begin class descriptor
*
* @param[in] p_ctx Class descriptor context
*/
#define APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx) \
switch ((p_ctx)->line) \
{ \
case 0: \
;
/**
* @brief Yield class descriptor
*
* @param[in] p_ctx Class descriptor context
*/
#define APP_USBD_CLASS_DESCRIPTOR_YIELD(p_ctx) \
do \
{ \
(p_ctx)->line = __LINE__; \
return true; \
case __LINE__: \
; \
} while (0)
/*lint -emacro(438 527, APP_USBD_CLASS_DESCRIPTOR_END)*/
/**
* @brief End class descriptor
*
* This function has to be called at the end of class descriptor feeder function.
* No other operations in feeder function can be done after calling it.
*
* @param[in] p_ctx Class descriptor context
*/
#define APP_USBD_CLASS_DESCRIPTOR_END(p_ctx) \
} \
(p_ctx)->line = 0; \
return false;
/**
* @brief Write descriptor using protothreads
*
* This function writes one byte to the buffer with offset. If buffer is full
* it yields.
*
* It is used by the class descriptor feeders internally.
*
* @ref APP_USBD_CLASS_DESCRIPTOR_BEGIN has to be called before using this function.
* @ref APP_USBD_CLASS_DESCRIPTOR_END has to be called after last use of this function.
*
* @param data Byte to be written to buffer
* @param buff Buffer to write into
* @param cur_size Offset
* @param max_size Size of the buffer
*/
#define APP_USBD_CLASS_DESCRIPTOR_WRITE(data, buff, cur_size, max_size) \
do \
{ \
if(buff != NULL) \
{ \
*(buff + cur_size) = data; \
} \
cur_size++; \
if (cur_size >= max_size) \
{ \
APP_USBD_CLASS_DESCRIPTOR_YIELD(p_ctx); \
} \
} while(0);
/** @} */
#ifdef __cplusplus
File diff suppressed because it is too large Load Diff
+11 -102
View File
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -41,10 +41,6 @@
#ifndef APP_USBD_CORE_H__
#define APP_USBD_CORE_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "sdk_common.h"
@@ -52,6 +48,10 @@ extern "C" {
#include "app_usbd_types.h"
#include "app_usbd_class_base.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup app_usbd_core USB Device high level library core module
@@ -69,18 +69,6 @@ extern "C" {
*/
#define APP_USBD_CORE_CLASS_CONFIGURATION ((0, NRF_DRV_USBD_EPOUT0, NRF_DRV_USBD_EPIN0))
/**
* @brief Suspend state mask
*
* Mask used to mark suspended state, suspended state remembers also the target state after wake up
*/
#define APP_USBD_STATE_SUSPENDED_MASK 0x80
/**
* @brief Remove @ref APP_USBD_STATE_SUSPENDED_MASK bit from core state
*/
#define APP_USB_STATE_BASE(state) ((app_usbd_state_t)((uint32_t)(state) & (~APP_USBD_STATE_SUSPENDED_MASK)))
/**
* @brief USB Device state
*
@@ -88,17 +76,12 @@ extern "C" {
*/
typedef enum
{
APP_USBD_STATE_Disabled = 0x00, /**< The whole USBD library is disabled */
APP_USBD_STATE_Unattached = 0x01, /**< Device is currently not connected to the host */
APP_USBD_STATE_Powered = 0x02, /**< Device is connected to the host but has not been enumerated */
APP_USBD_STATE_Default = 0x03, /**< USB Reset condition detected, waiting for the address */
APP_USBD_STATE_Addressed = 0x04, /**< Device has been addressed but have not been configured */
APP_USBD_STATE_Configured = 0x05, /**< Device is addressed and configured */
APP_USBD_STATE_SuspendedPowered = APP_USBD_STATE_SUSPENDED_MASK | APP_USBD_STATE_Powered, /**< Device is Suspended and on wakeup it will return to Powered state */
APP_USBD_STATE_SuspendedDefault = APP_USBD_STATE_SUSPENDED_MASK | APP_USBD_STATE_Default, /**< Device is Suspended and on wakeup it will return to Default state */
APP_USBD_STATE_SuspendedAddressed = APP_USBD_STATE_SUSPENDED_MASK | APP_USBD_STATE_Addressed, /**< Device is Suspended and on wakeup it will return to Addressed state */
APP_USBD_STATE_SuspendedConfigured = APP_USBD_STATE_SUSPENDED_MASK | APP_USBD_STATE_Configured /**< Device is Suspended and on wakeup it will return to Configured state */
APP_USBD_STATE_Disabled , /**< The whole USBD library is disabled */
APP_USBD_STATE_Unattached, /**< Device is currently not connected to the host */
APP_USBD_STATE_Powered , /**< Device is connected to the host but has not been enumerated */
APP_USBD_STATE_Default , /**< USB Reset condition detected, waiting for the address */
APP_USBD_STATE_Addressed , /**< Device has been addressed but has not been configured */
APP_USBD_STATE_Configured, /**< Device is addressed and configured */
}app_usbd_state_t;
/**
@@ -185,80 +168,6 @@ ret_code_t app_usbd_core_setup_data_handler_set(
nrf_drv_usbd_ep_t ep,
app_usbd_core_setup_data_handler_desc_t const * const p_handler_desc);
/**
* @brief Endpoint transfer
*
* @param ep Endpoint number
* @param p_transfer Description of the transfer to be performed.
* The direction of the transfer is determined by the
* endpoint number.
*
* @retval NRF_ERROR_INVALID_STATE The state of the USB device does not allow
* data transfer on the endpoint.
*
* @return Values returned by @ref nrf_drv_usbd_ep_transfer
*
* @note This function can work only if the USB is in Configured state.
* See @ref app_usbd_core_setup_data_transfer for transfers before
* device configuration is done.
* @sa app_usbd_core_setup_data_transfer
*/
ret_code_t app_usbd_core_ep_transfer(
nrf_drv_usbd_ep_t ep,
nrf_drv_usbd_transfer_t const * const p_transfer);
/**
* @brief Setup data transfer
*
* Function similar to @ref app_usbd_core_ep_transfer.
* The only technical diference is that it should be used with setup transfers
* that are going to be performed before device is configured.
*
* @param ep See @ref app_usbd_core_ep_transfer.
* @param p_transfer See @ref app_usbd_core_ep_transfer.
*
* @return The same values like @ref app_usbd_core_ep_transfer
*/
ret_code_t app_usbd_core_setup_data_transfer(
nrf_drv_usbd_ep_t ep,
nrf_drv_usbd_transfer_t const * const p_transfer);
/**
* @brief Set up an endpoint-handled transfer.
*
* Configures a transfer handled by the feedback function.
*
* @param ep Endpoint number.
* @param p_handler Function called when the next chunk of data is requested.
*
* @retval NRF_ERROR_INVALID_STATE The state of the USB device does not allow
* data transfer on the endpoint.
*
* @return Values returned by @ref nrf_drv_usbd_ep_handled_transfer.
*/
ret_code_t app_usbd_ep_handled_transfer(
nrf_drv_usbd_ep_t ep,
nrf_drv_usbd_handler_desc_t const * const p_handler);
/**
* @brief Set up a data-handled transfer.
*
* Function similar to @ref app_usbd_ep_handled_transfer.
* The only technical diference is that it should be used with setup transfers
* that are performed before the device is configured.
*
* @param ep Endpoint number
* @param p_handler Function called when the next chunk of data is requested.
*
* @retval NRF_ERROR_INVALID_STATE The state of the USB device does not allow
* data transfer on the endpoint.
*
* @return Values returned by @ref nrf_drv_usbd_ep_handled_transfer.
*/
ret_code_t app_usbd_setup_data_handled_transfer(
nrf_drv_usbd_ep_t ep,
nrf_drv_usbd_handler_desc_t const * const p_handler);
/**
* @brief Set up a data transfer buffer.
*
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -41,17 +41,17 @@
#ifndef APP_USBD_DESCRIPTOR_H__
#define APP_USBD_DESCRIPTOR_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "nrf.h"
#include "nrf_drv_usbd.h"
#include "app_usbd_langid.h"
#include "app_util_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Compiler support for anonymous unions */
ANON_UNIONS_ENABLE
ANON_UNIONS_ENABLE;
/**
* @defgroup app_usbd_descriptor USB standard descriptors
@@ -122,12 +122,14 @@ typedef enum
APP_USBD_DESCRIPTOR_INTERFACE_POWER = 8, /**< @note Not supported */
APP_USBD_DESCRIPTOR_OTG = 9, /**< @note Not supported - Our USB have not OTG functionality */
APP_USBD_DESCRIPTOR_DEBUG = 10, /**< Debug channel descriptor if available, can be only reached by GetDescriptor */
APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION = 11 /**<
APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION = 11, /**<
* Descriptor used to describe that two or more interfaces are associated to the same function.
*
* @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION.
* Cannot be accessed by GetDescriptor or SetDescriptor
*/
APP_USBD_DESCRIPTOR_REPORT = 34, /**< HID Report descriptor. */
APP_USBD_DESCRIPTOR_PHYSICAL = 35 /**< HID Physical descriptor. */
} app_usbd_descriptor_t;
@@ -325,7 +327,7 @@ typedef struct
} app_usbd_descriptor_iad_t;
#pragma pack(pop)
ANON_UNIONS_DISABLE
ANON_UNIONS_DISABLE;
#ifdef __cplusplus
}
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -41,18 +41,18 @@
#ifndef APP_USBD_REQUEST_H__
#define APP_USBD_REQUEST_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "sdk_common.h"
#include "nrf.h"
#include "nrf_drv_usbd.h"
#include "app_usbd_descriptor.h"
#include "app_util_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Compiler support for anonymous unions */
ANON_UNIONS_ENABLE
ANON_UNIONS_ENABLE;
#pragma pack(push, 1)
@@ -345,7 +345,7 @@ static inline uint8_t app_usbd_setup_req_val(app_usbd_setup_reqrec_t rec,
}
ANON_UNIONS_DISABLE
ANON_UNIONS_DISABLE;
/** @} */
#ifdef __cplusplus
@@ -0,0 +1,87 @@
/**
* Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "app_usbd_serial_num.h"
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "app_usbd.h"
#define SERIAL_NUMBER_STRING_SIZE (12)
/**@brief Serial number generated
*
* Serial number generated by the @ref serial_number_string_create function
*/
uint16_t g_extern_serial_number[SERIAL_NUMBER_STRING_SIZE + 1];
/**@brief Function for creating the serial number string from a regular C string.
*
* @param[in] p_serial_number_string The serial number string. Must be terminated with \0.
*/
static void string_create(char * p_serial_number_string)
{
g_extern_serial_number[0] =
(uint16_t)APP_USBD_DESCRIPTOR_STRING << 8 | sizeof(g_extern_serial_number);
for (uint32_t i = 0; i < strlen(p_serial_number_string); i++)
{
g_extern_serial_number[i + 1] = (uint8_t)p_serial_number_string[i];
}
}
void app_usbd_serial_num_generate(void)
{
char serial_number_string[SERIAL_NUMBER_STRING_SIZE + 1];
const uint16_t serial_num_high_bytes = (uint16_t)NRF_FICR->DEVICEADDR[1] | 0xC000; // The masking makes the address match the Random Static BLE address.
const uint32_t serial_num_low_bytes = NRF_FICR->DEVICEADDR[0];
(void)snprintf(serial_number_string,
SERIAL_NUMBER_STRING_SIZE + 1,
"%04"PRIX16"%08"PRIX32,
serial_num_high_bytes,
serial_num_low_bytes);
string_create(serial_number_string);
}
@@ -0,0 +1,54 @@
/**
* Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef APP_USBD_SERIAL_NUM_H__
#define APP_USBD_SERIAL_NUM_H__
#include <stdint.h>
#include <stdio.h>
/**@brief Function for generating a default serial number string based on FIRC->DEVICEADDR.
*
* The generated string is identical to the default BLE address. After calling this function, the
* the serial number is ready for the USB driver.
*/
void app_usbd_serial_num_generate(void);
#endif // APP_USBD_SERIAL_NUM_H__
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -40,15 +40,15 @@
#ifndef APP_USBD_STRING_DESC_H__
#define APP_USBD_STRING_DESC_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "sdk_common.h"
#include "app_usbd.h"
#include "app_usbd_string_config.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup app_usbd_string_desc USBD string descriptors
* @ingroup app_usbd
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -41,16 +41,16 @@
#ifndef APP_USBD_TYPES_H__
#define APP_USBD_TYPES_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "sdk_errors.h"
#include "nrf_drv_usbd.h"
#include "app_usbd_request.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup app_usbd_types USB Device high level library variable types definition
* @ingroup app_usbd
@@ -101,6 +101,12 @@ typedef enum
APP_USBD_EVT_DRV_SETUP = NRF_DRV_USBD_EVT_SETUP, /**< This event type has special structure. See @ref app_usbd_setup_evt_t */
APP_USBD_EVT_DRV_EPTRANSFER = NRF_DRV_USBD_EVT_EPTRANSFER, /**< See documentation for @ref NRF_DRV_USBD_EVT_EPTRANSFER */
APP_USBD_EVT_FIRST_POWER, /**< First power event code - for internal static assert checking */
APP_USBD_EVT_POWER_DETECTED, /**< See documentation for @ref NRF_DRV_POWER_USB_EVT_DETECTED */
APP_USBD_EVT_POWER_REMOVED, /**< See documentation for @ref NRF_DRV_POWER_USB_EVT_REMOVED */
APP_USBD_EVT_POWER_READY, /**< See documentation for @ref NRF_DRV_POWER_USB_EVT_READY */
APP_USBD_EVT_FIRST_APP, /**< First application event code - for internal static assert checking */
@@ -110,6 +116,9 @@ typedef enum
APP_USBD_EVT_STARTED, /**< USBD library has just been started and functional - event passed to all instances, before USBD interrupts have been enabled */
APP_USBD_EVT_STOPPED, /**< USBD library has just been stopped and is not functional - event passed to all instances, after USBD interrupts have been disabled*/
APP_USBD_EVT_STATE_CHANGED, /**< Informs all the classes that base state has been changed.
* This event is processed before setup stage that caused the state change finishes (before acknowledging it). */
APP_USBD_EVT_FIRST_INTERNAL = 0x80, /**< First internal event, used by the APP library internally. */
APP_USBD_EVT_HFCLK_READY = APP_USBD_EVT_FIRST_INTERNAL, /**< High frequency clock started */
@@ -120,6 +129,8 @@ typedef enum
} app_usbd_event_type_t;
/**
* @brief Specific application event structure
*
@@ -165,6 +176,7 @@ typedef union
*/
} app_usbd_complex_evt_t;
/**
* @brief Internal event variable type
*
@@ -188,6 +200,7 @@ typedef union
*/
} app_usbd_internal_evt_t;
#ifdef DOXYGEN
/**
* @brief Base instance of a USBD class
@@ -229,4 +242,3 @@ typedef ret_code_t (*app_usbd_ep_event_handler_t)(
#endif
#endif /* APP_USBD_TYPES_H__ */
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -37,8 +37,9 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "sdk_config.h"
#if APP_USBD_CLASS_CDC_ACM_ENABLED
#include "sdk_common.h"
#if NRF_MODULE_ENABLED(APP_USBD_CDC_ACM)
#include "app_usbd_cdc_acm.h"
#include <inttypes.h>
@@ -177,37 +178,29 @@ static inline nrf_drv_usbd_ep_t data_ep_out_addr_get(app_usbd_class_inst_t const
static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst,
app_usbd_setup_evt_t const * p_setup_ev)
{
switch (p_setup_ev->setup.bmRequest)
/* Only Get Descriptor standard IN request is supported by CDC class */
if ((app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_INTERFACE)
&&
(p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR))
{
case APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR:
size_t dsc_len = 0;
size_t max_size;
uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
/* Try to find descriptor in class internals*/
ret_code_t ret = app_usbd_class_descriptor_find(
p_inst,
p_setup_ev->setup.wValue.hb,
p_setup_ev->setup.wValue.lb,
p_trans_buff,
&dsc_len);
if (ret != NRF_ERROR_NOT_FOUND)
{
size_t dsc_len = 0;
/* Try to find descriptor in class internals*/
void const * p_dsc = app_usbd_class_descriptor_find(p_inst,
p_setup_ev->setup.wValue.hb,
p_setup_ev->setup.wValue.lb,
&dsc_len);
if (p_dsc != NULL)
{
return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_dsc, dsc_len);
}
break;
ASSERT(dsc_len < NRF_DRV_USBD_EPSIZE);
return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, dsc_len);
}
case APP_USBD_SETUP_STDREQ_GET_INTERFACE:
{
size_t tx_maxsize;
uint8_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_maxsize);
p_tx_buff[0] = 0;
return app_usbd_core_setup_rsp(&p_setup_ev->setup,
p_tx_buff,
sizeof(uint8_t));
}
default:
break;
}
return NRF_ERROR_NOT_SUPPORTED;
@@ -333,7 +326,7 @@ static ret_code_t cdc_acm_req_out_datastage(app_usbd_class_inst_t const * p_inst
p_cdc_acm_ctx->request.len);
ret_code_t ret;
CRITICAL_REGION_ENTER();
ret = app_usbd_core_setup_data_transfer(NRF_DRV_USBD_EPOUT0, &transfer);
ret = app_usbd_ep_transfer(NRF_DRV_USBD_EPOUT0, &transfer);
if (ret == NRF_SUCCESS)
{
const app_usbd_core_setup_data_handler_desc_t desc = {
@@ -348,6 +341,28 @@ static ret_code_t cdc_acm_req_out_datastage(app_usbd_class_inst_t const * p_inst
return ret;
}
/**
* @brief Reset port to default state.
*
* @param p_inst Generic class instance.
*/
static void cdc_acm_reset_port(app_usbd_class_inst_t const * p_inst)
{
app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
p_cdc_acm_ctx->line_state = 0;
// Set rx transfers configuration to default state.
p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
p_cdc_acm_ctx->bytes_left = 0;
p_cdc_acm_ctx->bytes_read = 0;
p_cdc_acm_ctx->last_read = 0;
p_cdc_acm_ctx->cur_read = 0;
p_cdc_acm_ctx->p_copy_pos = p_cdc_acm_ctx->internal_rx_buf;
}
/**
* @brief Internal SETUP class OUT request handler.
*
@@ -404,9 +419,18 @@ static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst,
/*Abort DATA endpoints on port close */
nrf_drv_usbd_ep_t ep;
ep = data_ep_in_addr_get(p_inst);
usbd_drv_ep_abort(ep);
nrf_drv_usbd_ep_abort(ep);
ep = data_ep_out_addr_get(p_inst);
usbd_drv_ep_abort(ep);
nrf_drv_usbd_ep_abort(ep);
// Set rx transfers configuration to default state.
p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
p_cdc_acm_ctx->bytes_left = 0;
p_cdc_acm_ctx->bytes_read = 0;
p_cdc_acm_ctx->last_read = 0;
p_cdc_acm_ctx->cur_read = 0;
p_cdc_acm_ctx->p_copy_pos = p_cdc_acm_ctx->internal_rx_buf;
}
return NRF_SUCCESS;
@@ -460,6 +484,193 @@ static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst,
return NRF_ERROR_NOT_SUPPORTED;
}
/**
* @brief CDC ACM consumer
*
* @note See @ref nrf_drv_usbd_consumer_t
*/
static bool cdc_acm_consumer(nrf_drv_usbd_ep_transfer_t * p_next,
void * p_context,
size_t ep_size,
size_t data_size)
{
app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = (app_usbd_cdc_acm_ctx_t *) p_context;
p_next->size = data_size;
if (data_size <= p_cdc_acm_ctx->rx_transfer[0].read_left)
{
p_next->p_data.rx = p_cdc_acm_ctx->rx_transfer[0].p_buf;
p_cdc_acm_ctx->rx_transfer[0].p_buf += data_size;
p_cdc_acm_ctx->bytes_read += data_size;
p_cdc_acm_ctx->rx_transfer[0].read_left -= data_size;
NRF_LOG_DEBUG("Received %d bytes. Space left in user buffer: %d bytes.",
data_size,
p_cdc_acm_ctx->rx_transfer[0].read_left);
return (p_cdc_acm_ctx->rx_transfer[0].read_left) != 0;
}
else
{
p_next->p_data.rx = p_cdc_acm_ctx->internal_rx_buf;
p_cdc_acm_ctx->cur_read = data_size;
NRF_LOG_DEBUG("Received %d bytes. Stored in internal buffer.", data_size);
return false;
}
}
/**
* @brief CDC ACM single transfer consumer
*
* This function finalizes transfer after any received block
*
* @note See @ref nrf_drv_usbd_consumer_t
*/
static bool cdc_acm_single_shoot_consumer(nrf_drv_usbd_ep_transfer_t * p_next,
void * p_context,
size_t ep_size,
size_t data_size)
{
app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = (app_usbd_cdc_acm_ctx_t *) p_context;
p_next->size = data_size;
if (data_size <= p_cdc_acm_ctx->rx_transfer[0].read_left)
{
p_next->p_data.rx = p_cdc_acm_ctx->rx_transfer[0].p_buf;
p_cdc_acm_ctx->bytes_read = data_size;
p_cdc_acm_ctx->rx_transfer[0].read_left = data_size;
NRF_LOG_DEBUG("Received %d bytes. Space left in user buffer: %d bytes.",
data_size,
p_cdc_acm_ctx->rx_transfer[0].read_left);
}
else
{
p_next->p_data.rx = p_cdc_acm_ctx->internal_rx_buf;
p_cdc_acm_ctx->cur_read = data_size;
NRF_LOG_DEBUG("Received %d bytes. Stored in internal buffer.", data_size);
}
return false;
}
/**
* @brief Manage switching between user buffers and copying data from internal buffer.
*
* @param p_inst Generic USB class instance.
*
* @return Standard error code
*/
static ret_code_t cdc_acm_rx_block_finished(app_usbd_class_inst_t const * p_inst)
{
app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(p_inst);
nrf_drv_usbd_handler_desc_t handler_desc = {
.handler.consumer = cdc_acm_consumer,
.p_context = p_cdc_acm_ctx
};
if (p_cdc_acm_ctx->rx_transfer[0].read_left == 0) // Buffer completely filled by consumer
{
p_cdc_acm_ctx->last_read = p_cdc_acm_ctx->bytes_read;
p_cdc_acm_ctx->bytes_read = 0;
p_cdc_acm_ctx->bytes_left = 0;
if (p_cdc_acm_ctx->rx_transfer[1].p_buf != NULL)
{
p_cdc_acm_ctx->rx_transfer[0] = p_cdc_acm_ctx->rx_transfer[1];
p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
return app_usbd_ep_handled_transfer(ep, &handler_desc);
}
else
{
p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
return NRF_SUCCESS;
}
}
size_t bytes_read = p_cdc_acm_ctx->cur_read;
size_t bytes_to_cpy = bytes_read;
if (bytes_read > p_cdc_acm_ctx->rx_transfer[0].read_left)
{
bytes_to_cpy = p_cdc_acm_ctx->rx_transfer[0].read_left;
}
memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
p_cdc_acm_ctx->internal_rx_buf,
bytes_to_cpy);
// First buffer is full
p_cdc_acm_ctx->last_read = p_cdc_acm_ctx->bytes_read + bytes_to_cpy;
p_cdc_acm_ctx->bytes_read = 0;
p_cdc_acm_ctx->bytes_left = bytes_read - bytes_to_cpy;
p_cdc_acm_ctx->p_copy_pos = p_cdc_acm_ctx->internal_rx_buf + bytes_to_cpy;
if (p_cdc_acm_ctx->rx_transfer[1].p_buf != NULL)
{
// If there is second transfer, copy it to first
p_cdc_acm_ctx->rx_transfer[0] = p_cdc_acm_ctx->rx_transfer[1];
p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
while (p_cdc_acm_ctx->bytes_left > 0)
{
if (p_cdc_acm_ctx->bytes_left >= p_cdc_acm_ctx->rx_transfer[0].read_left)
{
// If there are enough bytes left in internal buffer to completely fill next transfer,
// we call user event handler to obtain next buffer and continue double buffering.
memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
p_cdc_acm_ctx->p_copy_pos,
p_cdc_acm_ctx->rx_transfer[0].read_left);
p_cdc_acm_ctx->bytes_left -= p_cdc_acm_ctx->rx_transfer[0].read_left;
p_cdc_acm_ctx->p_copy_pos += p_cdc_acm_ctx->rx_transfer[0].read_left;
p_cdc_acm_ctx->last_read = p_cdc_acm_ctx->rx_transfer[0].read_left;
user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_RX_DONE);
if (p_cdc_acm_ctx->rx_transfer[1].p_buf != NULL)
{
p_cdc_acm_ctx->rx_transfer[0] = p_cdc_acm_ctx->rx_transfer[1];
p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
}
else
{
// If user does not specify a second buffer, all data transfers are done
// and data left in internal buffer is lost.
p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
break;
}
}
else
{
memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
p_cdc_acm_ctx->p_copy_pos,
p_cdc_acm_ctx->bytes_left);
p_cdc_acm_ctx->bytes_read = p_cdc_acm_ctx->bytes_left;
p_cdc_acm_ctx->rx_transfer[0].read_left -= p_cdc_acm_ctx->bytes_left;
p_cdc_acm_ctx->rx_transfer[0].p_buf += p_cdc_acm_ctx->bytes_left;
break;
}
}
}
else
{
p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
}
if (p_cdc_acm_ctx->rx_transfer[0].p_buf != NULL)
{
return app_usbd_ep_handled_transfer(ep, &handler_desc);
}
return NRF_SUCCESS;
}
/**
* @brief Class specific endpoint transfer handler.
*
@@ -476,7 +687,7 @@ static ret_code_t cdc_acm_endpoint_ev(app_usbd_class_inst_t const * p_inst,
NRF_LOG_INFO("EPIN_COMM: notify");
return NRF_SUCCESS;
}
ret_code_t ret;
if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep))
{
switch (p_event->drv_evt.data.eptransfer.status)
@@ -497,9 +708,10 @@ static ret_code_t cdc_acm_endpoint_ev(app_usbd_class_inst_t const * p_inst,
switch (p_event->drv_evt.data.eptransfer.status)
{
case NRF_USBD_EP_OK:
ret = cdc_acm_rx_block_finished(p_inst);
NRF_LOG_INFO("EPOUT_DATA: %02x done", p_event->drv_evt.data.eptransfer.ep);
user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_RX_DONE);
return NRF_SUCCESS;
return ret;
case NRF_USBD_EP_WAITING:
case NRF_USBD_EP_ABORTED:
return NRF_SUCCESS;
@@ -527,6 +739,7 @@ static ret_code_t cdc_acm_event_handler(app_usbd_class_inst_t const * p_inst,
case APP_USBD_EVT_DRV_SOF:
break;
case APP_USBD_EVT_DRV_RESET:
cdc_acm_reset_port(p_inst);
break;
case APP_USBD_EVT_DRV_SETUP:
ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event);
@@ -539,19 +752,16 @@ static ret_code_t cdc_acm_event_handler(app_usbd_class_inst_t const * p_inst,
case APP_USBD_EVT_DRV_RESUME:
break;
case APP_USBD_EVT_INST_APPEND:
{
ret = app_usbd_class_sof_register(p_inst);
break;
}
case APP_USBD_EVT_INST_REMOVE:
{
ret = app_usbd_class_sof_unregister(p_inst);
break;
}
case APP_USBD_EVT_STARTED:
break;
case APP_USBD_EVT_STOPPED:
break;
case APP_USBD_EVT_POWER_REMOVED:
cdc_acm_reset_port(p_inst);
break;
default:
ret = NRF_ERROR_NOT_SUPPORTED;
break;
@@ -560,17 +770,186 @@ static ret_code_t cdc_acm_event_handler(app_usbd_class_inst_t const * p_inst,
return ret;
}
/**
* @brief @ref app_usbd_class_methods_t::get_descriptors
*/
static const void * cdc_acm_get_descriptors(app_usbd_class_inst_t const * p_inst,
size_t * p_size)
{
ASSERT(p_size != NULL);
app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
*p_size = p_cdc_acm->specific.inst.raw_desc_size;
return p_cdc_acm->specific.inst.p_raw_desc;
static bool cdc_acm_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
app_usbd_class_inst_t const * p_inst,
uint8_t * p_buff,
size_t max_size)
{
uint8_t cur_size = 0;
static uint8_t ifaces = 0;
app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
app_usbd_class_ep_conf_t const * cur_ep;
APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx);
// INTERFACE ASSOCIATION DESCRIPTOR
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x08, p_buff, cur_size, max_size); // bLength
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION,
p_buff,
cur_size,
max_size); // bDescriptorType = Interface Association
APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.comm_interface, p_buff, cur_size,
max_size); // bFirstInterface
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x02, p_buff, cur_size, max_size); // bInterfaceCount
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_COMM_CLASS, p_buff, cur_size, max_size); // bFunctionClass
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SUBCLASS_ACM, p_buff, cur_size, max_size); // bFunctionSubClass
APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.protocol, p_buff, cur_size, max_size); // bFunctionProtocol
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00, p_buff, cur_size, max_size); // iFunction
ifaces = app_usbd_class_iface_count_get(p_inst);
static uint8_t i = 0;
for (i = 0; i < ifaces; i++)
{
// INTERFACE DESCRIPTOR
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09, p_buff, cur_size, max_size); // bLength
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE, p_buff, cur_size, max_size); // bDescriptorType = Interface
static app_usbd_class_iface_conf_t const * cur_iface = 0;
cur_iface = app_usbd_class_iface_get(p_inst, i);
APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(cur_iface),
p_buff,
cur_size,
max_size); // bInterfaceNumber
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00, p_buff, cur_size, max_size); // bAlternateSetting
APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(cur_iface),
p_buff,
cur_size,
max_size); // bNumEndpoints
if (p_cdc_acm->specific.inst.comm_interface == app_usbd_class_iface_number_get(cur_iface))
{
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_COMM_CLASS, p_buff, cur_size, max_size); // bInterfaceClass = CDC COMM
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SUBCLASS_ACM, p_buff, cur_size, max_size); // bInterfaceSubclass
APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.protocol,
p_buff,
cur_size,
max_size); // bInterfaceProtocol
}
else if (p_cdc_acm->specific.inst.data_interface ==
app_usbd_class_iface_number_get(cur_iface))
{
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_DATA_CLASS, p_buff, cur_size, max_size); // bInterfaceClass = CDC DATA
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00, p_buff, cur_size, max_size); // bInterfaceSubclass
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00, p_buff, cur_size, max_size); // bInterfaceProtocol
}
else
{
ASSERT(0);
}
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00, p_buff, cur_size, max_size); // iInterface
if (p_cdc_acm->specific.inst.comm_interface == app_usbd_class_iface_number_get(cur_iface))
{
// HEADER DESCRIPTOR
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x05, p_buff, cur_size, max_size); // bLength
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE, p_buff, cur_size, max_size); // bDescriptorType = Class Specific Interface
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_HEADER, p_buff, cur_size, max_size); // bDescriptorSubtype = Header Functional Descriptor
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x10, p_buff, cur_size, max_size); // bcdCDC LSB
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01, p_buff, cur_size, max_size); // bcdCDC MSB
// CALL MANAGEMENT DESCRIPTOR
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x05, p_buff, cur_size, max_size); // bLength
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE, p_buff, cur_size, max_size); // bDescriptorType = Class Specific Interface
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_CALL_MGMT, p_buff, cur_size, max_size); // bDescriptorSubtype = Call Management Functional Descriptor
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x03, p_buff, cur_size, max_size); // bmCapabilities
APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.data_interface,
p_buff,
cur_size,
max_size); // bDataInterface
// ABSTRACT CONTROL MANAGEMENT DESCRIPTOR
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x04, p_buff, cur_size, max_size); // bLength
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE, p_buff, cur_size, max_size); // bDescriptorType = Class Specific Interface
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_ACM, p_buff, cur_size, max_size); // bDescriptorSubtype = Abstract Control Management Functional Descriptor
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x02, p_buff, cur_size, max_size); // bmCapabilities
// UNION DESCRIPTOR
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x05, p_buff, cur_size, max_size);
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE, p_buff, cur_size, max_size); // bDescriptorType = Class Specific Interface
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_UNION, p_buff, cur_size, max_size); // bDescriptorSubtype = Union Functional Descriptor
APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.comm_interface,
p_buff,
cur_size,
max_size); // bControlInterface
APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.data_interface,
p_buff,
cur_size,
max_size); // bSubordinateInterface
}
else if (p_cdc_acm->specific.inst.data_interface ==
app_usbd_class_iface_number_get(cur_iface))
{
;
}
else
{
ASSERT(0);
}
// ENDPOINT DESCRIPTORS
static uint8_t endpoints = 0;
endpoints = app_usbd_class_iface_ep_count_get(cur_iface);
static uint8_t j = 0;
for (j = 0; j < endpoints; j++)
{
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07, p_buff, cur_size, max_size); // bLength
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT, p_buff, cur_size, max_size); // bDescriptorType = Endpoint
cur_ep = app_usbd_class_iface_ep_get(cur_iface, j);
APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(cur_ep),
p_buff,
cur_size,
max_size); // bEndpointAddress
if (p_cdc_acm->specific.inst.comm_interface ==
app_usbd_class_iface_number_get(cur_iface))
{
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT,
p_buff,
cur_size,
max_size); // bmAttributes
}
else if (p_cdc_acm->specific.inst.data_interface ==
app_usbd_class_iface_number_get(cur_iface))
{
APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK,
p_buff,
cur_size,
max_size); // bmAttributes
}
else
{
ASSERT(0);
}
APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(NRF_DRV_USBD_EPSIZE), p_buff, cur_size, max_size); // wMaxPacketSize LSB
APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(NRF_DRV_USBD_EPSIZE), p_buff, cur_size, max_size); // wMaxPacketSize MSB
if (p_cdc_acm->specific.inst.comm_interface ==
app_usbd_class_iface_number_get(cur_iface))
{
APP_USBD_CLASS_DESCRIPTOR_WRITE(16, p_buff, cur_size, max_size); // bInterval
}
else if (p_cdc_acm->specific.inst.data_interface ==
app_usbd_class_iface_number_get(cur_iface))
{
APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00, p_buff, cur_size, max_size); // bInterval
}
else
{
ASSERT(0);
}
}
}
APP_USBD_CLASS_DESCRIPTOR_END(p_ctx);
}
/**
@@ -579,9 +958,10 @@ static const void * cdc_acm_get_descriptors(app_usbd_class_inst_t const * p_inst
*/
const app_usbd_class_methods_t app_usbd_cdc_acm_class_methods = {
.event_handler = cdc_acm_event_handler,
.get_descriptors = cdc_acm_get_descriptors,
.feed_descriptors = cdc_acm_feed_descriptors,
};
/** @} */
ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm,
const void * p_buf,
@@ -600,43 +980,151 @@ ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm,
nrf_drv_usbd_ep_t ep = data_ep_in_addr_get(p_inst);
NRF_DRV_USBD_TRANSFER_IN(transfer, p_buf, length);
return app_usbd_core_ep_transfer(ep, &transfer);
return app_usbd_ep_transfer(ep, &transfer);
}
size_t app_usbd_cdc_acm_rx_size(app_usbd_cdc_acm_t const * p_cdc_acm)
{
app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm);
nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(p_inst);
app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
size_t size;
ret_code_t ret = nrf_drv_usbd_ep_status_get(ep, &size);
if (ret != NRF_SUCCESS)
{
return 0;
}
return p_cdc_acm_ctx->last_read;
}
return size;
size_t app_usbd_cdc_acm_bytes_stored(app_usbd_cdc_acm_t const * p_cdc_acm)
{
app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
return p_cdc_acm_ctx->bytes_left;
}
ret_code_t app_usbd_cdc_acm_read(app_usbd_cdc_acm_t const * p_cdc_acm,
void * p_buf,
size_t length)
{
ASSERT((length % NRF_DRV_USBD_EPSIZE) == 0);
app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm);
ASSERT(p_buf != NULL);
ret_code_t ret;
app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
bool dtr_state = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ?
true : false;
if (!dtr_state)
if (0U == (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR))
{
/*Port is not opened*/
return NRF_ERROR_INVALID_STATE;
}
nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(p_inst);
NRF_DRV_USBD_TRANSFER_OUT(transfer, p_buf, length);
return app_usbd_core_ep_transfer(ep, &transfer);
#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
CRITICAL_REGION_ENTER();
#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
if (p_cdc_acm_ctx->rx_transfer[0].p_buf == NULL)
{
if (p_cdc_acm_ctx->bytes_left >= length)
{
memcpy(p_buf, p_cdc_acm_ctx->p_copy_pos, length);
p_cdc_acm_ctx->bytes_left -= length;
p_cdc_acm_ctx->p_copy_pos += length;
p_cdc_acm_ctx->last_read = length;
ret = NRF_SUCCESS;
}
else
{
p_cdc_acm_ctx->rx_transfer[0].p_buf = p_buf;
p_cdc_acm_ctx->rx_transfer[0].read_left = length;
nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(app_usbd_cdc_acm_class_inst_get(p_cdc_acm));
nrf_drv_usbd_handler_desc_t const handler_desc = {
.handler.consumer = cdc_acm_consumer,
.p_context = p_cdc_acm_ctx
};
if (p_cdc_acm_ctx->bytes_left > 0)
{
memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
p_cdc_acm_ctx->p_copy_pos,
p_cdc_acm_ctx->bytes_left);
p_cdc_acm_ctx->rx_transfer[0].read_left -= p_cdc_acm_ctx->bytes_left;
p_cdc_acm_ctx->rx_transfer[0].p_buf += p_cdc_acm_ctx->bytes_left;
p_cdc_acm_ctx->bytes_read = p_cdc_acm_ctx->bytes_left;
p_cdc_acm_ctx->bytes_left = 0;
}
ret = app_usbd_ep_handled_transfer(ep, &handler_desc);
if (ret == NRF_SUCCESS)
{
ret = NRF_ERROR_IO_PENDING;
}
}
}
else if (p_cdc_acm_ctx->rx_transfer[1].p_buf == NULL)
{
p_cdc_acm_ctx->rx_transfer[1].p_buf = p_buf;
p_cdc_acm_ctx->rx_transfer[1].read_left = length;
ret = NRF_ERROR_IO_PENDING;
}
else
{
ret = NRF_ERROR_BUSY;
}
#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
CRITICAL_REGION_EXIT();
#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
return ret;
}
ret_code_t app_usbd_cdc_acm_read_any(app_usbd_cdc_acm_t const * p_cdc_acm,
void * p_buf,
size_t length)
{
ASSERT(p_buf != NULL);
ret_code_t ret;
app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
if (0U == (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR))
{
/*Port is not opened*/
return NRF_ERROR_INVALID_STATE;
}
#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
CRITICAL_REGION_ENTER();
#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
if (p_cdc_acm_ctx->bytes_left > 0)
{
size_t to_copy = MIN(length, p_cdc_acm_ctx->bytes_left);
memcpy(p_buf, p_cdc_acm_ctx->p_copy_pos, to_copy);
p_cdc_acm_ctx->bytes_left -= to_copy;
p_cdc_acm_ctx->p_copy_pos += to_copy;
p_cdc_acm_ctx->last_read = to_copy;
ret = NRF_SUCCESS;
}
else
{
if (p_cdc_acm_ctx->rx_transfer[0].p_buf == NULL)
{
p_cdc_acm_ctx->rx_transfer[0].p_buf = p_buf;
p_cdc_acm_ctx->rx_transfer[0].read_left = length;
nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(app_usbd_cdc_acm_class_inst_get(p_cdc_acm));
nrf_drv_usbd_handler_desc_t const handler_desc = {
.handler.consumer = cdc_acm_single_shoot_consumer,
.p_context = p_cdc_acm_ctx
};
ret = app_usbd_ep_handled_transfer(ep, &handler_desc);
if (ret == NRF_SUCCESS)
{
ret = NRF_ERROR_IO_PENDING;
}
}
else
{
ret = NRF_ERROR_BUSY;
}
}
#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
CRITICAL_REGION_EXIT();
#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
return ret;
}
static ret_code_t cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm)
@@ -649,7 +1137,7 @@ static ret_code_t cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_a
NRF_DRV_USBD_TRANSFER_OUT(transfer,
&p_cdc_acm_ctx->request.payload,
sizeof(app_usbd_cdc_acm_notify_t));
return app_usbd_core_ep_transfer(ep, &transfer);
return app_usbd_ep_transfer(ep, &transfer);
}
ret_code_t app_usbd_cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm,
@@ -730,6 +1218,4 @@ ret_code_t app_usbd_cdc_acm_line_state_get(app_usbd_cdc_acm_t const * p_cdc_a
return ret;
}
#endif /* APP_USBD_CLASS_CDC_ACM_ENABLED */
/** @} */
#endif //NRF_MODULE_ENABLED(APP_USBD_CDC_ACM)
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -65,9 +65,9 @@ extern "C" {
*
* @details References:
* - "Universal Serial Bus Class Definitions for Communications Devices"
* Revision 1.2, November 3, 2010
* Revision 1.2, November 3, 2010
* - "Universal Serial Bus Communications Class Subclass Specification for PSTN Devices"
* Revision 1.2, February 9, 2007
* Revision 1.2, February 9, 2007
*
* @{
*/
@@ -144,21 +144,33 @@ typedef enum app_usbd_cdc_acm_user_event_e {
* @brief Global definition of app_usbd_cdc_acm_t class instance.
*
* @param instance_name Name of global instance.
* @param interfaces_configs Interfaces configurations.
* @param user_ev_handler User event handler (optional).
* @param raw_descriptors Raw descriptor table.
* @param comm_ifc Interface number of cdc_acm control.
* @param data_ifc Interface number of cdc_acm DATA.
* @param comm_ein COMM subclass IN endpoint.
* @param data_ein DATA subclass IN endpoint.
* @param data_eout DATA subclass OUT endpoint.
* @param cdc_protocol CDC protocol @ref app_usbd_cdc_comm_protocol_t
*
* @note This macro is just simplified version of @ref APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL.
*
*/
#define APP_USBD_CDC_ACM_GLOBAL_DEF(instance_name, \
interfaces_configs, \
user_ev_handler, \
raw_descriptors) \
APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \
interfaces_configs, \
user_ev_handler, \
raw_descriptors)
#define APP_USBD_CDC_ACM_GLOBAL_DEF(instance_name, \
user_ev_handler, \
comm_ifc, \
data_ifc, \
comm_ein, \
data_ein, \
data_eout, \
cdc_protocol) \
APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \
user_ev_handler, \
comm_ifc, \
data_ifc, \
comm_ein, \
data_ein, \
data_eout, \
cdc_protocol) \
/**
* @brief Helper function to get class instance from CDC ACM class.
@@ -217,10 +229,10 @@ ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm,
size_t length);
/**
* @brief Returns the amount of data to be read.
* @brief Returns the amount of data that was read.
*
* This function should be used on @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event to get
* information how many bytes have been transfered.
* information how many bytes have been transfered into user buffer.
*
* @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
*
@@ -228,18 +240,73 @@ ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm,
*/
size_t app_usbd_cdc_acm_rx_size(app_usbd_cdc_acm_t const * p_cdc_acm);
/**
* @brief Returns the amount of data that was stored into internal buffer
*
* This function should be used on @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event to get
* information how many bytes are waiting in internal buffer.
*
* @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
*
* @return Amount of data waiting.
*/
size_t app_usbd_cdc_acm_bytes_stored(app_usbd_cdc_acm_t const * p_cdc_acm);
/**
* @brief Reads data from CDC ACM serial port.
*
* This function uses internal buffer and double buffering for continuous transmission.
*
* If there is enough data in internal buffer to fill user buffer, NRF_SUCCESS is
* returned and data is immediately available in the user buffer.
*
* If not, up to two user buffers can be scheduled, function returns NRF_ERROR_IO_PENDING
* when first buffer is filled and @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event is generated.
*
* @sa app_usbd_cdc_acm_read_any
* @sa app_usbd_cdc_acm_rx_size
*
* @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
* @param[out] p_buf Output buffer.
* @param[in] length Output buffer length (must by multiple of @ref NRF_DRV_USBD_EPSIZE).
* @param[in] length Number of bytes to read.
*
* @return Standard error code.
* @retval NRF_SUCCESS Data is stored into user buffer.
* @retval NRF_ERROR_IO_PENDING Awaiting transmission, when data is stored into user buffer,
* @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event will be raised.
* @retval NRF_ERROR_BUSY There are already 2 buffers queued for transfers.
* @retval other Standard error code.
*/
ret_code_t app_usbd_cdc_acm_read(app_usbd_cdc_acm_t const * p_cdc_acm,
void * p_buf,
size_t length);
/**
* @brief Read any data from CDC ACM port up to given buffer size
*
* This function is very similar to the @ref app_usbd_cdc_acm_read but it returns
* data as quick as any data is available, even if the given buffer was not totally full.
*
* @note This function cannot use double buffering.
* @note To check the number of bytes really read use @ref app_usbd_cdc_acm_rx_size
* function.
*
* @sa app_usbd_cdc_acm_read
* @sa app_usbd_cdc_acm_rx_size
*
* @param p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
* @param[out] p_buf Output buffer.
* @param[in] length Maximum number of bytes to read.
*
* @retval NRF_SUCCESS Data is stored into user buffer.
* @retval NRF_ERROR_IO_PENDING Awaiting transmission, when data is stored into user buffer,
* @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event will be raised.
* @retval NRF_ERROR_BUSY There is already buffer set for a transfer.
* @retval other Standard error code.
*/
ret_code_t app_usbd_cdc_acm_read_any(app_usbd_cdc_acm_t const * p_cdc_acm,
void * p_buf,
size_t length);
/**
* @brief Serial state notifications.
* */
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -83,8 +83,13 @@ typedef void (*app_usbd_cdc_acm_user_ev_handler_t)(app_usbd_class_inst_t const *
* @brief CDC ACM class part of class instance data.
*/
typedef struct {
uint8_t const * p_raw_desc; //!< CDC ACM class descriptors.
size_t raw_desc_size; //!< CDC ACM class descriptors size.
uint8_t comm_interface; //!< Interface number of cdc_acm control.
uint8_t comm_epin; //!< COMM subclass IN endpoint.
uint8_t data_interface; //!< Interface number of cdc_acm DATA.
uint8_t data_epout; //!< DATA subclass OUT endpoint.
uint8_t data_epin; //!< DATA subclass IN endpoint.
app_usbd_cdc_comm_protocol_t protocol; //!< User specified CDC protocol.
app_usbd_cdc_acm_user_ev_handler_t user_ev_handler; //!< User event handler.
} app_usbd_cdc_acm_inst_t;
@@ -111,16 +116,33 @@ typedef struct {
} payload;
} app_usbd_cdc_acm_req_t;
/**
* @brief CDC ACM rx transfer buffer
*/
typedef struct {
uint8_t * p_buf; //!< User buffer pointer.
size_t read_left; //!< Bytes left to read into buffer.
} cdc_rx_buffer_t;
/**
* @brief CDC ACM class context
*/
typedef struct {
app_usbd_cdc_acm_req_t request; //!< CDC ACM class request.
app_usbd_cdc_line_coding_t line_coding; //!< CDC ACM current line coding.
app_usbd_cdc_acm_req_t request; //!< CDC ACM class request.
app_usbd_cdc_line_coding_t line_coding; //!< CDC ACM current line coding.
uint16_t line_state; //!< CDC ACM line state bitmap, DTE side.
uint16_t serial_state; //!< CDC ACM serial state bitmap, DCE side.
uint16_t line_state; //!< CDC ACM line state bitmap, DTE side.
uint16_t serial_state; //!< CDC ACM serial state bitmap, DCE side.
cdc_rx_buffer_t rx_transfer[2]; //!< User receive transfers.
uint8_t internal_rx_buf[NRF_DRV_USBD_EPSIZE]; //!< Internal receive buffer.
uint8_t * p_copy_pos; //!< Current copy position from internal buffer.
size_t bytes_left; //!< Bytes left in internal buffer to copy.
size_t bytes_read; //!< Bytes currently written to user buffer.
size_t last_read; //!< Bytes read in last transfer.
size_t cur_read; //!< Bytes currently read to internal buffer.
} app_usbd_cdc_acm_ctx_t;
@@ -132,8 +154,8 @@ typedef struct {
* @param iface_comm Interface number of cdc_acm control.
* @param epin_comm COMM subclass IN endpoint.
* @param iface_data Interface number of cdc_acm DATA.
* @param epin_data COMM subclass IN endpoint.
* @param epout_data COMM subclass OUT endpoint.
* @param epin_data DATA subclass IN endpoint.
* @param epout_data DATA subclass OUT endpoint.
*
*/
#define APP_USBD_CDC_ACM_CONFIG(iface_comm, epin_comm, iface_data, epin_data, epout_data) \
@@ -152,15 +174,25 @@ typedef struct {
/**
* @brief Configures cdc_acm class instance.
*
* @param descriptors Mass storage class descriptors (raw table).
* @param user_event_handler User event handler.
* @param comm_ifc Interface number of cdc_acm control.
* @param comm_ein COMM subclass IN endpoint.
* @param data_ifc Interface number of cdc_acm DATA.
* @param data_ein DATA subclass IN endpoint.
* @param data_eout DATA subclass OUT endpoint.
* @param cdc_protocol CDC protocol.
*/
#define APP_USBD_CDC_ACM_INST_CONFIG(descriptors, user_event_handler) \
.inst = { \
.p_raw_desc = descriptors, \
.raw_desc_size = sizeof(descriptors), \
.user_ev_handler = user_event_handler, \
}
#define APP_USBD_CDC_ACM_INST_CONFIG(user_event_handler, comm_ifc, comm_ein, data_ifc, data_ein, \
data_eout, cdc_protocol) \
.inst = { \
.user_ev_handler = user_event_handler, \
.comm_interface = comm_ifc, \
.comm_epin = comm_ifc, \
.data_interface = data_ifc, \
.data_epin = data_ein, \
.data_epout = data_eout, \
.protocol = cdc_protocol \
}
/**
* @brief Specific class data for cdc_acm class.
@@ -176,11 +208,11 @@ typedef struct {
* @param interface_number Interface number.
* @param ... Extracted endpoint list.
*/
#define APP_USBD_CDC_ACM_DSC_CONFIG(interface_number, ...) { \
APP_USBD_CDC_ACM_INTERFACE_DSC(interface_number, \
0, \
0, \
APP_USBD_CDC_ACM_SUBCLASS_CDC_ACMCONTROL) \
#define APP_USBD_CDC_ACM_DSC_CONFIG(interface_number, ...) { \
APP_USBD_CDC_ACM_INTERFACE_DSC(interface_number, \
0, \
0, \
APP_USBD_CDC_ACM_SUBCLASS_CDC_ACMCONTROL) \
}
/**
@@ -192,23 +224,38 @@ extern const app_usbd_class_methods_t app_usbd_cdc_acm_class_methods;
/**
* @brief Global definition of @ref app_usbd_cdc_acm_t class.
*
* @param instance_name Name of global instance.
* @param interfaces_configs Interfaces configurations.
* @param user_ev_handler User event handler (optional).
* @param raw_descriptors Raw descriptor table.
* @param instance_name Name of global instance.
* @param user_ev_handler User event handler.
* @param comm_ifc Interface number of cdc_acm control.
* @param data_ifc Interface number of cdc_acm DATA.
* @param comm_ein COMM subclass IN endpoint.
* @param data_ein DATA subclass IN endpoint.
* @param data_eout DATA subclass OUT endpoint.
* @param cdc_protocol CDC protocol @ref app_usbd_cdc_comm_protocol_t
*/
#define APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \
interfaces_configs, \
user_ev_handler, \
raw_descriptors) \
APP_USBD_CLASS_INST_GLOBAL_DEF( \
instance_name, \
app_usbd_cdc_acm, \
&app_usbd_cdc_acm_class_methods, \
interfaces_configs, \
(APP_USBD_CDC_ACM_INST_CONFIG(raw_descriptors, user_ev_handler)) \
)
/*lint -save -emacro(26 64 123 505 651, APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL)*/
#define APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \
user_ev_handler, \
comm_ifc, \
data_ifc, \
comm_ein, \
data_ein, \
data_eout, \
cdc_protocol) \
APP_USBD_CLASS_INST_GLOBAL_DEF( \
instance_name, \
app_usbd_cdc_acm, \
&app_usbd_cdc_acm_class_methods, \
APP_USBD_CDC_ACM_CONFIG(comm_ifc, comm_ein, data_ifc, data_ein, data_eout), \
(APP_USBD_CDC_ACM_INST_CONFIG(user_ev_handler, \
comm_ifc, \
comm_ein, \
data_ifc, \
data_ein, \
data_eout, \
cdc_protocol)) \
)
/*lint -restore*/
/** @} */
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -40,16 +40,16 @@
#ifndef APP_USBD_CDC_DESC_H__
#define APP_USBD_CDC_DESC_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include "app_usbd_descriptor.h"
#include "app_usbd_cdc_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup app_usbd_cdc_desc CDC class descriptors
* @brief @tagAPI52840 Descriptors used in the USB CDC class implementation.
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
@@ -40,13 +40,13 @@
#ifndef APP_USBD_CDC_TYPES_H__
#define APP_USBD_CDC_TYPES_H__
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
/**
* @defgroup app_usbd_cdc_types CDC class types
@@ -1,30 +1,30 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
*
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -35,7 +35,7 @@
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*/
#ifndef APP_USBD_STRING_CONFIG_H
#define APP_USBD_STRING_CONFIG_H
@@ -99,7 +99,7 @@
* @note
* There is only one SERIAL number inside the library and it is Language independent.
*/
#define APP_USBD_STRING_SERIAL gExternSerialNumber
#define APP_USBD_STRING_SERIAL g_extern_serial_number
/**
* @brief Define whether @ref APP_USBD_STRING_SERIAL is created by @ref APP_USBD_STRING_DESC
Binary file not shown.
@@ -1,39 +1,35 @@
; Windows 2000, XP, Vista, 7 and 8 (x32 and x64) driver for Nordic CDC ACM OpenThread device
; Copyright (c) 2017 Nordic Semiconductor
; Windows 2000, XP, Vista, 7 and 8 (x32 and x64) driver for Nordic CDC ACM example
[Version]
Signature = "$Windows NT$"
Class = Ports
ClassGuid = {4D36E978-E325-11CE-BFC1-08002BE10318}
Provider = %Manufacturer%
LayoutFile = layout.inf
DriverVer = 01/08/2013,6.0.0.0
CatalogFile = nordic_cdc_acm.cat
;----------------------------------------------------------
; Targets
;----------------------------------------------------------
[Manufacturer]
%Manufacturer%=DeviceList, NTAMD64, NTIA64, NT
%Manufacturer%=DeviceList, NTAMD64, NTIA64, NTx86
[DeviceList]
%NORDIC_CDC_ACM_EXAMPLE%=DriverInstall, USB\VID_1915&PID_CAFE
[DeviceList.NTx86]
%NORDIC_CDC_ACM_EXAMPLE%=DriverInstall, USB\VID_1915&PID_CAFE&MI_00
[DeviceList.NTAMD64]
%NORDIC_CDC_ACM_EXAMPLE%=DriverInstall.NTamd64, USB\VID_1915&PID_CAFE
%NORDIC_CDC_ACM_EXAMPLE%=DriverInstall.NTamd64, USB\VID_1915&PID_CAFE&MI_00
[DeviceList.NTIA64]
%NORDIC_CDC_ACM_EXAMPLE%=DriverInstall.NTamd64, USB\VID_1915&PID_CAFE
%NORDIC_CDC_ACM_EXAMPLE%=DriverInstall.NTamd64, USB\VID_1915&PID_CAFE&MI_00
[DeviceList.NT]
%NORDIC_CDC_ACM_EXAMPLE%=DriverInstall.NT, USB\VID_1915&PID_CAFE
;----------------------------------------------------------
; Windows 2000, XP, Vista, Windows 7, Windows 8 - 32bit
;----------------------------------------------------------
[Reader_Install.NTx86]
[DestinationDirs]
DefaultDestDir=12
@@ -45,7 +41,6 @@ CopyFiles=DriverInstall.NT.Copy
AddReg=DriverInstall.NT.AddReg
[DriverInstall.NT.Copy]
usbser.sys
[DriverInstall.NT.AddReg]
HKR,,DevLoader,,*ntkern
@@ -53,6 +48,7 @@ HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[DriverInstall.NT.Services]
include=mdmcpq.inf
AddService = usbser, 0x00000002, DriverService.NT
[DriverService.NT]
@@ -73,7 +69,6 @@ CopyFiles=DriverCopyFiles.NTamd64
AddReg=DriverInstall.NTamd64.AddReg
[DriverCopyFiles.NTamd64]
usbser.sys,,,0x20
[DriverInstall.NTamd64.AddReg]
HKR,,DevLoader,,*ntkern
@@ -81,14 +76,7 @@ HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[DriverInstall.NTamd64.Services]
AddService=usbser, 0x00000002, DriverService.NTamd64
[DriverService.NTamd64]
DisplayName=%Serial.SvcDesc%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\usbser.sys
AddService=usbser, 0x00000002, DriverService.NT
;----------------------------------------------------------
; String
+56
View File
@@ -0,0 +1,56 @@
# Changelog
All notable changes to this project are documented in this file.
## [Unreleased]
### Added
- Added wait-for function to improve time-out functionality in QSPI and SAADC drivers.
- Added glue layer for interrupt pending set/clear and is set functions.
- Added new interrupts and events to UARTE HAL.
### Changed
- Extended input pin configuration in GPIOTE driver.
- Unified the way of checking if required event handler was provided. Now, all drivers do it with assertion.
- Improved condition checking in uninit and init functions in SAADC driver.
- Enabled RNG bias correction by default.
- Updated MDK to 8.15.4.
- Refactored ADC driver and HAL.
- Corrected TIMER asserts to make it usable with PPI in debug.
- Improved buffer handling in I2S driver. The API of the driver has been sligthly modified.
### Fixed
- Fixed result value casting in TEMP HAL.
- Fixed types of conversion result and buffer size in ADC HAL and driver.
- Fixed timeout in SAADC driver in abort function.
## [0.8.0] - 2017-12-20
### Added
- Added XIP support in the QSPI driver.
- Implemented Errata 132 in the CLOCK driver.
- Added function for checking if a TIMER instance is enabled.
- Added extended SPIM support.
### Changed
- Updated MDK to 8.15.0. Introduced Segger Embedded Studio startup files.
- Updated drivers: COMP, PWM, QDEC, SAADC, SPIS, TIMER, TWI, TWIS.
- Changed the type used for transfer lengths to 'size_t' in drivers: SPI, SPIM, SPIS, TWI, TWIM, TWIS, UART, UARTE. Introduced checking of EasyDMA transfers limits.
- Updated HALs: COMP, NVMC, UART, UARTE, USBD.
- Updated template files and documentation of configuration options.
### Fixed
- Fixed TWI and TWIM drivers so that they now support GPIOs from all ports.
- Fixed definitions related to compare channels in the TIMER HAL.
### Removed
- Removed the possibility of passing NULL instead of configuration to get default settings during drivers initialization.
- Removed support for UART1 and PRS box #5.
## [0.7.0] - 2017-10-20
### Added
- This CHANGELOG.md file.
- README.md file with simple description and explanations.
- HAL for: ADC, CLOCK, COMP, ECB, EGU, GPIO, GPIOTE, I2S, LPCOMP, NVMC, PDM, POWER, PPI, PWM, QDEC, QSPI, RNG, RTC, SAADC, SPI, SPIM, SPIS, ARM(R) SysTick, TEMP, TIMER, TWI, TWIM, TWIS, UART, UARTE, USBD, WDT.
- Drivers for: ADC, CLOCK, COMP, GPIOTE, I2S, LPCOMP, PDM, POWER, PWM, QDEC, QSPI, RNG, RTC, SAADC, SPI, SPIM, SPIS, ARM(R) SysTick, TIMER, TWI, TWIM, TWIS, UART, UARTE, WDT.
- Allocators for: PPI, SWI/EGU.
- MDK in version 8.14.0.
- Offline documentation for every added driver and simple integration description.
- Template integration files.
+39
View File
@@ -0,0 +1,39 @@
/**
* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
+37
View File
@@ -0,0 +1,37 @@
# nrfx
## Overview
nrfx is an extract from the nRF5 SDK that contains solely the drivers for
peripherals present in Nordic SoCs, for convenience complemented with the MDK
package containing required structures and bitfields definitions, startup
files etc.
## Supported SoCs
* nRF51 Series
* nRF52810
* nRF52832
* nRF52840
## Directories
```
.
├── doc # Project documentation files
├── drivers # nrfx drivers files
│ └── include # nrfx drivers headers
│ └── src # nrfx drivers sources
├── hal # Hardware Access Layer files
├── mdk # Nordic MDK files
├── soc # Nordic SoC related files
└── templates # Templates of nrfx integration files
```
## Generating documentation
nrfx documentation is availabe in the `doc\html` folder of the release package.
You can also generate documentation yourself from the source code. To do it, install doxygen
and run one of the scripts: `generate_html_doc.bat` or `generate_html_doc.sh`. Generated
documentation will be stored in the `doc\html` directory. Use `index.html` to open it.
@@ -0,0 +1,156 @@
/**
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_BITMASK_H
#define NRF_BITMASK_H
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_bitmask Bitmask module
* @{
* @ingroup nrfx
* @brief Bitmask managing module.
*/
#define BITMASK_BYTE_GET(abs_bit) ((abs_bit)/8)
#define BITMASK_RELBIT_GET(abs_bit) ((abs_bit) & 0x00000007)
/**
* Function for checking if bit in the multi-byte bit mask is set.
*
* @param bit Bit index.
* @param p_mask A pointer to mask with bit fields.
*
* @return 0 if bit is not set, positive value otherwise.
*/
__STATIC_INLINE uint32_t nrf_bitmask_bit_is_set(uint32_t bit, void const * p_mask)
{
uint8_t const * p_mask8 = (uint8_t const *)p_mask;
uint32_t byte_idx = BITMASK_BYTE_GET(bit);
bit = BITMASK_RELBIT_GET(bit);
return (1 << bit) & p_mask8[byte_idx];
}
/**
* Function for setting a bit in the multi-byte bit mask.
*
* @param bit Bit index.
* @param p_mask A pointer to mask with bit fields.
*/
__STATIC_INLINE void nrf_bitmask_bit_set(uint32_t bit, void * p_mask)
{
uint8_t * p_mask8 = (uint8_t *)p_mask;
uint32_t byte_idx = BITMASK_BYTE_GET(bit);
bit = BITMASK_RELBIT_GET(bit);
p_mask8[byte_idx] |= (1 << bit);
}
/**
* Function for clearing a bit in the multi-byte bit mask.
*
* @param bit Bit index.
* @param p_mask A pointer to mask with bit fields.
*/
__STATIC_INLINE void nrf_bitmask_bit_clear(uint32_t bit, void * p_mask)
{
uint8_t * p_mask8 = (uint8_t *)p_mask;
uint32_t byte_idx = BITMASK_BYTE_GET(bit);
bit = BITMASK_RELBIT_GET(bit);
p_mask8[byte_idx] &= ~(1 << bit);
}
/**
* Function for performing bitwise OR operation on two multi-byte bit masks.
*
* @param p_mask1 A pointer to the first bit mask.
* @param p_mask2 A pointer to the second bit mask.
* @param p_out_mask A pointer to the output bit mask.
* @param length Length of output mask in bytes.
*/
__STATIC_INLINE void nrf_bitmask_masks_or(void const * p_mask1,
void const * p_mask2,
void * p_out_mask,
uint32_t length)
{
uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1;
uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2;
uint8_t * p_mask8_out = (uint8_t *)p_out_mask;
uint32_t i;
for (i = 0; i < length; i++)
{
p_mask8_out[i] = p_mask8_1[i] | p_mask8_2[i];
}
}
/**
* Function for performing bitwise AND operation on two multi-byte bit masks.
*
* @param p_mask1 A pointer to the first bit mask.
* @param p_mask2 A pointer to the second bit mask.
* @param p_out_mask A pointer to the output bit mask.
* @param length Length of output mask in bytes.
*/
__STATIC_INLINE void nrf_bitmask_masks_and(void const * p_mask1,
void const * p_mask2,
void * p_out_mask,
uint32_t length)
{
uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1;
uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2;
uint8_t * p_mask8_out = (uint8_t *)p_out_mask;
uint32_t i;
for (i = 0; i < length; i++)
{
p_mask8_out[i] = p_mask8_1[i] & p_mask8_2[i];
}
}
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_BITMASK_H
@@ -0,0 +1,281 @@
/**
* Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_ADC_H__
#define NRFX_ADC_H__
#include <nrfx.h>
#include <hal/nrf_adc.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_adc ADC driver
* @{
* @ingroup nrf_adc
* @brief Analog-to-Digital Converter (ADC) peripheral driver.
*/
/**
* @brief Driver event types.
*/
typedef enum
{
NRFX_ADC_EVT_DONE, ///< Event generated when the buffer is filled with samples.
NRFX_ADC_EVT_SAMPLE, ///< Event generated when the requested channel is sampled.
} nrfx_adc_evt_type_t;
/**
* @brief Analog-to-digital converter driver DONE event.
*/
typedef struct
{
nrf_adc_value_t * p_buffer; ///< Pointer to the buffer with converted samples.
uint16_t size; ///< Number of samples in the buffer.
} nrfx_adc_done_evt_t;
/**
* @brief Analog-to-digital converter driver SAMPLE event.
*/
typedef struct
{
nrf_adc_value_t sample; ///< Converted sample.
} nrfx_adc_sample_evt_t;
/**
* @brief Analog-to-digital converter driver event.
*/
typedef struct
{
nrfx_adc_evt_type_t type; ///< Event type.
union
{
nrfx_adc_done_evt_t done; ///< Data for DONE event.
nrfx_adc_sample_evt_t sample; ///< Data for SAMPLE event.
} data;
} nrfx_adc_evt_t;
/**@brief Macro for initializing the ADC channel with the default configuration. */
#define NRFX_ADC_DEFAULT_CHANNEL(analog_input) \
{ \
NULL, \
{ \
.resolution = NRF_ADC_CONFIG_RES_10BIT, \
.scaling = NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE, \
.reference = NRF_ADC_CONFIG_REF_VBG, \
.input = (analog_input), \
.extref = NRF_ADC_CONFIG_EXTREFSEL_NONE \
} \
}
// Forward declaration of the nrfx_adc_channel_t type.
typedef struct nrfx_adc_channel_s nrfx_adc_channel_t;
/**
* @brief ADC channel.
*
* This structure is defined by the user and used by the driver. Therefore, it should
* not be defined on the stack as a local variable.
*/
struct nrfx_adc_channel_s
{
nrfx_adc_channel_t * p_next; ///< Pointer to the next enabled channel (for internal use).
nrf_adc_config_t config; ///< ADC configuration for the current channel.
};
/**
* @brief ADC configuration.
*/
typedef struct
{
uint8_t interrupt_priority; ///< Priority of ADC interrupt.
} nrfx_adc_config_t;
/** @brief ADC default configuration. */
#define NRFX_ADC_DEFAULT_CONFIG \
{ \
.interrupt_priority = NRFX_ADC_CONFIG_IRQ_PRIORITY \
}
/**
* @brief User event handler prototype.
*
* This function is called when the requested number of samples has been processed.
*
* @param p_event Event.
*/
typedef void (*nrfx_adc_event_handler_t)(nrfx_adc_evt_t const * p_event);
/**
* @brief Function for initializing the ADC.
*
* If a valid event handler is provided, the driver is initialized in non-blocking mode.
* If event_handler is NULL, the driver works in blocking mode.
*
* @param[in] p_config Pointer to the structure with initial configuration.
* @param[in] event_handler Event handler provided by the user.
*
* @retval NRFX_SUCCESS If initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE If the driver is already initialized.
*/
nrfx_err_t nrfx_adc_init(nrfx_adc_config_t const * p_config,
nrfx_adc_event_handler_t event_handler);
/**
* @brief Function for uninitializing the ADC.
*
* This function stops all ongoing conversions and disables all channels.
*/
void nrfx_adc_uninit(void);
/**
* @brief Function for enabling an ADC channel.
*
* This function configures and enables the channel. When @ref nrfx_adc_buffer_convert is
* called, all channels that have been enabled with this function are sampled.
*
* @note The channel instance variable @p p_channel is used by the driver as an item
* in a list. Therefore, it cannot be an automatic variable that is located on the stack.
*/
void nrfx_adc_channel_enable(nrfx_adc_channel_t * const p_channel);
/**
* @brief Function for disabling an ADC channel.
*/
void nrfx_adc_channel_disable(nrfx_adc_channel_t * const p_channel);
/**
* @brief Function for starting ADC sampling.
*
* This function triggers single ADC sampling. If more than one channel is enabled, the driver
* emulates scanning and all channels are sampled in the order they were enabled.
*/
void nrfx_adc_sample(void);
/**
* @brief Function for executing a single ADC conversion.
*
* This function selects the desired input and starts a single conversion. If a valid pointer
* is provided for the result, the function blocks until the conversion is completed. Otherwise, the
* function returns when the conversion is started, and the result is provided in an event (driver
* must be initialized in non-blocking mode, otherwise an assertion will fail). The function will
* fail if ADC is busy. The channel does not need to be enabled to perform a single conversion.
*
* @param[in] p_channel Channel.
* @param[out] p_value Pointer to the location where the result should be placed. Unless NULL is
* provided, the function is blocking.
*
* @retval NRFX_SUCCESS If conversion was successful.
* @retval NRFX_ERROR_BUSY If the ADC driver is busy.
*/
nrfx_err_t nrfx_adc_sample_convert(nrfx_adc_channel_t const * const p_channel,
nrf_adc_value_t * p_value);
/**
* @brief Function for converting data to the buffer.
*
* If the driver is initialized in non-blocking mode, this function returns when the first
* conversion is set up. When the buffer is filled, the application is notified by the event
* handler. If the driver is initialized in blocking mode, the function returns when the buffer is
* filled.
*
* Conversion is done on all enabled channels, but it is not triggered by this
* function. This function will prepare the ADC for sampling and then
* wait for the SAMPLE task. Sampling can be triggered manually by the @ref
* nrfx_adc_sample function or by PPI using the @ref NRF_ADC_TASK_START task.
*
* @note If more than one channel is enabled, the function emulates scanning, and
* a single START task will trigger conversion on all enabled channels. For example:
* If 3 channels are enabled and the user requests 6 samples, the completion event
* handler will be called after 2 START tasks.
*
* @note The application must adjust the sampling frequency. The maximum frequency
* depends on the sampling timer and the maximum latency of the ADC interrupt. If
* an interrupt is not handled before the next sampling is triggered, the sample
* will be lost.
*
* @param[in] buffer Result buffer.
* @param[in] size Buffer size in samples.
*
* @retval NRFX_SUCCESS If conversion was successful.
* @retval NRFX_ERROR_BUSY If the driver is busy.
*/
nrfx_err_t nrfx_adc_buffer_convert(nrf_adc_value_t * buffer, uint16_t size);
/**
* @brief Function for retrieving the ADC state.
*
* @retval true If the ADC is busy.
* @retval false If the ADC is ready.
*/
bool nrfx_adc_is_busy(void);
/**
* @brief Function for getting the address of the ADC START task.
*
* This function is used to get the address of the START task, which can be used to trigger ADC
* conversion.
*
* @return Start task address.
*/
__STATIC_INLINE uint32_t nrfx_adc_start_task_get(void);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE uint32_t nrfx_adc_start_task_get(void)
{
return nrf_adc_task_address_get(NRF_ADC_TASK_START);
}
#endif
void nrfx_adc_irq_handler(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRFX_ADC_H__
@@ -0,0 +1,223 @@
/**
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_CLOCK_H__
#define NRFX_CLOCK_H__
#include <nrfx.h>
#include <hal/nrf_clock.h>
#include <nrfx_power_clock.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_clock CLOCK driver
* @{
* @ingroup nrf_clock
* @brief CLOCK peripheral driver.
*/
/**
* @brief Clock events.
*/
typedef enum
{
NRFX_CLOCK_EVT_HFCLK_STARTED, ///< HFCLK has been started.
NRFX_CLOCK_EVT_LFCLK_STARTED, ///< LFCLK has been started.
NRFX_CLOCK_EVT_CTTO, ///< Calibration timeout.
NRFX_CLOCK_EVT_CAL_DONE ///< Calibration has been done.
} nrfx_clock_evt_type_t;
/**
* @brief Clock event handler.
*
* @param[in] event Event.
*/
typedef void (*nrfx_clock_event_handler_t)(nrfx_clock_evt_type_t event);
/**
* @brief Function for initializing internal structures in the nrfx_clock module.
*
* After initialization, the module is in power off state (clocks are not started).
*
* @param[in] event_handler Event handler provided by the user.
* Must not be NULL.
*
* @retval NRFX_SUCCESS If the procedure was successful.
* @retval NRFX_ERROR_ALREADY_INITIALIZED If the driver was already initialized.
*/
nrfx_err_t nrfx_clock_init(nrfx_clock_event_handler_t event_handler);
/**
* @brief Function for enabling interrupts in the clock module.
*/
void nrfx_clock_enable(void);
/**
* @brief Function for disabling interrupts in the clock module.
*/
void nrfx_clock_disable(void);
/**
* @brief Function for uninitializing the clock module.
*/
void nrfx_clock_uninit(void);
/**
* @brief Function for starting the LFCLK.
*/
void nrfx_clock_lfclk_start(void);
/**
* @brief Function for stoping the LFCLK.
*/
void nrfx_clock_lfclk_stop(void);
/**
* @brief Function for checking the LFCLK state.
*
* @retval true If the LFCLK is running.
* @retval false If the LFCLK is not running.
*/
__STATIC_INLINE bool nrfx_clock_lfclk_is_running(void);
/**
* @brief Function for starting the high-accuracy source HFCLK.
*/
void nrfx_clock_hfclk_start(void);
/**
* @brief Function for stoping external high-accuracy source HFCLK.
*/
void nrfx_clock_hfclk_stop(void);
/**
* @brief Function for checking the HFCLK state.
*
* @retval true If the HFCLK is running (XTAL source).
* @retval false If the HFCLK is not running.
*/
__STATIC_INLINE bool nrfx_clock_hfclk_is_running(void);
/**
* @brief Function for starting calibration of internal LFCLK.
*
* This function starts the calibration process. The process cannot be aborted. LFCLK and HFCLK
* must be running before this function is called.
*
* @retval NRFX_SUCCESS If the procedure was successful.
* @retval NRFX_ERROR_INVALID_STATE If the low-frequency of high-frequency clock is off.
* @retval NRFX_ERROR_BUSY If calibration is in progress.
*/
nrfx_err_t nrfx_clock_calibration_start(void);
/**
* @brief Function for checking if calibration is in progress.
*
* This function indicates that the system is in calibration phase.
*
* @retval NRFX_SUCCESS If the procedure was successful.
* @retval NRFX_ERROR_BUSY If calibration is in progress.
*/
nrfx_err_t nrfx_clock_is_calibrating(void);
/**
* @brief Function for starting calibration timer.
* @param interval Time after which the CTTO event and interrupt will be generated (in 0.25 s units).
*/
void nrfx_clock_calibration_timer_start(uint8_t interval);
/**
* @brief Function for stoping calibration timer.
*/
void nrfx_clock_calibration_timer_stop(void);
/**@brief Function for returning a requested task address for the clock driver module.
*
* @param[in] task One of the peripheral tasks.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_clock_ppi_task_addr(nrf_clock_task_t task);
/**@brief Function for returning a requested event address for the clock driver module.
*
* @param[in] event One of the peripheral events.
*
* @return Event address.
*/
__STATIC_INLINE uint32_t nrfx_clock_ppi_event_addr(nrf_clock_event_t event);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE uint32_t nrfx_clock_ppi_task_addr(nrf_clock_task_t task)
{
return nrf_clock_task_address_get(task);
}
__STATIC_INLINE uint32_t nrfx_clock_ppi_event_addr(nrf_clock_event_t event)
{
return nrf_clock_event_address_get(event);
}
__STATIC_INLINE bool nrfx_clock_hfclk_is_running(void)
{
return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY);
}
__STATIC_INLINE bool nrfx_clock_lfclk_is_running(void)
{
return nrf_clock_lf_is_running();
}
#endif //SUPPRESS_INLINE_IMPLEMENTATION
void nrfx_clock_irq_handler(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRFX_CLOCK_H__
@@ -0,0 +1,247 @@
/**
* Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_COMP_H__
#define NRFX_COMP_H__
#include <nrfx.h>
#include <hal/nrf_comp.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_comp COMP driver
* @{
* @ingroup nrf_comp
* @brief Comparator (COMP) peripheral driver.
*/
/**
* @brief Macro to convert the threshold voltage to an integer value
* (needed by the COMP_TH register).
*
* @param[in] vol Voltage to be changed to COMP_TH register value. This value
* must not be smaller than reference voltage divided by 64.
* @param[in] ref Reference voltage.
*/
#define NRFX_VOLTAGE_THRESHOLD_TO_INT(vol, ref) \
(uint8_t)(((vol) > ((ref) / 64)) ? (NRFX_ROUNDED_DIV((vol) * 64,(ref)) - 1) : 0)
/**
* @brief COMP event handler function type.
* @param[in] event COMP event.
*/
typedef void (* nrfx_comp_event_handler_t)(nrf_comp_event_t event);
/** @brief COMP shortcut masks. */
typedef enum
{
NRFX_COMP_SHORT_STOP_AFTER_CROSS_EVT = COMP_SHORTS_CROSS_STOP_Msk, /*!< Shortcut between the CROSS event and the STOP task. */
NRFX_COMP_SHORT_STOP_AFTER_UP_EVT = COMP_SHORTS_UP_STOP_Msk, /*!< Shortcut between the UP event and the STOP task. */
NRFX_COMP_SHORT_STOP_AFTER_DOWN_EVT = COMP_SHORTS_DOWN_STOP_Msk /*!< Shortcut between the DOWN event and the STOP task. */
} nrfx_comp_short_mask_t;
/** @brief COMP events masks. */
typedef enum
{
NRFX_COMP_EVT_EN_CROSS_MASK = COMP_INTENSET_CROSS_Msk, /*!< CROSS event (generated after VIN+ == VIN-). */
NRFX_COMP_EVT_EN_UP_MASK = COMP_INTENSET_UP_Msk, /*!< UP event (generated when VIN+ crosses VIN- while increasing). */
NRFX_COMP_EVT_EN_DOWN_MASK = COMP_INTENSET_DOWN_Msk, /*!< DOWN event (generated when VIN+ crosses VIN- while decreasing). */
NRFX_COMP_EVT_EN_READY_MASK = COMP_INTENSET_READY_Msk /*!< READY event (generated when the module is ready). */
} nrfx_comp_evt_en_mask_t;
/** @brief COMP configuration. */
typedef struct
{
nrf_comp_ref_t reference; /**< Reference selection. */
nrf_comp_ext_ref_t ext_ref; /**< External analog reference selection. */
nrf_comp_main_mode_t main_mode; /**< Main operation mode. */
nrf_comp_th_t threshold; /**< Structure holding THDOWN and THUP values needed by the COMP_TH register. */
nrf_comp_sp_mode_t speed_mode; /**< Speed and power mode. */
nrf_comp_hyst_t hyst; /**< Comparator hysteresis.*/
#if defined (COMP_ISOURCE_ISOURCE_Msk) || defined (__NRFX_DOXYGEN__)
nrf_isource_t isource; /**< Current source selected on analog input. */
#endif
nrf_comp_input_t input; /**< Input to be monitored. */
uint8_t interrupt_priority; /**< Interrupt priority. */
} nrfx_comp_config_t;
/** @brief COMP threshold default configuration. */
#define NRFX_COMP_CONFIG_TH \
{ \
.th_down = NRFX_VOLTAGE_THRESHOLD_TO_INT(0.5, 1.8), \
.th_up = NRFX_VOLTAGE_THRESHOLD_TO_INT(1.5, 1.8) \
}
/** @brief COMP driver default configuration including the COMP HAL configuration. */
#if defined (COMP_ISOURCE_ISOURCE_Msk) || defined (__NRFX_DOXYGEN__)
#define NRFX_COMP_DEFAULT_CONFIG(_input) \
{ \
.reference = (nrf_comp_ref_t)NRFX_COMP_CONFIG_REF, \
.main_mode = (nrf_comp_main_mode_t)NRFX_COMP_CONFIG_MAIN_MODE, \
.threshold = NRFX_COMP_CONFIG_TH, \
.speed_mode = (nrf_comp_sp_mode_t)NRFX_COMP_CONFIG_SPEED_MODE, \
.hyst = (nrf_comp_hyst_t)NRFX_COMP_CONFIG_HYST, \
.isource = (nrf_isource_t)NRFX_COMP_CONFIG_ISOURCE, \
.input = (nrf_comp_input_t)_input, \
.interrupt_priority = NRFX_COMP_CONFIG_IRQ_PRIORITY \
}
#else
#define NRFX_COMP_DEFAULT_CONFIG(_input) \
{ \
.reference = (nrf_comp_ref_t)NRFX_COMP_CONFIG_REF, \
.main_mode = (nrf_comp_main_mode_t)NRFX_COMP_CONFIG_MAIN_MODE, \
.threshold = NRFX_COMP_CONFIG_TH, \
.speed_mode = (nrf_comp_sp_mode_t)NRFX_COMP_CONFIG_SPEED_MODE, \
.hyst = (nrf_comp_hyst_t)NRFX_COMP_CONFIG_HYST, \
.input = (nrf_comp_input_t)_input, \
.interrupt_priority = NRFX_COMP_CONFIG_IRQ_PRIORITY \
}
#endif
/**
* @brief Function for initializing the COMP driver.
*
* This function initializes the COMP driver, but does not enable the peripheral or any interrupts.
* To start the driver, call the function @ref nrfx_comp_start() after initialization.
*
* @param[in] p_config Pointer to the structure with initial configuration.
* @param[in] event_handler Event handler provided by the user.
* Must not be NULL.
*
* @retval NRFX_SUCCESS If initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE If the driver has already been initialized.
* @retval NRFX_ERROR_BUSY If the LPCOMP peripheral is already in use.
* This is possible only if @ref nrfx_prs module
* is enabled.
*/
nrfx_err_t nrfx_comp_init(nrfx_comp_config_t const * p_config,
nrfx_comp_event_handler_t event_handler);
/**
* @brief Function for uninitializing the COMP driver.
*
* This function uninitializes the COMP driver. The COMP peripheral and
* its interrupts are disabled, and local variables are cleaned. After this call, you must
* initialize the driver again by calling nrfx_comp_init() if you want to use it.
*
* @sa nrfx_comp_stop()
*/
void nrfx_comp_uninit(void);
/**
* @brief Function for setting the analog input.
*
* @param[in] psel COMP analog pin selection.
*/
void nrfx_comp_pin_select(nrf_comp_input_t psel);
/**
* @brief Function for starting the COMP peripheral and interrupts.
*
* Before calling this function, the driver must be initialized. This function
* enables the COMP peripheral and its interrupts.
*
* @param[in] comp_evt_en_mask Mask of events to be enabled. This parameter should be built as
* 'or' of elements from @ref nrfx_comp_evt_en_mask_t.
* @param[in] comp_shorts_mask Mask of shorts to be enabled. This parameter should be built as
* 'or' of elements from @ref nrfx_comp_short_mask_t.
*
* @sa nrfx_comp_init()
*
*/
void nrfx_comp_start(uint32_t comp_evt_en_mask, uint32_t comp_shorts_mask);
/**@brief Function for stopping the COMP peripheral.
*
* Before calling this function, the driver must be enabled. This function disables the COMP
* peripheral and its interrupts.
*
* @sa nrfx_comp_uninit()
*
*/
void nrfx_comp_stop(void);
/**
* @brief Function for copying the current state of the comparator result to the RESULT register.
*
* @retval 0 If the input voltage is below the threshold (VIN+ < VIN-).
* @retval 1 If the input voltage is above the threshold (VIN+ > VIN-).
*/
uint32_t nrfx_comp_sample(void);
/**
* @brief Function for getting the address of a COMP task.
*
* @param[in] task COMP task.
*
* @return Address of the given COMP task.
*/
__STATIC_INLINE uint32_t nrfx_comp_task_address_get(nrf_comp_task_t task)
{
return (uint32_t)nrf_comp_task_address_get(task);
}
/**
* @brief Function for getting the address of a COMP event.
*
* @param[in] event COMP event.
*
* @return Address of the given COMP event.
*/
__STATIC_INLINE uint32_t nrfx_comp_event_address_get(nrf_comp_event_t event)
{
return (uint32_t)nrf_comp_event_address_get(event);
}
void nrfx_comp_irq_handler(void);
/** @} **/
#ifdef __cplusplus
}
#endif
#endif // NRFX_COMP_H__
@@ -0,0 +1,423 @@
/**
* Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_GPIOTE_H__
#define NRFX_GPIOTE_H__
#include <nrfx.h>
#include <hal/nrf_gpiote.h>
#include <hal/nrf_gpio.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_gpiote GPIOTE driver
* @{
* @ingroup nrf_gpiote
* @brief GPIOTE peripheral driver.
*/
/**@brief Input pin configuration. */
typedef struct
{
nrf_gpiote_polarity_t sense; /**< Transition that triggers interrupt. */
nrf_gpio_pin_pull_t pull; /**< Pulling mode. */
bool is_watcher : 1; /**< True when the input pin is tracking an output pin. */
bool hi_accuracy : 1; /**< True when high accuracy (IN_EVENT) is used. */
bool skip_gpio_setup : 1; /**< Do not change GPIO configuration */
} nrfx_gpiote_in_config_t;
/**@brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect low-to-high transition.
* @details Set hi_accu to true to use IN_EVENT. */
#define NRFX_GPIOTE_CONFIG_IN_SENSE_LOTOHI(hi_accu) \
{ \
.is_watcher = false, \
.hi_accuracy = hi_accu, \
.pull = NRF_GPIO_PIN_NOPULL, \
.sense = NRF_GPIOTE_POLARITY_LOTOHI, \
}
/**@brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect high-to-low transition.
* @details Set hi_accu to true to use IN_EVENT. */
#define NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(hi_accu) \
{ \
.is_watcher = false, \
.hi_accuracy = hi_accu, \
.pull = NRF_GPIO_PIN_NOPULL, \
.sense = NRF_GPIOTE_POLARITY_HITOLO, \
}
/**@brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect any change on the pin.
* @details Set hi_accu to true to use IN_EVENT.*/
#define NRFX_GPIOTE_CONFIG_IN_SENSE_TOGGLE(hi_accu) \
{ \
.is_watcher = false, \
.hi_accuracy = hi_accu, \
.pull = NRF_GPIO_PIN_NOPULL, \
.sense = NRF_GPIOTE_POLARITY_TOGGLE, \
}
/**@brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect low-to-high transition.
* @details Set hi_accu to true to use IN_EVENT.
* @note This macro prepares configuration that skips GPIO setup. */
#define NRFX_GPIOTE_RAW_CONFIG_IN_SENSE_LOTOHI(hi_accu) \
{ \
.is_watcher = false, \
.hi_accuracy = hi_accu, \
.pull = NRF_GPIO_PIN_NOPULL, \
.sense = NRF_GPIOTE_POLARITY_LOTOHI, \
.skip_gpio_setup = true, \
}
/**@brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect high-to-low transition.
* @details Set hi_accu to true to use IN_EVENT.
* @note This macro prepares configuration that skips GPIO setup. */
#define NRFX_GPIOTE_RAW_CONFIG_IN_SENSE_HITOLO(hi_accu) \
{ \
.is_watcher = false, \
.hi_accuracy = hi_accu, \
.pull = NRF_GPIO_PIN_NOPULL, \
.sense = NRF_GPIOTE_POLARITY_HITOLO, \
.skip_gpio_setup = true, \
}
/**@brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect any change on the pin.
* @details Set hi_accu to true to use IN_EVENT.
* @note This macro prepares configuration that skips GPIO setup. */
#define NRFX_GPIOTE_RAW_CONFIG_IN_SENSE_TOGGLE(hi_accu) \
{ \
.is_watcher = false, \
.hi_accuracy = hi_accu, \
.pull = NRF_GPIO_PIN_NOPULL, \
.sense = NRF_GPIOTE_POLARITY_TOGGLE, \
.skip_gpio_setup = true, \
}
/**@brief Output pin configuration. */
typedef struct
{
nrf_gpiote_polarity_t action; /**< Configuration of the pin task. */
nrf_gpiote_outinit_t init_state; /**< Initial state of the output pin. */
bool task_pin; /**< True if the pin is controlled by a GPIOTE task. */
} nrfx_gpiote_out_config_t;
/**@brief Macro for configuring a pin to use as output. GPIOTE is not used for the pin. */
#define NRFX_GPIOTE_CONFIG_OUT_SIMPLE(init_high) \
{ \
.init_state = init_high ? NRF_GPIOTE_INITIAL_VALUE_HIGH : NRF_GPIOTE_INITIAL_VALUE_LOW, \
.task_pin = false, \
}
/**@brief Macro for configuring a pin to use the GPIO OUT TASK to change the state from high to low.
* @details The task will clear the pin. Therefore, the pin is set initially. */
#define NRFX_GPIOTE_CONFIG_OUT_TASK_LOW \
{ \
.init_state = NRF_GPIOTE_INITIAL_VALUE_HIGH, \
.task_pin = true, \
.action = NRF_GPIOTE_POLARITY_HITOLO, \
}
/**@brief Macro for configuring a pin to use the GPIO OUT TASK to change the state from low to high.
* @details The task will set the pin. Therefore, the pin is cleared initially. */
#define NRFX_GPIOTE_CONFIG_OUT_TASK_HIGH \
{ \
.init_state = NRF_GPIOTE_INITIAL_VALUE_LOW, \
.task_pin = true, \
.action = NRF_GPIOTE_POLARITY_LOTOHI, \
}
/**@brief Macro for configuring a pin to use the GPIO OUT TASK to toggle the pin state.
* @details The initial pin state must be provided. */
#define NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(init_high) \
{ \
.init_state = init_high ? NRF_GPIOTE_INITIAL_VALUE_HIGH : NRF_GPIOTE_INITIAL_VALUE_LOW, \
.task_pin = true, \
.action = NRF_GPIOTE_POLARITY_TOGGLE, \
}
/** @brief Pin. */
typedef uint32_t nrfx_gpiote_pin_t;
/**
* @brief Pin event handler prototype.
*
* @param pin Pin that triggered this event.
* @param action Action that lead to triggering this event.
*/
typedef void (*nrfx_gpiote_evt_handler_t)(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action);
/**
* @brief Function for initializing the GPIOTE module.
*
* @details Only static configuration is supported to prevent the shared
* resource being customized by the initiator.
*
* @retval NRFX_SUCCESS If initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE If the driver was already initialized.
*/
nrfx_err_t nrfx_gpiote_init(void);
/**
* @brief Function for checking if the GPIOTE module is initialized.
*
* @details The GPIOTE module is a shared module. Therefore, you should check if
* the module is already initialized and skip initialization if it is.
*
* @retval true If the module is already initialized.
* @retval false If the module is not initialized.
*/
bool nrfx_gpiote_is_init(void);
/**
* @brief Function for uninitializing the GPIOTE module.
*/
void nrfx_gpiote_uninit(void);
/**
* @brief Function for initializing a GPIOTE output pin.
* @details The output pin can be controlled by the CPU or by PPI. The initial
* configuration specifies which mode is used. If PPI mode is used, the driver
* attempts to allocate one of the available GPIOTE channels. If no channel is
* available, an error is returned.
*
* @param[in] pin Pin.
* @param[in] p_config Initial configuration.
*
* @retval NRFX_SUCCESS If initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE If the driver is not initialized or the pin is already used.
* @retval NRFX_ERROR_NO_MEM If no GPIOTE channel is available.
*/
nrfx_err_t nrfx_gpiote_out_init(nrfx_gpiote_pin_t pin,
nrfx_gpiote_out_config_t const * p_config);
/**
* @brief Function for uninitializing a GPIOTE output pin.
* @details The driver frees the GPIOTE channel if the output pin was using one.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_uninit(nrfx_gpiote_pin_t pin);
/**
* @brief Function for setting a GPIOTE output pin.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_set(nrfx_gpiote_pin_t pin);
/**
* @brief Function for clearing a GPIOTE output pin.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_clear(nrfx_gpiote_pin_t pin);
/**
* @brief Function for toggling a GPIOTE output pin.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_toggle(nrfx_gpiote_pin_t pin);
/**
* @brief Function for enabling a GPIOTE output pin task.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_task_enable(nrfx_gpiote_pin_t pin);
/**
* @brief Function for disabling a GPIOTE output pin task.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_task_disable(nrfx_gpiote_pin_t pin);
/**
* @brief Function for getting the address of a configurable GPIOTE task.
*
* @param[in] pin Pin.
*
* @return Address of OUT task.
*/
uint32_t nrfx_gpiote_out_task_addr_get(nrfx_gpiote_pin_t pin);
#if defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for getting the address of a configurable GPIOTE task.
*
* @param[in] pin Pin.
*
* @return Address of SET task.
*/
uint32_t nrfx_gpiote_set_task_addr_get(nrfx_gpiote_pin_t pin);
#endif // defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__NRFX_DOXYGEN__)
#if defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for getting the address of a configurable GPIOTE task.
*
* @param[in] pin Pin.
*
* @return Address of CLR task.
*/
uint32_t nrfx_gpiote_clr_task_addr_get(nrfx_gpiote_pin_t pin);
#endif // defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for initializing a GPIOTE input pin.
* @details The input pin can act in two ways:
* - lower accuracy but low power (high frequency clock not needed)
* - higher accuracy (high frequency clock required)
*
* The initial configuration specifies which mode is used.
* If high-accuracy mode is used, the driver attempts to allocate one
* of the available GPIOTE channels. If no channel is
* available, an error is returned.
* In low accuracy mode SENSE feature is used. In this case only one active pin
* can be detected at a time. It can be worked around by setting all of the used
* low accuracy pins to toggle mode.
* For more information about SENSE functionality, refer to Product Specification.
*
* @param[in] pin Pin.
* @param[in] p_config Initial configuration.
* @param[in] evt_handler User function to be called when the configured transition occurs.
*
* @retval NRFX_SUCCESS If initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE If the driver is not initialized or the pin is already used.
* @retval NRFX_ERROR_NO_MEM If no GPIOTE channel is available.
*/
nrfx_err_t nrfx_gpiote_in_init(nrfx_gpiote_pin_t pin,
nrfx_gpiote_in_config_t const * p_config,
nrfx_gpiote_evt_handler_t evt_handler);
/**
* @brief Function for uninitializing a GPIOTE input pin.
* @details The driver frees the GPIOTE channel if the input pin was using one.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_in_uninit(nrfx_gpiote_pin_t pin);
/**
* @brief Function for enabling sensing of a GPIOTE input pin.
*
* @details If the input pin is configured as high-accuracy pin, the function
* enables an IN_EVENT. Otherwise, the function enables the GPIO sense mechanism.
* Note that a PORT event is shared between multiple pins, therefore the
* interrupt is always enabled.
*
* @param[in] pin Pin.
* @param[in] int_enable True to enable the interrupt. Always valid for a high-accuracy pin.
*/
void nrfx_gpiote_in_event_enable(nrfx_gpiote_pin_t pin, bool int_enable);
/**
* @brief Function for disabling a GPIOTE input pin.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_in_event_disable(nrfx_gpiote_pin_t pin);
/**
* @brief Function for checking if a GPIOTE input pin is set.
*
* @param[in] pin Pin.
*
* @retval true If the input pin is set.
* @retval false If the input pin is not set.
*/
bool nrfx_gpiote_in_is_set(nrfx_gpiote_pin_t pin);
/**
* @brief Function for getting the address of a GPIOTE input pin event.
* @details If the pin is configured to use low-accuracy mode, the address of the PORT event is returned.
*
* @param[in] pin Pin.
*/
uint32_t nrfx_gpiote_in_event_addr_get(nrfx_gpiote_pin_t pin);
/**
* @brief Function for forcing a specific state on the pin configured as task.
*
* @param[in] pin Pin.
* @param[in] state Pin state.
*/
void nrfx_gpiote_out_task_force(nrfx_gpiote_pin_t pin, uint8_t state);
/**
* @brief Function for triggering the task OUT manually.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_out_task_trigger(nrfx_gpiote_pin_t pin);
#if defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for triggering the task SET manually.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_set_task_trigger(nrfx_gpiote_pin_t pin);
#endif // defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__NRFX_DOXYGEN__)
#if defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for triggering the task CLR manually.
*
* @param[in] pin Pin.
*/
void nrfx_gpiote_clr_task_trigger(nrfx_gpiote_pin_t pin);
#endif // defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__NRFX_DOXYGEN__)
void nrfx_gpiote_irq_handler(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRFX_GPIOTE_H__
@@ -0,0 +1,254 @@
/**
* Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_I2S_H__
#define NRFX_I2S_H__
#include <nrfx.h>
#include <hal/nrf_i2s.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_i2s I2S driver
* @{
* @ingroup nrf_i2s
* @brief Inter-IC Sound (I2S) peripheral driver.
*/
/**
* @brief This value can be provided instead of a pin number for the signals
* SDOUT, SDIN, and MCK to specify that a given signal is not used
* and therefore does not need to be connected to a pin.
*/
#define NRFX_I2S_PIN_NOT_USED 0xFF
/** @brief I2S driver configuration structure. */
typedef struct
{
uint8_t sck_pin; ///< SCK pin number.
uint8_t lrck_pin; ///< LRCK pin number.
uint8_t mck_pin; ///< MCK pin number.
/**< Optional. Use @ref NRFX_I2S_PIN_NOT_USED
* if this signal is not needed. */
uint8_t sdout_pin; ///< SDOUT pin number.
/**< Optional. Use @ref NRFX_I2S_PIN_NOT_USED
* if this signal is not needed. */
uint8_t sdin_pin; ///< SDIN pin number.
/**< Optional. Use @ref NRFX_I2S_PIN_NOT_USED
* if this signal is not needed. */
uint8_t irq_priority; ///< Interrupt priority.
nrf_i2s_mode_t mode; ///< Mode of operation.
nrf_i2s_format_t format; ///< Frame format.
nrf_i2s_align_t alignment; ///< Alignment of sample within a frame.
nrf_i2s_swidth_t sample_width; ///< Sample width.
nrf_i2s_channels_t channels; ///< Enabled channels.
nrf_i2s_mck_t mck_setup; ///< Master clock setup.
nrf_i2s_ratio_t ratio; ///< MCK/LRCK ratio.
} nrfx_i2s_config_t;
/** @brief I2S driver buffers structure. */
typedef struct
{
uint32_t * p_rx_buffer;
uint32_t const * p_tx_buffer;
} nrfx_i2s_buffers_t;
/**
* @brief I2S driver default configuration.
*/
#define NRFX_I2S_DEFAULT_CONFIG \
{ \
.sck_pin = NRFX_I2S_CONFIG_SCK_PIN, \
.lrck_pin = NRFX_I2S_CONFIG_LRCK_PIN, \
.mck_pin = NRFX_I2S_CONFIG_MCK_PIN, \
.sdout_pin = NRFX_I2S_CONFIG_SDOUT_PIN, \
.sdin_pin = NRFX_I2S_CONFIG_SDIN_PIN, \
.irq_priority = NRFX_I2S_CONFIG_IRQ_PRIORITY, \
.mode = (nrf_i2s_mode_t)NRFX_I2S_CONFIG_MASTER, \
.format = (nrf_i2s_format_t)NRFX_I2S_CONFIG_FORMAT, \
.alignment = (nrf_i2s_align_t)NRFX_I2S_CONFIG_ALIGN, \
.sample_width = (nrf_i2s_swidth_t)NRFX_I2S_CONFIG_SWIDTH, \
.channels = (nrf_i2s_channels_t)NRFX_I2S_CONFIG_CHANNELS, \
.mck_setup = (nrf_i2s_mck_t)NRFX_I2S_CONFIG_MCK_SETUP, \
.ratio = (nrf_i2s_ratio_t)NRFX_I2S_CONFIG_RATIO, \
}
#define NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED (1UL << 0)
/**< The application should provide buffers that are to be used in the next
* part of the transfer. A call to @ref nrfx_i2s_next_buffers_set should
* be done before the currently used buffers are completely processed
* (i.e. the time remaining for supplying the next buffers depends on
* the used size of the buffers). */
/**
* @brief I2S driver data handler type.
*
* A data handling function of this type must be specified during initialization
* of the driver. The driver will call this function when it finishes using
* buffers passed to it by the application, and when it needs to be provided
* with buffers for the next part of the transfer.
*
* @note The @c p_released pointer passed to this function is temporary and
* will be invalid after the function returns, hence it cannot be stored
* and used later. If needed, the pointed content (i.e. buffers pointers)
* should be copied instead.
*
* @param[in] p_released Pointer to a structure with pointers to buffers
* passed previously to the driver that will no longer
* be access by it (they can be now safely released or
* used for another purpose, in particular for a next
* part of the transfer).
* This pointer will be NULL if the application did not
* supply the buffers for the next part of the transfer
* (via a call to @ref nrfx_i2s_next_buffers_set) since
* the previous time the data handler signaled such need.
* This means that data corruption occurred (the previous
* buffers are used for the second time) and no buffers
* can be released at the moment.
* Both pointers in this structure are NULL when the
* handler is called for the first time after a transfer
* is started, because no data has been transferred yet
* at this point. In all successive calls the pointers
* specify what has been sent (TX) and what has been
* received (RX) in the part of transfer that has just
* been completed (provided that a given direction is
* enabled, see @ref nrfx_i2s_start).
* @param[in] status Bit field describing the current status of the transfer.
* It can be 0 or a combination of the following flags:
* - @ref NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED
*/
typedef void (* nrfx_i2s_data_handler_t)(nrfx_i2s_buffers_t const * p_released,
uint32_t status);
/**
* @brief Function for initializing the I2S driver.
*
* @param[in] p_config Pointer to the structure with initial configuration.
* @param[in] handler Data handler provided by the user. Must not be NULL.
*
* @retval NRFX_SUCCESS If initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE If the driver was already initialized.
* @retval NRFX_ERROR_INVALID_PARAM If the requested combination of configuration
* options is not allowed by the I2S peripheral.
*/
nrfx_err_t nrfx_i2s_init(nrfx_i2s_config_t const * p_config,
nrfx_i2s_data_handler_t handler);
/** @brief Function for uninitializing the I2S driver. */
void nrfx_i2s_uninit(void);
/**
* @brief Function for starting the continuous I2S transfer.
*
* The I2S data transfer can be performed in one of three modes: RX (reception)
* only, TX (transmission) only, or in both directions simultaneously.
* The mode is selected by specifying a proper buffer for a given direction
* in the call to this function or by passing NULL instead if this direction
* should be disabled.
*
* The length of the buffer (which is a common value for RX and TX if both
* directions are enabled) is specified in 32-bit words. One 32-bit memory
* word can either contain four 8-bit samples, two 16-bit samples, or one
* right-aligned 24-bit sample sign-extended to a 32-bit value.
* For a detailed memory mapping for different supported configurations,
* see the @linkProductSpecification52.
*
* @note Peripherals using EasyDMA (including I2S) require the transfer buffers
* to be placed in the Data RAM region. If this condition is not met,
* this function will fail with the error code NRFX_ERROR_INVALID_ADDR.
*
* @param[in] p_initial_buffers Pointer to a structure specifying the buffers
* to be used in the initial part of the transfer
* (buffers for all consecutive parts are provided
* through the data handler).
* @param[in] buffer_size Size of the buffers (in 32-bit words).
* Must not be 0.
* @param[in] flags Transfer options (0 for default settings).
* Currently, no additional flags are available.
*
* @retval NRFX_SUCCESS If the operation was successful.
* @retval NRFX_ERROR_INVALID_STATE If a transfer was already started or
* the driver has not been initialized.
* @retval NRFX_ERROR_INVALID_ADDR If the provided buffers are not placed
* in the Data RAM region.
*/
nrfx_err_t nrfx_i2s_start(nrfx_i2s_buffers_t const * p_initial_buffers,
uint16_t buffer_size,
uint8_t flags);
/**
* @brief Function for supplying the buffers to be used in the next part of
* the transfer.
*
* The application should call this function when the data handler receives
* @ref NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED in the @c status parameter.
* The call can be done immediately from the data handler function or later,
* but it has to be done before the I2S peripheral finishes processing the
* buffers supplied previously. Otherwise, data corruption will occur.
*
* @sa nrfx_i2s_data_handler_t
*
* @retval NRFX_SUCCESS If the operation was successful.
* @retval NRFX_ERROR_INVALID_STATE If the buffers were already supplied or
* the peripheral is currently being stopped.
*/
nrfx_err_t nrfx_i2s_next_buffers_set(nrfx_i2s_buffers_t const * p_buffers);
/** @brief Function for stopping the I2S transfer. */
void nrfx_i2s_stop(void);
/** @} */
void nrfx_i2s_irq_handler(void);
#ifdef __cplusplus
}
#endif
#endif // NRFX_I2S_H__
@@ -0,0 +1,150 @@
/**
* Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_LPCOMP_H__
#define NRFX_LPCOMP_H__
#include <nrfx.h>
#include <hal/nrf_lpcomp.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_lpcomp LPCOMP driver
* @{
* @ingroup nrf_lpcomp
* @brief Low Power Comparator (LPCOMP) peripheral driver.
*/
/**
* @brief LPCOMP event handler function type.
* @param[in] event LPCOMP event.
*/
typedef void (* nrfx_lpcomp_event_handler_t)(nrf_lpcomp_event_t event);
/** @brief LPCOMP configuration. */
typedef struct
{
nrf_lpcomp_config_t hal; /**< LPCOMP HAL configuration. */
nrf_lpcomp_input_t input; /**< Input to be monitored. */
uint8_t interrupt_priority; /**< LPCOMP interrupt priority. */
} nrfx_lpcomp_config_t;
/** @brief LPCOMP driver default configuration including the LPCOMP HAL configuration. */
#ifdef NRF52_SERIES
#define NRFX_LPCOMP_DEFAULT_CONFIG \
{ \
.hal = { (nrf_lpcomp_ref_t)NRFX_LPCOMP_CONFIG_REFERENCE , \
(nrf_lpcomp_detect_t)NRFX_LPCOMP_CONFIG_DETECTION, \
(nrf_lpcomp_hysteresis_t)NRFX_LPCOMP_CONFIG_HYST }, \
.input = (nrf_lpcomp_input_t)NRFX_LPCOMP_CONFIG_INPUT, \
.interrupt_priority = NRFX_LPCOMP_CONFIG_IRQ_PRIORITY \
}
#else
#define NRFX_LPCOMP_DEFAULT_CONFIG \
{ \
.hal = { (nrf_lpcomp_ref_t)NRFX_LPCOMP_CONFIG_REFERENCE , \
(nrf_lpcomp_detect_t)NRFX_LPCOMP_CONFIG_DETECTION }, \
.input = (nrf_lpcomp_input_t)NRFX_LPCOMP_CONFIG_INPUT, \
.interrupt_priority = NRFX_LPCOMP_CONFIG_IRQ_PRIORITY \
}
#endif
/**
* @brief Function for initializing the LPCOMP driver.
*
* This function initializes the LPCOMP driver, but does not enable the peripheral or any interrupts.
* To start the driver, call the function nrfx_lpcomp_enable() after initialization.
*
* @param[in] p_config Pointer to the structure with initial configuration.
* @param[in] event_handler Event handler provided by the user.
* Must not be NULL.
*
* @retval NRFX_SUCCESS If initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE If the driver has already been initialized.
* @retval NRFX_ERROR_BUSY If the COMP peripheral is already in use.
* This is possible only if @ref nrfx_prs module
* is enabled.
*/
nrfx_err_t nrfx_lpcomp_init(nrfx_lpcomp_config_t const * p_config,
nrfx_lpcomp_event_handler_t event_handler);
/**
* @brief Function for uninitializing the LCOMP driver.
*
* This function uninitializes the LPCOMP driver. The LPCOMP peripheral and
* its interrupts are disabled, and local variables are cleaned. After this call, you must
* initialize the driver again by calling nrfx_lpcomp_init() if you want to use it.
*
* @sa nrfx_lpcomp_disable()
* @sa nrfx_lpcomp_init()
*/
void nrfx_lpcomp_uninit(void);
/**@brief Function for enabling the LPCOMP peripheral and interrupts.
*
* Before calling this function, the driver must be initialized. This function
* enables the LPCOMP peripheral and its interrupts.
*
* @sa nrfx_lpcomp_disable()
*/
void nrfx_lpcomp_enable(void);
/**@brief Function for disabling the LPCOMP peripheral.
*
* Before calling this function, the driver must be initialized. This function disables the LPCOMP
* peripheral and its interrupts.
*
* @sa nrfx_lpcomp_enable()
*/
void nrfx_lpcomp_disable(void);
void nrfx_lpcomp_irq_handler(void);
/** @} **/
#ifdef __cplusplus
}
#endif
#endif // NRFX_LPCOMP_H__
@@ -0,0 +1,214 @@
/**
* Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_PDM_H__
#define NRFX_PDM_H__
#include <nrfx.h>
#include <hal/nrf_pdm.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_pdm PDM driver
* @{
* @ingroup nrf_pdm
* @brief Pulse Density Modulation (PDM) peripheral driver.
*/
#define NRFX_PDM_MAX_BUFFER_SIZE 32767
/**
* @brief PDM error type.
*/
typedef enum
{
NRFX_PDM_NO_ERROR = 0,
NRFX_PDM_ERROR_OVERFLOW = 1
} nrfx_pdm_error_t;
/**
* @brief PDM event structure.
*/
typedef struct
{
bool buffer_requested; ///< Buffer request flag.
int16_t * buffer_released; ///< Pointer to the released buffer. Can be NULL.
nrfx_pdm_error_t error; ///< Error type.
} nrfx_pdm_evt_t;
/**
* @brief PDM interface driver configuration structure.
*/
typedef struct
{
nrf_pdm_mode_t mode; ///< Interface operation mode.
nrf_pdm_edge_t edge; ///< Sampling mode.
uint8_t pin_clk; ///< CLK pin.
uint8_t pin_din; ///< DIN pin.
nrf_pdm_freq_t clock_freq; ///< Clock frequency.
nrf_pdm_gain_t gain_l; ///< Left channel gain.
nrf_pdm_gain_t gain_r; ///< Right channel gain.
uint8_t interrupt_priority; ///< Interrupt priority.
} nrfx_pdm_config_t;
/**
* @brief Macro for setting @ref nrfx_pdm_config_t to default settings
* in single ended mode.
*
* @param _pin_clk CLK output pin.
* @param _pin_din DIN input pin.
*/
#define NRFX_PDM_DEFAULT_CONFIG(_pin_clk, _pin_din) \
{ \
.mode = (nrf_pdm_mode_t)NRFX_PDM_CONFIG_MODE, \
.edge = (nrf_pdm_edge_t)NRFX_PDM_CONFIG_EDGE, \
.pin_clk = _pin_clk, \
.pin_din = _pin_din, \
.clock_freq = (nrf_pdm_freq_t)NRFX_PDM_CONFIG_CLOCK_FREQ, \
.gain_l = NRF_PDM_GAIN_DEFAULT, \
.gain_r = NRF_PDM_GAIN_DEFAULT, \
.interrupt_priority = NRFX_PDM_CONFIG_IRQ_PRIORITY \
}
/**
* @brief Handler for PDM interface ready events.
*
* This event handler is called on a buffer request, an error or when a buffer
* is full and ready to be processed.
*
* @param[in] p_evt Pointer to the PDM event structure.
*/
typedef void (*nrfx_pdm_event_handler_t)(nrfx_pdm_evt_t const * const p_evt);
/**
* @brief Function for initializing the PDM interface.
*
* @param[in] p_config Pointer to the structure with initial configuration.
* @param[in] event_handler Event handler provided by the user. Cannot be NULL.
*
* @retval NRFX_SUCCESS If initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE If the driver is already initialized.
* @retval NRFX_ERROR_INVALID_PARAM If invalid configuration was specified.
*/
nrfx_err_t nrfx_pdm_init(nrfx_pdm_config_t const * p_config,
nrfx_pdm_event_handler_t event_handler);
/**
* @brief Function for uninitializing the PDM interface.
*
* This function stops PDM sampling, if it is in progress.
*/
void nrfx_pdm_uninit(void);
/**
* @brief Function for getting the address of a PDM interface task.
*
* @param[in] task Task.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_pdm_task_address_get(nrf_pdm_task_t task)
{
return nrf_pdm_task_address_get(task);
}
/**
* @brief Function for getting the state of the PDM interface.
*
* @retval true If the PDM interface is enabled.
* @retval false If the PDM interface is disabled.
*/
__STATIC_INLINE bool nrfx_pdm_enable_check(void)
{
return nrf_pdm_enable_check();
}
/**
* @brief Function for starting PDM sampling.
*
* @retval NRFX_SUCCESS If sampling was started successfully or was already in progress.
* @retval NRFX_ERROR_BUSY If a previous start/stop operation is in progress.
*/
nrfx_err_t nrfx_pdm_start(void);
/**
* @brief Function for stopping PDM sampling.
*
* When this function is called, the PDM interface is stopped after finishing
* the current frame.
* The event handler function might be called once more after calling this function.
*
* @retval NRFX_SUCCESS If sampling was stopped successfully or was already stopped before.
* @retval NRFX_ERROR_BUSY If a previous start/stop operation is in progress.
*/
nrfx_err_t nrfx_pdm_stop(void);
/**
* @brief Function for supplying the sample buffer.
*
* Call this function after every buffer request event.
*
* @param[in] buffer Pointer to the receive buffer. Cannot be NULL.
* @param[in] buffer_length Length of the receive buffer in 16-bit words.
*
* @retval NRFX_SUCCESS If the buffer was applied successfully.
* @retval NRFX_ERROR_BUSY If the buffer was already supplied or the peripheral is currently being stopped.
* @retval NRFX_ERROR_INVALID_STATE If the driver was not initialized.
* @retval NRFX_ERROR_INVALID_PARAM If invalid parameters were provided.
*/
nrfx_err_t nrfx_pdm_buffer_set(int16_t * buffer, uint16_t buffer_length);
void nrfx_pdm_irq_handler(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRFX_PDM_H__
@@ -0,0 +1,382 @@
/**
* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_POWER_H__
#define NRFX_POWER_H__
#include <nrfx.h>
#include <hal/nrf_power.h>
#include <nrfx_power_clock.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_power POWER driver
* @{
* @ingroup nrf_power
* @brief POWER peripheral driver.
*/
/**
* @brief Power mode possible configurations
*/
typedef enum
{
NRFX_POWER_MODE_CONSTLAT, /**< Constant latency mode */
NRFX_POWER_MODE_LOWPWR /**< Low power mode */
}nrfx_power_mode_t;
#if NRF_POWER_HAS_SLEEPEVT || defined(__NRFX_DOXYGEN__)
/**
* @brief Events from power system
*/
typedef enum
{
NRFX_POWER_SLEEP_EVT_ENTER, /**< CPU entered WFI/WFE sleep
*
* Keep in mind that if this interrupt is enabled,
* it means that CPU was waken up just after WFI by this interrupt.
*/
NRFX_POWER_SLEEP_EVT_EXIT /**< CPU exited WFI/WFE sleep */
}nrfx_power_sleep_evt_t;
#endif /* NRF_POWER_HAS_SLEEPEVT */
#if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/**
* @brief Events from USB power system
*/
typedef enum
{
NRFX_POWER_USB_EVT_DETECTED, /**< USB power detected on the connector (plugged in). */
NRFX_POWER_USB_EVT_REMOVED, /**< USB power removed from the connector. */
NRFX_POWER_USB_EVT_READY /**< USB power regulator ready. */
}nrfx_power_usb_evt_t;
/**
* @brief USB power state
*
* The single enumerator that holds all data about current state of USB
* related POWER.
*
* Organized this way that higher power state has higher numeric value
*/
typedef enum
{
NRFX_POWER_USB_STATE_DISCONNECTED, /**< No power on USB lines detected */
NRFX_POWER_USB_STATE_CONNECTED, /**< The USB power is detected, but USB power regulator is not ready */
NRFX_POWER_USB_STATE_READY /**< From the power point of view USB is ready for working */
}nrfx_power_usb_state_t;
#endif /* NRF_POWER_HAS_USBREG */
/**
* @name Callback types
*
* Defined types of callback functions
* @{
*/
/**
* @brief Event handler for power failure warning
*/
typedef void (*nrfx_power_pofwarn_event_handler_t)(void);
#if NRF_POWER_HAS_SLEEPEVT || defined(__NRFX_DOXYGEN__)
/**
* @brief Event handler for entering/exiting sleep
*
* @param event Event type
*/
typedef void (*nrfx_power_sleep_event_handler_t)(nrfx_power_sleep_evt_t event);
#endif
#if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/**
* @brief Event handler for USB related power events
*
* @param event Event type
*/
typedef void (*nrfx_power_usb_event_handler_t)(nrfx_power_usb_evt_t event);
#endif
/** @} */
/**
* @brief General power configuration
*
* Parameters required to initialize power driver.
*/
typedef struct
{
/**
* @brief Enable main DCDC regulator
*
* This bit only informs the driver that elements for DCDC regulator
* are installed and regulator can be used.
* The regulator would be enabled or disabled automatically
* by the hardware, basing on current power requirement.
*/
bool dcdcen:1;
#if NRF_POWER_HAS_VDDH || defined(__NRFX_DOXYGEN__)
/**
* @brief Enable HV DCDC regulator
*
* This bit only informs the driver that elements for DCDC regulator
* are installed and regulator can be used.
* The regulator would be enabled or disabled automatically
* by the hardware, basing on current power requirement.
*/
bool dcdcenhv: 1;
#endif
}nrfx_power_config_t;
/**
* @brief The configuration for power failure comparator
*
* Configuration used to enable and configure power failure comparator
*/
typedef struct
{
nrfx_power_pofwarn_event_handler_t handler; //!< Event handler
nrf_power_pof_thr_t thr; //!< Threshold for power failure detection
#if NRF_POWER_HAS_VDDH || defined(__NRFX_DOXYGEN__)
nrf_power_pof_thrvddh_t thrvddh; //!< Threshold for power failure detection on VDDH pin
#endif
}nrfx_power_pofwarn_config_t;
#if NRF_POWER_HAS_SLEEPEVT || defined(__NRFX_DOXYGEN__)
/**
* @brief The configuration of sleep event processing
*
* Configuration used to enable and configure sleep event handling
*/
typedef struct
{
nrfx_power_sleep_event_handler_t handler; //!< Event handler
bool en_enter:1; //!< Enable event on sleep entering
bool en_exit :1; //!< Enable event on sleep exiting
}nrfx_power_sleepevt_config_t;
#endif
#if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/**
* @brief The configuration of USB related power events
*
* Configuration used to enable and configure USB power event handling
*/
typedef struct
{
nrfx_power_usb_event_handler_t handler; //!< Event processing
}nrfx_power_usbevt_config_t;
#endif /* NRF_POWER_HAS_USBREG */
/**
* @brief Function for getting the handler of the power failure comparator.
* @return Handler of the power failure comparator.
*/
nrfx_power_pofwarn_event_handler_t nrfx_power_pof_handler_get(void);
#if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for getting the handler of the USB power.
* @return Handler of the USB power.
*/
nrfx_power_usb_event_handler_t nrfx_power_usb_handler_get(void);
#endif
/**
* @brief Initialize power module driver
*
* Enabled power module driver would process all the interrupts from power system.
*
* @param[in] p_config Pointer to the structure with initial configuration.
*
* @retval NRFX_SUCCESS Successfully initialized.
* @retval NRFX_ERROR_ALREADY_INITIALIZED Module was already initialized.
*/
nrfx_err_t nrfx_power_init(nrfx_power_config_t const * p_config);
/**
* @brief Unintialize power module driver
*
* Disables all the interrupt handling in the module.
*
* @sa nrfx_power_init
*/
void nrfx_power_uninit(void);
/**
* @brief Initialize power failure comparator
*
* Configures the power failure comparator. This function does not setup and enable it.
* Those steps can be done with functions @ref nrfx_power_pof_enable and @ref nrfx_power_pof_disable
* or with Softdevice API (when Softdevice is using).
*
* @param[in] p_config Configuration with values and event handler.
* If event handler is set to NULL, interrupt would be disabled.
*/
void nrfx_power_pof_init(nrfx_power_pofwarn_config_t const * p_config);
/**
* @brief Enable power failure comparator
* Sets and enables interrupt of the power failure comparator. This functions cannot be using
* when Softdevice is enabled. If event handler set in init function is set to NULL, interrupt
* would be disabled.
*
* @param[in] p_config Configuration with values and event handler.
*/
void nrfx_power_pof_enable(nrfx_power_pofwarn_config_t const * p_config);
/**
* @brief Disable the power failure comparator
*
* Disables the power failure comparator interrupt.
*/
void nrfx_power_pof_disable(void);
/**
* @brief Clear the power failure comparator settings
*
* Clears the settings of the power failure comparator.
*/
void nrfx_power_pof_uninit(void);
#if NRF_POWER_HAS_SLEEPEVT || defined(__NRFX_DOXYGEN__)
/**
* @brief Initialize sleep entering and exiting events processing
*
* Configures and setups the sleep event processing.
*
* @param[in] p_config Configuration with values and event handler.
*
* @sa nrfx_power_sleepevt_uninit
*
*/
void nrfx_power_sleepevt_init(nrfx_power_sleepevt_config_t const * p_config);
/**
* @brief Enable sleep entering and exiting events processing
*
* @param[in] p_config Configuration with values and event handler.
*/
void nrfx_power_sleepevt_enable(nrfx_power_sleepevt_config_t const * p_config);
/**
* @brief Disable sleep entering and exiting events processing
*/
void nrfx_power_sleepevt_disable(void);
/**
* @brief Uninitialize sleep entering and exiting events processing
*
* @sa nrfx_power_sleepevt_init
*/
void nrfx_power_sleepevt_uninit(void);
#endif /* NRF_POWER_HAS_SLEEPEVT */
#if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
/**
* @brief Initialize USB power event processing
*
* Configures and setups the USB power event processing.
*
* @param[in] p_config Configuration with values and event handler.
*
* @sa nrfx_power_usbevt_uninit
*/
void nrfx_power_usbevt_init(nrfx_power_usbevt_config_t const * p_config);
/**
* @brief Enable USB power event processing
*/
void nrfx_power_usbevt_enable(void);
/**
* @brief Disable USB power event processing
*/
void nrfx_power_usbevt_disable(void);
/**
* @brief Uninitalize USB power event processing
*
* @sa nrfx_power_usbevt_init
*/
void nrfx_power_usbevt_uninit(void);
/**
* @brief Get the status of USB power
*
* @return Current USB power status
*/
__STATIC_INLINE nrfx_power_usb_state_t nrfx_power_usbstatus_get(void);
#endif /* NRF_POWER_HAS_USBREG */
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
#if NRF_POWER_HAS_USBREG
__STATIC_INLINE nrfx_power_usb_state_t nrfx_power_usbstatus_get(void)
{
uint32_t status = nrf_power_usbregstatus_get();
if(0 == (status & NRF_POWER_USBREGSTATUS_VBUSDETECT_MASK))
{
return NRFX_POWER_USB_STATE_DISCONNECTED;
}
if(0 == (status & NRF_POWER_USBREGSTATUS_OUTPUTRDY_MASK))
{
return NRFX_POWER_USB_STATE_CONNECTED;
}
return NRFX_POWER_USB_STATE_READY;
}
#endif /* NRF_POWER_HAS_USBREG */
#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
void nrfx_power_irq_handler(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* NRFX_POWER_H__ */
@@ -0,0 +1,90 @@
/**
* Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_POWER_CLOCK_H__
#define NRFX_POWER_CLOCK_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
__STATIC_INLINE void nrfx_power_clock_irq_init(void);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrfx_power_clock_irq_init(void)
{
uint8_t priority;
#if NRFX_CHECK(NRFX_POWER_ENABLED) && NRFX_CHECK(NRFX_CLOCK_ENABLED)
#if NRFX_POWER_CONFIG_IRQ_PRIORITY != NRFX_CLOCK_CONFIG_IRQ_PRIORITY
#error "IRQ priority for POWER and CLOCK have to be the same. Check <nrfx_config.h>."
#endif
priority = NRFX_POWER_CONFIG_IRQ_PRIORITY;
#elif NRFX_CHECK(NRFX_POWER_ENABLED)
priority = NRFX_POWER_CONFIG_IRQ_PRIORITY;
#elif NRFX_CHECK(NRFX_CLOCK_ENABLED)
priority = NRFX_CLOCK_CONFIG_IRQ_PRIORITY;
#endif
if (!NRFX_IRQ_IS_ENABLED(POWER_CLOCK_IRQn))
{
NRFX_IRQ_PRIORITY_SET(POWER_CLOCK_IRQn, priority);
NRFX_IRQ_ENABLE(POWER_CLOCK_IRQn);
}
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
#if NRFX_CHECK(NRFX_POWER_ENABLED) && NRFX_CHECK(NRFX_CLOCK_ENABLED)
void nrfx_power_clock_irq_handler(void);
#elif NRFX_CHECK(NRFX_POWER_ENABLED)
#define nrfx_power_irq_handler nrfx_power_clock_irq_handler
#elif NRFX_CHECK(NRFX_CLOCK_ENABLED)
#define nrfx_clock_irq_handler nrfx_power_clock_irq_handler
#endif
#ifdef __cplusplus
}
#endif
#endif // NRFX_POWER_CLOCK_H__
@@ -0,0 +1,327 @@
/**
* Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_PPI_H__
#define NRFX_PPI_H__
#include <nrfx.h>
#include <hal/nrf_ppi.h>
/**
* @defgroup nrfx_ppi PPI allocator
* @{
* @ingroup nrf_ppi
* @brief Programmable Peripheral Interconnect (PPI) allocator.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef NRFX_PPI_CHANNELS_USED
#define NRFX_PPI_CHANNELS_USED 0
#endif
#ifndef NRFX_PPI_GROUPS_USED
#define NRFX_PPI_GROUPS_USED 0
#endif
#if PPI_CH_NUM > 16
#define NRFX_PPI_ALL_APP_CHANNELS_MASK ((uint32_t)0xFFFFFFFFuL & ~(NRFX_PPI_CHANNELS_USED)) /**< All PPI channels available to the application. */
#define NRFX_PPI_PROG_APP_CHANNELS_MASK ((uint32_t)0x000FFFFFuL & ~(NRFX_PPI_CHANNELS_USED)) /**< Programmable PPI channels available to the application. */
#else
#define NRFX_PPI_ALL_APP_CHANNELS_MASK ((uint32_t)0xFFF0FFFFuL & ~(NRFX_PPI_CHANNELS_USED)) /**< All PPI channels available to the application. */
#define NRFX_PPI_PROG_APP_CHANNELS_MASK ((uint32_t)0x0000FFFFuL & ~(NRFX_PPI_CHANNELS_USED)) /**< Programmable PPI channels available to the application. */
#endif
#define NRFX_PPI_ALL_APP_GROUPS_MASK (((1uL << PPI_GROUP_NUM) - 1) & ~(NRFX_PPI_GROUPS_USED)) /**< All PPI groups available to the application. */
/**
* @brief Function for uninitializing the PPI module.
*
* This function disables all channels and clears the channel groups.
*/
void nrfx_ppi_free_all(void);
/**
* @brief Function for allocating a PPI channel.
* @details This function allocates the first unused PPI channel.
*
* @param[out] p_channel Pointer to the PPI channel that has been allocated.
*
* @retval NRFX_SUCCESS If the channel was successfully allocated.
* @retval NRFX_ERROR_NO_MEM If there is no available channel to be used.
*/
nrfx_err_t nrfx_ppi_channel_alloc(nrf_ppi_channel_t * p_channel);
/**
* @brief Function for freeing a PPI channel.
* @details This function also disables the chosen channel.
*
* @param[in] channel PPI channel to be freed.
*
* @retval NRFX_SUCCESS If the channel was successfully freed.
* @retval NRFX_ERROR_INVALID_PARAM If the channel is not user-configurable.
*/
nrfx_err_t nrfx_ppi_channel_free(nrf_ppi_channel_t channel);
/**
* @brief Function for assigning task and event endpoints to the PPI channel.
*
* @param[in] channel PPI channel to be assigned endpoints.
* @param[in] eep Event endpoint address.
* @param[in] tep Task endpoint address.
*
* @retval NRFX_SUCCESS If the channel was successfully assigned.
* @retval NRFX_ERROR_INVALID_STATE If the channel is not allocated for the user.
* @retval NRFX_ERROR_INVALID_PARAM If the channel is not user-configurable.
*/
nrfx_err_t nrfx_ppi_channel_assign(nrf_ppi_channel_t channel, uint32_t eep, uint32_t tep);
/**
* @brief Function for assigning or clearing fork endpoint to the PPI channel.
*
* @param[in] channel PPI channel to be assigned endpoints.
* @param[in] fork_tep Fork task endpoint address or 0 to clear.
*
* @retval NRFX_SUCCESS If the channel was successfully assigned.
* @retval NRFX_ERROR_INVALID_STATE If the channel is not allocated for the user.
* @retval NRFX_ERROR_INVALID_PARAM If the channel is not user-configurable.
* @retval NRFX_ERROR_NOT_SUPPORTED If function is not supported.
*/
nrfx_err_t nrfx_ppi_channel_fork_assign(nrf_ppi_channel_t channel, uint32_t fork_tep);
/**
* @brief Function for enabling a PPI channel.
*
* @param[in] channel PPI channel to be enabled.
*
* @retval NRFX_SUCCESS If the channel was successfully enabled.
* @retval NRFX_ERROR_INVALID_STATE If the user-configurable channel is not allocated.
* @retval NRFX_ERROR_INVALID_PARAM If the channel cannot be enabled by the user.
*/
nrfx_err_t nrfx_ppi_channel_enable(nrf_ppi_channel_t channel);
/**
* @brief Function for disabling a PPI channel.
*
* @param[in] channel PPI channel to be disabled.
*
* @retval NRFX_SUCCESS If the channel was successfully disabled.
* @retval NRFX_ERROR_INVALID_STATE If the user-configurable channel is not allocated.
* @retval NRFX_ERROR_INVALID_PARAM If the channel cannot be disabled by the user.
*/
nrfx_err_t nrfx_ppi_channel_disable(nrf_ppi_channel_t channel);
/**
* @brief Function for allocating a PPI channel group.
* @details This function allocates the first unused PPI group.
*
* @param[out] p_group Pointer to the PPI channel group that has been allocated.
*
* @retval NRFX_SUCCESS If the channel group was successfully allocated.
* @retval NRFX_ERROR_NO_MEM If there is no available channel group to be used.
*/
nrfx_err_t nrfx_ppi_group_alloc(nrf_ppi_channel_group_t * p_group);
/**
* @brief Function for freeing a PPI channel group.
* @details This function also disables the chosen group.
*
* @param[in] group PPI channel group to be freed.
*
* @retval NRFX_SUCCESS If the channel group was successfully freed.
* @retval NRFX_ERROR_INVALID_PARAM If the channel group is not user-configurable.
*/
nrfx_err_t nrfx_ppi_group_free(nrf_ppi_channel_group_t group);
/**
* @brief Compute a channel mask for NRF_PPI registers.
*
* @param[in] channel Channel number to transform to a mask.
*
* @retval Channel mask.
*/
__STATIC_INLINE uint32_t nrfx_ppi_channel_to_mask(nrf_ppi_channel_t channel)
{
return (1uL << (uint32_t) channel);
}
/**
* @brief Function for including multiple PPI channels in a channel group.
*
* @param[in] channel_mask PPI channels to be added.
* @param[in] group Channel group in which to include the channels.
*
* @retval NRFX_SUCCESS If the channels was successfully included.
* @retval NRFX_ERROR_INVALID_PARAM If group is not an application group or channels are not an
* application channels.
* @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
*/
nrfx_err_t nrfx_ppi_channels_include_in_group(uint32_t channel_mask,
nrf_ppi_channel_group_t group);
/**
* @brief Function for including a PPI channel in a channel group.
*
* @param[in] channel PPI channel to be added.
* @param[in] group Channel group in which to include the channel.
*
* @retval NRFX_SUCCESS If the channel was successfully included.
* @retval NRFX_ERROR_INVALID_PARAM If group is not an application group or channel is not an
* application channel.
* @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
*/
__STATIC_INLINE nrfx_err_t nrfx_ppi_channel_include_in_group(nrf_ppi_channel_t channel,
nrf_ppi_channel_group_t group)
{
return nrfx_ppi_channels_include_in_group(nrfx_ppi_channel_to_mask(channel), group);
}
/**
* @brief Function for removing multiple PPI channels from a channel group.
*
* @param[in] channel_mask PPI channels to be removed.
* @param[in] group Channel group from which to remove the channels.
*
* @retval NRFX_SUCCESS If the channel was successfully removed.
* @retval NRFX_ERROR_INVALID_PARAM If group is not an application group or channels are not an
* application channels.
* @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
*/
nrfx_err_t nrfx_ppi_channels_remove_from_group(uint32_t channel_mask,
nrf_ppi_channel_group_t group);
/**
* @brief Function for removing a PPI channel from a channel group.
*
* @param[in] channel PPI channel to be removed.
* @param[in] group Channel group from which to remove the channel.
*
* @retval NRFX_SUCCESS If the channel was successfully removed.
* @retval NRFX_ERROR_INVALID_PARAM If group is not an application group or channel is not an
* application channel.
* @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
*/
__STATIC_INLINE nrfx_err_t nrfx_ppi_channel_remove_from_group(nrf_ppi_channel_t channel,
nrf_ppi_channel_group_t group)
{
return nrfx_ppi_channels_remove_from_group(nrfx_ppi_channel_to_mask(channel), group);
}
/**
* @brief Function for clearing a PPI channel group.
*
* @param[in] group Channel group to be cleared.
*
* @retval NRFX_SUCCESS If the group was successfully cleared.
* @retval NRFX_ERROR_INVALID_PARAM If group is not an application group.
* @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
*/
__STATIC_INLINE nrfx_err_t nrfx_ppi_group_clear(nrf_ppi_channel_group_t group)
{
return nrfx_ppi_channels_remove_from_group(NRFX_PPI_ALL_APP_CHANNELS_MASK, group);
}
/**
* @brief Function for enabling a PPI channel group.
*
* @param[in] group Channel group to be enabled.
*
* @retval NRFX_SUCCESS If the group was successfully enabled.
* @retval NRFX_ERROR_INVALID_PARAM If group is not an application group.
* @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
*/
nrfx_err_t nrfx_ppi_group_enable(nrf_ppi_channel_group_t group);
/**
* @brief Function for disabling a PPI channel group.
*
* @param[in] group Channel group to be disabled.
*
* @retval NRFX_SUCCESS If the group was successfully disabled.
* @retval NRFX_ERROR_INVALID_PARAM If group is not an application group.
* @retval NRFX_ERROR_INVALID_STATE If group is not an allocated group.
*/
nrfx_err_t nrfx_ppi_group_disable(nrf_ppi_channel_group_t group);
/**
* @brief Function for getting the address of a PPI task.
*
* @param[in] task Task.
*
* @retval Task address.
*/
__STATIC_INLINE uint32_t nrfx_ppi_task_addr_get(nrf_ppi_task_t task)
{
return (uint32_t) nrf_ppi_task_address_get(task);
}
/**
* @brief Function for getting the address of a PPI group enable task.
*
* @param[in] group PPI channel group
*
* @retval Task address.
*/
__STATIC_INLINE uint32_t nrfx_ppi_task_addr_group_enable_get(nrf_ppi_channel_group_t group)
{
return (uint32_t) nrf_ppi_task_group_enable_address_get(group);
}
/**
* @brief Function for getting the address of a PPI group enable task.
*
* @param[in] group PPI channel group
*
* @retval Task address.
*/
__STATIC_INLINE uint32_t nrfx_ppi_task_addr_group_disable_get(nrf_ppi_channel_group_t group)
{
return (uint32_t) nrf_ppi_task_group_disable_address_get(group);
}
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRFX_PPI_H__
@@ -0,0 +1,497 @@
/**
* Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_PWM_H__
#define NRFX_PWM_H__
#include <nrfx.h>
#include <hal/nrf_pwm.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_pwm PWM driver
* @{
* @ingroup nrf_pwm
* @brief Pulse Width Modulation (PWM) peripheral driver.
*/
/**
* @brief PWM driver instance data structure.
*/
typedef struct
{
NRF_PWM_Type * p_registers; ///< Pointer to the structure with PWM peripheral instance registers.
uint8_t drv_inst_idx; ///< Driver instance index.
} nrfx_pwm_t;
/**
* @brief Macro for creating a PWM driver instance.
*/
#define NRFX_PWM_INSTANCE(id) \
{ \
.p_registers = NRFX_CONCAT_2(NRF_PWM, id), \
.drv_inst_idx = NRFX_CONCAT_3(NRFX_PWM, id, _INST_IDX), \
}
enum {
#if NRFX_CHECK(NRFX_PWM0_ENABLED)
NRFX_PWM0_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_PWM1_ENABLED)
NRFX_PWM1_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_PWM2_ENABLED)
NRFX_PWM2_INST_IDX,
#endif
#if NRFX_CHECK(NRFX_PWM3_ENABLED)
NRFX_PWM3_INST_IDX,
#endif
NRFX_PWM_ENABLED_COUNT
};
/**
* @brief This value can be provided instead of a pin number for any channel
* to specify that its output is not used and therefore does not need
* to be connected to a pin.
*/
#define NRFX_PWM_PIN_NOT_USED 0xFF
/**
* @brief This value can be added to a pin number to inverse its polarity
* (set idle state = 1).
*/
#define NRFX_PWM_PIN_INVERTED 0x80
/**
* @brief PWM driver configuration structure.
*/
typedef struct
{
uint8_t output_pins[NRF_PWM_CHANNEL_COUNT]; ///< Pin numbers for individual output channels (optional).
/**< Use @ref NRFX_PWM_PIN_NOT_USED
* if a given output channel is not needed. */
uint8_t irq_priority; ///< Interrupt priority.
nrf_pwm_clk_t base_clock; ///< Base clock frequency.
nrf_pwm_mode_t count_mode; ///< Operating mode of the pulse generator counter.
uint16_t top_value; ///< Value up to which the pulse generator counter counts.
nrf_pwm_dec_load_t load_mode; ///< Mode of loading sequence data from RAM.
nrf_pwm_dec_step_t step_mode; ///< Mode of advancing the active sequence.
} nrfx_pwm_config_t;
/**
* @brief PWM driver default configuration.
*/
#define NRFX_PWM_DEFAULT_CONFIG \
{ \
.output_pins = { NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN, \
NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN, \
NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN, \
NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN }, \
.irq_priority = NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY, \
.base_clock = (nrf_pwm_clk_t)NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK, \
.count_mode = (nrf_pwm_mode_t)NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE, \
.top_value = NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE, \
.load_mode = (nrf_pwm_dec_load_t)NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE, \
.step_mode = (nrf_pwm_dec_step_t)NRFX_PWM_DEFAULT_CONFIG_STEP_MODE, \
}
/**
* @brief PWM flags providing additional playback options.
*/
typedef enum
{
NRFX_PWM_FLAG_STOP = 0x01, /**< When the requested playback is finished,
the peripheral should be stopped.
@note The STOP task is triggered when
the last value of the final sequence is
loaded from RAM, and the peripheral stops
at the end of the current PWM period.
For sequences with configured repeating
of duty cycle values, this might result in
less than the requested number of repeats
of the last value. */
NRFX_PWM_FLAG_LOOP = 0x02, /**< When the requested playback is finished,
it should be started from the beginning.
This flag is ignored if used together
with @ref NRFX_PWM_FLAG_STOP.
@note The playback restart is done via a
shortcut configured in the PWM peripheral.
This shortcut triggers the proper starting
task when the final value of previous
playback is read from RAM and applied to
the pulse generator counter.
When this mechanism is used together with
the @ref NRF_PWM_STEP_TRIGGERED mode,
the playback restart will occur right
after switching to the final value (this
final value will be played only once). */
NRFX_PWM_FLAG_SIGNAL_END_SEQ0 = 0x04, /**< The event handler should be
called when the last value
from sequence 0 is loaded. */
NRFX_PWM_FLAG_SIGNAL_END_SEQ1 = 0x08, /**< The event handler should be
called when the last value
from sequence 1 is loaded. */
NRFX_PWM_FLAG_NO_EVT_FINISHED = 0x10, /**< The playback finished event
(enabled by default) should be
suppressed. */
NRFX_PWM_FLAG_START_VIA_TASK = 0x80, /**< The playback should not be
started directly by the called
function. Instead, the function
should only prepare it and
return the address of the task
to be triggered to start the
playback. */
} nrfx_pwm_flag_t;
/**
* @brief PWM driver event type.
*/
typedef enum
{
NRFX_PWM_EVT_FINISHED, ///< Sequence playback finished.
NRFX_PWM_EVT_END_SEQ0, /**< End of sequence 0 reached. Its data can be
safely modified now. */
NRFX_PWM_EVT_END_SEQ1, /**< End of sequence 1 reached. Its data can be
safely modified now. */
NRFX_PWM_EVT_STOPPED, ///< The PWM peripheral has been stopped.
} nrfx_pwm_evt_type_t;
/**
* @brief PWM driver event handler type.
*/
typedef void (* nrfx_pwm_handler_t)(nrfx_pwm_evt_type_t event_type);
/**
* @brief Function for initializing the PWM driver.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_config Pointer to the structure with initial configuration.
*
* @param[in] handler Event handler provided by the user. If NULL is passed
* instead, event notifications are not done and PWM
* interrupts are disabled.
*
* @retval NRFX_SUCCESS If initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE If the driver was already initialized.
*/
nrfx_err_t nrfx_pwm_init(nrfx_pwm_t const * const p_instance,
nrfx_pwm_config_t const * p_config,
nrfx_pwm_handler_t handler);
/**
* @brief Function for uninitializing the PWM driver.
*
* If any sequence playback is in progress, it is stopped immediately.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
void nrfx_pwm_uninit(nrfx_pwm_t const * const p_instance);
/**
* @brief Function for starting a single sequence playback.
*
* To take advantage of the looping mechanism in the PWM peripheral, both
* sequences must be used (single sequence can be played back only once by
* the peripheral). Therefore, the provided sequence is internally set and
* played back as both sequence 0 and sequence 1. Consequently, if end of
* sequence notifications are required, events for both sequences should be
* used (that means that both the @ref NRFX_PWM_FLAG_SIGNAL_END_SEQ0 flag
* and the @ref NRFX_PWM_FLAG_SIGNAL_END_SEQ1 flag should be specified and
* the @ref NRFX_PWM_EVT_END_SEQ0 event and the @ref NRFX_PWM_EVT_END_SEQ1
* event should be handled in the same way).
*
* Use the @ref NRFX_PWM_FLAG_START_VIA_TASK flag if you want the playback
* to be only prepared by this function, and you want to start it later by
* triggering a task (using PPI for instance). The function will then return
* the address of the task to be triggered.
*
* @note The array containing the duty cycle values for the specified sequence
* must be in RAM and cannot be allocated on stack.
* For detailed information, see @ref nrf_pwm_sequence_t.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_sequence Sequence to be played back.
* @param[in] playback_count Number of playbacks to be performed (must not be 0).
* @param[in] flags Additional options. Pass any combination of
* @ref nrfx_pwm_flag_t "playback flags", or 0
* for default settings.
*
* @return Address of the task to be triggered to start the playback if the @ref
* NRFX_PWM_FLAG_START_VIA_TASK flag was used, 0 otherwise.
*/
uint32_t nrfx_pwm_simple_playback(nrfx_pwm_t const * const p_instance,
nrf_pwm_sequence_t const * p_sequence,
uint16_t playback_count,
uint32_t flags);
/**
* @brief Function for starting a two-sequence playback.
*
* Use the @ref NRFX_PWM_FLAG_START_VIA_TASK flag if you want the playback
* to be only prepared by this function, and you want to start it later by
* triggering a task (using PPI for instance). The function will then return
* the address of the task to be triggered.
*
* @note The array containing the duty cycle values for the specified sequence
* must be in RAM and cannot be allocated on stack.
* For detailed information, see @ref nrf_pwm_sequence_t.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] p_sequence_0 First sequence to be played back.
* @param[in] p_sequence_1 Second sequence to be played back.
* @param[in] playback_count Number of playbacks to be performed (must not be 0).
* @param[in] flags Additional options. Pass any combination of
* @ref nrfx_pwm_flag_t "playback flags", or 0
* for default settings.
*
* @return Address of the task to be triggered to start the playback if the @ref
* NRFX_PWM_FLAG_START_VIA_TASK flag was used, 0 otherwise.
*/
uint32_t nrfx_pwm_complex_playback(nrfx_pwm_t const * const p_instance,
nrf_pwm_sequence_t const * p_sequence_0,
nrf_pwm_sequence_t const * p_sequence_1,
uint16_t playback_count,
uint32_t flags);
/**
* @brief Function for advancing the active sequence.
*
* This function only applies to @ref NRF_PWM_STEP_TRIGGERED mode.
*
* @param[in] p_instance Pointer to the driver instance structure.
*/
__STATIC_INLINE void nrfx_pwm_step(nrfx_pwm_t const * const p_instance);
/**
* @brief Function for stopping the sequence playback.
*
* The playback is stopped at the end of the current PWM period.
* This means that if the active sequence is configured to repeat each duty
* cycle value for a certain number of PWM periods, the last played value
* might appear on the output less times than requested.
*
* @note This function can be instructed to wait until the playback is stopped
* (by setting @p wait_until_stopped to true). Note that, depending on
* the length of the PMW period, this might take a significant amount of
* time. Alternatively, the @ref nrfx_pwm_is_stopped function can be
* used to poll the status, or the @ref NRFX_PWM_EVT_STOPPED event can
* be used to get the notification when the playback is stopped, provided
* the event handler is defined.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] wait_until_stopped If true, the function will not return until
* the playback is stopped.
*
* @retval true If the PWM peripheral is stopped.
* @retval false If the PWM peripheral is not stopped.
*/
bool nrfx_pwm_stop(nrfx_pwm_t const * const p_instance,
bool wait_until_stopped);
/**
* @brief Function for checking the status of the PWM peripheral.
*
* @param[in] p_instance Pointer to the driver instance structure.
*
* @retval true If the PWM peripheral is stopped.
* @retval false If the PWM peripheral is not stopped.
*/
bool nrfx_pwm_is_stopped(nrfx_pwm_t const * const p_instance);
/**
* @brief Function for updating the sequence data during playback.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] p_sequence Pointer to the new sequence definition.
*/
__STATIC_INLINE void nrfx_pwm_sequence_update(
nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
nrf_pwm_sequence_t const * p_sequence);
/**
* @brief Function for updating the pointer to the duty cycle values
* in the specified sequence during playback.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] values New pointer to the duty cycle values.
*/
__STATIC_INLINE void nrfx_pwm_sequence_values_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
nrf_pwm_values_t values);
/**
* @brief Function for updating the number of duty cycle values
* in the specified sequence during playback.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] length New number of the duty cycle values.
*/
__STATIC_INLINE void nrfx_pwm_sequence_length_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
uint16_t length);
/**
* @brief Function for updating the number of repeats for duty cycle values
* in specified sequence during playback.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] repeats New number of repeats.
*/
__STATIC_INLINE void nrfx_pwm_sequence_repeats_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
uint32_t repeats);
/**
* @brief Function for updating the additional delay after the specified
* sequence during playback.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] end_delay New end delay value (in PWM periods).
*/
__STATIC_INLINE void nrfx_pwm_sequence_end_delay_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
uint32_t end_delay);
/**
* @brief Function for returning the address of a specified PWM task that can
* be used in PPI module.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] task Requested task.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_pwm_task_address_get(nrfx_pwm_t const * const p_instance,
nrf_pwm_task_t task);
/**@brief Function for returning the address of a specified PWM event that can
* be used in PPI module.
*
* @param[in] p_instance Pointer to the driver instance structure.
* @param[in] event Requested event.
*
* @return Event address.
*/
__STATIC_INLINE uint32_t nrfx_pwm_event_address_get(nrfx_pwm_t const * const p_instance,
nrf_pwm_event_t event);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrfx_pwm_step(nrfx_pwm_t const * const p_instance)
{
nrf_pwm_task_trigger(p_instance->p_registers, NRF_PWM_TASK_NEXTSTEP);
}
__STATIC_INLINE void nrfx_pwm_sequence_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
nrf_pwm_sequence_t const * p_sequence)
{
nrf_pwm_sequence_set(p_instance->p_registers, seq_id, p_sequence);
}
__STATIC_INLINE void nrfx_pwm_sequence_values_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
nrf_pwm_values_t values)
{
nrf_pwm_seq_ptr_set(p_instance->p_registers, seq_id, values.p_raw);
}
__STATIC_INLINE void nrfx_pwm_sequence_length_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
uint16_t length)
{
nrf_pwm_seq_cnt_set(p_instance->p_registers, seq_id, length);
}
__STATIC_INLINE void nrfx_pwm_sequence_repeats_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
uint32_t repeats)
{
nrf_pwm_seq_refresh_set(p_instance->p_registers, seq_id, repeats);
}
__STATIC_INLINE void nrfx_pwm_sequence_end_delay_update(nrfx_pwm_t const * const p_instance,
uint8_t seq_id,
uint32_t end_delay)
{
nrf_pwm_seq_end_delay_set(p_instance->p_registers, seq_id, end_delay);
}
__STATIC_INLINE uint32_t nrfx_pwm_task_address_get(nrfx_pwm_t const * const p_instance,
nrf_pwm_task_t task)
{
return nrf_pwm_task_address_get(p_instance->p_registers, task);
}
__STATIC_INLINE uint32_t nrfx_pwm_event_address_get(nrfx_pwm_t const * const p_instance,
nrf_pwm_event_t event)
{
return nrf_pwm_event_address_get(p_instance->p_registers, event);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
void nrfx_pwm_0_irq_handler(void);
void nrfx_pwm_1_irq_handler(void);
void nrfx_pwm_2_irq_handler(void);
void nrfx_pwm_3_irq_handler(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRFX_PWM_H__
@@ -0,0 +1,186 @@
/**
* Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_QDEC_H__
#define NRFX_QDEC_H__
#include <nrfx.h>
#include <hal/nrf_qdec.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_qdec QDEC driver
* @{
* @ingroup nrf_qdec
* @brief Quadrature Decoder (QDEC) peripheral driver.
*/
/**@brief QDEC configuration structure.*/
typedef struct
{
nrf_qdec_reportper_t reportper; /**< Report period in samples. */
nrf_qdec_sampleper_t sampleper; /**< Sampling period in microseconds. */
uint32_t psela; /**< Pin number for A input. */
uint32_t pselb; /**< Pin number for B input. */
uint32_t pselled; /**< Pin number for LED output. */
uint32_t ledpre; /**< Time (in microseconds) how long LED is switched on before sampling. */
nrf_qdec_ledpol_t ledpol; /**< Active LED polarity. */
bool dbfen; /**< State of debouncing filter. */
bool sample_inten; /**< Enabling sample ready interrupt. */
uint8_t interrupt_priority; /**< QDEC interrupt priority. */
} nrfx_qdec_config_t;
/**@brief QDEC default configuration. */
#define NRFX_QDEC_DEFAULT_CONFIG \
{ \
.reportper = (nrf_qdec_reportper_t)NRFX_QDEC_CONFIG_REPORTPER, \
.sampleper = (nrf_qdec_sampleper_t)NRFX_QDEC_CONFIG_SAMPLEPER, \
.psela = NRFX_QDEC_CONFIG_PIO_A, \
.pselb = NRFX_QDEC_CONFIG_PIO_B, \
.pselled = NRFX_QDEC_CONFIG_PIO_LED, \
.ledpre = NRFX_QDEC_CONFIG_LEDPRE, \
.ledpol = (nrf_qdec_ledpol_t)NRFX_QDEC_CONFIG_LEDPOL, \
.interrupt_priority = NRFX_QDEC_CONFIG_IRQ_PRIORITY, \
.dbfen = NRFX_QDEC_CONFIG_DBFEN, \
.sample_inten = NRFX_QDEC_CONFIG_SAMPLE_INTEN \
}
/**@brief QDEC sample event data.*/
typedef struct
{
int8_t value; /**< Sample value. */
} nrfx_qdec_sample_data_evt_t;
/**@brief QDEC report event data.*/
typedef struct
{
int16_t acc; /**< Accumulated transitions. */
uint16_t accdbl; /**< Accumulated double transitions. */
} nrfx_qdec_report_data_evt_t;
/**@brief QDEC event handler structure. */
typedef struct
{
nrf_qdec_event_t type;
union
{
nrfx_qdec_sample_data_evt_t sample; /**< Sample event data. */
nrfx_qdec_report_data_evt_t report; /**< Report event data. */
} data;
} nrfx_qdec_event_t;
/**@brief QDEC event handler.
* @param[in] event QDEC event structure.
*/
typedef void (*nrfx_qdec_event_handler_t)(nrfx_qdec_event_t event);
/**@brief Function for initializing QDEC.
*
* @param[in] p_config Pointer to the structure with initial configuration.
* @param[in] event_handler Event handler provided by the user.
* Must not be NULL.
*
* @retval NRFX_SUCCESS If initialization was successful.
* @retval NRFX_ERROR_INVALID_STATE If QDEC was already initialized.
*/
nrfx_err_t nrfx_qdec_init(nrfx_qdec_config_t const * p_config,
nrfx_qdec_event_handler_t event_handler);
/**@brief Function for uninitializing QDEC.
* @note Function asserts if module is uninitialized.
*/
void nrfx_qdec_uninit(void);
/**@brief Function for enabling QDEC.
* @note Function asserts if module is uninitialized or enabled.
*/
void nrfx_qdec_enable(void);
/**@brief Function for disabling QDEC.
* @note Function asserts if module is uninitialized or disabled.
*/
void nrfx_qdec_disable(void);
/**@brief Function for reading accumulated transitions QDEC.
* @note Function asserts if module is not enabled.
* @note Accumulators are cleared after reading.
*
* @param[out] p_acc Pointer to store accumulated transitions.
* @param[out] p_accdbl Pointer to store accumulated double transitions.
*/
void nrfx_qdec_accumulators_read(int16_t * p_acc, int16_t * p_accdbl);
/**
* @brief Function for returning the address of a specific QDEC task.
*
* @param task QDEC task.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrfx_qdec_task_address_get(nrf_qdec_task_t task)
{
return (uint32_t)nrf_qdec_task_address_get(task);
}
/**
* @brief Function for returning the address of a specific QDEC event.
*
* @param event QDEC event.
*
* @return Event address.
*/
__STATIC_INLINE uint32_t nrfx_qdec_event_address_get(nrf_qdec_event_t event)
{
return (uint32_t)nrf_qdec_event_address_get(event);
}
void nrfx_qdec_irq_handler(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRFX_QDEC_H__
@@ -0,0 +1,297 @@
/**
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRFX_QSPI_H__
#define NRFX_QSPI_H__
#include <nrfx.h>
#include <hal/nrf_qspi.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrfx_qspi QSPI driver
* @{
* @ingroup nrf_qspi
* @brief Quad Serial Peripheral Interface (QSPI) peripheral driver.
*/
/**
* @brief QSPI driver instance configuration structure.
*/
typedef struct
{
uint32_t xip_offset; /**< Address offset into the external memory for Execute in Place operation. */
nrf_qspi_pins_t pins; /**< Pins configuration structure. */
nrf_qspi_prot_conf_t prot_if; /**< Protocol layer interface configuration structure. */
nrf_qspi_phy_conf_t phy_if; /**< Physical layer interface configuration structure. */
uint8_t irq_priority; /**< Interrupt priority. */
} nrfx_qspi_config_t;
/**
* @brief QSPI instance default configuration.
*/
#define NRFX_QSPI_DEFAULT_CONFIG \
{ \
.xip_offset = NRFX_QSPI_CONFIG_XIP_OFFSET, \
.pins = { \
.sck_pin = NRFX_QSPI_PIN_SCK, \
.csn_pin = NRFX_QSPI_PIN_CSN, \
.io0_pin = NRFX_QSPI_PIN_IO0, \
.io1_pin = NRFX_QSPI_PIN_IO1, \
.io2_pin = NRFX_QSPI_PIN_IO2, \
.io3_pin = NRFX_QSPI_PIN_IO3, \
}, \
.irq_priority = (uint8_t)NRFX_QSPI_CONFIG_IRQ_PRIORITY, \
.prot_if = { \
.readoc = (nrf_qspi_readoc_t)NRFX_QSPI_CONFIG_READOC, \
.writeoc = (nrf_qspi_writeoc_t)NRFX_QSPI_CONFIG_WRITEOC, \
.addrmode = (nrf_qspi_addrmode_t)NRFX_QSPI_CONFIG_ADDRMODE, \
.dpmconfig = false, \
}, \
.phy_if = { \
.sck_freq = (nrf_qspi_frequency_t)NRFX_QSPI_CONFIG_FREQUENCY, \
.sck_delay = (uint8_t)NRFX_QSPI_CONFIG_SCK_DELAY, \
.spi_mode = (nrf_qspi_spi_mode_t)NRFX_QSPI_CONFIG_MODE, \
.dpmen = false \
}, \
}
/**
* @brief QSPI custom instruction helper with default configuration.
*/
#define NRFX_QSPI_DEFAULT_CINSTR(opc, len) \
{ \
.opcode = (opc), \
.length = (len), \
.io2_level = false, \
.io3_level = false, \
.wipwait = false, \
.wren = false \
}
/**
* @brief QSPI master driver event types, passed to the handler routine provided
* during initialization.
*/
typedef enum
{
NRFX_QSPI_EVENT_DONE, /**< Transfer done. */
} nrfx_qspi_evt_t;
/**
* @brief QSPI driver event handler type.
*/
typedef void (*nrfx_qspi_handler_t)(nrfx_qspi_evt_t event, void * p_context);
/**
* @brief Function for initializing the QSPI driver instance.
*
* This function configures the peripheral and its interrupts and activates it. During the
* activation process, the internal clocks are started and the QSPI peripheral tries to read
* the status byte to read the busy bit. Reading the status byte is done in a simple poll and wait
* mechanism.
* If the busy bit is 1, this indicates issues with the external memory device. As a result,
* @ref nrfx_qspi_init returns NRFX_ERROR_TIMEOUT.
*
* In case of issues:
* - Check the connection.
* - Make sure that the memory device does not perform other operations like erasing or writing.
* - Check if there is a short circuit.
*
* @param[in] p_config Pointer to the structure with initial configuration.
* @param[in] handler Event handler provided by the user. If NULL, transfers
* will be performed in blocking mode.
* @param[in] p_context Pointer to context. Use in interrupt handler.
*
* @retval NRFX_SUCCESS If initialization was successful.
* @retval NRFX_ERROR_TIMEOUT If the peripheral cannot connect with external memory.
* @retval NRFX_ERROR_INVALID_STATE If the driver was already initialized.
* @retval NRFX_ERROR_INVALID_PARAM If the pin configuration was incorrect.
*/
nrfx_err_t nrfx_qspi_init(nrfx_qspi_config_t const * p_config,
nrfx_qspi_handler_t handler,
void * p_context);
/**
* @brief Function for uninitializing the QSPI driver instance.
*/
void nrfx_qspi_uninit(void);
/**
* @brief Function for reading data from QSPI memory.
*
* Write, read, and erase operations check memory device busy state before starting the operation.
* If the memory is busy, the resulting action depends on the mode in which the read operation is used:
* - blocking mode (without handler) - a delay occurs until the last operation still runs and
* until operation data is still being read.
* - interrupt mode (with handler) - event emission occurs after the last operation
* and reading of data are finished.
*
* @param[out] p_rx_buffer Pointer to the receive buffer.
* @param[in] rx_buffer_length Size of the data to read.
* @param[in] src_address Address in memory to read from.
*
* @retval NRFX_SUCCESS If the operation was successful (blocking mode) or operation
* was commissioned (handler mode).
* @retval NRFX_ERROR_BUSY If the driver currently handles another operation.
* @retval NRFX_ERROR_INVALID_ADDR If the provided buffer is not placed in the Data RAM region.
*/
nrfx_err_t nrfx_qspi_read(void * p_rx_buffer,
size_t rx_buffer_length,
uint32_t src_address);
/**
* @brief Function for writing data to QSPI memory.
*
* Write, read, and erase operations check memory device busy state before starting the operation.
* If the memory is busy, the resulting action depends on the mode in which the write operation is used:
* - blocking mode (without handler) - a delay occurs until the last operation still runs and
* until operation data is still being sent.
* - interrupt mode (with handler) - event emission occurs after the last operation
* and sending of operation data are finished.
* To manually control operation execution in the memory device, use @ref nrfx_qspi_mem_busy_check
* after executing the write function.
* Remember that an incoming event signalizes only that data was sent to the memory device and the periheral
* before the write operation checked if memory was busy.
*
* @param[in] p_tx_buffer Pointer to the writing buffer.
* @param[in] tx_buffer_length Size of the data to write.
* @param[in] dst_address Address in memory to write to.
*
* @retval NRFX_SUCCESS If the operation was successful (blocking mode) or operation
* was commissioned (handler mode).
* @retval NRFX_ERROR_BUSY If the driver currently handles other operation.
* @retval NRFX_ERROR_INVALID_ADDR If the provided buffer is not placed in the Data RAM region.
*/
nrfx_err_t nrfx_qspi_write(void const * p_tx_buffer,
size_t tx_buffer_length,
uint32_t dst_address);
/**
* @brief Function for starting erasing of one memory block - 4KB, 64KB, or the whole chip.
*
* Write, read, and erase operations check memory device busy state before starting the operation.
* If the memory is busy, the resulting action depends on the mode in which the erase operation is used:
* - blocking mode (without handler) - a delay occurs until the last operation still runs and
* until operation data is still being sent.
* - interrupt mode (with handler) - event emission occurs after the last operation
* and sending of operation data are finished.
* To manually control operation execution in the memory device, use @ref nrfx_qspi_mem_busy_check
* after executing the erase function.
* Remember that an incoming event signalizes only that data was sent to the memory device and the periheral
* before the erase operation checked if memory was busy.
*
* @param[in] length Size of data to erase. See @ref nrf_qspi_erase_len_t.
* @param[in] start_address Memory address to start erasing. If chip erase is performed, address
* field is ommited.
*
* @retval NRFX_SUCCESS If the operation was successful (blocking mode) or operation
* was commissioned (handler mode).
* @retval NRFX_ERROR_BUSY If the driver currently handles another operation.
*/
nrfx_err_t nrfx_qspi_erase(nrf_qspi_erase_len_t length,
uint32_t start_address);
/**
* @brief Function for starting an erase operation of the whole chip.
*
* @retval NRFX_SUCCESS If the operation was successful (blocking mode) or operation
* was commissioned (handler mode).
* @retval NRFX_ERROR_BUSY If the driver currently handles another operation.
*/
nrfx_err_t nrfx_qspi_chip_erase(void);
/**
* @brief Function for getting the current driver status and status byte of memory device with
* testing WIP (write in progress) bit.
*
* @retval NRFX_SUCCESS If the driver and memory are ready to handle a new operation.
* @retval NRFX_ERROR_BUSY If the driver or memory currently handle another operation.
*/
nrfx_err_t nrfx_qspi_mem_busy_check(void);
/**
* @brief Function for sending operation code, sending data, and receiving data from the memory device.
*
* Use this function to transfer configuration data to memory and to receive data from memory.
* Pointers can be addresses from flash memory.
* This function is a synchronous function and should be used only if necessary.
*
* @param[in] p_config Pointer to the structure with opcode and transfer configuration.
* @param[in] p_tx_buffer Pointer to the array with data to send. Can be NULL if only opcode is transmitted.
* @param[out] p_rx_buffer Pointer to the array for data to receive. Can be NULL if there is nothing to receive.
*
* @retval NRFX_SUCCESS If the operation was successful.
* @retval NRFX_ERROR_TIMEOUT If the external memory is busy or there are connection issues.
* @retval NRFX_ERROR_BUSY If the driver currently handles other operation.
*/
nrfx_err_t nrfx_qspi_cinstr_xfer(nrf_qspi_cinstr_conf_t const * p_config,
void const * p_tx_buffer,
void * p_rx_buffer);
/**
* @brief Function for sending operation code and data to the memory device with simpler configuration.
*
* Use this function to transfer configuration data to memory and to receive data from memory.
* This function is a synchronous function and should be used only if necessary.
*
* @param[in] opcode Operation code. Sending first.
* @param[in] length Length of the data to send and opcode. See @ref nrf_qspi_cinstr_len_t.
* @param[in] p_tx_buffer Pointer to input data array.
*
* @retval NRFX_SUCCESS If the operation was successful.
* @retval NRFX_ERROR_BUSY If the driver currently handles another operation.
*/
nrfx_err_t nrfx_qspi_cinstr_quick_send(uint8_t opcode,
nrf_qspi_cinstr_len_t length,
void const * p_tx_buffer);
void nrfx_qspi_irq_handler(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRFX_QSPI_H__

Some files were not shown because too many files have changed in this diff Show More