mirror of
https://github.com/espressif/openthread.git
synced 2026-08-10 04:37:47 +00:00
[nRF52840] add USB CDC ACM support (#2215)
This commit is contained in:
committed by
Jonathan Hui
parent
b905fa590e
commit
44cb528a7a
@@ -85,6 +85,10 @@ else
|
||||
COMMONCFLAGS += -DOPENTHREAD_CONFIG_LOG_OUTPUT=OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
|
||||
endif
|
||||
|
||||
ifeq ($(USB),1)
|
||||
COMMONCFLAGS += -DUSB_CDC_AS_SERIAL_TRANSPORT=1
|
||||
endif
|
||||
|
||||
CPPFLAGS += \
|
||||
$(COMMONCFLAGS) \
|
||||
$(target_CPPFLAGS) \
|
||||
|
||||
@@ -45,10 +45,20 @@ COMMONCPPFLAGS
|
||||
-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 \
|
||||
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio \
|
||||
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal \
|
||||
-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/atfifo \
|
||||
-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/segger_rtt \
|
||||
$(NULL)
|
||||
|
||||
@@ -59,13 +69,14 @@ PLATFORM_COMMON_SOURCES
|
||||
logging.c \
|
||||
misc.c \
|
||||
platform.c \
|
||||
uart.c \
|
||||
platform-config.h \
|
||||
platform-fem.h \
|
||||
platform-nrf5.h \
|
||||
radio.c \
|
||||
random.c \
|
||||
temp.c \
|
||||
uart.c \
|
||||
usb-cdc-uart.c \
|
||||
$(NULL)
|
||||
|
||||
SINGLEPHY_SOURCES = \
|
||||
@@ -140,7 +151,17 @@ libopenthread_nrf52840_a_SOURCES
|
||||
$(PLATFORM_SOURCES) \
|
||||
$(NORDICSEMI_SOURCES) \
|
||||
$(SINGLEPHY_SOURCES) \
|
||||
@top_builddir@/third_party/NordicSemiconductor/dependencies/app_util_platform.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/libraries/atfifo/nrf_atfifo.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/class/cdc/acm/app_usbd_cdc_acm.c \
|
||||
$(NULL)
|
||||
|
||||
libopenthread_nrf52840_sdk_a_CPPFLAGS = \
|
||||
|
||||
@@ -37,6 +37,17 @@ files using `arm-none-eabi-objcopy`:
|
||||
$ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex
|
||||
```
|
||||
|
||||
## Native USB support
|
||||
|
||||
You can build the libraries with support for native USB CDC ACM as a serial transport.
|
||||
To do so, build the libraries with the following parameter:
|
||||
```
|
||||
$ make -f examples/Makefile-nrf52840 USB=1
|
||||
```
|
||||
|
||||
Note, that if Windows 7 or earlier is used, an additional USB CDC driver has to be loaded.
|
||||
It can be found in third_party/NordicSemiconductor/libraries/usb/nordic_cdc_acm_example.inf
|
||||
|
||||
## Flashing the binaries
|
||||
|
||||
Flash the compiled binaries onto nRF52840 using `nrfjprog` which is
|
||||
|
||||
@@ -57,8 +57,6 @@
|
||||
|
||||
#define RTC_FREQUENCY 32768ULL
|
||||
|
||||
#define CEIL_DIV(A, B) (((A) + (B) - 1ULL) / (B))
|
||||
|
||||
#define US_PER_MS 1000ULL
|
||||
#define US_PER_S 1000000ULL
|
||||
#define US_PER_TICK CEIL_DIV(US_PER_S, RTC_FREQUENCY)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <openthread/config.h>
|
||||
#include <openthread-core-config.h>
|
||||
#include <openthread/platform/misc.h>
|
||||
#include <openthread/platform/platform.h>
|
||||
|
||||
#include <device/nrf.h>
|
||||
|
||||
@@ -69,6 +70,9 @@ void nrf5MiscDeinit(void)
|
||||
void otPlatReset(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
|
||||
PlatformDeinit();
|
||||
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,9 @@
|
||||
* UART Instance.
|
||||
*
|
||||
*/
|
||||
#ifndef UART_INSTANCE
|
||||
#define UART_INSTANCE NRF_UART0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def UART_PARITY
|
||||
@@ -64,7 +66,9 @@
|
||||
* \ref NRF_UART_PARITY_INCLUDED - Parity bit is present.
|
||||
*
|
||||
*/
|
||||
#ifndef UART_PARITY
|
||||
#define UART_PARITY NRF_UART_PARITY_EXCLUDED
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def UART_HWFC
|
||||
@@ -76,7 +80,9 @@
|
||||
* \ref NRF_UART_HWFC_DISABLED - HW Flow control disabled.
|
||||
*
|
||||
*/
|
||||
#ifndef UART_HWFC
|
||||
#define UART_HWFC NRF_UART_HWFC_ENABLED
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def UART_BAUDRATE
|
||||
@@ -102,7 +108,9 @@
|
||||
* \ref NRF_UART_BAUDRATE_1000000 - 1000000 baud.
|
||||
*
|
||||
*/
|
||||
#ifndef UART_BAUDRATE
|
||||
#define UART_BAUDRATE NRF_UART_BAUDRATE_115200
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def UART_IRQN
|
||||
@@ -110,7 +118,9 @@
|
||||
* UART Interrupt number.
|
||||
*
|
||||
*/
|
||||
#ifndef UART_IRQN
|
||||
#define UART_IRQN UARTE0_UART0_IRQn
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def UART_IRQ_PRIORITY
|
||||
@@ -118,7 +128,9 @@
|
||||
* UART Interrupt priority.
|
||||
*
|
||||
*/
|
||||
#ifndef UART_IRQ_PRIORITY
|
||||
#define UART_IRQ_PRIORITY 6
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def UART_RX_BUFFER_SIZE
|
||||
@@ -126,7 +138,9 @@
|
||||
* UART Receive buffer size.
|
||||
*
|
||||
*/
|
||||
#ifndef UART_RX_BUFFER_SIZE
|
||||
#define UART_RX_BUFFER_SIZE 256
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def UART_PIN_TX
|
||||
@@ -134,7 +148,9 @@
|
||||
* UART TX Pin.
|
||||
*
|
||||
*/
|
||||
#ifndef UART_PIN_TX
|
||||
#define UART_PIN_TX 6
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def UART_PIN_RX
|
||||
@@ -142,7 +158,9 @@
|
||||
* UART RX Pin.
|
||||
*
|
||||
*/
|
||||
#ifndef UART_PIN_RX
|
||||
#define UART_PIN_RX 8
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def UART_PIN_CTS
|
||||
@@ -150,7 +168,9 @@
|
||||
* UART CTS Pin.
|
||||
*
|
||||
*/
|
||||
#ifndef UART_PIN_CTS
|
||||
#define UART_PIN_CTS 7
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def UART_PIN_RTS
|
||||
@@ -158,7 +178,9 @@
|
||||
* UART RTS Pin.
|
||||
*
|
||||
*/
|
||||
#ifndef UART_PIN_RTS
|
||||
#define UART_PIN_RTS 5
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* @section Alarm Driver Configuration.
|
||||
@@ -170,7 +192,9 @@
|
||||
* RTC Instance.
|
||||
*
|
||||
*/
|
||||
#ifndef RTC_INSTANCE
|
||||
#define RTC_INSTANCE NRF_RTC2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def RTC_IRQ_HANDLER
|
||||
@@ -178,7 +202,9 @@
|
||||
* RTC interrupt handler name
|
||||
*
|
||||
*/
|
||||
#ifndef RTC_IRQ_HANDLER
|
||||
#define RTC_IRQ_HANDLER RTC2_IRQHandler
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def RTC_IRQN
|
||||
@@ -186,7 +212,9 @@
|
||||
* RTC Interrupt number.
|
||||
*
|
||||
*/
|
||||
#ifndef RTC_IRQN
|
||||
#define RTC_IRQN RTC2_IRQn
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def RTC_IRQ_PRIORITY
|
||||
@@ -194,7 +222,9 @@
|
||||
* RTC Interrupt priority.
|
||||
*
|
||||
*/
|
||||
#ifndef RTC_IRQ_PRIORITY
|
||||
#define RTC_IRQ_PRIORITY 6
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* @section Random Number Generator Driver Configuration.
|
||||
@@ -206,7 +236,9 @@
|
||||
* True Random Number Generator buffer size.
|
||||
*
|
||||
*/
|
||||
#ifndef RNG_BUFFER_SIZE
|
||||
#define RNG_BUFFER_SIZE 64
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def RNG_IRQ_PRIORITY
|
||||
@@ -214,7 +246,9 @@
|
||||
* RNG Interrupt priority.
|
||||
*
|
||||
*/
|
||||
#ifndef RNG_IRQ_PRIORITY
|
||||
#define RNG_IRQ_PRIORITY 6
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* @section Log module configuration.
|
||||
@@ -226,7 +260,9 @@
|
||||
* RTT's buffer index.
|
||||
*
|
||||
*/
|
||||
#ifndef LOG_RTT_BUFFER_INDEX
|
||||
#define LOG_RTT_BUFFER_INDEX 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def LOG_RTT_BUFFER_NAME
|
||||
@@ -234,7 +270,9 @@
|
||||
* RTT's name.
|
||||
*
|
||||
*/
|
||||
#ifndef LOG_RTT_BUFFER_NAME
|
||||
#define LOG_RTT_BUFFER_NAME "Terminal"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def LOG_RTT_BUFFER_SIZE
|
||||
@@ -242,7 +280,9 @@
|
||||
* LOG RTT's buffer size.
|
||||
*
|
||||
*/
|
||||
#ifndef LOG_RTT_BUFFER_SIZE
|
||||
#define LOG_RTT_BUFFER_SIZE 256
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def LOG_RTT_COLOR_ENABLE
|
||||
@@ -250,7 +290,9 @@
|
||||
* Enable colors on RTT Viewer.
|
||||
*
|
||||
*/
|
||||
#ifndef LOG_RTT_COLOR_ENABLE
|
||||
#define LOG_RTT_COLOR_ENABLE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def LOG_PARSE_BUFFER_SIZE
|
||||
@@ -259,7 +301,9 @@
|
||||
* stack.
|
||||
*
|
||||
*/
|
||||
#ifndef LOG_PARSE_BUFFER_SIZE
|
||||
#define LOG_PARSE_BUFFER_SIZE 128
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def LOG_TIMESTAMP_ENABLE
|
||||
@@ -267,6 +311,27 @@
|
||||
* Enable timestamp in the logs.
|
||||
*
|
||||
*/
|
||||
#ifndef LOG_TIMESTAMP_ENABLE
|
||||
#define LOG_TIMESTAMP_ENABLE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def USB_INITIAL_DELAY_MS
|
||||
*
|
||||
* Init delay for USB driver, used when software reset was detected to help OS to re-enumerate the device.
|
||||
*
|
||||
*/
|
||||
#ifndef USB_INITIAL_DELAY_MS
|
||||
#define USB_INITIAL_DELAY_MS 600
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def USB_CDC_AS_SERIAL_TRANSPORT
|
||||
*
|
||||
* Use USB CDC driver for serial communication.
|
||||
*/
|
||||
#ifndef USB_CDC_AS_SERIAL_TRANSPORT
|
||||
#define USB_CDC_AS_SERIAL_TRANSPORT 0
|
||||
#endif
|
||||
|
||||
#endif // PLATFORM_CONFIG_H_
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
#include <hal/nrf_gpio.h>
|
||||
#include "platform-nrf5.h"
|
||||
|
||||
#if (USB_CDC_AS_SERIAL_TRANSPORT == 0)
|
||||
|
||||
/**
|
||||
* UART TX buffer variables.
|
||||
*/
|
||||
@@ -288,6 +290,8 @@ void UARTE0_UART0_IRQHandler(void)
|
||||
}
|
||||
}
|
||||
|
||||
#endif // USB_CDC_AS_SERIAL_TRANSPORT == 0
|
||||
|
||||
/**
|
||||
* The UART driver weak functions definition.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* Copyright (c) 2017, The OpenThread Authors.
|
||||
* 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 the copyright holder 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
|
||||
* This file implements the OpenThread platform abstraction for UART communication over USB CDC.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||
|
||||
#include <openthread/config.h>
|
||||
#include <openthread-core-config.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <openthread/types.h>
|
||||
#include <openthread/platform/uart.h>
|
||||
#include <openthread/platform/alarm-milli.h>
|
||||
#include <openthread/platform/misc.h>
|
||||
|
||||
#include "platform-nrf5.h"
|
||||
|
||||
#include "drivers/clock/nrf_drv_clock.h"
|
||||
#include "drivers/power/nrf_drv_power.h"
|
||||
#include "libraries/usb/app_usbd.h"
|
||||
#include "libraries/usb/class/cdc/acm/app_usbd_cdc_acm.h"
|
||||
|
||||
#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
|
||||
|
||||
static void cdcAcmUserEventHandler(app_usbd_class_inst_t const *aInstance,
|
||||
app_usbd_cdc_acm_user_event_t aEvent);
|
||||
|
||||
#define CDC_ACM_COMM_INTERFACE 0
|
||||
#define CDC_ACM_COMM_EPIN NRF_DRV_USBD_EPIN2
|
||||
|
||||
#define CDC_ACM_DATA_INTERFACE 1
|
||||
#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);
|
||||
|
||||
// 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)];
|
||||
|
||||
static volatile struct
|
||||
{
|
||||
const uint8_t *mTxBuffer;
|
||||
uint16_t mTxSize;
|
||||
size_t mReceivedDataSize;
|
||||
bool mUartEnabled;
|
||||
bool mLastConnectionStatus;
|
||||
bool mConnected;
|
||||
bool mReady;
|
||||
bool mTransferDone;
|
||||
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);
|
||||
|
||||
switch (aEvent)
|
||||
{
|
||||
case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
|
||||
// Setup first transfer.
|
||||
(void)app_usbd_cdc_acm_read(&sAppCdcAcm, sRxBuffer, sizeof(sRxBuffer));
|
||||
break;
|
||||
|
||||
case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
|
||||
break;
|
||||
|
||||
case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
|
||||
sUsbState.mTransferDone = true;
|
||||
break;
|
||||
|
||||
case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
|
||||
sUsbState.mReceiveDone = true;
|
||||
// Get amount of data received.
|
||||
sUsbState.mReceivedDataSize = app_usbd_cdc_acm_rx_size(cdcAcmClass);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void usbdUserEventHandler(app_usbd_event_type_t aEvent)
|
||||
{
|
||||
switch (aEvent)
|
||||
{
|
||||
case APP_USBD_EVT_STOPPED:
|
||||
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:
|
||||
// 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:
|
||||
sUsbState.mConnected = false;
|
||||
break;
|
||||
|
||||
case NRF_DRV_POWER_USB_EVT_READY:
|
||||
sUsbState.mReady = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
static bool isPortOpened(void)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
if (app_usbd_cdc_acm_line_state_get(&sAppCdcAcm, APP_USBD_CDC_ACM_LINE_STATE_DTR, &value) == NRF_SUCCESS)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void processConnection(void)
|
||||
{
|
||||
if (sUsbState.mLastConnectionStatus != (sUsbState.mUartEnabled && sUsbState.mConnected))
|
||||
{
|
||||
sUsbState.mLastConnectionStatus = sUsbState.mUartEnabled && sUsbState.mConnected;
|
||||
|
||||
if (sUsbState.mUartEnabled && sUsbState.mConnected)
|
||||
{
|
||||
if (!nrf_drv_usbd_is_enabled())
|
||||
{
|
||||
app_usbd_enable();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nrf_drv_usbd_is_started())
|
||||
{
|
||||
app_usbd_stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
app_usbd_disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Provide some delay so the OS can re-enumerate the device in case of reset.
|
||||
if (sUsbState.mReady)
|
||||
{
|
||||
if (((otPlatGetResetReason(NULL) == OT_PLAT_RESET_REASON_EXTERNAL) ||
|
||||
(otPlatGetResetReason(NULL) == OT_PLAT_RESET_REASON_SOFTWARE)) &&
|
||||
(otPlatAlarmMilliGetNow() < USB_INITIAL_DELAY_MS))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sUsbState.mReady = false;
|
||||
|
||||
if (nrf_drv_usbd_is_enabled())
|
||||
{
|
||||
app_usbd_start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void processReceive(void)
|
||||
{
|
||||
if (sUsbState.mReceiveDone)
|
||||
{
|
||||
sUsbState.mReceiveDone = false;
|
||||
|
||||
otPlatUartReceived((const uint8_t *)sRxBuffer, sUsbState.mReceivedDataSize);
|
||||
|
||||
// Setup next transfer.
|
||||
(void)app_usbd_cdc_acm_read(&sAppCdcAcm, sRxBuffer, sizeof(sRxBuffer));
|
||||
}
|
||||
}
|
||||
|
||||
static void processTransmit(void)
|
||||
{
|
||||
// If some data was requested to send while port was closed, send it now.
|
||||
if ((sUsbState.mTxBuffer != NULL) && isPortOpened())
|
||||
{
|
||||
if (app_usbd_cdc_acm_write(&sAppCdcAcm, sUsbState.mTxBuffer, sUsbState.mTxSize) == NRF_SUCCESS)
|
||||
{
|
||||
sUsbState.mTxBuffer = NULL;
|
||||
sUsbState.mTxSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (sUsbState.mTransferDone)
|
||||
{
|
||||
sUsbState.mTransferDone = false;
|
||||
|
||||
otPlatUartSendDone();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
ret_code_t ret = nrf_drv_power_init(NULL);
|
||||
assert(ret == NRF_SUCCESS);
|
||||
|
||||
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);
|
||||
assert(ret == NRF_SUCCESS);
|
||||
}
|
||||
|
||||
void nrf5UartDeinit(void)
|
||||
{
|
||||
nrf_drv_power_usbevt_uninit();
|
||||
|
||||
app_usbd_class_remove_all();
|
||||
app_usbd_uninit();
|
||||
|
||||
nrf_drv_power_uninit();
|
||||
}
|
||||
|
||||
void nrf5UartProcess(void)
|
||||
{
|
||||
while (app_usbd_event_queue_process()) { }
|
||||
|
||||
processConnection();
|
||||
processReceive();
|
||||
processTransmit();
|
||||
}
|
||||
|
||||
otError otPlatUartEnable(void)
|
||||
{
|
||||
sUsbState.mUartEnabled = true;
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatUartDisable(void)
|
||||
{
|
||||
sUsbState.mUartEnabled = false;
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
if (!isPortOpened())
|
||||
{
|
||||
// If port is closed, queue the message until it can be sent.
|
||||
if (sUsbState.mTxBuffer == NULL)
|
||||
{
|
||||
sUsbState.mTxBuffer = aBuf;
|
||||
sUsbState.mTxSize = aBufLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
return OT_ERROR_BUSY;
|
||||
}
|
||||
}
|
||||
else if (app_usbd_cdc_acm_write(&sAppCdcAcm, aBuf, aBufLength) != NRF_SUCCESS)
|
||||
{
|
||||
return OT_ERROR_FAILED;
|
||||
}
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
|
||||
+10
-6
@@ -5,14 +5,18 @@ in process of building the OpenThread's nRF52840 platform.
|
||||
nRF5 SDKs used:
|
||||
- nRF5 SDK 12.2.0: [URL][nrf5-sdk-12-2-0]
|
||||
- nRF5 SDK 13.0.0: [URL][nrf5-sdk-13-0-0]
|
||||
- nRF5 SDK 14.0.0: [URL][nrf5-sdk-14-0-0]
|
||||
|
||||
Directory consists of following folders:
|
||||
- /cmsis - Core Peripheral Access Layer Headers files (nRF5 SDK 12.2.0)
|
||||
- /device - MDK for the nRF52840 chip (nRF5 SDK 12.2.0)
|
||||
- /drivers - Drivers for the nRF52840 that are used in the platform (custom files)
|
||||
- /hal - Hardware Access Layer for the nRF52840 chip (nRF5 SDK 12.2.0)
|
||||
- /segger_rtt - Library for the RTT communication (nRF5 SDK 12.2.0)
|
||||
- /softdevice - SoftDevice s140 headers (nRF5 SDK 13.0.0)
|
||||
- /cmsis - Core Peripheral Access Layer Headers files (nRF5 SDK 12.2.0)
|
||||
- /dependencies - Dependencies for drivers and libraries from nrf5 SDK (nRF5 SDK 14.0.0)
|
||||
- /device - MDK for the nRF52840 chip (nRF5 SDK 12.2.0)
|
||||
- /drivers - Drivers for the nRF52840 that are used in the platform (custom files)
|
||||
- /hal - Hardware Access Layer for the nRF52840 chip (nRF5 SDK 12.2.0)
|
||||
- /libraries - Libraries for the nRF52840 chip (nRF5 SDK 14.0.0)
|
||||
- /segger_rtt - Library for the RTT communication (nRF5 SDK 12.2.0)
|
||||
- /softdevice - SoftDevice s140 headers (nRF5 SDK 13.0.0)
|
||||
|
||||
[nrf5-sdk-12-2-0]: http://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v12.x.x/nRF5_SDK_12.2.0_f012efa.zip
|
||||
[nrf5-sdk-13-0-0]: http://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v13.x.x/nRF5_SDK_13.0.0_04a0bfd.zip
|
||||
[nrf5-sdk-14-0-0]: http://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v14.x.x/nRF5_SDK_14.0.0_3bcc1f7.zip
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
/**
|
||||
* 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__
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* 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__
|
||||
+1060
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 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 "app_util_platform.h"
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
/* Global nvic state instance, required by nrf_nvic.h */
|
||||
nrf_nvic_state_t nrf_nvic_state;
|
||||
#endif
|
||||
|
||||
static uint32_t m_in_critical_region = 0;
|
||||
|
||||
void app_util_disable_irq(void)
|
||||
{
|
||||
__disable_irq();
|
||||
m_in_critical_region++;
|
||||
}
|
||||
|
||||
void app_util_enable_irq(void)
|
||||
{
|
||||
m_in_critical_region--;
|
||||
if (m_in_critical_region == 0)
|
||||
{
|
||||
__enable_irq();
|
||||
}
|
||||
}
|
||||
|
||||
void app_util_critical_region_enter(uint8_t *p_nested)
|
||||
{
|
||||
#if __CORTEX_M == (0x04U)
|
||||
ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get())
|
||||
#endif
|
||||
|
||||
#if defined(SOFTDEVICE_PRESENT)
|
||||
/* return value can be safely ignored */
|
||||
(void) sd_nvic_critical_region_enter(p_nested);
|
||||
#else
|
||||
app_util_disable_irq();
|
||||
#endif
|
||||
}
|
||||
|
||||
void app_util_critical_region_exit(uint8_t nested)
|
||||
{
|
||||
#if __CORTEX_M == (0x04U)
|
||||
ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get())
|
||||
#endif
|
||||
|
||||
#if defined(SOFTDEVICE_PRESENT)
|
||||
/* return value can be safely ignored */
|
||||
(void) sd_nvic_critical_region_exit(nested);
|
||||
#else
|
||||
app_util_enable_irq();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
uint8_t privilege_level_get(void)
|
||||
{
|
||||
#if __CORTEX_M == (0x00U) || defined(_WIN32) || defined(__unix) || defined(__APPLE__)
|
||||
/* the Cortex-M0 has no concept of privilege */
|
||||
return APP_LEVEL_PRIVILEGED;
|
||||
#elif __CORTEX_M == (0x04U)
|
||||
uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ;
|
||||
if (0 == isr_vector_num)
|
||||
{
|
||||
/* Thread Mode, check nPRIV */
|
||||
int32_t control = __get_CONTROL();
|
||||
return control & CONTROL_nPRIV_Msk ? APP_LEVEL_UNPRIVILEGED : APP_LEVEL_PRIVILEGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handler Mode, always privileged */
|
||||
return APP_LEVEL_PRIVILEGED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
uint8_t current_int_priority_get(void)
|
||||
{
|
||||
uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ;
|
||||
if (isr_vector_num > 0)
|
||||
{
|
||||
int32_t irq_type = ((int32_t)isr_vector_num - EXTERNAL_INT_VECTOR_OFFSET);
|
||||
return (NVIC_GetPriority((IRQn_Type)irq_type) & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
return APP_IRQ_PRIORITY_THREAD;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 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_util_platform Utility Functions and Definitions (Platform)
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief Various types and definitions available to all applications when using SoftDevice.
|
||||
*/
|
||||
|
||||
#ifndef APP_UTIL_PLATFORM_H__
|
||||
#define APP_UTIL_PLATFORM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "compiler_abstraction.h"
|
||||
#include "nrf.h"
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
#include "nrf_soc.h"
|
||||
#include "nrf_nvic.h"
|
||||
#endif
|
||||
#include "nrf_assert.h"
|
||||
#include "app_error.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if __CORTEX_M == (0x00U)
|
||||
#define _PRIO_SD_HIGH 0
|
||||
#define _PRIO_APP_HIGH 1
|
||||
#define _PRIO_APP_MID 1
|
||||
#define _PRIO_SD_LOW 2
|
||||
#define _PRIO_APP_LOW 3
|
||||
#define _PRIO_APP_LOWEST 3
|
||||
#define _PRIO_THREAD 4
|
||||
#elif __CORTEX_M == (0x04U)
|
||||
#define _PRIO_SD_HIGH 0
|
||||
#define _PRIO_SD_MID 1
|
||||
#define _PRIO_APP_HIGH 2
|
||||
#define _PRIO_APP_MID 3
|
||||
#define _PRIO_SD_LOW 4
|
||||
#define _PRIO_SD_LOWEST 5
|
||||
#define _PRIO_APP_LOW 6
|
||||
#define _PRIO_APP_LOWEST 7
|
||||
#define _PRIO_THREAD 15
|
||||
#else
|
||||
#error "No platform defined"
|
||||
#endif
|
||||
|
||||
|
||||
//lint -save -e113 -e452
|
||||
/**@brief The interrupt priorities available to the application while the SoftDevice is active. */
|
||||
typedef enum
|
||||
{
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
APP_IRQ_PRIORITY_HIGHEST = _PRIO_SD_HIGH,
|
||||
#else
|
||||
APP_IRQ_PRIORITY_HIGHEST = _PRIO_APP_HIGH,
|
||||
#endif
|
||||
APP_IRQ_PRIORITY_HIGH = _PRIO_APP_HIGH,
|
||||
#ifndef SOFTDEVICE_PRESENT
|
||||
APP_IRQ_PRIORITY_MID = _PRIO_SD_LOW,
|
||||
#else
|
||||
APP_IRQ_PRIORITY_MID = _PRIO_APP_MID,
|
||||
#endif
|
||||
APP_IRQ_PRIORITY_LOW = _PRIO_APP_LOW,
|
||||
APP_IRQ_PRIORITY_LOWEST = _PRIO_APP_LOWEST,
|
||||
APP_IRQ_PRIORITY_THREAD = _PRIO_THREAD /**< "Interrupt level" when running in Thread Mode. */
|
||||
} app_irq_priority_t;
|
||||
//lint -restore
|
||||
|
||||
|
||||
/*@brief The privilege levels available to applications in Thread Mode */
|
||||
typedef enum
|
||||
{
|
||||
APP_LEVEL_UNPRIVILEGED,
|
||||
APP_LEVEL_PRIVILEGED
|
||||
} app_level_t;
|
||||
|
||||
/**@cond NO_DOXYGEN */
|
||||
#define EXTERNAL_INT_VECTOR_OFFSET 16
|
||||
/**@endcond */
|
||||
|
||||
/**@brief Macro for setting a breakpoint.
|
||||
*/
|
||||
#if defined(__GNUC__)
|
||||
#define NRF_BREAKPOINT __builtin_trap()
|
||||
#else
|
||||
#define NRF_BREAKPOINT __BKPT(0)
|
||||
#endif
|
||||
|
||||
/** @brief Macro for setting a breakpoint.
|
||||
*
|
||||
* If it is possible to detect debugger presence then it is set only in that case.
|
||||
*
|
||||
*/
|
||||
#if __CORTEX_M == 0x04
|
||||
#define NRF_BREAKPOINT_COND do { \
|
||||
/* C_DEBUGEN == 1 -> Debugger Connected */ \
|
||||
if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) \
|
||||
{ \
|
||||
/* Generate breakpoint if debugger is connected */ \
|
||||
NRF_BREAKPOINT; \
|
||||
} \
|
||||
}while (0)
|
||||
#else
|
||||
#define NRF_BREAKPOINT_COND NRF_BREAKPOINT
|
||||
#endif // __CORTEX_M == 0x04
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#define PACKED(TYPE) __packed TYPE
|
||||
#define PACKED_STRUCT PACKED(struct)
|
||||
#elif defined ( __GNUC__ )
|
||||
#define PACKED __attribute__((packed))
|
||||
#define PACKED_STRUCT struct PACKED
|
||||
#elif defined (__ICCARM__)
|
||||
#define PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
|
||||
void app_util_critical_region_enter (uint8_t *p_nested);
|
||||
void app_util_critical_region_exit (uint8_t nested);
|
||||
|
||||
/**@brief Macro for entering a critical region.
|
||||
*
|
||||
* @note Due to implementation details, there must exist one and only one call to
|
||||
* CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located
|
||||
* in the same scope.
|
||||
*/
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
#define CRITICAL_REGION_ENTER() \
|
||||
{ \
|
||||
uint8_t __CR_NESTED = 0; \
|
||||
app_util_critical_region_enter(&__CR_NESTED);
|
||||
#else
|
||||
#define CRITICAL_REGION_ENTER() app_util_critical_region_enter(NULL)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for leaving a critical region.
|
||||
*
|
||||
* @note Due to implementation details, there must exist one and only one call to
|
||||
* CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located
|
||||
* in the same scope.
|
||||
*/
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
#define CRITICAL_REGION_EXIT() \
|
||||
app_util_critical_region_exit(__CR_NESTED); \
|
||||
}
|
||||
#else
|
||||
#define CRITICAL_REGION_EXIT() app_util_critical_region_exit(0)
|
||||
#endif
|
||||
|
||||
/* Workaround for Keil 4 */
|
||||
#ifndef IPSR_ISR_Msk
|
||||
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**@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")
|
||||
#elif defined(__ICCARM__)
|
||||
#define ANON_UNIONS_ENABLE _Pragma("language=extended")
|
||||
#else
|
||||
#define ANON_UNIONS_ENABLE
|
||||
// No action will be taken.
|
||||
// For GCC anonymous unions are enabled by default.
|
||||
#endif
|
||||
|
||||
/**@brief Macro to disable anonymous unions from a certain point in the code.
|
||||
* @note Call only after first calling @ref ANON_UNIONS_ENABLE.
|
||||
*/
|
||||
#if defined(__CC_ARM)
|
||||
#define ANON_UNIONS_DISABLE _Pragma("pop")
|
||||
#elif defined(__ICCARM__)
|
||||
#define ANON_UNIONS_DISABLE
|
||||
// for IAR leave anonymous unions enabled
|
||||
#else
|
||||
#define ANON_UNIONS_DISABLE
|
||||
// No action will be taken.
|
||||
// For GCC anonymous unions are enabled by default.
|
||||
#endif
|
||||
|
||||
/**@brief Macro for adding pragma directive only for GCC.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
#define GCC_PRAGMA(v) _Pragma(v)
|
||||
#else
|
||||
#define GCC_PRAGMA(v)
|
||||
#endif
|
||||
|
||||
/* Workaround for Keil 4 */
|
||||
#ifndef CONTROL_nPRIV_Msk
|
||||
#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
|
||||
#endif
|
||||
|
||||
/**@brief Function for finding the current interrupt level.
|
||||
*
|
||||
* @return Current interrupt level.
|
||||
* @retval APP_IRQ_PRIORITY_HIGH We are running in Application High interrupt level.
|
||||
* @retval APP_IRQ_PRIORITY_LOW We are running in Application Low interrupt level.
|
||||
* @retval APP_IRQ_PRIORITY_THREAD We are running in Thread Mode.
|
||||
*/
|
||||
uint8_t current_int_priority_get(void);
|
||||
|
||||
|
||||
/**@brief Function for finding out the current privilege level.
|
||||
*
|
||||
* @return Current privilege level.
|
||||
* @retval APP_LEVEL_UNPRIVILEGED We are running in unprivileged level.
|
||||
* @retval APP_LEVEL_PRIVILEGED We are running in privileged level.
|
||||
*/
|
||||
uint8_t privilege_level_get(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // APP_UTIL_PLATFORM_H__
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,211 @@
|
||||
/**
|
||||
* Copyright (c) 2008 - 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
|
||||
* @brief Common defines and macros for firmware developed by Nordic Semiconductor.
|
||||
*/
|
||||
|
||||
#ifndef NORDIC_COMMON_H__
|
||||
#define NORDIC_COMMON_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Check if selected module is enabled
|
||||
*
|
||||
* This is save function for driver enable checking.
|
||||
* Correct from Lint point of view (not using default of undefined value).
|
||||
*
|
||||
* Usage:
|
||||
* @code
|
||||
#if NRF_MODULE_ENABLED(UART)
|
||||
...
|
||||
#endif
|
||||
* @endcode
|
||||
*
|
||||
* @param module The module name.
|
||||
*
|
||||
* @retval 1 The macro <module>_ENABLE is defined and is non-zero.
|
||||
* @retval 0 The macro <module>_ENABLE is not defined or it equals zero.
|
||||
*
|
||||
* @note
|
||||
* This macro intentionally does not implement second expansion level.
|
||||
* The name of the module to be checked has to be given directly as a parameter.
|
||||
* And given parameter would be connected with @c _ENABLED postfix directly
|
||||
* without evaluating its value.
|
||||
*/
|
||||
//lint -emacro(491,NRF_MODULE_ENABLED) // Suppers warning 491 "non-standard use of 'defined' preprocessor operator"
|
||||
#define NRF_MODULE_ENABLED(module) \
|
||||
((defined(module ## _ENABLED) && (module ## _ENABLED)) ? 1 : 0)
|
||||
|
||||
/** The upper 8 bits of a 32 bit value */
|
||||
//lint -emacro(572,MSB_32) // Suppress warning 572 "Excessive shift value"
|
||||
#define MSB_32(a) (((a) & 0xFF000000) >> 24)
|
||||
/** The lower 8 bits (of a 32 bit value) */
|
||||
#define LSB_32(a) ((a) & 0x000000FF)
|
||||
|
||||
/** The upper 8 bits of a 16 bit value */
|
||||
//lint -emacro(572,MSB_16) // Suppress warning 572 "Excessive shift value"
|
||||
#define MSB_16(a) (((a) & 0xFF00) >> 8)
|
||||
/** The lower 8 bits (of a 16 bit value) */
|
||||
#define LSB_16(a) ((a) & 0x00FF)
|
||||
|
||||
/** Leaves the minimum of the two 32-bit arguments */
|
||||
/*lint -emacro(506, MIN) */ /* Suppress "Constant value Boolean */
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
/** Leaves the maximum of the two 32-bit arguments */
|
||||
/*lint -emacro(506, MAX) */ /* Suppress "Constant value Boolean */
|
||||
#define MAX(a, b) ((a) < (b) ? (b) : (a))
|
||||
|
||||
/**@brief Concatenates two parameters.
|
||||
*
|
||||
* It realizes two level expansion to make it sure that all the parameters
|
||||
* are actually expanded before gluing them together.
|
||||
*
|
||||
* @param p1 First parameter to concatenating
|
||||
* @param p2 Second parameter to concatenating
|
||||
*
|
||||
* @return Two parameters glued together.
|
||||
* They have to create correct C mnemonic in other case
|
||||
* preprocessor error would be generated.
|
||||
*
|
||||
* @sa CONCAT_3
|
||||
*/
|
||||
#define CONCAT_2(p1, p2) CONCAT_2_(p1, p2)
|
||||
/** Auxiliary macro used by @ref CONCAT_2 */
|
||||
#define CONCAT_2_(p1, p2) p1##p2
|
||||
|
||||
/**@brief Concatenates three parameters.
|
||||
*
|
||||
* It realizes two level expansion to make it sure that all the parameters
|
||||
* are actually expanded before gluing them together.
|
||||
*
|
||||
* @param p1 First parameter to concatenating
|
||||
* @param p2 Second parameter to concatenating
|
||||
* @param p3 Third parameter to concatenating
|
||||
*
|
||||
* @return Three parameters glued together.
|
||||
* They have to create correct C mnemonic in other case
|
||||
* preprocessor error would be generated.
|
||||
*
|
||||
* @sa CONCAT_2
|
||||
*/
|
||||
#define CONCAT_3(p1, p2, p3) CONCAT_3_(p1, p2, p3)
|
||||
/** Auxiliary macro used by @ref CONCAT_3 */
|
||||
#define CONCAT_3_(p1, p2, p3) p1##p2##p3
|
||||
|
||||
#define STRINGIFY_(val) #val
|
||||
/** Converts a macro argument into a character constant.
|
||||
*/
|
||||
#define STRINGIFY(val) STRINGIFY_(val)
|
||||
|
||||
/** Counts number of elements inside the array
|
||||
*/
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
/**@brief Set a bit in the uint32 word.
|
||||
*
|
||||
* @param[in] W Word whose bit is being set.
|
||||
* @param[in] B Bit number in the word to be set.
|
||||
*/
|
||||
#define SET_BIT(W, B) ((W) |= (uint32_t)(1U << (B)))
|
||||
|
||||
|
||||
/**@brief Clears a bit in the uint32 word.
|
||||
*
|
||||
* @param[in] W Word whose bit is to be cleared.
|
||||
* @param[in] B Bit number in the word to be cleared.
|
||||
*/
|
||||
#define CLR_BIT(W, B) ((W) &= (~(uint32_t)(1U << (B))))
|
||||
|
||||
|
||||
/**@brief Checks if a bit is set.
|
||||
*
|
||||
* @param[in] W Word whose bit is to be checked.
|
||||
* @param[in] B Bit number in the word to be checked.
|
||||
*
|
||||
* @retval 1 if bit is set.
|
||||
* @retval 0 if bit is not set.
|
||||
*/
|
||||
#define IS_SET(W, B) (((W) >> (B)) & 1)
|
||||
|
||||
#define BIT_0 0x01 /**< The value of bit 0 */
|
||||
#define BIT_1 0x02 /**< The value of bit 1 */
|
||||
#define BIT_2 0x04 /**< The value of bit 2 */
|
||||
#define BIT_3 0x08 /**< The value of bit 3 */
|
||||
#define BIT_4 0x10 /**< The value of bit 4 */
|
||||
#define BIT_5 0x20 /**< The value of bit 5 */
|
||||
#define BIT_6 0x40 /**< The value of bit 6 */
|
||||
#define BIT_7 0x80 /**< The value of bit 7 */
|
||||
#define BIT_8 0x0100 /**< The value of bit 8 */
|
||||
#define BIT_9 0x0200 /**< The value of bit 9 */
|
||||
#define BIT_10 0x0400 /**< The value of bit 10 */
|
||||
#define BIT_11 0x0800 /**< The value of bit 11 */
|
||||
#define BIT_12 0x1000 /**< The value of bit 12 */
|
||||
#define BIT_13 0x2000 /**< The value of bit 13 */
|
||||
#define BIT_14 0x4000 /**< The value of bit 14 */
|
||||
#define BIT_15 0x8000 /**< The value of bit 15 */
|
||||
#define BIT_16 0x00010000 /**< The value of bit 16 */
|
||||
#define BIT_17 0x00020000 /**< The value of bit 17 */
|
||||
#define BIT_18 0x00040000 /**< The value of bit 18 */
|
||||
#define BIT_19 0x00080000 /**< The value of bit 19 */
|
||||
#define BIT_20 0x00100000 /**< The value of bit 20 */
|
||||
#define BIT_21 0x00200000 /**< The value of bit 21 */
|
||||
#define BIT_22 0x00400000 /**< The value of bit 22 */
|
||||
#define BIT_23 0x00800000 /**< The value of bit 23 */
|
||||
#define BIT_24 0x01000000 /**< The value of bit 24 */
|
||||
#define BIT_25 0x02000000 /**< The value of bit 25 */
|
||||
#define BIT_26 0x04000000 /**< The value of bit 26 */
|
||||
#define BIT_27 0x08000000 /**< The value of bit 27 */
|
||||
#define BIT_28 0x10000000 /**< The value of bit 28 */
|
||||
#define BIT_29 0x20000000 /**< The value of bit 29 */
|
||||
#define BIT_30 0x40000000 /**< The value of bit 30 */
|
||||
#define BIT_31 0x80000000 /**< The value of bit 31 */
|
||||
|
||||
#define UNUSED_VARIABLE(X) ((void)(X))
|
||||
#define UNUSED_PARAMETER(X) UNUSED_VARIABLE(X)
|
||||
#define UNUSED_RETURN_VALUE(X) UNUSED_VARIABLE(X)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NORDIC_COMMON_H__
|
||||
@@ -0,0 +1,495 @@
|
||||
/**
|
||||
* 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__ */
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,234 @@
|
||||
/**
|
||||
* 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__ */
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,268 @@
|
||||
/**
|
||||
* 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
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright (c) 2012 - 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.
|
||||
*
|
||||
*/
|
||||
/* Header guard */
|
||||
#ifndef NRF_ERROR_H__
|
||||
#define NRF_ERROR_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
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
|
||||
#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base
|
||||
#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base
|
||||
#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base
|
||||
/** @} */
|
||||
|
||||
#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command
|
||||
#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing
|
||||
#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled
|
||||
#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error
|
||||
#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation
|
||||
#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found
|
||||
#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported
|
||||
#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter
|
||||
#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state
|
||||
#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length
|
||||
#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags
|
||||
#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data
|
||||
#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Data size exceeds limit
|
||||
#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out
|
||||
#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer
|
||||
#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation
|
||||
#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
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
@@ -0,0 +1,234 @@
|
||||
/**
|
||||
* 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_log Logger module
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief The nrf_log module interface.
|
||||
*/
|
||||
|
||||
#ifndef NRF_LOG_H_
|
||||
#define NRF_LOG_H_
|
||||
|
||||
#include "sdk_common.h"
|
||||
#include "nrf_section.h"
|
||||
#if NRF_MODULE_ENABLED(NRF_LOG)
|
||||
#include "nrf_strerror.h"
|
||||
#define NRF_LOG_ERROR_STRING_GET(code) nrf_strerror_get(code)
|
||||
#else
|
||||
#define NRF_LOG_ERROR_STRING_GET(code) ""
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @brief Severity level for the module.
|
||||
*
|
||||
* The severity level can be defined in a module to override the default.
|
||||
*/
|
||||
#ifndef NRF_LOG_LEVEL
|
||||
#define NRF_LOG_LEVEL NRF_LOG_DEFAULT_LEVEL
|
||||
#endif
|
||||
|
||||
|
||||
#include "nrf_log_internal.h"
|
||||
|
||||
/** @def NRF_LOG_ERROR
|
||||
* @brief Macro for logging error messages. It takes a printf-like, formatted
|
||||
* string with up to seven arguments.
|
||||
*
|
||||
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
|
||||
*/
|
||||
|
||||
/** @def NRF_LOG_WARNING
|
||||
* @brief Macro for logging error messages. It takes a printf-like, formatted
|
||||
* string with up to seven arguments.
|
||||
*
|
||||
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs.
|
||||
*/
|
||||
|
||||
/** @def NRF_LOG_INFO
|
||||
* @brief Macro for logging error messages. It takes a printf-like, formatted
|
||||
* string with up to seven arguments.
|
||||
*
|
||||
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs.
|
||||
*/
|
||||
|
||||
/** @def NRF_LOG_DEBUG
|
||||
* @brief Macro for logging error messages. It takes a printf-like, formatted
|
||||
* string with up to seven arguments.
|
||||
*
|
||||
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs.
|
||||
*/
|
||||
|
||||
#define NRF_LOG_ERROR(...) NRF_LOG_INTERNAL_ERROR(__VA_ARGS__)
|
||||
#define NRF_LOG_WARNING(...) NRF_LOG_INTERNAL_WARNING( __VA_ARGS__)
|
||||
#define NRF_LOG_INFO(...) NRF_LOG_INTERNAL_INFO( __VA_ARGS__)
|
||||
#define NRF_LOG_DEBUG(...) NRF_LOG_INTERNAL_DEBUG( __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief A 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.
|
||||
*
|
||||
* @param p_data Pointer to data.
|
||||
* @param len Data length in bytes.
|
||||
*/
|
||||
/** @def NRF_LOG_HEXDUMP_WARNING
|
||||
* @brief Macro for logging raw bytes.
|
||||
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs.
|
||||
*
|
||||
* @param p_data Pointer to data.
|
||||
* @param len Data length in bytes.
|
||||
*/
|
||||
/** @def NRF_LOG_HEXDUMP_INFO
|
||||
* @brief Macro for logging raw bytes.
|
||||
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs.
|
||||
*
|
||||
* @param p_data Pointer to data.
|
||||
* @param len Data length in bytes.
|
||||
*/
|
||||
/** @def NRF_LOG_HEXDUMP_DEBUG
|
||||
* @brief Macro for logging raw bytes.
|
||||
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs.
|
||||
*
|
||||
* @param p_data Pointer to data.
|
||||
* @param len Data length in bytes.
|
||||
*/
|
||||
#define NRF_LOG_HEXDUMP_ERROR(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len)
|
||||
#define NRF_LOG_HEXDUMP_WARNING(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len)
|
||||
#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)
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* @param _str String.
|
||||
*/
|
||||
#define NRF_LOG_PUSH(_str) NRF_LOG_INTERNAL_LOG_PUSH(_str)
|
||||
|
||||
/**
|
||||
* @brief Function for copying a string to the internal logger buffer if logs are deferred.
|
||||
*
|
||||
* Use this function to store a string that is volatile (for example allocated
|
||||
* on stack) or that may change before the deferred logs are processed. Such string is copied
|
||||
* into the internal logger buffer and is persistent until the log is processed.
|
||||
*
|
||||
* @note If the logs are not deferred, then this function returns the input parameter.
|
||||
*
|
||||
* @param p_str Pointer to the user string.
|
||||
*
|
||||
* @return Address to the location where the string is stored in the internal logger buffer.
|
||||
*/
|
||||
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
|
||||
* @ref NRF_LOG_FLOAT macro.
|
||||
* Example: NRF_LOG_INFO("My float number" NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(f)))
|
||||
*/
|
||||
#define NRF_LOG_FLOAT_MARKER "%s%d.%02d"
|
||||
|
||||
/**
|
||||
* @brief Macro for dissecting a float number into two numbers (integer and residuum).
|
||||
*/
|
||||
#define NRF_LOG_FLOAT(val) (uint32_t)(((val) < 0 && (val) > -1.0) ? "-" : ""), \
|
||||
(int32_t)(val), \
|
||||
(int32_t)((((val) > 0) ? (val) - (int32_t)(val) \
|
||||
: (int32_t)(val) - (val))*100)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @def NRF_LOG_MODULE_REGISTER
|
||||
* @brief Macro for registering an independent module.
|
||||
*/
|
||||
#if NRF_LOG_ENABLED
|
||||
|
||||
#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
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF_LOG_H_
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,534 @@
|
||||
/**
|
||||
* 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_LOG_INTERNAL_H__
|
||||
#define NRF_LOG_INTERNAL_H__
|
||||
#include "sdk_common.h"
|
||||
#include "nrf.h"
|
||||
#include "nrf_error.h"
|
||||
#include "app_util.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef NRF_LOG_ERROR_COLOR
|
||||
#define NRF_LOG_ERROR_COLOR NRF_LOG_COLOR_DEFAULT
|
||||
#endif
|
||||
|
||||
#ifndef NRF_LOG_WARNING_COLOR
|
||||
#define NRF_LOG_WARNING_COLOR NRF_LOG_COLOR_DEFAULT
|
||||
#endif
|
||||
|
||||
#ifndef NRF_LOG_INFO_COLOR
|
||||
#define NRF_LOG_INFO_COLOR NRF_LOG_COLOR_DEFAULT
|
||||
#endif
|
||||
|
||||
#ifndef NRF_LOG_DEBUG_COLOR
|
||||
#define NRF_LOG_DEBUG_COLOR NRF_LOG_COLOR_DEFAULT
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NRF_LOG_COLOR_DEFAULT
|
||||
#define NRF_LOG_COLOR_DEFAULT 0
|
||||
#endif
|
||||
|
||||
#ifndef NRF_LOG_DEFAULT_LEVEL
|
||||
#define NRF_LOG_DEFAULT_LEVEL 0
|
||||
#endif
|
||||
|
||||
#ifndef NRF_LOG_USES_COLORS
|
||||
#define NRF_LOG_USES_COLORS 0
|
||||
#endif
|
||||
|
||||
#ifndef NRF_LOG_USES_TIMESTAMP
|
||||
#define NRF_LOG_USES_TIMESTAMP 0
|
||||
#endif
|
||||
|
||||
#ifndef NRF_LOG_FILTERS_ENABLED
|
||||
#define NRF_LOG_FILTERS_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifndef NRF_LOG_MODULE_NAME
|
||||
#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
|
||||
#else
|
||||
#undef NRF_LOG_FILTER
|
||||
#define NRF_LOG_FILTER NRF_LOG_LEVEL_DEBUG
|
||||
#endif
|
||||
|
||||
#if NRF_LOG_ENABLED
|
||||
#define NRF_LOG_MODULE_ID NRF_LOG_MODULE_DATA_DYNAMIC.module_id
|
||||
#else
|
||||
#define NRF_LOG_MODULE_ID 0
|
||||
#endif
|
||||
|
||||
|
||||
#define LOG_INTERNAL_X(N, ...) CONCAT_2(LOG_INTERNAL_, N) (__VA_ARGS__)
|
||||
#define LOG_INTERNAL(type, ...) LOG_INTERNAL_X(NUM_VA_ARGS_LESS_1( \
|
||||
__VA_ARGS__), type, __VA_ARGS__)
|
||||
#if NRF_LOG_ENABLED
|
||||
#define NRF_LOG_INTERNAL_LOG_PUSH(_str) nrf_log_push(_str)
|
||||
#define LOG_INTERNAL_0(type, str) \
|
||||
nrf_log_frontend_std_0(type, str)
|
||||
#define LOG_INTERNAL_1(type, str, arg0) \
|
||||
/*lint -save -e571*/nrf_log_frontend_std_1(type, str, (uint32_t)(arg0))/*lint -restore*/
|
||||
#define LOG_INTERNAL_2(type, str, arg0, arg1) \
|
||||
/*lint -save -e571*/nrf_log_frontend_std_2(type, str, (uint32_t)(arg0), \
|
||||
(uint32_t)(arg1))/*lint -restore*/
|
||||
#define LOG_INTERNAL_3(type, str, arg0, arg1, arg2) \
|
||||
/*lint -save -e571*/nrf_log_frontend_std_3(type, str, (uint32_t)(arg0), \
|
||||
(uint32_t)(arg1), (uint32_t)(arg2))/*lint -restore*/
|
||||
#define LOG_INTERNAL_4(type, str, arg0, arg1, arg2, arg3) \
|
||||
/*lint -save -e571*/nrf_log_frontend_std_4(type, str, (uint32_t)(arg0), \
|
||||
(uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3))/*lint -restore*/
|
||||
#define LOG_INTERNAL_5(type, str, arg0, arg1, arg2, arg3, arg4) \
|
||||
/*lint -save -e571*/nrf_log_frontend_std_5(type, str, (uint32_t)(arg0), \
|
||||
(uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3), (uint32_t)(arg4))/*lint -restore*/
|
||||
#define LOG_INTERNAL_6(type, str, arg0, arg1, arg2, arg3, arg4, arg5) \
|
||||
/*lint -save -e571*/nrf_log_frontend_std_6(type, str, (uint32_t)(arg0), \
|
||||
(uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3), (uint32_t)(arg4), (uint32_t)(arg5))/*lint -restore*/
|
||||
|
||||
|
||||
#else //NRF_LOG_ENABLED
|
||||
#define NRF_LOG_INTERNAL_LOG_PUSH(_str) (void)(_str)
|
||||
#define LOG_INTERNAL_0(_type, _str) \
|
||||
(void)(_type); (void)(_str)
|
||||
#define LOG_INTERNAL_1(_type, _str, _arg0) \
|
||||
(void)(_type); (void)(_str); (void)(_arg0)
|
||||
#define LOG_INTERNAL_2(_type, _str, _arg0, _arg1) \
|
||||
(void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1)
|
||||
#define LOG_INTERNAL_3(_type, _str, _arg0, _arg1, _arg2) \
|
||||
(void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2)
|
||||
#define LOG_INTERNAL_4(_type, _str, _arg0, _arg1, _arg2, _arg3) \
|
||||
(void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3)
|
||||
#define LOG_INTERNAL_5(_type, _str, _arg0, _arg1, _arg2, _arg3, _arg4) \
|
||||
(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)
|
||||
|
||||
#define LOG_SEVERITY_MOD_ID(severity) ((severity) | NRF_LOG_MODULE_ID << NRF_LOG_MODULE_ID_POS)
|
||||
|
||||
#if NRF_LOG_ENABLED
|
||||
#define LOG_HEXDUMP(_severity, _p_data, _length) \
|
||||
nrf_log_frontend_hexdump((_severity), (_p_data), (_length))
|
||||
#else
|
||||
#define LOG_HEXDUMP(_severity, _p_data, _length) \
|
||||
(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_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_HEXDUMP_WARNING(p_data, len) \
|
||||
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_HEXDUMP(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_WARNING, \
|
||||
(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)) \
|
||||
{ \
|
||||
if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_INFO) \
|
||||
{ \
|
||||
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), \
|
||||
(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_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)); \
|
||||
} \
|
||||
}
|
||||
|
||||
#if NRF_MODULE_ENABLED(NRF_LOG)
|
||||
#define NRF_LOG_INTERNAL_GETCHAR() nrf_log_getchar()
|
||||
#else
|
||||
#define NRF_LOG_INTERNAL_GETCHAR() (void)
|
||||
#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;
|
||||
|
||||
extern nrf_log_module_dynamic_data_t NRF_LOG_MODULE_DATA_DYNAMIC;
|
||||
|
||||
/**
|
||||
* Set of macros for encoding and decoding header for log entries.
|
||||
* There are 3 types of entries:
|
||||
* 1. Standard entry (STD)
|
||||
* An entry consists of header, pointer to string and values. Header contains
|
||||
* severity leveland determines number of arguments and thus size of the entry.
|
||||
* Since flash address space starts from 0x00000000 and is limited to kB rather
|
||||
* than MB 22 bits are used to store the address (4MB). It is used that way to
|
||||
* save one RAM memory.
|
||||
*
|
||||
* --------------------------------
|
||||
* |TYPE|SEVERITY|NARGS| P_STR |
|
||||
* |------------------------------|
|
||||
* | Module_ID (optional) |
|
||||
* |------------------------------|
|
||||
* | TIMESTAMP (optional) |
|
||||
* |------------------------------|
|
||||
* | ARG0 |
|
||||
* |------------------------------|
|
||||
* | .... |
|
||||
* |------------------------------|
|
||||
* | ARG(nargs-1) |
|
||||
* --------------------------------
|
||||
*
|
||||
* 2. Hexdump entry (HEXDUMP) is used for dumping raw data. An entry consists of
|
||||
* header, optional timestamp, pointer to string and data. A header contains
|
||||
* length (10bit) and offset which is updated after backend processes part of
|
||||
* data.
|
||||
*
|
||||
* --------------------------------
|
||||
* |TYPE|SEVERITY|NARGS|OFFSET|LEN|
|
||||
* |------------------------------|
|
||||
* | Module_ID (optional) |
|
||||
* |------------------------------|
|
||||
* | TIMESTAMP (optional) |
|
||||
* |------------------------------|
|
||||
* | P_STR |
|
||||
* |------------------------------|
|
||||
* | data |
|
||||
* |------------------------------|
|
||||
* | data | dummy |
|
||||
* --------------------------------
|
||||
*
|
||||
* 3. Pushed string. If string is pushed into the logger internal buffer it is
|
||||
* stored as PUSHED entry. It consists of header, unused data (optional) and
|
||||
* string. Unused data is present if string does not not fit into a buffer
|
||||
* without wrapping (and string cannot be wrapped). In that case header
|
||||
* contains information about offset.
|
||||
*
|
||||
* --------------------------------
|
||||
* |TYPE| OFFSET | LEN |
|
||||
* |------------------------------|
|
||||
* | OFFSET |
|
||||
* |------------------------------|
|
||||
* end| OFFSET |
|
||||
* 0|------------------------------|
|
||||
* | STRING |
|
||||
* |------------------------------|
|
||||
* | STRING | dummy |
|
||||
* --------------------------------
|
||||
*/
|
||||
|
||||
#define STD_ADDR_MASK ((uint32_t)(1U << 22) - 1U)
|
||||
#define HEADER_TYPE_STD 1U
|
||||
#define HEADER_TYPE_HEXDUMP 2U
|
||||
#define HEADER_TYPE_PUSHED 0U
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t type : 2;
|
||||
uint32_t raw : 1;
|
||||
uint32_t data : 29;
|
||||
} nrf_log_generic_header_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t type : 2;
|
||||
uint32_t raw : 1;
|
||||
uint32_t severity : 3;
|
||||
uint32_t nargs : 4;
|
||||
uint32_t addr : 22;
|
||||
} nrf_log_std_header_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t type : 2;
|
||||
uint32_t raw : 1;
|
||||
uint32_t severity : 3;
|
||||
uint32_t offset : 10;
|
||||
uint32_t reserved : 6;
|
||||
uint32_t len : 10;
|
||||
} nrf_log_hexdump_header_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t type : 2;
|
||||
uint32_t reserved0 : 4;
|
||||
uint32_t offset : 10;
|
||||
uint32_t reserved1 : 6;
|
||||
uint32_t len : 10;
|
||||
} nrf_log_pushed_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;
|
||||
uint32_t module_id;
|
||||
uint32_t timestamp;
|
||||
} nrf_log_header_t;
|
||||
|
||||
#define HEADER_SIZE (sizeof(nrf_log_header_t)/sizeof(uint32_t) - \
|
||||
(NRF_LOG_USES_TIMESTAMP ? 0 : 1))
|
||||
|
||||
#define PUSHED_HEADER_SIZE (sizeof(nrf_log_pushed_header_t)/sizeof(uint32_t))
|
||||
|
||||
//Implementation assumes that pushed header has one word.
|
||||
STATIC_ASSERT(PUSHED_HEADER_SIZE == 1);
|
||||
/**
|
||||
* @brief A function for logging raw string.
|
||||
*
|
||||
* @param severity_mid Severity.
|
||||
* @param p_str A pointer to a string.
|
||||
*/
|
||||
void nrf_log_frontend_std_0(uint32_t severity_mid, char const * const p_str);
|
||||
|
||||
/**
|
||||
* @brief A function for logging a formatted string with one argument.
|
||||
*
|
||||
* @param severity_mid Severity.
|
||||
* @param p_str A pointer to a formatted string.
|
||||
* @param val0 An argument.
|
||||
*/
|
||||
void nrf_log_frontend_std_1(uint32_t severity_mid,
|
||||
char const * const p_str,
|
||||
uint32_t val0);
|
||||
|
||||
/**
|
||||
* @brief A function for logging a formatted string with 2 arguments.
|
||||
*
|
||||
* @param severity_mid Severity.
|
||||
* @param p_str A pointer to a formatted string.
|
||||
* @param val0, val1 Arguments for formatting string.
|
||||
*/
|
||||
void nrf_log_frontend_std_2(uint32_t severity_mid,
|
||||
char const * const p_str,
|
||||
uint32_t val0,
|
||||
uint32_t val1);
|
||||
|
||||
/**
|
||||
* @brief A function for logging a formatted string with 3 arguments.
|
||||
*
|
||||
* @param severity_mid Severity.
|
||||
* @param p_str A pointer to a formatted string.
|
||||
* @param val0, val1, val2 Arguments for formatting string.
|
||||
*/
|
||||
void nrf_log_frontend_std_3(uint32_t severity_mid,
|
||||
char const * const p_str,
|
||||
uint32_t val0,
|
||||
uint32_t val1,
|
||||
uint32_t val2);
|
||||
|
||||
/**
|
||||
* @brief A function for logging a formatted string with 4 arguments.
|
||||
*
|
||||
* @param severity_mid Severity.
|
||||
* @param p_str A pointer to a formatted string.
|
||||
* @param val0, val1, val2, val3 Arguments for formatting string.
|
||||
*/
|
||||
void nrf_log_frontend_std_4(uint32_t severity_mid,
|
||||
char const * const p_str,
|
||||
uint32_t val0,
|
||||
uint32_t val1,
|
||||
uint32_t val2,
|
||||
uint32_t val3);
|
||||
|
||||
/**
|
||||
* @brief A function for logging a formatted string with 5 arguments.
|
||||
*
|
||||
* @param severity_mid Severity.
|
||||
* @param p_str A pointer to a formatted string.
|
||||
* @param val0, val1, val2, val3, val4 Arguments for formatting string.
|
||||
*/
|
||||
void nrf_log_frontend_std_5(uint32_t severity_mid,
|
||||
char const * const p_str,
|
||||
uint32_t val0,
|
||||
uint32_t val1,
|
||||
uint32_t val2,
|
||||
uint32_t val3,
|
||||
uint32_t val4);
|
||||
|
||||
/**
|
||||
* @brief A function for logging a formatted string with 6 arguments.
|
||||
*
|
||||
* @param severity_mid Severity.
|
||||
* @param p_str A pointer to a formatted string.
|
||||
* @param val0, val1, val2, val3, val4, val5 Arguments for formatting string.
|
||||
*/
|
||||
void nrf_log_frontend_std_6(uint32_t severity_mid,
|
||||
char const * const p_str,
|
||||
uint32_t val0,
|
||||
uint32_t val1,
|
||||
uint32_t val2,
|
||||
uint32_t val3,
|
||||
uint32_t val4,
|
||||
uint32_t val5);
|
||||
|
||||
/**
|
||||
* @brief A function for logging raw data.
|
||||
*
|
||||
* @param severity_mid Severity.
|
||||
* @param p_str A pointer to a string which is prefixing the data.
|
||||
* @param p_data A pointer to data to be dumped.
|
||||
* @param length Length of data (in bytes).
|
||||
*
|
||||
*/
|
||||
void nrf_log_frontend_hexdump(uint32_t severity_mid,
|
||||
const void * const p_data,
|
||||
uint16_t length);
|
||||
|
||||
/**
|
||||
* @brief A function for reading a byte from log backend.
|
||||
*
|
||||
* @return Byte.
|
||||
*/
|
||||
uint8_t nrf_log_getchar(void);
|
||||
#endif // NRF_LOG_INTERNAL_H__
|
||||
@@ -0,0 +1,191 @@
|
||||
/**
|
||||
* 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_SECTION_H__
|
||||
#define NRF_SECTION_H__
|
||||
|
||||
#include "nordic_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup section_vars Section variables
|
||||
* @ingroup app_common
|
||||
* @{
|
||||
*
|
||||
* @brief Section variables.
|
||||
*/
|
||||
|
||||
//lint -save -e27 -esym(526,*)
|
||||
|
||||
#if defined(__ICCARM__)
|
||||
// Enable IAR language extensions
|
||||
#pragma language=extended
|
||||
#endif
|
||||
|
||||
/**@brief Macro for obtaining the address of the beginning of a section.
|
||||
*
|
||||
* param[in] section_name Name of the section.
|
||||
* @hideinitializer
|
||||
*/
|
||||
#if defined(__CC_ARM)
|
||||
#define NRF_SECTION_START_ADDR(section_name) &CONCAT_2(section_name, $$Base)
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
#define NRF_SECTION_START_ADDR(section_name) &CONCAT_2(__start_, section_name)
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
#define NRF_SECTION_START_ADDR(section_name) __section_begin(STRINGIFY(section_name))
|
||||
#endif
|
||||
|
||||
|
||||
/**@brief Macro for obtaining the address of the end of a section.
|
||||
*
|
||||
* @param[in] section_name Name of the section.
|
||||
* @hideinitializer
|
||||
*/
|
||||
#if defined(__CC_ARM)
|
||||
#define NRF_SECTION_END_ADDR(section_name) &CONCAT_2(section_name, $$Limit)
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
#define NRF_SECTION_END_ADDR(section_name) &CONCAT_2(__stop_, section_name)
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
#define NRF_SECTION_END_ADDR(section_name) __section_end(STRINGIFY(section_name))
|
||||
#endif
|
||||
|
||||
|
||||
/**@brief Macro for retrieving the length of a given section, in bytes.
|
||||
*
|
||||
* @param[in] section_name Name of the section.
|
||||
* @hideinitializer
|
||||
*/
|
||||
#define NRF_SECTION_LENGTH(section_name) \
|
||||
((size_t)NRF_SECTION_END_ADDR(section_name) - \
|
||||
(size_t)NRF_SECTION_START_ADDR(section_name))
|
||||
|
||||
|
||||
/**@brief Macro for creating a section.
|
||||
*
|
||||
* @param[in] section_name Name of the section.
|
||||
* @param[in] data_type Data type of the variables to be registered in the section.
|
||||
*
|
||||
* @warning Data type must be word aligned to prevent padding.
|
||||
* @hideinitializer
|
||||
*/
|
||||
#if defined(__CC_ARM)
|
||||
#define NRF_SECTION_DEF(section_name, data_type) \
|
||||
extern data_type * CONCAT_2(section_name, $$Base); \
|
||||
extern void * CONCAT_2(section_name, $$Limit)
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
#define NRF_SECTION_DEF(section_name, data_type) \
|
||||
extern data_type * CONCAT_2(__start_, section_name); \
|
||||
extern void * CONCAT_2(__stop_, section_name)
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
#define NRF_SECTION_DEF(section_name, data_type) \
|
||||
_Pragma(STRINGIFY(section = STRINGIFY(section_name)));
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**@brief Macro for declaring a variable and registering it in a section.
|
||||
*
|
||||
* @details Declares a variable and registers it in a named section. This macro ensures that the
|
||||
* variable is not stripped away when using optimizations.
|
||||
*
|
||||
* @note The order in which variables are placed in a section is dependent on the order in
|
||||
* which the linker script encounters the variables during linking.
|
||||
*
|
||||
* @param[in] section_name Name of the section.
|
||||
* @param[in] section_var Variable to register in the given section.
|
||||
* @hideinitializer
|
||||
*/
|
||||
#if defined(__CC_ARM)
|
||||
#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
|
||||
section_var __attribute__ ((section(STRINGIFY(section_name)))) __attribute__((used))
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
|
||||
section_var __attribute__ ((section("." STRINGIFY(section_name)))) __attribute__((used))
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
|
||||
__root section_var @ STRINGIFY(section_name)
|
||||
#endif
|
||||
|
||||
|
||||
/**@brief Macro for retrieving a variable from a section.
|
||||
*
|
||||
* @warning The stored symbol can only be resolved using this macro if the
|
||||
* type of the data is word aligned. The operation of acquiring
|
||||
* the stored symbol relies on the size of the stored type. No
|
||||
* padding can exist in the named section in between individual
|
||||
* stored items or this macro will fail.
|
||||
*
|
||||
* @param[in] section_name Name of the section.
|
||||
* @param[in] data_type Data type of the variable.
|
||||
* @param[in] i Index of the variable in section.
|
||||
* @hideinitializer
|
||||
*/
|
||||
#define NRF_SECTION_ITEM_GET(section_name, data_type, i) \
|
||||
((data_type*)NRF_SECTION_START_ADDR(section_name) + (i))
|
||||
|
||||
|
||||
/**@brief Macro for getting the number of variables in a section.
|
||||
*
|
||||
* @param[in] section_name Name of the section.
|
||||
* @param[in] data_type Data type of the variables in the section.
|
||||
* @hideinitializer
|
||||
*/
|
||||
#define NRF_SECTION_ITEM_COUNT(section_name, data_type) \
|
||||
NRF_SECTION_LENGTH(section_name) / sizeof(data_type)
|
||||
|
||||
/** @} */
|
||||
|
||||
//lint -restore
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF_SECTION_H__
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
/** @cond */
|
||||
/**@file
|
||||
*
|
||||
* @ingroup experimental_api
|
||||
* @defgroup sdk_common SDK Common Header
|
||||
* @brief All common headers needed for SDK examples will be included here so that application
|
||||
* developer does not have to include headers on him/herself.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef SDK_COMMON_H__
|
||||
#define SDK_COMMON_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "sdk_config.h"
|
||||
#include "nordic_common.h"
|
||||
#include "compiler_abstraction.h"
|
||||
#include "sdk_os.h"
|
||||
#include "sdk_errors.h"
|
||||
#include "app_util.h"
|
||||
#include "sdk_macros.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** @} */
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDK_COMMON_H__
|
||||
|
||||
@@ -0,0 +1,254 @@
|
||||
#ifndef SDK_CONFIG_H
|
||||
#define SDK_CONFIG_H
|
||||
|
||||
#include <openthread/config.h>
|
||||
#undef PACKAGE
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
//==========================================================
|
||||
// <e> APP_USBD_ENABLED - app_usbd - USB Device library
|
||||
//==========================================================
|
||||
#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
|
||||
#ifndef APP_USBD_ENABLED
|
||||
#define APP_USBD_ENABLED 1
|
||||
#endif
|
||||
#else // USB_CDC_AS_SERIAL_TRANSPORT == 1
|
||||
#ifndef APP_USBD_ENABLED
|
||||
#define APP_USBD_ENABLED 0
|
||||
#endif
|
||||
#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
|
||||
|
||||
// <s> APP_USBD_VID - Vendor ID
|
||||
|
||||
// <i> Vendor ID ordered from USB IF: http://www.usb.org/developers/vendor/
|
||||
#ifndef APP_USBD_VID
|
||||
#define APP_USBD_VID 0x1915
|
||||
#endif
|
||||
|
||||
// <s> APP_USBD_PID - Product ID
|
||||
|
||||
// <i> Selected Product ID
|
||||
#ifndef APP_USBD_PID
|
||||
#define APP_USBD_PID 0xCAFE
|
||||
#endif
|
||||
|
||||
// <o> APP_USBD_DEVICE_VER_MAJOR - Device version, major part <0-99>
|
||||
|
||||
|
||||
// <i> Device version, will be converted automatically to BCD notation. Use just decimal values.
|
||||
|
||||
#ifndef APP_USBD_DEVICE_VER_MAJOR
|
||||
#define APP_USBD_DEVICE_VER_MAJOR 1
|
||||
#endif
|
||||
|
||||
// <o> APP_USBD_DEVICE_VER_MINOR - Device version, minor part <0-99>
|
||||
|
||||
|
||||
// <i> Device version, will be converted automatically to BCD notation. Use just decimal values.
|
||||
|
||||
#ifndef APP_USBD_DEVICE_VER_MINOR
|
||||
#define APP_USBD_DEVICE_VER_MINOR 0
|
||||
#endif
|
||||
|
||||
// <e> APP_USBD_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
|
||||
#endif
|
||||
// <o> APP_USBD_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
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
|
||||
// <e> APP_USBD_CONFIG_LOG_ENABLED - Enable logging in the module
|
||||
//==========================================================
|
||||
#ifndef APP_USBD_CONFIG_LOG_ENABLED
|
||||
#define APP_USBD_CONFIG_LOG_ENABLED 0
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
|
||||
// </e>
|
||||
|
||||
// <e> CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver
|
||||
//==========================================================
|
||||
#ifndef CLOCK_ENABLED
|
||||
#define CLOCK_ENABLED 1
|
||||
#endif
|
||||
// <o> CLOCK_CONFIG_XTAL_FREQ - HF XTAL Frequency
|
||||
|
||||
// <0=> Default (64 MHz)
|
||||
|
||||
#ifndef CLOCK_CONFIG_XTAL_FREQ
|
||||
#define CLOCK_CONFIG_XTAL_FREQ 0
|
||||
#endif
|
||||
|
||||
// <o> CLOCK_CONFIG_LF_SRC - LF Clock Source
|
||||
|
||||
// <0=> RC
|
||||
// <1=> XTAL
|
||||
// <2=> Synth
|
||||
|
||||
#ifndef CLOCK_CONFIG_LF_SRC
|
||||
#define CLOCK_CONFIG_LF_SRC 1
|
||||
#endif
|
||||
|
||||
// <o> CLOCK_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 CLOCK_CONFIG_IRQ_PRIORITY
|
||||
#define CLOCK_CONFIG_IRQ_PRIORITY 7
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
|
||||
// <e> POWER_ENABLED - nrf_drv_power - POWER peripheral driver
|
||||
//==========================================================
|
||||
|
||||
#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
|
||||
#ifndef POWER_ENABLED
|
||||
#define POWER_ENABLED 1
|
||||
#endif
|
||||
#else // USB_CDC_AS_SERIAL_TRANSPORT == 1
|
||||
#ifndef POWER_ENABLED
|
||||
#define POWER_ENABLED 0
|
||||
#endif
|
||||
#endif // USB_CDC_AS_SERIAL_TRANSPORT == 1
|
||||
|
||||
// <o> POWER_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 POWER_CONFIG_IRQ_PRIORITY
|
||||
#define POWER_CONFIG_IRQ_PRIORITY 7
|
||||
#endif
|
||||
|
||||
// <q> POWER_CONFIG_DEFAULT_DCDCEN - The default configuration of main DCDC regulator
|
||||
|
||||
|
||||
// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
|
||||
|
||||
#ifndef POWER_CONFIG_DEFAULT_DCDCEN
|
||||
#define POWER_CONFIG_DEFAULT_DCDCEN 0
|
||||
#endif
|
||||
|
||||
// <q> POWER_CONFIG_DEFAULT_DCDCENHV - The default configuration of High Voltage DCDC regulator
|
||||
|
||||
|
||||
// <i> This settings means only that components for DCDC regulator are installed and it can be enabled.
|
||||
|
||||
#ifndef POWER_CONFIG_DEFAULT_DCDCENHV
|
||||
#define POWER_CONFIG_DEFAULT_DCDCENHV 0
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
|
||||
// <q> SYSTICK_ENABLED - nrf_drv_systick - SysTick driver
|
||||
|
||||
#if (USB_CDC_AS_SERIAL_TRANSPORT == 1)
|
||||
#ifndef SYSTICK_ENABLED
|
||||
#define SYSTICK_ENABLED 1
|
||||
#endif
|
||||
#else // USB_CDC_AS_SERIAL_TRANSPORT == 1
|
||||
#ifndef SYSTICK_ENABLED
|
||||
#define SYSTICK_ENABLED 0
|
||||
#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
|
||||
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* 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 sdk_error SDK Error codes
|
||||
* @{
|
||||
* @ingroup app_common
|
||||
* @{
|
||||
* @details Error codes are 32-bit unsigned integers with the most significant 16-bit reserved for
|
||||
* identifying the module where the error occurred while the least least significant LSB
|
||||
* are used to provide the cause or nature of error. Each module is assigned a 16-bit
|
||||
* unsigned integer. Which it will use to identify all errors that occurred in it. 16-bit
|
||||
* LSB range is with module id as the MSB in the 32-bit error code is reserved for the
|
||||
* module. As an example, if 0x8800 identifies a certain SDK module, all values from
|
||||
* 0x88000000 - 0x8800FFFF are reserved for this module.
|
||||
* It should be noted that common error reasons have been assigned values to make it
|
||||
* possible to decode error reason easily. As an example, lets module uninitialized has
|
||||
* been assigned an error code 0x000A0. Then, if application encounters an error code
|
||||
* 0xZZZZ00A0, it knows that it accessing a certain module without initializing it.
|
||||
* Apart from this, each module is allowed to define error codes that are not covered by
|
||||
* the common ones, however, these values are defined in a range that does not conflict
|
||||
* with common error values. For module, specific error however, it is possible that the
|
||||
* same error value is used by two different modules to indicated errors of very different
|
||||
* nature. If error is already defined by the NRF common error codes, these are reused.
|
||||
* A range is reserved for application as well, it can use this range for defining
|
||||
* application specific errors.
|
||||
*
|
||||
* @note Success code, NRF_SUCCESS, does not include any module identifier.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SDK_ERRORS_H__
|
||||
#define SDK_ERRORS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf_error.h"
|
||||
#include "sdk_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup sdk_err_base Base defined for SDK Modules
|
||||
* @{
|
||||
*/
|
||||
#define NRF_ERROR_SDK_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x8000) /**< Base value defined for SDK module identifiers. */
|
||||
#define NRF_ERROR_SDK_COMMON_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x0080) /**< Base error value to be used for SDK error values. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @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)
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup sdk_iot_errors Codes reserved as identification for IoT errors.
|
||||
* @{
|
||||
*/
|
||||
#define NRF_ERROR_IOT_ERR_BASE_START (0xA000)
|
||||
#define NRF_ERROR_IOT_ERR_BASE_STOP (0xAFFF)
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @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)
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @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)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief API Result.
|
||||
*
|
||||
* @details Indicates success or failure of an API procedure. In case of failure, a comprehensive
|
||||
* error code indicating cause or reason for failure is provided.
|
||||
*
|
||||
* Though called an API result, it could used in Asynchronous notifications callback along
|
||||
* with asynchronous callback as event result. This mechanism is employed when an event
|
||||
* marks the end of procedure initiated using API. API result, in this case, will only be
|
||||
* an indicative of whether the procedure has been requested successfully.
|
||||
*/
|
||||
typedef uint32_t ret_code_t;
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDK_ERRORS_H__
|
||||
@@ -0,0 +1,191 @@
|
||||
/**
|
||||
* 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 sdk_common_macros SDK Common Header
|
||||
* @ingroup app_common
|
||||
* @brief Macros for parameter checking and similar tasks
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef SDK_MACROS_H__
|
||||
#define SDK_MACROS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**@brief Macro for verifying statement to be true. It will cause the exterior function to return
|
||||
* err_code if the statement is not true.
|
||||
*
|
||||
* @param[in] statement Statement to test.
|
||||
* @param[in] err_code Error value to return if test was invalid.
|
||||
*
|
||||
* @retval nothing, but will cause the exterior function to return @p err_code if @p statement
|
||||
* is false.
|
||||
*/
|
||||
#define VERIFY_TRUE(statement, err_code) \
|
||||
do \
|
||||
{ \
|
||||
if (!(statement)) \
|
||||
{ \
|
||||
return err_code; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**@brief Macro for verifying statement to be true. It will cause the exterior function to return
|
||||
* if the statement is not true.
|
||||
*
|
||||
* @param[in] statement Statement to test.
|
||||
*/
|
||||
#define VERIFY_TRUE_VOID(statement) VERIFY_TRUE((statement), )
|
||||
|
||||
|
||||
/**@brief Macro for verifying statement to be false. It will cause the exterior function to return
|
||||
* err_code if the statement is not false.
|
||||
*
|
||||
* @param[in] statement Statement to test.
|
||||
* @param[in] err_code Error value to return if test was invalid.
|
||||
*
|
||||
* @retval nothing, but will cause the exterior function to return @p err_code if @p statement
|
||||
* is true.
|
||||
*/
|
||||
#define VERIFY_FALSE(statement, err_code) \
|
||||
do \
|
||||
{ \
|
||||
if ((statement)) \
|
||||
{ \
|
||||
return err_code; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**@brief Macro for verifying statement to be false. It will cause the exterior function to return
|
||||
* if the statement is not false.
|
||||
*
|
||||
* @param[in] statement Statement to test.
|
||||
*/
|
||||
#define VERIFY_FALSE_VOID(statement) VERIFY_FALSE((statement), )
|
||||
|
||||
|
||||
/**@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.
|
||||
*
|
||||
* @param[in] err_code The error code to check.
|
||||
*/
|
||||
#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 */
|
||||
|
||||
|
||||
/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior
|
||||
* function to return if the err_code is not @ref NRF_SUCCESS.
|
||||
*
|
||||
* @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
|
||||
* return @ref NRF_ERROR_INVALID_STATE if not.
|
||||
*
|
||||
* @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
|
||||
* return if not.
|
||||
*
|
||||
* @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
|
||||
* return if not.
|
||||
*
|
||||
* @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
|
||||
* return if not.
|
||||
*
|
||||
* @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 */
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDK_MACROS_H__
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
/** @cond */
|
||||
/**@file
|
||||
*
|
||||
* @defgroup sdk_os SDK OS Abstraction
|
||||
* @ingroup experimental_api
|
||||
* @details In order to made SDK modules independent of use of an embedded OS, and permit
|
||||
* application with varied task architecture, SDK abstracts the OS specific
|
||||
* elements here in order to make all other modules agnostic to the OS or task
|
||||
* architecture.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef SDK_OS_H__
|
||||
#define SDK_OS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SDK_MUTEX_DEFINE(X)
|
||||
#define SDK_MUTEX_INIT(X)
|
||||
#define SDK_MUTEX_LOCK(X)
|
||||
#define SDK_MUTEX_UNLOCK(X)
|
||||
|
||||
/**
|
||||
* @defgroup os_data_type Data types.
|
||||
*/
|
||||
|
||||
/** @} */
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDK_OS_H__
|
||||
|
||||
+105
-86
@@ -6,38 +6,47 @@
|
||||
* nrf52840 from Nordic Semiconductor.
|
||||
*
|
||||
* @version V1
|
||||
* @date 18. November 2016
|
||||
* @date 6. June 2017
|
||||
*
|
||||
* @note Generated with SVDConv V2.81d
|
||||
* from CMSIS SVD File 'nrf52840.svd' Version 1,
|
||||
*
|
||||
* @par Copyright (c) 2016, Nordic Semiconductor ASA
|
||||
* @par Copyright (c) 2010 - 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:
|
||||
* 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
|
||||
* 1. 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.
|
||||
* 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.
|
||||
*
|
||||
* * 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.
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*******************************************************************************************************/
|
||||
@@ -118,8 +127,8 @@ typedef enum {
|
||||
UARTE1_IRQn = 40, /*!< 40 UARTE1 */
|
||||
QSPI_IRQn = 41, /*!< 41 QSPI */
|
||||
CRYPTOCELL_IRQn = 42, /*!< 42 CRYPTOCELL */
|
||||
SPIM3_IRQn = 43, /*!< 43 SPIM3 */
|
||||
PWM3_IRQn = 45 /*!< 45 PWM3 */
|
||||
PWM3_IRQn = 45, /*!< 45 PWM3 */
|
||||
SPIM3_IRQn = 47 /*!< 47 SPIM3 */
|
||||
} IRQn_Type;
|
||||
|
||||
|
||||
@@ -181,7 +190,7 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
__I uint32_t PART; /*!< Part code */
|
||||
__I uint32_t VARIANT; /*!< Part variant (hardware version and production configuration). */
|
||||
__I uint32_t VARIANT; /*!< Part variant (hardware version and production configuration) */
|
||||
__I uint32_t PACKAGE; /*!< Package option */
|
||||
__I uint32_t RAM; /*!< RAM variant */
|
||||
__I uint32_t FLASH; /*!< Flash variant */
|
||||
@@ -189,33 +198,33 @@ typedef struct {
|
||||
} FICR_INFO_Type;
|
||||
|
||||
typedef struct {
|
||||
__I uint32_t A0; /*!< Slope definition A0. */
|
||||
__I uint32_t A1; /*!< Slope definition A1. */
|
||||
__I uint32_t A2; /*!< Slope definition A2. */
|
||||
__I uint32_t A3; /*!< Slope definition A3. */
|
||||
__I uint32_t A4; /*!< Slope definition A4. */
|
||||
__I uint32_t A5; /*!< Slope definition A5. */
|
||||
__I uint32_t B0; /*!< y-intercept B0. */
|
||||
__I uint32_t B1; /*!< y-intercept B1. */
|
||||
__I uint32_t B2; /*!< y-intercept B2. */
|
||||
__I uint32_t B3; /*!< y-intercept B3. */
|
||||
__I uint32_t B4; /*!< y-intercept B4. */
|
||||
__I uint32_t B5; /*!< y-intercept B5. */
|
||||
__I uint32_t T0; /*!< Segment end T0. */
|
||||
__I uint32_t T1; /*!< Segment end T1. */
|
||||
__I uint32_t T2; /*!< Segment end T2. */
|
||||
__I uint32_t T3; /*!< Segment end T3. */
|
||||
__I uint32_t T4; /*!< Segment end T4. */
|
||||
__I uint32_t A0; /*!< Slope definition A0 */
|
||||
__I uint32_t A1; /*!< Slope definition A1 */
|
||||
__I uint32_t A2; /*!< Slope definition A2 */
|
||||
__I uint32_t A3; /*!< Slope definition A3 */
|
||||
__I uint32_t A4; /*!< Slope definition A4 */
|
||||
__I uint32_t A5; /*!< Slope definition A5 */
|
||||
__I uint32_t B0; /*!< Y-intercept B0 */
|
||||
__I uint32_t B1; /*!< Y-intercept B1 */
|
||||
__I uint32_t B2; /*!< Y-intercept B2 */
|
||||
__I uint32_t B3; /*!< Y-intercept B3 */
|
||||
__I uint32_t B4; /*!< Y-intercept B4 */
|
||||
__I uint32_t B5; /*!< Y-intercept B5 */
|
||||
__I uint32_t T0; /*!< Segment end T0 */
|
||||
__I uint32_t T1; /*!< Segment end T1 */
|
||||
__I uint32_t T2; /*!< Segment end T2 */
|
||||
__I uint32_t T3; /*!< Segment end T3 */
|
||||
__I uint32_t T4; /*!< Segment end T4 */
|
||||
} FICR_TEMP_Type;
|
||||
|
||||
typedef struct {
|
||||
__I uint32_t TAGHEADER0; /*!< Default header for NFC Tag. Software can read these values to
|
||||
__I uint32_t TAGHEADER0; /*!< Default header for NFC tag. Software can read these values to
|
||||
populate NFCID1_3RD_LAST, NFCID1_2ND_LAST and NFCID1_LAST. */
|
||||
__I uint32_t TAGHEADER1; /*!< Default header for NFC Tag. Software can read these values to
|
||||
__I uint32_t TAGHEADER1; /*!< Default header for NFC tag. Software can read these values to
|
||||
populate NFCID1_3RD_LAST, NFCID1_2ND_LAST and NFCID1_LAST. */
|
||||
__I uint32_t TAGHEADER2; /*!< Default header for NFC Tag. Software can read these values to
|
||||
__I uint32_t TAGHEADER2; /*!< Default header for NFC tag. Software can read these values to
|
||||
populate NFCID1_3RD_LAST, NFCID1_2ND_LAST and NFCID1_LAST. */
|
||||
__I uint32_t TAGHEADER3; /*!< Default header for NFC Tag. Software can read these values to
|
||||
__I uint32_t TAGHEADER3; /*!< Default header for NFC tag. Software can read these values to
|
||||
populate NFCID1_3RD_LAST, NFCID1_2ND_LAST and NFCID1_LAST. */
|
||||
} FICR_NFC_Type;
|
||||
|
||||
@@ -385,12 +394,12 @@ typedef struct {
|
||||
} QDEC_PSEL_Type;
|
||||
|
||||
typedef struct {
|
||||
__IO uint32_t PTR; /*!< Description cluster[0]: Beginning address in Data RAM of sequence
|
||||
A */
|
||||
__IO uint32_t CNT; /*!< Description cluster[0]: Amount of values (duty cycles) in sequence
|
||||
A */
|
||||
__IO uint32_t PTR; /*!< Description cluster[0]: Beginning address in Data RAM of this
|
||||
sequence */
|
||||
__IO uint32_t CNT; /*!< Description cluster[0]: Amount of values (duty cycles) in this
|
||||
sequence */
|
||||
__IO uint32_t REFRESH; /*!< Description cluster[0]: Amount of additional PWM periods between
|
||||
samples loaded to compare register (load every CNT+1 PWM periods) */
|
||||
samples loaded into compare register */
|
||||
__IO uint32_t ENDDELAY; /*!< Description cluster[0]: Time added after the sequence */
|
||||
__I uint32_t RESERVED1[4];
|
||||
} PWM_SEQ_Type;
|
||||
@@ -511,7 +520,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
__IO uint32_t EPOUT[8]; /*!< Description collection[0]: Amount of bytes received last in
|
||||
the data stage of this OUT endpoint */
|
||||
__IO uint32_t ISOOUT; /*!< Amount of bytes received last on this iso OUT data endpoint */
|
||||
__I uint32_t ISOOUT; /*!< Amount of bytes received last on this iso OUT data endpoint */
|
||||
} USBD_SIZE_Type;
|
||||
|
||||
typedef struct {
|
||||
@@ -576,7 +585,7 @@ typedef struct {
|
||||
|
||||
|
||||
/**
|
||||
* @brief Factory Information Configuration Registers (FICR)
|
||||
* @brief Factory information configuration registers (FICR)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< FICR Structure */
|
||||
@@ -605,7 +614,7 @@ typedef struct { /*!< FICR Structure
|
||||
|
||||
|
||||
/**
|
||||
* @brief User Information Configuration Registers (UICR)
|
||||
* @brief User information configuration registers (UICR)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< UICR Structure */
|
||||
@@ -622,11 +631,12 @@ typedef struct { /*!< UICR Structure
|
||||
__IO uint32_t APPROTECT; /*!< Access port protection */
|
||||
__IO uint32_t NFCPINS; /*!< Setting of pins dedicated to NFC functionality: NFC antenna
|
||||
or GPIO */
|
||||
__I uint32_t RESERVED2[60];
|
||||
__IO uint32_t DEBUGCTRL; /*!< Processor debug control */
|
||||
__I uint32_t RESERVED2[59];
|
||||
__IO uint32_t EXTSUPPLY; /*!< Enable external circuitry to be supplied from VDD pin. Applicable
|
||||
in 'High voltage mode' only. */
|
||||
__IO uint32_t REGOUT0; /*!< GPIO reference voltage / external output supply voltage in 'High
|
||||
voltage mode'. */
|
||||
in high voltage mode only. */
|
||||
__IO uint32_t REGOUT0; /*!< GPIO reference voltage / external output supply voltage in high
|
||||
voltage mode */
|
||||
} NRF_UICR_Type;
|
||||
|
||||
|
||||
@@ -713,10 +723,15 @@ typedef struct { /*!< CLOCK Structure
|
||||
__I uint32_t LFCLKSRCCOPY; /*!< Copy of LFCLKSRC register, set when LFCLKSTART task was triggered */
|
||||
__I uint32_t RESERVED5[62];
|
||||
__IO uint32_t LFCLKSRC; /*!< Clock source for the LFCLK */
|
||||
__I uint32_t RESERVED6[7];
|
||||
__I uint32_t RESERVED6[3];
|
||||
__IO uint32_t HFXODEBOUNCE; /*!< HFXO debounce time. The HFXO is started by triggering the TASKS_HFCLKSTART
|
||||
task. */
|
||||
__I uint32_t RESERVED7[3];
|
||||
__IO uint32_t CTIV; /*!< Calibration timer interval */
|
||||
__I uint32_t RESERVED7[8];
|
||||
__I uint32_t RESERVED8[8];
|
||||
__IO uint32_t TRACECONFIG; /*!< Clocking options for the Trace Port debug interface */
|
||||
__I uint32_t RESERVED9[21];
|
||||
__IO uint32_t LFRCMODE; /*!< LFRC mode configuration */
|
||||
} NRF_CLOCK_Type;
|
||||
|
||||
|
||||
@@ -770,18 +785,22 @@ typedef struct { /*!< RADIO Structure
|
||||
__IO uint32_t EVENTS_TXREADY; /*!< RADIO has ramped up and is ready to be started TX path */
|
||||
__IO uint32_t EVENTS_RXREADY; /*!< RADIO has ramped up and is ready to be started RX path */
|
||||
__IO uint32_t EVENTS_MHRMATCH; /*!< MAC Header match found. */
|
||||
__I uint32_t RESERVED3[40];
|
||||
__I uint32_t RESERVED3[3];
|
||||
__IO uint32_t EVENTS_PHYEND; /*!< Generated in Ble_LR125Kbit, Ble_LR500Kbit and BleIeee802154_250Kbit
|
||||
modes when last bit is sent on air. */
|
||||
__I uint32_t RESERVED4[36];
|
||||
__IO uint32_t SHORTS; /*!< Shortcut register */
|
||||
__I uint32_t RESERVED4[64];
|
||||
__I uint32_t RESERVED5[64];
|
||||
__IO uint32_t INTENSET; /*!< Enable interrupt */
|
||||
__IO uint32_t INTENCLR; /*!< Disable interrupt */
|
||||
__I uint32_t RESERVED5[61];
|
||||
__I uint32_t RESERVED6[61];
|
||||
__I uint32_t CRCSTATUS; /*!< CRC status */
|
||||
__I uint32_t RESERVED6;
|
||||
__I uint32_t RESERVED7;
|
||||
__I uint32_t RXMATCH; /*!< Received address */
|
||||
__I uint32_t RXCRC; /*!< CRC field of previously received packet */
|
||||
__I uint32_t DAI; /*!< Device address match index */
|
||||
__I uint32_t RESERVED7[60];
|
||||
__I uint32_t PDUSTAT; /*!< Payload status */
|
||||
__I uint32_t RESERVED8[59];
|
||||
__IO uint32_t PACKETPTR; /*!< Packet pointer */
|
||||
__IO uint32_t FREQUENCY; /*!< Frequency */
|
||||
__IO uint32_t TXPOWER; /*!< Output power */
|
||||
@@ -797,28 +816,28 @@ typedef struct { /*!< RADIO Structure
|
||||
__IO uint32_t CRCCNF; /*!< CRC configuration */
|
||||
__IO uint32_t CRCPOLY; /*!< CRC polynomial */
|
||||
__IO uint32_t CRCINIT; /*!< CRC initial value */
|
||||
__I uint32_t RESERVED8;
|
||||
__I uint32_t RESERVED9;
|
||||
__IO uint32_t TIFS; /*!< Inter Frame Spacing in us */
|
||||
__I uint32_t RSSISAMPLE; /*!< RSSI sample */
|
||||
__I uint32_t RESERVED9;
|
||||
__I uint32_t RESERVED10;
|
||||
__I uint32_t STATE; /*!< Current radio state */
|
||||
__IO uint32_t DATAWHITEIV; /*!< Data whitening initial value */
|
||||
__I uint32_t RESERVED10[2];
|
||||
__I uint32_t RESERVED11[2];
|
||||
__IO uint32_t BCC; /*!< Bit counter compare */
|
||||
__I uint32_t RESERVED11[39];
|
||||
__I uint32_t RESERVED12[39];
|
||||
__IO uint32_t DAB[8]; /*!< Description collection[0]: Device address base segment 0 */
|
||||
__IO uint32_t DAP[8]; /*!< Description collection[0]: Device address prefix 0 */
|
||||
__IO uint32_t DACNF; /*!< Device address match configuration */
|
||||
__IO uint32_t MHRMATCHCONF; /*!< Search Pattern Configuration */
|
||||
__IO uint32_t MHRMATCHMAS; /*!< Pattern mask */
|
||||
__I uint32_t RESERVED12;
|
||||
__I uint32_t RESERVED13;
|
||||
__IO uint32_t MODECNF0; /*!< Radio mode configuration register 0 */
|
||||
__I uint32_t RESERVED13[3];
|
||||
__I uint32_t RESERVED14[3];
|
||||
__IO uint32_t SFD; /*!< IEEE 802.15.4 Start of Frame Delimiter */
|
||||
__IO uint32_t EDCNT; /*!< IEEE 802.15.4 Energy Detect Loop Count */
|
||||
__IO uint32_t EDSAMPLE; /*!< IEEE 802.15.4 Energy Detect Level */
|
||||
__IO uint32_t CCACTRL; /*!< IEEE 802.15.4 Clear Channel Assessment Control */
|
||||
__I uint32_t RESERVED14[611];
|
||||
__I uint32_t RESERVED15[611];
|
||||
__IO uint32_t POWER; /*!< Peripheral power control */
|
||||
} NRF_RADIO_Type;
|
||||
|
||||
@@ -1891,17 +1910,16 @@ typedef struct { /*!< NVMC Structure
|
||||
__I uint32_t READY; /*!< Ready flag */
|
||||
__I uint32_t RESERVED1[64];
|
||||
__IO uint32_t CONFIG; /*!< Configuration register */
|
||||
|
||||
__IO uint32_t ERASEPAGE; /*!< Register for erasing a page in Code area */
|
||||
__IO uint32_t ERASEPAGE; /*!< Register for erasing a page in code area */
|
||||
__IO uint32_t ERASEALL; /*!< Register for erasing all non-volatile user memory */
|
||||
__IO uint32_t ERASEPCR0; /*!< Deprecated register - Register for erasing a page in Code area.
|
||||
__IO uint32_t ERASEPCR0; /*!< Deprecated register - Register for erasing a page in code area.
|
||||
Equivalent to ERASEPAGE. */
|
||||
__IO uint32_t ERASEUICR; /*!< Register for erasing User Information Configuration Registers */
|
||||
__IO uint32_t ERASEUICR; /*!< Register for erasing user information configuration registers */
|
||||
__I uint32_t RESERVED2[10];
|
||||
__IO uint32_t ICACHECNF; /*!< I-Code cache configuration register. */
|
||||
__IO uint32_t ICACHECNF; /*!< I-code cache configuration register. */
|
||||
__I uint32_t RESERVED3;
|
||||
__IO uint32_t IHIT; /*!< I-Code cache hit counter. */
|
||||
__IO uint32_t IMISS; /*!< I-Code cache miss counter. */
|
||||
__IO uint32_t IHIT; /*!< I-code cache hit counter. */
|
||||
__IO uint32_t IMISS; /*!< I-code cache miss counter. */
|
||||
} NRF_NVMC_Type;
|
||||
|
||||
|
||||
@@ -1915,10 +1933,7 @@ typedef struct { /*!< NVMC Structure
|
||||
*/
|
||||
|
||||
typedef struct { /*!< ACL Structure */
|
||||
__I uint32_t RESERVED0[449];
|
||||
__IO uint32_t DISABLEINDEBUG; /*!< Disable all ACL protection mechanisms for regions while in debug
|
||||
mode */
|
||||
__I uint32_t RESERVED1[62];
|
||||
__I uint32_t RESERVED0[512];
|
||||
ACL_ACL_Type ACL[8]; /*!< Unspecified */
|
||||
} NRF_ACL_Type;
|
||||
|
||||
@@ -2134,7 +2149,9 @@ typedef struct { /*!< USBD Structure
|
||||
__O uint32_t EPSTALL; /*!< STALL endpoints */
|
||||
__IO uint32_t ISOSPLIT; /*!< Controls the split of ISO buffers */
|
||||
__I uint32_t FRAMECNTR; /*!< Returns the current value of the start of frame counter */
|
||||
__I uint32_t RESERVED9[3];
|
||||
__I uint32_t RESERVED9[2];
|
||||
__IO uint32_t LOWPOWER; /*!< First silicon only: Controls USBD peripheral low-power mode
|
||||
during USB suspend */
|
||||
__IO uint32_t ISOINCONFIG; /*!< Controls the response of the ISO IN endpoint to an IN token
|
||||
when no data is ready to be sent */
|
||||
__I uint32_t RESERVED10[51];
|
||||
@@ -2160,7 +2177,8 @@ typedef struct { /*!< QSPI Structure
|
||||
__O uint32_t TASKS_READSTART; /*!< Start transfer from external flash memory to internal RAM */
|
||||
__O uint32_t TASKS_WRITESTART; /*!< Start transfer from internal RAM to external flash memory */
|
||||
__O uint32_t TASKS_ERASESTART; /*!< Start external flash memory erase operation */
|
||||
__I uint32_t RESERVED0[60];
|
||||
__O uint32_t TASKS_DEACTIVATE; /*!< Deactivate QSPI interface */
|
||||
__I uint32_t RESERVED0[59];
|
||||
__IO uint32_t EVENTS_READY; /*!< QSPI peripheral is ready. This event will be generated as a
|
||||
response to any QSPI task. */
|
||||
__I uint32_t RESERVED1[127];
|
||||
@@ -2323,8 +2341,8 @@ typedef struct { /*!< CRYPTOCELL Structure
|
||||
#define NRF_USBD_BASE 0x40027000UL
|
||||
#define NRF_UARTE1_BASE 0x40028000UL
|
||||
#define NRF_QSPI_BASE 0x40029000UL
|
||||
#define NRF_SPIM3_BASE 0x4002B000UL
|
||||
#define NRF_PWM3_BASE 0x4002D000UL
|
||||
#define NRF_SPIM3_BASE 0x4002F000UL
|
||||
#define NRF_P0_BASE 0x50000000UL
|
||||
#define NRF_P1_BASE 0x50000300UL
|
||||
#define NRF_CRYPTOCELL_BASE 0x5002A000UL
|
||||
@@ -2401,8 +2419,8 @@ typedef struct { /*!< CRYPTOCELL Structure
|
||||
#define NRF_USBD ((NRF_USBD_Type *) NRF_USBD_BASE)
|
||||
#define NRF_UARTE1 ((NRF_UARTE_Type *) NRF_UARTE1_BASE)
|
||||
#define NRF_QSPI ((NRF_QSPI_Type *) NRF_QSPI_BASE)
|
||||
#define NRF_SPIM3 ((NRF_SPIM_Type *) NRF_SPIM3_BASE)
|
||||
#define NRF_PWM3 ((NRF_PWM_Type *) NRF_PWM3_BASE)
|
||||
#define NRF_SPIM3 ((NRF_SPIM_Type *) NRF_SPIM3_BASE)
|
||||
#define NRF_P0 ((NRF_GPIO_Type *) NRF_P0_BASE)
|
||||
#define NRF_P1 ((NRF_GPIO_Type *) NRF_P1_BASE)
|
||||
#define NRF_CRYPTOCELL ((NRF_CRYPTOCELL_Type *) NRF_CRYPTOCELL_BASE)
|
||||
@@ -2418,3 +2436,4 @@ typedef struct { /*!< CRYPTOCELL Structure
|
||||
|
||||
|
||||
#endif /* nrf52840_H */
|
||||
|
||||
|
||||
+306
-204
File diff suppressed because it is too large
Load Diff
+41
-29
@@ -1,32 +1,43 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
|
||||
Copyright (c) 2010 - 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 _NRF52840_PERIPHERALS_H
|
||||
#define _NRF52840_PERIPHERALS_H
|
||||
@@ -87,6 +98,7 @@
|
||||
#define PPI_COUNT 1
|
||||
|
||||
#define PPI_CH_NUM 20
|
||||
#define PPI_FIXED_CH_NUM 12
|
||||
#define PPI_GROUP_NUM 6
|
||||
#define PPI_FEATURE_FORKS_PRESENT
|
||||
|
||||
|
||||
+538
-77
@@ -1,36 +1,72 @@
|
||||
/* Copyright (c) 2016, Nordic Semiconductor ASA
|
||||
/**
|
||||
* 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 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.
|
||||
*
|
||||
*
|
||||
* 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 "sdk_common.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_ERROR_MODULE_ALREADY_INITIALIZED 0x8085
|
||||
#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);
|
||||
|
||||
/*lint -save -e652 */
|
||||
#define NRF_CLOCK_LFCLK_RC CLOCK_LFCLKSRC_SRC_RC
|
||||
@@ -38,14 +74,46 @@
|
||||
#define NRF_CLOCK_LFCLK_Synth CLOCK_LFCLKSRC_SRC_Synth
|
||||
/*lint -restore */
|
||||
|
||||
volatile uint32_t m_hfclk_requests; /*< High frequency clock requests. */
|
||||
volatile uint32_t m_lfclk_requests; /*< Low frequency clock requests. */
|
||||
#if (CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LFCLK_RC) && !defined(SOFTDEVICE_PRESENT)
|
||||
#define CALIBRATION_SUPPORT 1
|
||||
#else
|
||||
#define CALIBRATION_SUPPORT 0
|
||||
#endif
|
||||
typedef enum
|
||||
{
|
||||
CAL_STATE_IDLE,
|
||||
CAL_STATE_CT,
|
||||
CAL_STATE_HFCLK_REQ,
|
||||
CAL_STATE_CAL,
|
||||
CAL_STATE_ABORT,
|
||||
} nrf_drv_clock_cal_state_t;
|
||||
|
||||
/**@brief CLOCK control block. */
|
||||
typedef struct
|
||||
{
|
||||
bool module_initialized; /*< Indicate the state of module */
|
||||
volatile bool hfclk_on; /*< High-frequency clock state. */
|
||||
volatile bool lfclk_on; /*< Low-frequency clock state. */
|
||||
volatile uint32_t hfclk_requests; /*< High-frequency clock request counter. */
|
||||
volatile nrf_drv_clock_handler_item_t * p_hf_head;
|
||||
volatile uint32_t lfclk_requests; /*< Low-frequency clock request counter. */
|
||||
volatile nrf_drv_clock_handler_item_t * p_lf_head;
|
||||
#if CALIBRATION_SUPPORT
|
||||
nrf_drv_clock_handler_item_t cal_hfclk_started_handler_item;
|
||||
nrf_drv_clock_event_handler_t cal_done_handler;
|
||||
volatile nrf_drv_clock_cal_state_t cal_state;
|
||||
#endif // CALIBRATION_SUPPORT
|
||||
} nrf_drv_clock_cb_t;
|
||||
|
||||
static nrf_drv_clock_cb_t m_clock_cb;
|
||||
|
||||
|
||||
/**@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);
|
||||
}
|
||||
|
||||
@@ -53,114 +121,507 @@ static void lfclk_start(void)
|
||||
*/
|
||||
static void lfclk_stop(void)
|
||||
{
|
||||
nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTOP);
|
||||
#if CALIBRATION_SUPPORT
|
||||
(void)nrf_drv_clock_calibration_abort();
|
||||
#endif
|
||||
|
||||
while (nrf_clock_lf_is_running()) {}
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
// If LFCLK is requested to stop while SD is still enabled,
|
||||
// it indicates an error in the application.
|
||||
// Enabling SD should increment the LFCLK request.
|
||||
ASSERT(!nrf_sdh_is_enabled());
|
||||
#endif // SOFTDEVICE_PRESENT
|
||||
|
||||
nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTOP);
|
||||
while (nrf_clock_lf_is_running())
|
||||
{}
|
||||
m_clock_cb.lfclk_on = false;
|
||||
}
|
||||
|
||||
static void hfclk_start(void)
|
||||
{
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
if (nrf_sdh_is_enabled())
|
||||
{
|
||||
(void)sd_clock_hfclk_request();
|
||||
return;
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
||||
static void hfclk_stop(void)
|
||||
{
|
||||
nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP);
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
if (nrf_sdh_is_enabled())
|
||||
{
|
||||
(void)sd_clock_hfclk_release();
|
||||
return;
|
||||
}
|
||||
#endif // SOFTDEVICE_PRESENT
|
||||
|
||||
while (nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY)) {}
|
||||
nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP);
|
||||
while (nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY))
|
||||
{}
|
||||
m_clock_cb.hfclk_on = false;
|
||||
}
|
||||
|
||||
uint32_t nrf_drv_clock_init(void)
|
||||
bool nrf_drv_clock_init_check(void)
|
||||
{
|
||||
nrf_clock_lf_src_set(NRF_CLOCK_LFCLK_Xtal);
|
||||
return 0;
|
||||
return m_clock_cb.module_initialized;
|
||||
}
|
||||
|
||||
ret_code_t nrf_drv_clock_init(void)
|
||||
{
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
if (m_clock_cb.module_initialized)
|
||||
{
|
||||
err_code = NRF_ERROR_MODULE_ALREADY_INITIALIZED;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clock_cb.p_hf_head = NULL;
|
||||
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();
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
if (!nrf_sdh_is_enabled())
|
||||
#endif
|
||||
{
|
||||
nrf_clock_lf_src_set((nrf_clock_lfclk_t)CLOCK_CONFIG_LF_SRC);
|
||||
}
|
||||
|
||||
#if CALIBRATION_SUPPORT
|
||||
m_clock_cb.cal_state = CAL_STATE_IDLE;
|
||||
#endif
|
||||
|
||||
m_clock_cb.module_initialized = true;
|
||||
}
|
||||
|
||||
NRF_LOG_INFO("Function: %s, error code: %s.",
|
||||
(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.");
|
||||
}
|
||||
|
||||
void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t *p_handler_item)
|
||||
static void item_enqueue(nrf_drv_clock_handler_item_t ** p_head,
|
||||
nrf_drv_clock_handler_item_t * p_item)
|
||||
{
|
||||
volatile uint32_t lfclk_requests;
|
||||
(void) p_handler_item;
|
||||
|
||||
do
|
||||
nrf_drv_clock_handler_item_t * p_next = *p_head;
|
||||
while (p_next)
|
||||
{
|
||||
|
||||
lfclk_requests = __LDREXW(&m_lfclk_requests);
|
||||
lfclk_requests += 1;
|
||||
if (p_next == p_item)
|
||||
{
|
||||
return;
|
||||
}
|
||||
p_next = p_next->p_next;
|
||||
}
|
||||
while (__STREXW(lfclk_requests, &m_lfclk_requests));
|
||||
|
||||
if (!nrf_clock_lf_is_running())
|
||||
p_item->p_next = (*p_head ? *p_head : NULL);
|
||||
*p_head = p_item;
|
||||
}
|
||||
|
||||
static nrf_drv_clock_handler_item_t * item_dequeue(nrf_drv_clock_handler_item_t ** p_head)
|
||||
{
|
||||
nrf_drv_clock_handler_item_t * p_item = *p_head;
|
||||
if (p_item)
|
||||
{
|
||||
lfclk_start();
|
||||
*p_head = p_item->p_next;
|
||||
}
|
||||
return p_item;
|
||||
}
|
||||
|
||||
void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t * p_handler_item)
|
||||
{
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
|
||||
if (m_clock_cb.lfclk_on)
|
||||
{
|
||||
if (p_handler_item)
|
||||
{
|
||||
p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_LFCLK_STARTED);
|
||||
}
|
||||
CRITICAL_REGION_ENTER();
|
||||
++(m_clock_cb.lfclk_requests);
|
||||
CRITICAL_REGION_EXIT();
|
||||
}
|
||||
else
|
||||
{
|
||||
CRITICAL_REGION_ENTER();
|
||||
if (p_handler_item)
|
||||
{
|
||||
item_enqueue((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_lf_head,
|
||||
p_handler_item);
|
||||
}
|
||||
if (m_clock_cb.lfclk_requests == 0)
|
||||
{
|
||||
lfclk_start();
|
||||
}
|
||||
++(m_clock_cb.lfclk_requests);
|
||||
CRITICAL_REGION_EXIT();
|
||||
}
|
||||
|
||||
ASSERT(m_clock_cb.lfclk_requests > 0);
|
||||
}
|
||||
|
||||
void nrf_drv_clock_lfclk_release(void)
|
||||
{
|
||||
volatile uint32_t lfclk_requests;
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
ASSERT(m_clock_cb.lfclk_requests > 0);
|
||||
|
||||
do
|
||||
{
|
||||
lfclk_requests = __LDREXW(&m_lfclk_requests);
|
||||
lfclk_requests -= 1;
|
||||
}
|
||||
while (__STREXW(lfclk_requests, &m_lfclk_requests));
|
||||
|
||||
if (nrf_clock_lf_is_running() && m_lfclk_requests == 0)
|
||||
CRITICAL_REGION_ENTER();
|
||||
--(m_clock_cb.lfclk_requests);
|
||||
if (m_clock_cb.lfclk_requests == 0)
|
||||
{
|
||||
lfclk_stop();
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
}
|
||||
|
||||
bool nrf_drv_clock_lfclk_is_running(void)
|
||||
{
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
if (nrf_sdh_is_enabled())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif // SOFTDEVICE_PRESENT
|
||||
|
||||
return nrf_clock_lf_is_running();
|
||||
}
|
||||
|
||||
void nrf_drv_clock_hfclk_request(nrf_drv_clock_handler_item_t *p_handler_item)
|
||||
void nrf_drv_clock_hfclk_request(nrf_drv_clock_handler_item_t * p_handler_item)
|
||||
{
|
||||
volatile uint32_t hfclk_requests;
|
||||
(void) p_handler_item;
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
|
||||
do
|
||||
if (m_clock_cb.hfclk_on)
|
||||
{
|
||||
|
||||
hfclk_requests = __LDREXW(&m_hfclk_requests);
|
||||
hfclk_requests += 1;
|
||||
if (p_handler_item)
|
||||
{
|
||||
p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_HFCLK_STARTED);
|
||||
}
|
||||
CRITICAL_REGION_ENTER();
|
||||
++(m_clock_cb.hfclk_requests);
|
||||
CRITICAL_REGION_EXIT();
|
||||
}
|
||||
while (__STREXW(hfclk_requests, &m_hfclk_requests));
|
||||
|
||||
if (!nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY))
|
||||
else
|
||||
{
|
||||
hfclk_start();
|
||||
CRITICAL_REGION_ENTER();
|
||||
if (p_handler_item)
|
||||
{
|
||||
item_enqueue((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_hf_head,
|
||||
p_handler_item);
|
||||
}
|
||||
if (m_clock_cb.hfclk_requests == 0)
|
||||
{
|
||||
hfclk_start();
|
||||
}
|
||||
++(m_clock_cb.hfclk_requests);
|
||||
CRITICAL_REGION_EXIT();
|
||||
}
|
||||
|
||||
ASSERT(m_clock_cb.hfclk_requests > 0);
|
||||
}
|
||||
|
||||
void nrf_drv_clock_hfclk_release(void)
|
||||
{
|
||||
volatile uint32_t hfclk_requests;
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
ASSERT(m_clock_cb.hfclk_requests > 0);
|
||||
|
||||
do
|
||||
{
|
||||
hfclk_requests = __LDREXW(&m_hfclk_requests);
|
||||
hfclk_requests -= 1;
|
||||
}
|
||||
while (__STREXW(hfclk_requests, &m_hfclk_requests));
|
||||
|
||||
if (nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY) && m_hfclk_requests == 0)
|
||||
CRITICAL_REGION_ENTER();
|
||||
--(m_clock_cb.hfclk_requests);
|
||||
if (m_clock_cb.hfclk_requests == 0)
|
||||
{
|
||||
hfclk_stop();
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
}
|
||||
|
||||
bool nrf_drv_clock_hfclk_is_running(void)
|
||||
{
|
||||
ASSERT(m_clock_cb.module_initialized);
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
if (nrf_sdh_is_enabled())
|
||||
{
|
||||
uint32_t is_running;
|
||||
UNUSED_VARIABLE(sd_clock_hfclk_is_running(&is_running));
|
||||
return (is_running ? true : false);
|
||||
}
|
||||
#endif // SOFTDEVICE_PRESENT
|
||||
|
||||
return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY);
|
||||
}
|
||||
|
||||
#if CALIBRATION_SUPPORT
|
||||
static void clock_calibration_hf_started(nrf_drv_clock_evt_type_t event)
|
||||
{
|
||||
if (m_clock_cb.cal_state == CAL_STATE_ABORT)
|
||||
{
|
||||
nrf_drv_clock_hfclk_release();
|
||||
m_clock_cb.cal_state = CAL_STATE_IDLE;
|
||||
if (m_clock_cb.cal_done_handler)
|
||||
{
|
||||
m_clock_cb.cal_done_handler(NRF_DRV_CLOCK_EVT_CAL_ABORTED);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
#endif // CALIBRATION_SUPPORT
|
||||
|
||||
ret_code_t nrf_drv_clock_calibration_start(uint8_t interval, nrf_drv_clock_event_handler_t handler)
|
||||
{
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
#if CALIBRATION_SUPPORT
|
||||
ASSERT(m_clock_cb.cal_state == CAL_STATE_IDLE);
|
||||
if (m_clock_cb.lfclk_on == false)
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
else if (m_clock_cb.cal_state == CAL_STATE_IDLE)
|
||||
{
|
||||
m_clock_cb.cal_done_handler = handler;
|
||||
m_clock_cb.cal_hfclk_started_handler_item.event_handler = clock_calibration_hf_started;
|
||||
if (interval == 0)
|
||||
{
|
||||
m_clock_cb.cal_state = CAL_STATE_HFCLK_REQ;
|
||||
nrf_drv_clock_hfclk_request(&m_clock_cb.cal_hfclk_started_handler_item);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
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));
|
||||
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));
|
||||
return err_code;
|
||||
#endif // CALIBRATION_SUPPORT
|
||||
}
|
||||
|
||||
ret_code_t nrf_drv_clock_calibration_abort(void)
|
||||
{
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
#if CALIBRATION_SUPPORT
|
||||
CRITICAL_REGION_ENTER();
|
||||
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);
|
||||
m_clock_cb.cal_state = CAL_STATE_IDLE;
|
||||
if (m_clock_cb.cal_done_handler)
|
||||
{
|
||||
m_clock_cb.cal_done_handler(NRF_DRV_CLOCK_EVT_CAL_ABORTED);
|
||||
}
|
||||
break;
|
||||
case CAL_STATE_HFCLK_REQ:
|
||||
/* fall through. */
|
||||
case CAL_STATE_CAL:
|
||||
m_clock_cb.cal_state = CAL_STATE_ABORT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
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));
|
||||
return err_code;
|
||||
#endif // CALIBRATION_SUPPORT
|
||||
}
|
||||
|
||||
ret_code_t nrf_drv_clock_is_calibrating(bool * p_is_calibrating)
|
||||
{
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
#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));
|
||||
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));
|
||||
return err_code;
|
||||
#endif // CALIBRATION_SUPPORT
|
||||
}
|
||||
|
||||
__STATIC_INLINE void clock_clk_started_notify(nrf_drv_clock_evt_type_t evt_type)
|
||||
{
|
||||
nrf_drv_clock_handler_item_t **p_head;
|
||||
if (evt_type == NRF_DRV_CLOCK_EVT_HFCLK_STARTED)
|
||||
{
|
||||
p_head = (nrf_drv_clock_handler_item_t **)&m_clock_cb.p_hf_head;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_head = (nrf_drv_clock_handler_item_t **)&m_clock_cb.p_lf_head;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
nrf_drv_clock_handler_item_t * p_item = item_dequeue(p_head);
|
||||
if (!p_item)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
p_item->event_handler(evt_type);
|
||||
}
|
||||
}
|
||||
|
||||
#if NRF_DRV_COMMON_POWER_CLOCK_ISR
|
||||
void nrf_drv_clock_onIRQ(void)
|
||||
#else
|
||||
void POWER_CLOCK_IRQHandler(void)
|
||||
#endif
|
||||
{
|
||||
if (nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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;
|
||||
if (m_clock_cb.cal_done_handler)
|
||||
{
|
||||
m_clock_cb.cal_done_handler(aborted ?
|
||||
NRF_DRV_CLOCK_EVT_CAL_ABORTED : NRF_DRV_CLOCK_EVT_CAL_DONE);
|
||||
}
|
||||
}
|
||||
#endif // CALIBRATION_SUPPORT
|
||||
}
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
/**
|
||||
* @brief SoftDevice SoC event handler.
|
||||
*
|
||||
* @param[in] evt_id SoC event.
|
||||
* @param[in] p_context Context.
|
||||
*/
|
||||
static void soc_evt_handler(uint32_t evt_id, void * p_context)
|
||||
{
|
||||
if (evt_id == NRF_EVT_HFCLKSTARTED)
|
||||
{
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief SoftDevice enable/disable state handler.
|
||||
*
|
||||
* @param[in] state State.
|
||||
* @param[in] p_context Context.
|
||||
*/
|
||||
static void sd_state_evt_handler(nrf_sdh_state_evt_t state, void * p_context)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case NRF_SDH_EVT_STATE_ENABLE_PREPARE:
|
||||
NVIC_DisableIRQ(POWER_CLOCK_IRQn);
|
||||
break;
|
||||
|
||||
case NRF_SDH_EVT_STATE_ENABLED:
|
||||
CRITICAL_REGION_ENTER();
|
||||
/* Make sure that nrf_drv_clock module is initialized */
|
||||
if (!m_clock_cb.module_initialized)
|
||||
{
|
||||
(void)nrf_drv_clock_init();
|
||||
}
|
||||
/* SD is one of the LFCLK requesters, but it will enable it by itself. */
|
||||
++(m_clock_cb.lfclk_requests);
|
||||
m_clock_cb.lfclk_on = true;
|
||||
CRITICAL_REGION_EXIT();
|
||||
break;
|
||||
|
||||
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);
|
||||
|
||||
/* SD leaves LFCLK enabled - disable it if it is no longer required. */
|
||||
nrf_drv_clock_lfclk_release();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NRF_SDH_STATE_OBSERVER(m_sd_state_observer, CLOCK_CONFIG_STATE_OBSERVER_PRIO) =
|
||||
{
|
||||
.handler = sd_state_evt_handler,
|
||||
.p_context = NULL,
|
||||
};
|
||||
|
||||
#endif // SOFTDEVICE_PRESENT
|
||||
|
||||
#undef NRF_CLOCK_LFCLK_RC
|
||||
#undef NRF_CLOCK_LFCLK_Xtal
|
||||
#undef NRF_CLOCK_LFCLK_Synth
|
||||
|
||||
#endif // NRF_MODULE_ENABLED(CLOCK)
|
||||
|
||||
+176
-34
@@ -1,48 +1,108 @@
|
||||
/* Copyright (c) 2016, Nordic Semiconductor ASA
|
||||
/**
|
||||
* 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 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.
|
||||
*
|
||||
*
|
||||
* 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_DRV_CLOCK_H__
|
||||
#define NRF_DRV_CLOCK_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <nrf_clock.h>
|
||||
#include "sdk_errors.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "nrf_clock.h"
|
||||
#include "sdk_config.h"
|
||||
#include "nrf_drv_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Simplify version to keep API of SDK.
|
||||
*
|
||||
* @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
|
||||
* @{
|
||||
* @ingroup nrf_clock
|
||||
* @brief Driver for managing the low-frequency clock (LFCLK) and the high-frequency clock (HFCLK).
|
||||
*/
|
||||
typedef void nrf_drv_clock_handler_item_t;
|
||||
|
||||
/**
|
||||
* @brief Clock events.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_DRV_CLOCK_EVT_HFCLK_STARTED, ///< HFCLK has been started.
|
||||
NRF_DRV_CLOCK_EVT_LFCLK_STARTED, ///< LFCLK has been started.
|
||||
NRF_DRV_CLOCK_EVT_CAL_DONE, ///< Calibration is done.
|
||||
NRF_DRV_CLOCK_EVT_CAL_ABORTED, ///< Calibration has been aborted.
|
||||
} nrf_drv_clock_evt_type_t;
|
||||
|
||||
/**
|
||||
* @brief Clock event handler.
|
||||
*
|
||||
* @param[in] event Event.
|
||||
*/
|
||||
typedef void (*nrf_drv_clock_event_handler_t)(nrf_drv_clock_evt_type_t event);
|
||||
|
||||
// Forward declaration of the nrf_drv_clock_handler_item_t type.
|
||||
typedef struct nrf_drv_clock_handler_item_s nrf_drv_clock_handler_item_t;
|
||||
|
||||
struct nrf_drv_clock_handler_item_s
|
||||
{
|
||||
nrf_drv_clock_handler_item_t * p_next; ///< A pointer to the next handler that should be called when the clock is started.
|
||||
nrf_drv_clock_event_handler_t event_handler; ///< Function to be called when the clock is started.
|
||||
};
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
bool nrf_drv_clock_init_check(void);
|
||||
|
||||
/**
|
||||
* @brief Function for initializing the nrf_drv_clock module.
|
||||
@@ -52,7 +112,7 @@ typedef void nrf_drv_clock_handler_item_t;
|
||||
* @retval NRF_SUCCESS If the procedure was successful.
|
||||
* @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED If the driver was already initialized.
|
||||
*/
|
||||
uint32_t nrf_drv_clock_init(void);
|
||||
ret_code_t nrf_drv_clock_init(void);
|
||||
|
||||
/**
|
||||
* @brief Function for uninitializing the clock module.
|
||||
@@ -81,7 +141,7 @@ void nrf_drv_clock_uninit(void);
|
||||
*
|
||||
* @param[in] p_handler_item A pointer to the event handler structure.
|
||||
*/
|
||||
void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t *p_handler_item);
|
||||
void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t * p_handler_item);
|
||||
|
||||
/**
|
||||
* @brief Function for releasing the LFCLK.
|
||||
@@ -119,7 +179,7 @@ bool nrf_drv_clock_lfclk_is_running(void);
|
||||
*
|
||||
* @param[in] p_handler_item A pointer to the event handler structure.
|
||||
*/
|
||||
void nrf_drv_clock_hfclk_request(nrf_drv_clock_handler_item_t *p_handler_item);
|
||||
void nrf_drv_clock_hfclk_request(nrf_drv_clock_handler_item_t * p_handler_item);
|
||||
|
||||
/**
|
||||
* @brief Function for releasing the high-accuracy source HFCLK.
|
||||
@@ -136,6 +196,88 @@ void nrf_drv_clock_hfclk_release(void);
|
||||
*/
|
||||
bool nrf_drv_clock_hfclk_is_running(void);
|
||||
|
||||
/**
|
||||
* @brief Function for starting a single calibration process.
|
||||
*
|
||||
* This function can also delay the start of calibration by a user-specified value. The delay will use
|
||||
* a low-power timer that is part of the CLOCK module. @ref nrf_drv_clock_is_calibrating can be called to
|
||||
* check if calibration is still in progress. If a handler is provided, the user can be notified when
|
||||
* calibration is completed. The ext calibration can be started from the handler context.
|
||||
*
|
||||
* The calibration process consists of three phases:
|
||||
* - Delay (optional)
|
||||
* - 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.
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief Function for aborting calibration.
|
||||
*
|
||||
* This function aborts on-going calibration. If calibration was started, it cannot be stopped. If a handler
|
||||
* was provided by @ref nrf_drv_clock_calibration_start, this handler will be called once
|
||||
* 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.
|
||||
*/
|
||||
ret_code_t nrf_drv_clock_calibration_abort(void);
|
||||
|
||||
/**
|
||||
* @brief Function for checking if calibration is in progress.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @return Event address.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_drv_clock_ppi_event_addr(nrf_clock_event_t event);
|
||||
/**
|
||||
*@}
|
||||
**/
|
||||
|
||||
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
||||
__STATIC_INLINE uint32_t nrf_drv_clock_ppi_task_addr(nrf_clock_task_t task)
|
||||
{
|
||||
return nrf_clock_task_address_get(task);
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t nrf_drv_clock_ppi_event_addr(nrf_clock_event_t event)
|
||||
{
|
||||
return nrf_clock_event_address_get(event);
|
||||
}
|
||||
#endif //SUPPRESS_INLINE_IMPLEMENTATION
|
||||
|
||||
/*lint --flb "Leave library region" */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,297 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#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"
|
||||
|
||||
#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
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF_DRV_COMMON_H__
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,477 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 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 "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"
|
||||
#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);
|
||||
|
||||
/**
|
||||
* @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 =
|
||||
{
|
||||
.dcdcen = POWER_CONFIG_DEFAULT_DCDCEN,
|
||||
#if NRF_POWER_HAS_VDDH
|
||||
.dcdcenhv = 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;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void nrf_drv_power_uninit(void)
|
||||
{
|
||||
ASSERT(m_initialized);
|
||||
nrf_drv_power_pof_uninit();
|
||||
#if NRF_POWER_HAS_SLEEPEVT
|
||||
nrf_drv_power_sleepevt_uninit();
|
||||
#endif
|
||||
#if NRF_POWER_HAS_USBREG
|
||||
nrf_drv_power_usbevt_uninit();
|
||||
#endif
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
if (nrf_sdh_is_enabled())
|
||||
{
|
||||
/* Currently when SD is enabled - the configuration can be changed
|
||||
* in very limited range.
|
||||
* It is the SoftDevice limitation.
|
||||
*/
|
||||
#if NRF_POWER_HAS_VDDH
|
||||
if (p_config->thrvddh != nrf_power_pofcon_vddh_get())
|
||||
{
|
||||
/* Cannot change THRVDDH with current SD API */
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
#endif
|
||||
if (p_config->thr != nrf_power_pofcon_get(NULL))
|
||||
{
|
||||
/* Only limited number of THR values are supported and
|
||||
* the values taken by SD is different than the one in hardware
|
||||
*/
|
||||
uint8_t thr;
|
||||
switch (p_config->thr)
|
||||
{
|
||||
case NRF_POWER_POFTHR_V21:
|
||||
thr = NRF_POWER_THRESHOLD_V21;
|
||||
break;
|
||||
case NRF_POWER_POFTHR_V23:
|
||||
thr = NRF_POWER_THRESHOLD_V23;
|
||||
break;
|
||||
case NRF_POWER_POFTHR_V25:
|
||||
thr = NRF_POWER_THRESHOLD_V25;
|
||||
break;
|
||||
case NRF_POWER_POFTHR_V27:
|
||||
thr = NRF_POWER_THRESHOLD_V27;
|
||||
break;
|
||||
default:
|
||||
/* Cannot configure */
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
ASSERT(sd_power_pof_threshold_set(thr));
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void nrf_drv_power_pof_uninit(void)
|
||||
{
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
if (nrf_sdh_is_enabled())
|
||||
{
|
||||
(void) sd_power_pof_enable(false);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nrf_power_int_disable(NRF_POWER_INT_POFWARN_MASK);
|
||||
}
|
||||
m_pofwarn_handler = NULL;
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nrf_power_int_enable(enmask);
|
||||
}
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
void nrf_drv_power_sleepevt_uninit(void)
|
||||
{
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
if (nrf_sdh_is_enabled())
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nrf_power_int_disable(
|
||||
NRF_POWER_INT_SLEEPENTER_MASK |
|
||||
NRF_POWER_INT_SLEEPEXIT_MASK);
|
||||
}
|
||||
m_sleepevt_handler = NULL;
|
||||
}
|
||||
#endif /* NRF_POWER_HAS_SLEEPEVT */
|
||||
|
||||
#if NRF_POWER_HAS_USBREG
|
||||
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;
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
if (nrf_sdh_is_enabled())
|
||||
{
|
||||
/** @todo Implement USB power events when SD support it */
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nrf_power_int_enable(
|
||||
NRF_POWER_INT_USBDETECTED_MASK |
|
||||
NRF_POWER_INT_USBREMOVED_MASK |
|
||||
NRF_POWER_INT_USBPWRRDY_MASK);
|
||||
}
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
void nrf_drv_power_usbevt_uninit(void)
|
||||
{
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
if (nrf_sdh_is_enabled())
|
||||
{
|
||||
/** @todo Implement USB power events when SD support it */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nrf_power_int_disable(
|
||||
NRF_POWER_INT_USBDETECTED_MASK |
|
||||
NRF_POWER_INT_USBREMOVED_MASK |
|
||||
NRF_POWER_INT_USBPWRRDY_MASK);
|
||||
}
|
||||
m_usbevt_handler = NULL;
|
||||
}
|
||||
#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);
|
||||
|
||||
NRF_SDH_SOC_OBSERVER(m_soc_observer, POWER_CONFIG_SOC_OBSERVER_PRIO,
|
||||
nrf_drv_power_sdh_soc_evt_handler, NULL);
|
||||
|
||||
NRF_SDH_STATE_OBSERVER(m_sd_observer, POWER_CONFIG_STATE_OBSERVER_PRIO) =
|
||||
{
|
||||
.handler = nrf_drv_power_sdh_state_evt_handler,
|
||||
.p_context = NULL
|
||||
};
|
||||
|
||||
static void nrf_drv_power_sdh_soc_evt_handler(uint32_t evt_id, void * p_context)
|
||||
{
|
||||
if (evt_id == NRF_EVT_POWER_FAILURE_WARNING)
|
||||
{
|
||||
/* Cannot be null if event is enabled */
|
||||
ASSERT(m_pofwarn_handler != NULL);
|
||||
m_pofwarn_handler();
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
(void) sd_power_pof_enable(true);
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
nrf_power_int_enable(NRF_POWER_INT_POFWARN_MASK);
|
||||
}
|
||||
#if NRF_POWER_HAS_USBREG
|
||||
if (m_usbevt_handler != NULL)
|
||||
{
|
||||
nrf_power_int_enable(
|
||||
NRF_POWER_INT_USBDETECTED_MASK |
|
||||
NRF_POWER_INT_USBREMOVED_MASK |
|
||||
NRF_POWER_INT_USBPWRRDY_MASK);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void nrf_drv_power_sdh_state_evt_handler(nrf_sdh_state_evt_t state, void * p_context)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case NRF_SDH_EVT_STATE_ENABLED:
|
||||
nrf_drv_power_on_sd_enable();
|
||||
break;
|
||||
|
||||
case NRF_SDH_EVT_STATE_DISABLED:
|
||||
nrf_drv_power_on_sd_disable();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SOFTDEVICE_PRESENT
|
||||
|
||||
#endif /* NRF_MODULE_ENABLED(POWER) */
|
||||
@@ -0,0 +1,371 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 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_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"
|
||||
|
||||
#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
|
||||
* @{
|
||||
* @ingroup nrf_power
|
||||
* @brief Driver for managing events and the state of POWER peripheral.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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);
|
||||
#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 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 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_clock tries to disable the interrupt.
|
||||
*
|
||||
* @retval true Driver is initialized
|
||||
* @retval false Driver is uninitialized
|
||||
*
|
||||
* @sa nrf_drv_power_uninit
|
||||
*/
|
||||
bool nrf_drv_power_init_check(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize power module driver
|
||||
*
|
||||
* Enabled power module driver would process all the interrupts from power system.
|
||||
*
|
||||
* @param[in] p_config Driver configuration. Can be NULL - the default configuration
|
||||
* from @em sdk_config.h file would be used then.
|
||||
*
|
||||
* @retval NRF_ERROR_INVALID_STATE Power driver has to be enabled
|
||||
* before SoftDevice.
|
||||
* @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED Module is initialized already.
|
||||
* @retval NRF_SUCCESS Successfully initialized.
|
||||
*/
|
||||
ret_code_t nrf_drv_power_init(nrf_drv_power_config_t const * p_config);
|
||||
|
||||
/**
|
||||
* @brief Unintialize power module driver
|
||||
*
|
||||
* Disables all the interrupt handling in the module.
|
||||
*
|
||||
* @sa nrf_drv_power_init
|
||||
*/
|
||||
void nrf_drv_power_uninit(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize power failure comparator
|
||||
*
|
||||
* Configures and setups the power failure comparator and enables it.
|
||||
*
|
||||
* @param[in] p_config Configuration with values and event handler.
|
||||
* If event handler is set to NULL, interrupt would be disabled.
|
||||
*
|
||||
* @retval NRF_ERROR_INVALID_STATE POF is initialized when SD is enabled and
|
||||
* the configuration differs from the old one and
|
||||
* is not possible to be set using SD interface.
|
||||
* @retval NRF_SUCCESS Successfully initialized and configured.
|
||||
*/
|
||||
ret_code_t nrf_drv_power_pof_init(nrf_drv_power_pofwarn_config_t const * p_config);
|
||||
|
||||
/**
|
||||
* @brief Turn off the power failure comparator
|
||||
*
|
||||
* Disables and clears the settings of the power failure comparator.
|
||||
*/
|
||||
void nrf_drv_power_pof_uninit(void);
|
||||
|
||||
#if NRF_POWER_HAS_SLEEPEVT
|
||||
/**
|
||||
* @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 nrf_drv_power_sleepevt_uninit
|
||||
*
|
||||
* @note Sleep events are not available when SoftDevice is enabled.
|
||||
* @note If sleep event is enabled when SoftDevice is initialized, sleep events
|
||||
* would be automatically disabled - it is the limitation of the
|
||||
* SoftDevice itself.
|
||||
*
|
||||
* @retval NRF_ERROR_INVALID_STATE This event cannot be initialized
|
||||
* when SD is enabled.
|
||||
* @retval NRF_SUCCESS Successfully initialized and configured.
|
||||
*/
|
||||
ret_code_t nrf_drv_power_sleepevt_init(nrf_drv_power_sleepevt_config_t const * p_config);
|
||||
|
||||
/**
|
||||
* @brief Uninitialize sleep entering and exiting events processing
|
||||
*
|
||||
* @sa nrf_drv_power_sleepevt_init
|
||||
*/
|
||||
void nrf_drv_power_sleepevt_uninit(void);
|
||||
#endif /* NRF_POWER_HAS_SLEEPEVT */
|
||||
|
||||
#if NRF_POWER_HAS_USBREG
|
||||
/**
|
||||
* @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 nrf_drv_power_usbevt_uninit
|
||||
*
|
||||
* @retval NRF_ERROR_INVALID_STATE This event cannot be initialized
|
||||
* when SD is enabled and SD does not support
|
||||
* USB power events.
|
||||
* @retval NRF_SUCCESS Successfully initialized and configured.
|
||||
*/
|
||||
ret_code_t nrf_drv_power_usbevt_init(nrf_drv_power_usbevt_config_t const * p_config);
|
||||
|
||||
/**
|
||||
* @brief Uninitalize USB power event processing
|
||||
*
|
||||
* @sa nrf_drv_power_usbevt_init
|
||||
*/
|
||||
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 */
|
||||
|
||||
/** @} */
|
||||
|
||||
#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__ */
|
||||
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include "sdk_common.h"
|
||||
#if NRF_MODULE_ENABLED(SYSTICK)
|
||||
#include "nrf_drv_systick.h"
|
||||
#include "nrf_systick.h"
|
||||
#include "nrf.h"
|
||||
#include "nrf_assert.h"
|
||||
|
||||
/**
|
||||
* @brief Maximum number of ticks to delay
|
||||
*
|
||||
* The maximum number of ticks should be much lower than
|
||||
* Physical maximum count of the SysTick timer.
|
||||
* It is dictated by the fact that it would be impossible to detect delay
|
||||
* properly when the timer value warps around the starting point.
|
||||
*/
|
||||
#define NRF_DRV_SYSTICK_TICKS_MAX (NRF_SYSTICK_VAL_MASK / 2UL)
|
||||
|
||||
/**
|
||||
* @brief Number of milliseconds in a second
|
||||
*/
|
||||
#define NRF_DRV_SYSTICK_MS (1000UL)
|
||||
|
||||
/**
|
||||
* @brief Number of microseconds in a second
|
||||
*/
|
||||
#define NRF_DRV_SYSTICK_US (1000UL * NRF_DRV_SYSTICK_MS)
|
||||
|
||||
/**
|
||||
* @brief Number of milliseconds to wait in single loop
|
||||
*
|
||||
* Constant used by @ref nrd_drv_systick_delay_ms function
|
||||
* to split waiting into loops and rest.
|
||||
*
|
||||
* It describes the number of milliseconds to wait in single loop.
|
||||
*
|
||||
* See @ref nrf_drv_systick_delay_ms source code for details.
|
||||
*/
|
||||
#define NRF_DRV_SYSTICK_MS_STEP (64U)
|
||||
|
||||
/**
|
||||
* @brief Checks if the given time is in correct range
|
||||
*
|
||||
* Function tests given time is not to big for this library.
|
||||
* Assertion is used for testing.
|
||||
*
|
||||
* @param us Time in microseconds to check
|
||||
*/
|
||||
#define NRF_DRV_SYSTICK_ASSERT_TIMEOUT(us) \
|
||||
ASSERT(us <= (NRF_DRV_SYSTICK_TICKS_MAX / ((SystemCoreClock) / NRF_DRV_SYSTICK_US)));
|
||||
|
||||
/**
|
||||
* @brief Function that converts microseconds to ticks
|
||||
*
|
||||
* Function converts from microseconds to CPU ticks.
|
||||
*
|
||||
* @param us Number of microseconds
|
||||
*
|
||||
* @return Number of ticks
|
||||
*
|
||||
* @sa nrf_drv_systick_ms_tick
|
||||
*/
|
||||
static inline uint32_t nrf_drv_systick_us_tick(uint32_t us)
|
||||
{
|
||||
return us * ((SystemCoreClock) / NRF_DRV_SYSTICK_US);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function that converts milliseconds to ticks
|
||||
*
|
||||
* Function converts from milliseconds to CPU ticks.
|
||||
*
|
||||
* @param us Number of milliseconds
|
||||
*
|
||||
* @return Number of ticks
|
||||
*
|
||||
* @sa nrf_drv_systick_us_tick
|
||||
*/
|
||||
static inline uint32_t nrf_drv_systick_ms_tick(uint32_t ms)
|
||||
{
|
||||
return ms * ((SystemCoreClock) / NRF_DRV_SYSTICK_MS);
|
||||
}
|
||||
|
||||
void nrf_drv_systick_init(void)
|
||||
{
|
||||
nrf_systick_load_set(NRF_SYSTICK_VAL_MASK);
|
||||
nrf_systick_csr_set(
|
||||
NRF_SYSTICK_CSR_CLKSOURCE_CPU |
|
||||
NRF_SYSTICK_CSR_TICKINT_DISABLE |
|
||||
NRF_SYSTICK_CSR_ENABLE);
|
||||
}
|
||||
|
||||
void nrf_drv_systick_get(nrf_drv_systick_state_t * p_state)
|
||||
{
|
||||
p_state->time = nrf_systick_val_get();
|
||||
}
|
||||
|
||||
bool nrf_drv_systick_test(nrf_drv_systick_state_t const * p_state, uint32_t us)
|
||||
{
|
||||
NRF_DRV_SYSTICK_ASSERT_TIMEOUT(us);
|
||||
|
||||
const uint32_t diff = NRF_SYSTICK_VAL_MASK & ((p_state->time) - nrf_systick_val_get());
|
||||
return (diff >= nrf_drv_systick_us_tick(us));
|
||||
}
|
||||
|
||||
void nrf_drv_systick_delay_ticks(uint32_t ticks)
|
||||
{
|
||||
ASSERT(ticks <= NRF_DRV_SYSTICK_TICKS_MAX)
|
||||
|
||||
const uint32_t start = nrf_systick_val_get();
|
||||
while ((NRF_SYSTICK_VAL_MASK & (start - nrf_systick_val_get())) < ticks)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
}
|
||||
|
||||
void nrf_drv_systick_delay_us(uint32_t us)
|
||||
{
|
||||
NRF_DRV_SYSTICK_ASSERT_TIMEOUT(us);
|
||||
nrf_drv_systick_delay_ticks(nrf_drv_systick_us_tick(us));
|
||||
}
|
||||
|
||||
void nrf_drv_systick_delay_ms(uint32_t ms)
|
||||
{
|
||||
uint32_t n = ms / NRF_DRV_SYSTICK_MS_STEP;
|
||||
uint32_t r = ms % NRF_DRV_SYSTICK_MS_STEP;
|
||||
while (0 != (n--))
|
||||
{
|
||||
nrf_drv_systick_delay_ticks(nrf_drv_systick_ms_tick(NRF_DRV_SYSTICK_MS_STEP));
|
||||
}
|
||||
nrf_drv_systick_delay_ticks(nrf_drv_systick_ms_tick(r));
|
||||
}
|
||||
|
||||
#endif // NRF_MODULE_ENABLED(SYSTICK)
|
||||
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* 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_DRV_SYSTICK_H__
|
||||
#define NRF_DRV_SYSTICK_H__
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @{
|
||||
* @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 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 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);
|
||||
|
||||
|
||||
/** @} */
|
||||
#endif /* NRF_DRV_SYSTICK_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,925 @@
|
||||
/**
|
||||
* 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_DRV_USBD_H__
|
||||
#define NRF_DRV_USBD_H__
|
||||
|
||||
#include "nrf_drv_common.h"
|
||||
#include "sdk_errors.h"
|
||||
#include "nrf_usbd.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "app_util.h"
|
||||
#include "nrf_drv_usbd_errata.h"
|
||||
|
||||
/**
|
||||
* @defgroup nrf_drv_usbd USB Device HAL and driver
|
||||
* @ingroup nrf_drivers
|
||||
* @brief @tagAPI52840 USB Device APIs.
|
||||
* @details The USB Device HAL provides basic APIs for accessing
|
||||
* the registers of the USBD.
|
||||
* The USB Device driver provides APIs on a higher level.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Possible schemes of DMA scheduling
|
||||
*
|
||||
* Definition of available configuration constants used by DMA scheduler
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Highly prioritized access
|
||||
*
|
||||
* Endpoint with lower number has always higher priority and its data would
|
||||
* be transfered first.
|
||||
* OUT endpoints ale processed before IN endpoints
|
||||
*/
|
||||
#define NRF_DRV_USBD_DMASCHEDULER_PRIORITIZED 0
|
||||
|
||||
/**
|
||||
* @brief Round robin scheme
|
||||
*
|
||||
* All endpoints are processed in round-robin scheme.
|
||||
* It means that when one endpoint is processed next in order would be
|
||||
* the nearest with lower number.
|
||||
* When no endpoints with lower number requires processing - then
|
||||
* all endpoints from 0 are tested.
|
||||
*/
|
||||
#define NRF_DRV_USBD_DMASCHEDULER_ROUNDROBIN 1
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Number of bytes in the endpoint
|
||||
*
|
||||
* Constant that informs about endpoint size
|
||||
*/
|
||||
#define NRF_DRV_USBD_EPSIZE 64
|
||||
|
||||
/**
|
||||
* @brief Number of bytes for isochronous endpoints
|
||||
*
|
||||
* Number of bytes for isochronous endpoints in total.
|
||||
* This number would be shared between IN and OUT endpoint.
|
||||
* It may be also assigned totaly to one endpoint.
|
||||
* @sa nrf_usbd_isosplit_set
|
||||
* @sa nrf_usbd_isosplit_get
|
||||
*/
|
||||
#define NRF_DRV_USBD_ISOSIZE 1024
|
||||
|
||||
/**
|
||||
* @brief The size of internal feeder buffer.
|
||||
*
|
||||
* @sa nrf_drv_usbd_feeder_buffer_get
|
||||
*/
|
||||
#define NRF_DRV_USBD_FEEDER_BUFFER_SIZE NRF_DRV_USBD_EPSIZE
|
||||
|
||||
/**
|
||||
* @name Macros for creating endpoint identifiers
|
||||
*
|
||||
* Auxiliary macros to be used to create Endpoint identifier that is compatible
|
||||
* with USB specification.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Create identifier for IN endpoint
|
||||
*
|
||||
* Simple macro to create IN endpoint identifier for given endpoint number.
|
||||
*
|
||||
* @param[in] n Endpoint number.
|
||||
*
|
||||
* @return Endpoint identifier that connects endpoint number and endpoint direction.
|
||||
*/
|
||||
#define NRF_DRV_USBD_EPIN(n) ((nrf_drv_usbd_ep_t)NRF_USBD_EPIN(n))
|
||||
/**
|
||||
* @brief Create identifier for OUT endpoint
|
||||
*
|
||||
* Simple macro to create OUT endpoint identifier for given endpoint number.
|
||||
*
|
||||
* @param[in] n Endpoint number.
|
||||
*
|
||||
* @return Endpoint identifier that connects endpoint number and endpoint direction.
|
||||
*/
|
||||
#define NRF_DRV_USBD_EPOUT(n) ((nrf_drv_usbd_ep_t)NRF_USBD_EPOUT(n))
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Endpoint identifier
|
||||
*
|
||||
* Endpoint identifier used in the driver.
|
||||
* This endpoint number is consistent with USB 2.0 specification.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_DRV_USBD_EPOUT0 = NRF_USBD_EPOUT(0), /**< Endpoint OUT 0 */
|
||||
NRF_DRV_USBD_EPOUT1 = NRF_USBD_EPOUT(1), /**< Endpoint OUT 1 */
|
||||
NRF_DRV_USBD_EPOUT2 = NRF_USBD_EPOUT(2), /**< Endpoint OUT 2 */
|
||||
NRF_DRV_USBD_EPOUT3 = NRF_USBD_EPOUT(3), /**< Endpoint OUT 3 */
|
||||
NRF_DRV_USBD_EPOUT4 = NRF_USBD_EPOUT(4), /**< Endpoint OUT 4 */
|
||||
NRF_DRV_USBD_EPOUT5 = NRF_USBD_EPOUT(5), /**< Endpoint OUT 5 */
|
||||
NRF_DRV_USBD_EPOUT6 = NRF_USBD_EPOUT(6), /**< Endpoint OUT 6 */
|
||||
NRF_DRV_USBD_EPOUT7 = NRF_USBD_EPOUT(7), /**< Endpoint OUT 7 */
|
||||
NRF_DRV_USBD_EPOUT8 = NRF_USBD_EPOUT(8), /**< Endpoint OUT 8 */
|
||||
|
||||
NRF_DRV_USBD_EPIN0 = NRF_USBD_EPIN(0), /**< Endpoint IN 0 */
|
||||
NRF_DRV_USBD_EPIN1 = NRF_USBD_EPIN(1), /**< Endpoint IN 1 */
|
||||
NRF_DRV_USBD_EPIN2 = NRF_USBD_EPIN(2), /**< Endpoint IN 2 */
|
||||
NRF_DRV_USBD_EPIN3 = NRF_USBD_EPIN(3), /**< Endpoint IN 3 */
|
||||
NRF_DRV_USBD_EPIN4 = NRF_USBD_EPIN(4), /**< Endpoint IN 4 */
|
||||
NRF_DRV_USBD_EPIN5 = NRF_USBD_EPIN(5), /**< Endpoint IN 5 */
|
||||
NRF_DRV_USBD_EPIN6 = NRF_USBD_EPIN(6), /**< Endpoint IN 6 */
|
||||
NRF_DRV_USBD_EPIN7 = NRF_USBD_EPIN(7), /**< Endpoint IN 7 */
|
||||
NRF_DRV_USBD_EPIN8 = NRF_USBD_EPIN(8), /**< Endpoint IN 8 */
|
||||
}nrf_drv_usbd_ep_t;
|
||||
|
||||
/**
|
||||
* @brief Events generated by the library
|
||||
*
|
||||
* Enumeration of possible events that may be generated by the library.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_DRV_USBD_EVT_SOF, /**< Start Of Frame event on USB bus detected */
|
||||
NRF_DRV_USBD_EVT_RESET, /**< Reset condition on USB bus detected */
|
||||
NRF_DRV_USBD_EVT_SUSPEND, /**< This device should go to suspend mode now */
|
||||
NRF_DRV_USBD_EVT_RESUME, /**< This device should resume from suspend now */
|
||||
NRF_DRV_USBD_EVT_WUREQ, /**< Wakeup request - the USBD peripheral is ready to generate WAKEUP signal after exiting low power mode. */
|
||||
NRF_DRV_USBD_EVT_SETUP, /**< Setup frame received and decoded */
|
||||
NRF_DRV_USBD_EVT_EPTRANSFER, /**<
|
||||
* For Rx (OUT: Host->Device):
|
||||
* 1. The packet has been received but there is no buffer prepared for transfer already.
|
||||
* 2. Whole transfer has been finished
|
||||
*
|
||||
* For Tx (IN: Device->Host):
|
||||
* The last packet from requested transfer has been transfered over USB bus and acknowledged
|
||||
*/
|
||||
NRF_DRV_USBD_EVT_CNT /**< Number of defined events */
|
||||
}nrf_drv_usbd_event_type_t;
|
||||
|
||||
/**
|
||||
* @brief Possible endpoint error codes
|
||||
*
|
||||
* Error codes that may be returned with @ref NRF_DRV_USBD_EVT_EPTRANSFER
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_USBD_EP_OK, /**< No error */
|
||||
NRF_USBD_EP_WAITING, /**< Data received, no buffer prepared already - waiting for configured transfer */
|
||||
NRF_USBD_EP_OVERLOAD, /**< Received number of bytes cannot fit given buffer
|
||||
* This error would also be returned when next_transfer function has been defined
|
||||
* but currently received data cannot fit completely in current buffer.
|
||||
* No data split from single endpoint transmission is supported.
|
||||
*
|
||||
* When this error is reported - data is left inside endpoint buffer.
|
||||
* Clear endpoint or prepare new buffer and read it.
|
||||
*/
|
||||
NRF_USBD_EP_ABORTED, /**< EP0 transfer can be aborted when new setup comes.
|
||||
* Any other transfer can be aborted by USB reset or library stopping.
|
||||
*/
|
||||
}nrf_drv_usbd_ep_status_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Event structure
|
||||
*
|
||||
* Structure passed to event handler
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
nrf_drv_usbd_event_type_t type;
|
||||
union
|
||||
{
|
||||
struct{
|
||||
uint16_t framecnt; //!< Current value of frame counter
|
||||
}sof; //!< Data aviable for @ref NRF_DRV_USBD_EVT_SOF
|
||||
struct{
|
||||
nrf_drv_usbd_ep_t ep; //!< Endpoint number
|
||||
}isocrc;
|
||||
struct{
|
||||
nrf_drv_usbd_ep_t ep; //!< Endpoint number
|
||||
nrf_drv_usbd_ep_status_t status; //!< Status for the endpoint
|
||||
}eptransfer;
|
||||
}data;
|
||||
}nrf_drv_usbd_evt_t;
|
||||
|
||||
/**
|
||||
* @brief USBD event callback function type.
|
||||
*
|
||||
* @param[in] p_event Event information structure.
|
||||
*/
|
||||
typedef void (*nrf_drv_usbd_event_handler_t)(nrf_drv_usbd_evt_t const * const p_event);
|
||||
|
||||
/**
|
||||
* @brief Universal data pointer.
|
||||
*
|
||||
* Universal data pointer that can be used for any type of transfer.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
void const * tx; //!< Constant TX buffer pointer.
|
||||
void * rx; //!< Writable RX buffer pointer.
|
||||
uint32_t ptr; //!< Numeric value used internally by the library.
|
||||
}nrf_drv_usbd_data_ptr_t;
|
||||
|
||||
/**
|
||||
* @brief Structure to be filled with information about the next transfer.
|
||||
*
|
||||
* This is used mainly for transfer feeders and consumers.
|
||||
* It describes a single endpoint transfer and therefore the size of the buffer
|
||||
* can never be higher than the endpoint size.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
nrf_drv_usbd_data_ptr_t p_data; //!< Union with available data pointers used by the library.
|
||||
size_t size; //!< Size of the requested transfer.
|
||||
}nrf_drv_usbd_ep_transfer_t;
|
||||
|
||||
/**
|
||||
* @brief Flags for the current transfer.
|
||||
*
|
||||
* Flags configured for the transfer that can be merged using the bitwise 'or' operator (|).
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_DRV_USBD_TRANSFER_ZLP_FLAG = 1U << 0, //!< Add a zero-length packet.
|
||||
}nrf_drv_usbd_transfer_flags_t;
|
||||
|
||||
/**
|
||||
* @brief Total transfer configuration.
|
||||
*
|
||||
* This structure is used to configure total transfer information.
|
||||
* It is used by internal built-in feeders and consumers.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
nrf_drv_usbd_data_ptr_t p_data; //!< Union with available data pointers used by the library.
|
||||
size_t size; //!< Total size of the requested transfer.
|
||||
uint32_t flags; //!< Transfer flags.
|
||||
/**< Use the @ref nrf_drv_usbd_transfer_flags_t values. */
|
||||
}nrf_drv_usbd_transfer_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Auxiliary macro for declaring IN transfer description with flags.
|
||||
*
|
||||
* The base macro for creating transfers with any configuration option.
|
||||
*
|
||||
* @param name Instance name.
|
||||
* @param tx_buff Buffer to transfer.
|
||||
* @param tx_size Transfer size.
|
||||
* @param tx_flags Flags for the transfer (see @ref nrf_drv_usbd_transfer_flags_t).
|
||||
*
|
||||
* @return Configured variable with total transfer description.
|
||||
*/
|
||||
#define NRF_DRV_USBD_TRANSFER_IN_FLAGS(name, tx_buff, tx_size, tx_flags) \
|
||||
const nrf_drv_usbd_transfer_t name = { \
|
||||
.p_data = { .tx = (tx_buff) }, \
|
||||
.size = (tx_size), \
|
||||
.flags = (tx_flags) \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper macro for declaring IN transfer description
|
||||
*
|
||||
* Normal transfer mode, no ZLP would be automatically generated.
|
||||
*
|
||||
* @sa nrf_drv_usbd_transfer_t
|
||||
* @sa NRF_DRV_USBD_TRANSFER_IN_ZLP
|
||||
*
|
||||
* @param name Instance name
|
||||
* @param tx_buff Buffer to transfer
|
||||
* @param tx_size Transfer size
|
||||
*
|
||||
* @return Configured variable with total transfer description
|
||||
*
|
||||
*/
|
||||
#define NRF_DRV_USBD_TRANSFER_IN(name, tx_buff, tx_size) \
|
||||
NRF_DRV_USBD_TRANSFER_IN_FLAGS(name, tx_buff, tx_size, 0)
|
||||
|
||||
/**
|
||||
* @brief Helper macro for declaring IN transfer description
|
||||
*
|
||||
* ZLP mode - Zero Length Packet would be generated on the end of the transfer
|
||||
* (always!).
|
||||
*
|
||||
* @sa nrf_drv_usbd_transfer_t
|
||||
* @sa NRF_DRV_USBD_TRANSFER_IN
|
||||
*
|
||||
* @param name Instance name
|
||||
* @param tx_buff Buffer to transfer
|
||||
* @param tx_size Transfer size
|
||||
*
|
||||
* @return Configured variable with total transfer description
|
||||
*/
|
||||
#define NRF_DRV_USBD_TRANSFER_IN_ZLP(name, tx_buff, tx_size) \
|
||||
NRF_DRV_USBD_TRANSFER_IN_FLAGS( \
|
||||
name, \
|
||||
tx_buff, \
|
||||
tx_size, \
|
||||
NRF_DRV_USBD_TRANSFER_ZLP_FLAG)
|
||||
|
||||
/**
|
||||
* @brief Helper macro for declaring OUT transfer item (@ref nrf_drv_usbd_transfer_t)
|
||||
*
|
||||
* @param name Instance name
|
||||
* @param rx_buff Buffer to transfer
|
||||
* @param rx_size Transfer size
|
||||
* */
|
||||
#define NRF_DRV_USBD_TRANSFER_OUT(name, rx_buff, rx_size) \
|
||||
const nrf_drv_usbd_transfer_t name = { \
|
||||
.p_data = { .rx = (rx_buff) }, \
|
||||
.size = (rx_size), \
|
||||
.flags = 0 \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD transfer feeder.
|
||||
*
|
||||
* Pointer for a transfer feeder.
|
||||
* Transfer feeder is a feedback function used to prepare a single
|
||||
* TX (Device->Host) endpoint transfer.
|
||||
*
|
||||
* The transfers provided by the feeder must be simple:
|
||||
* - The size of the transfer provided by this function is limited to a single endpoint buffer.
|
||||
* Bigger transfers are not handled automatically in this case.
|
||||
* - Flash transfers are not automatically supported- you must copy them to the RAM buffer before.
|
||||
*
|
||||
* @note
|
||||
* This function may use @ref nrf_drv_usbd_feeder_buffer_get to gain a temporary buffer
|
||||
* that can be used to prepare transfer.
|
||||
*
|
||||
* @param[out] p_next Structure with the data for the next transfer to be filled.
|
||||
* Required only if the function returns true.
|
||||
* @param[in,out] p_context Context variable configured with the transfer.
|
||||
* @param[in] ep_size The endpoint size.
|
||||
*
|
||||
* @retval false The current transfer is the last one - you do not need to call
|
||||
* the function again.
|
||||
* @retval true There is more data to be prepared and when the current transfer
|
||||
* finishes, the feeder function is expected to be called again.
|
||||
*/
|
||||
typedef bool (*nrf_drv_usbd_feeder_t)(
|
||||
nrf_drv_usbd_ep_transfer_t * p_next,
|
||||
void * p_context,
|
||||
size_t ep_size);
|
||||
|
||||
/**
|
||||
* @brief USBD transfer consumer.
|
||||
*
|
||||
* Pointer for a transfer consumer.
|
||||
* Transfer consumer is a feedback function used to prepare a single
|
||||
* RX (Host->Device) endpoint transfer.
|
||||
*
|
||||
* The transfer must provide a buffer big enough to fit the whole data from the endpoint.
|
||||
* Otherwise, the NRF_USBD_EP_OVERLOAD event is generated.
|
||||
*
|
||||
* @param[out] p_next Structure with the data for the next transfer to be filled.
|
||||
* Required only if the function returns true.
|
||||
* @param[in,out] p_context Context variable configured with the transfer.
|
||||
* @param[in] ep_size The endpoint size.
|
||||
* @param[in] data_size Number of received bytes in the endpoint buffer.
|
||||
*
|
||||
* @retval false Current transfer is the last one - you do not need to call
|
||||
* the function again.
|
||||
* @retval true There is more data to be prepared and when current transfer
|
||||
* finishes, the feeder function is expected to be called again.
|
||||
*/
|
||||
typedef bool (*nrf_drv_usbd_consumer_t)(
|
||||
nrf_drv_usbd_ep_transfer_t * p_next,
|
||||
void * p_context,
|
||||
size_t ep_size,
|
||||
size_t data_size);
|
||||
|
||||
/**
|
||||
* @brief Universal transfer handler.
|
||||
*
|
||||
* Union with feeder and consumer function pointer.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
nrf_drv_usbd_feeder_t feeder; //!< Feeder function pointer.
|
||||
nrf_drv_usbd_consumer_t consumer; //!< Consumer function pointer.
|
||||
}nrf_drv_usbd_handler_t;
|
||||
|
||||
/**
|
||||
* @brief USBD transfer descriptor.
|
||||
*
|
||||
* Universal structure that may hold the setup for callback configuration for
|
||||
* IN or OUT type of the transfer.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
nrf_drv_usbd_handler_t handler; //!< Handler for the current transfer, function pointer.
|
||||
void * p_context; //!< Context for the transfer handler.
|
||||
}nrf_drv_usbd_handler_desc_t;
|
||||
|
||||
/**
|
||||
* @brief Setup packet structure
|
||||
*
|
||||
* Structure that contains interpreted SETUP packet.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bmRequestType; //!< byte 0
|
||||
uint8_t bmRequest; //!< byte 1
|
||||
uint16_t wValue; //!< byte 2
|
||||
uint16_t wIndex; //!< byte 4, 5
|
||||
uint16_t wLength; //!< byte 6, 7
|
||||
}nrf_drv_usbd_setup_t;
|
||||
|
||||
/**
|
||||
* @brief Library initialization
|
||||
*
|
||||
* @param[in] event_handler Event handler provided by the user.
|
||||
*/
|
||||
ret_code_t nrf_drv_usbd_init(nrf_drv_usbd_event_handler_t const event_handler);
|
||||
|
||||
/**
|
||||
* @brief Library deinitialization
|
||||
*/
|
||||
ret_code_t nrf_drv_usbd_uninit(void);
|
||||
|
||||
/**
|
||||
* @brief Enable the USBD port
|
||||
*
|
||||
* After calling this function USBD peripheral would be enabled.
|
||||
* The USB LDO would be enabled.
|
||||
* Enabled USBD peripheral would request HFCLK.
|
||||
* This function does not enable external oscillator, so if it is not enabled by other part of the
|
||||
* program after enabling USBD driver HFINT would be used for the USBD peripheral.
|
||||
* It is perfectly fine until USBD is started. See @ref nrf_drv_usbd_start.
|
||||
*
|
||||
* In normal situation this function should be called in reaction to USBDETECTED
|
||||
* event from POWER peripheral.
|
||||
*
|
||||
* Interrupts and USB pins pull-up would stay disabled until @ref nrf_drv_usbd_start
|
||||
* function is called.
|
||||
*/
|
||||
void nrf_drv_usbd_enable(void);
|
||||
|
||||
/**
|
||||
* @brief Disable the USBD port
|
||||
*
|
||||
* After calling this function USBD peripheral would be disabled.
|
||||
* No events would be detected or processed by the library.
|
||||
* Clock for the peripheral would be disconnected.
|
||||
*/
|
||||
void nrf_drv_usbd_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Start USB functionality
|
||||
*
|
||||
* After calling this function USBD peripheral should be fully functional
|
||||
* and all new incoming events / interrupts would be processed by the library.
|
||||
*
|
||||
* Also only after calling this function host sees new connected device.
|
||||
*
|
||||
* Call this function when USBD power LDO regulator is ready - on USBPWRRDY event
|
||||
* from POWER peripheral.
|
||||
*
|
||||
* Before USBD interrupts are enabled, external HFXO is requested.
|
||||
*
|
||||
* @param enable_sof The flag that is used to enable SOF processing.
|
||||
* If it is false, SOF interrupt is left disabled and will not be generated.
|
||||
* This improves power saving if SOF is not required.
|
||||
*
|
||||
* @note If the isochronous endpoints are going to be used,
|
||||
* it is required to enable the SOF.
|
||||
* In other case any isochronous endpoint would stay busy
|
||||
* after first transmission.
|
||||
*/
|
||||
void nrf_drv_usbd_start(bool enable_sof);
|
||||
|
||||
/**
|
||||
* @brief Stop USB functionality
|
||||
*
|
||||
* This function disables USBD pull-up and interrupts.
|
||||
*
|
||||
* The HFXO request is released in this function.
|
||||
*
|
||||
* @note
|
||||
* This function can also be used to logically disconnect USB from the HOST that
|
||||
* would force it to enumerate device after calling @ref nrf_drv_usbd_start.
|
||||
*/
|
||||
void nrf_drv_usbd_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Check if driver is initialized
|
||||
*
|
||||
* @retval false Driver is not initialized
|
||||
* @retval true Driver is initialized
|
||||
*/
|
||||
bool nrf_drv_usbd_is_initialized(void);
|
||||
|
||||
/**
|
||||
* @brief Check if driver is enabled
|
||||
*
|
||||
* @retval false Driver is disabled
|
||||
* @retval true Driver is enabled
|
||||
*/
|
||||
bool nrf_drv_usbd_is_enabled(void);
|
||||
|
||||
/**
|
||||
* @brief Check if driver is started
|
||||
*
|
||||
* @retval false Driver is not started
|
||||
* @retval true Driver is started (fully functional)
|
||||
* @note The USBD peripheral interrupt state is checked
|
||||
*/
|
||||
bool nrf_drv_usbd_is_started(void);
|
||||
|
||||
/**
|
||||
* @brief Suspend USBD operation
|
||||
*
|
||||
* The USBD peripheral is forced to go into the low power mode.
|
||||
* The function has to be called in the reaction to @ref NRF_DRV_USBD_EVT_SUSPEND event
|
||||
* when the firmware is ready.
|
||||
*
|
||||
* After successful call of this function most of the USBD registers would be unavailable.
|
||||
*
|
||||
* @note Check returned value for the feedback if suspending was successful.
|
||||
*
|
||||
* @retval true USBD peripheral successfully suspended
|
||||
* @retval false USBD peripheral was not suspended due to resume detection.
|
||||
*
|
||||
*/
|
||||
bool nrf_drv_usbd_suspend(void);
|
||||
|
||||
/**
|
||||
* @brief Start wake up procedure
|
||||
*
|
||||
* The USBD peripheral is forced to quit the low power mode.
|
||||
* After calling this function all the USBD registers would be available.
|
||||
*
|
||||
* The hardware starts measuring time when wake up is possible.
|
||||
* This may take 0-5 ms depending on how long the SUSPEND state was kept on the USB line.
|
||||
|
||||
* When NRF_DRV_USBD_EVT_WUREQ event is generated it means that Wake Up signaling has just been
|
||||
* started on the USB lines.
|
||||
*
|
||||
* @note Do not expect only @ref NRF_DRV_USBD_EVT_WUREQ event.
|
||||
* There always may appear @ref NRF_DRV_USBD_EVT_RESUME event.
|
||||
* @note NRF_DRV_USBD_EVT_WUREQ event means that Remote WakeUp signal
|
||||
* has just begun to be generated.
|
||||
* This may take up to 20 ms for the bus to become active.
|
||||
*
|
||||
* @retval true WakeUp procedure started.
|
||||
* @retval false No WakeUp procedure started - bus is already active.
|
||||
*/
|
||||
bool nrf_drv_usbd_wakeup_req(void);
|
||||
|
||||
/**
|
||||
* @brief Check if USBD is in SUSPEND mode
|
||||
*
|
||||
* @note This is the information about peripheral itself, not about the bus state.
|
||||
*
|
||||
* @retval true USBD peripheral is suspended
|
||||
* @retval false USBD peripheral is active
|
||||
*/
|
||||
bool nrf_drv_usbd_suspend_check(void);
|
||||
|
||||
/**
|
||||
* @brief Enable only interrupts that should be processed in SUSPEND mode
|
||||
*
|
||||
* Auxiliary function to help with SUSPEND mode integration.
|
||||
* It enables only the interrupts that can be properly processed without stable HFCLK.
|
||||
*
|
||||
* Normally all the interrupts are enabled.
|
||||
* Use this function to suspend interrupt processing that may require stable HFCLK until the
|
||||
* clock is enabled.
|
||||
*
|
||||
* @sa nrf_drv_usbd_active_irq_config
|
||||
*/
|
||||
void nrf_drv_usbd_suspend_irq_config(void);
|
||||
|
||||
/**
|
||||
* @brief Default active interrupt configuration
|
||||
*
|
||||
* Default interrupt configuration.
|
||||
* Use in a pair with @ref nrf_drv_usbd_active_irq_config.
|
||||
*
|
||||
* @sa nrf_drv_usbd_suspend_irq_config
|
||||
*/
|
||||
void nrf_drv_usbd_active_irq_config(void);
|
||||
|
||||
/**
|
||||
* @brief Check the bus state
|
||||
*
|
||||
* This function checks if the bus state is suspended
|
||||
*
|
||||
* @note The value returned by this function changes on SUSPEND and RESUME event processing.
|
||||
*
|
||||
* @retval true USBD bus is suspended
|
||||
* @retval false USBD bus is active
|
||||
*/
|
||||
bool nrf_drv_usbd_bus_suspend_check(void);
|
||||
|
||||
/**
|
||||
* @brief Configure packet size that should be supported by the endpoint
|
||||
*
|
||||
* The real endpoint buffer size is always the same.
|
||||
* This value sets max packet size that would be transmitted over the endpoint.
|
||||
* This is required by the library
|
||||
*
|
||||
* @param[in] ep Endpoint number
|
||||
* @param[in] size Required maximum packet size
|
||||
*
|
||||
* @note Endpoint size is always set to @ref NRF_DRV_USBD_EPSIZE or @ref NRF_DRV_USBD_ISOSIZE / 2
|
||||
* when @ref nrf_drv_usbd_ep_enable function is called.
|
||||
*/
|
||||
void nrf_drv_usbd_ep_max_packet_size_set(nrf_drv_usbd_ep_t ep, uint16_t size);
|
||||
|
||||
/**
|
||||
* @brief Get configured endpoint packet size
|
||||
*
|
||||
* Function to get configured endpoint size on the buffer.
|
||||
*
|
||||
* @param[in] ep Endpoint number
|
||||
*
|
||||
* @return Maximum pocket size configured on selected endpoint
|
||||
*/
|
||||
uint16_t nrf_drv_usbd_ep_max_packet_size_get(nrf_drv_usbd_ep_t ep);
|
||||
|
||||
/**
|
||||
* @brief Check if the selected endpoint is enabled.
|
||||
*
|
||||
* @param ep Endpoint number to check.
|
||||
*
|
||||
* @retval true Endpoint is enabled.
|
||||
* @retval false Endpoint is disabled.
|
||||
*/
|
||||
bool nrf_drv_usbd_ep_enable_check(nrf_drv_usbd_ep_t ep);
|
||||
|
||||
/**
|
||||
* @brief Enable selected endpoint
|
||||
*
|
||||
* This function enables endpoint itself and its interrupts.
|
||||
* @param ep Endpoint number to enable
|
||||
*
|
||||
* @note
|
||||
* Max packet size is set to endpoint default maximum value.
|
||||
*
|
||||
* @sa nrf_drv_usbd_ep_max_packet_size_set
|
||||
*/
|
||||
void nrf_drv_usbd_ep_enable(nrf_drv_usbd_ep_t ep);
|
||||
|
||||
/**
|
||||
* @brief Disable selected endpoint
|
||||
*
|
||||
* This function disables endpoint itself and its interrupts.
|
||||
* @param ep Endpoint number to disable
|
||||
*/
|
||||
void nrf_drv_usbd_ep_disable(nrf_drv_usbd_ep_t ep);
|
||||
|
||||
/**
|
||||
* @brief Start sending data over endpoint
|
||||
*
|
||||
* Function initializes endpoint transmission.
|
||||
* This is asynchronous function - it finishes immediately after configuration
|
||||
* for transmission is prepared.
|
||||
*
|
||||
* @note Data buffer pointed by p_data have to be kept active till
|
||||
* @ref NRF_DRV_USBD_EVT_EPTRANSFER event is generated.
|
||||
*
|
||||
* @param[in] ep Endpoint number.
|
||||
* For IN endpoint sending would be initiated.
|
||||
* For OUT endpoint receiving would be initiated.
|
||||
* @param[in] p_transfer
|
||||
*
|
||||
* @retval NRF_ERROR_BUSY Selected endpoint is pending.
|
||||
* @retval NRF_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0.
|
||||
* @retval NRF_ERROR_FORBIDDEN Endpoint stalled.
|
||||
* @retval NRF_SUCCESS Transfer queued or started.
|
||||
*/
|
||||
ret_code_t nrf_drv_usbd_ep_transfer(
|
||||
nrf_drv_usbd_ep_t ep,
|
||||
nrf_drv_usbd_transfer_t const * const p_transfer);
|
||||
|
||||
/**
|
||||
* @brief Start sending data over the endpoint using the transfer handler function.
|
||||
*
|
||||
* This function initializes an endpoint transmission.
|
||||
* Just before data is transmitted, the transfer handler
|
||||
* is called and it prepares a data chunk.
|
||||
*
|
||||
* @param[in] ep Endpoint number.
|
||||
* For an IN endpoint, sending is initiated.
|
||||
* For an OUT endpoint, receiving is initiated.
|
||||
* @param p_handler Transfer handler - feeder for IN direction and consumer for
|
||||
* OUT direction.
|
||||
*
|
||||
* @retval NRF_ERROR_BUSY Selected endpoint is pending.
|
||||
* @retval NRF_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0.
|
||||
* @retval NRF_ERROR_FORBIDDEN Endpoint stalled.
|
||||
* @retval NRF_SUCCESS Transfer queued or started.
|
||||
*/
|
||||
ret_code_t nrf_drv_usbd_ep_handled_transfer(
|
||||
nrf_drv_usbd_ep_t ep,
|
||||
nrf_drv_usbd_handler_desc_t const * const p_handler);
|
||||
|
||||
/**
|
||||
* @brief Get the temporary buffer to be used by the feeder.
|
||||
*
|
||||
* This buffer is used for TX transfers and it can be reused automatically
|
||||
* when the transfer is finished.
|
||||
* Use it for transfer preparation.
|
||||
*
|
||||
* May be used inside the feeder configured in @ref nrf_drv_usbd_ep_handled_transfer.
|
||||
*
|
||||
* @return Pointer to the buffer that can be used temporarily.
|
||||
*
|
||||
* @sa NRF_DRV_USBD_FEEDER_BUFFER_SIZE
|
||||
*/
|
||||
void * nrf_drv_usbd_feeder_buffer_get(void);
|
||||
|
||||
/**
|
||||
* @brief Get the information about last finished or current transfer
|
||||
*
|
||||
* Function returns the status of the last buffer set for transfer on selected endpoint.
|
||||
* The status considers last buffer set by @ref nrf_drv_usbd_ep_transfer function or
|
||||
* by transfer callback function.
|
||||
*
|
||||
* @param[in] ep Endpoint number.
|
||||
* @param[out] p_size Information about the current/last transfer size.
|
||||
*
|
||||
* @retval NRF_SUCCESS Transfer already finished
|
||||
* @retval NRF_ERROR_BUSY Ongoing transfer
|
||||
* @retval NRF_ERROR_DATA_SIZE Too much of data received that cannot fit into buffer and cannot be splited into chunks.
|
||||
* This may happen if buffer size is not a multiplication of endpoint buffer size.
|
||||
*/
|
||||
ret_code_t nrf_drv_usbd_ep_status_get(nrf_drv_usbd_ep_t ep, size_t * p_size);
|
||||
|
||||
/**
|
||||
* @brief Get number of received bytes
|
||||
*
|
||||
* Get the number of received bytes.
|
||||
* The function behavior is undefined when called on IN endpoint.
|
||||
*
|
||||
* @param ep Endpoint number.
|
||||
*
|
||||
* @return Number of received bytes
|
||||
*/
|
||||
size_t nrf_drv_usbd_epout_size_get(nrf_drv_usbd_ep_t ep);
|
||||
|
||||
/**
|
||||
* @brief Check if endpoint buffer is ready or is under USB IP control
|
||||
*
|
||||
* Function to test if endpoint is busy.
|
||||
* Endpoint that is busy cannot be accessed by MCU.
|
||||
* It means that:
|
||||
* - OUT (TX) endpoint: Last uploaded data is still in endpoint and is waiting
|
||||
* to be received by the host.
|
||||
* - IN (RX) endpoint: Endpoint is ready to receive data from the host
|
||||
* and the endpoint does not have any data.
|
||||
* When endpoint is not busy:
|
||||
* - OUT (TX) endpoint: New data can be uploaded.
|
||||
* - IN (RX) endpoint: New data can be downloaded using @ref nrf_drv_usbd_ep_transfer
|
||||
* function.
|
||||
*/
|
||||
bool nrf_drv_usbd_ep_is_busy(nrf_drv_usbd_ep_t ep);
|
||||
|
||||
/**
|
||||
* @brief Stall endpoint
|
||||
*
|
||||
* Stall endpoit to send error information during next transfer request from
|
||||
* the host.
|
||||
*
|
||||
* @note To stall endpoint it is safer to use @ref nrf_drv_usbd_setup_stall
|
||||
* @note Stalled endpoint would not be cleared when DMA transfer finishes.
|
||||
*
|
||||
* @param ep Endpoint number to stall
|
||||
*
|
||||
*/
|
||||
void nrf_drv_usbd_ep_stall(nrf_drv_usbd_ep_t ep);
|
||||
|
||||
/**
|
||||
* @brief Clear stall flag on endpoint
|
||||
*
|
||||
* This function clears endpoint that is stalled.
|
||||
* @note
|
||||
* If it is OUT endpoint (receiving) it would be also prepared for reception.
|
||||
* It means that busy flag would be set.
|
||||
* @note
|
||||
* In endpoint (transmitting) would not be cleared - it gives possibility to
|
||||
* write new data before transmitting.
|
||||
*/
|
||||
void nrf_drv_usbd_ep_stall_clear(nrf_drv_usbd_ep_t ep);
|
||||
|
||||
/**
|
||||
* @brief Check if endpoint is stalled
|
||||
*
|
||||
* This function gets stall state of selected endpoint
|
||||
*
|
||||
* @param ep Endpoint number to check
|
||||
*/
|
||||
bool nrf_drv_usbd_ep_stall_check(nrf_drv_usbd_ep_t ep);
|
||||
|
||||
/**
|
||||
* @brief Get parsed setup data
|
||||
*
|
||||
* Function fills the parsed setup data structure.
|
||||
*
|
||||
* @param[out] p_setup Pointer to data structure that would be filled by
|
||||
* parsed data.
|
||||
*/
|
||||
void nrf_drv_usbd_setup_get(nrf_drv_usbd_setup_t * const p_setup);
|
||||
|
||||
/**
|
||||
* @brief Clear only for data transmission on setup endpoint
|
||||
*
|
||||
* This function may be called if any more data in control write transfer is expected.
|
||||
* Clears only OUT endpoint to be able to take another OUT data token.
|
||||
* It does not allow STATUS stage.
|
||||
* @sa nrf_drv_usbd_setup_clear
|
||||
*/
|
||||
void nrf_drv_usbd_setup_data_clear(void);
|
||||
|
||||
/**
|
||||
* @brief Clear setup endpoint
|
||||
*
|
||||
* This function acknowledges setup when SETUP command was received and processed.
|
||||
* It has to be called if no data respond for the SETUP command is sent.
|
||||
*
|
||||
* When there is any data transmission after SETUP command the data transmission
|
||||
* itself would clear the endpoint.
|
||||
*/
|
||||
void nrf_drv_usbd_setup_clear(void);
|
||||
|
||||
/**
|
||||
* @brief Stall setup endpoint
|
||||
*
|
||||
* Mark and error on setup endpoint.
|
||||
*/
|
||||
void nrf_drv_usbd_setup_stall(void);
|
||||
|
||||
/**
|
||||
* @note
|
||||
* This function locks interrupts that may be costly.
|
||||
* It is good idea to test if the endpoint is still busy before calling this function:
|
||||
* @code
|
||||
(m_ep_dma_waiting & (1U << ep2bit(ep)))
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief Get the information about expected transfer SETUP data direction
|
||||
*
|
||||
* Function returns the information about last expected transfer direction.
|
||||
*
|
||||
* @retval NRF_DRV_USBD_EPOUT0 Expecting OUT (Host->Device) direction or no data
|
||||
* @retval NRF_DRV_USBD_EPIN0 Expecting IN (Device->Host) direction
|
||||
*/
|
||||
nrf_drv_usbd_ep_t nrf_drv_usbd_last_setup_dir_get(void);
|
||||
|
||||
/**
|
||||
* @brief Drop transfer on OUT endpoint
|
||||
*
|
||||
* @param[in] ep OUT endpoint ID
|
||||
*/
|
||||
void nrf_drv_usbd_transfer_out_drop(nrf_drv_usbd_ep_t ep);
|
||||
|
||||
/** @} */
|
||||
#endif /* NRF_DRV_USBD_H__ */
|
||||
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 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_DRV_USBD_ERRATA_H__
|
||||
#define NRF_DRV_USBD_ERRATA_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
/**
|
||||
* @defgroup nrf_drv_usbd_errata Functions to check if selected PAN is present in current chip
|
||||
* @{
|
||||
* @ingroup nrf_drv_usbd
|
||||
*
|
||||
* Functions here are checking the presence of an error in current chip.
|
||||
* The checking is done at runtime based on the microcontroller version.
|
||||
* This file is subject to removal when nRF51840 prototype support is removed.
|
||||
*/
|
||||
|
||||
#ifndef NRF_DRV_USBD_ERRATA_ENABLE
|
||||
/**
|
||||
* @brief The constant that informs if errata should be enabled at all
|
||||
*
|
||||
* If this constant is set to 0, all the Errata bug fixes will be automatically disabled.
|
||||
*/
|
||||
#define NRF_DRV_USBD_ERRATA_ENABLE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Function to check if chip requires errata 104
|
||||
*
|
||||
* Errata: USBD: EPDATA event is not always generated.
|
||||
*
|
||||
* @retval true Errata should be implemented
|
||||
* @retval false Errata should not be implemented
|
||||
*/
|
||||
static inline bool nrf_drv_usbd_errata_104(void);
|
||||
|
||||
/**
|
||||
* @brief Function to check if chip requires errata 154
|
||||
*
|
||||
* Errata: During setup read/write transfer USBD acknowledges setup stage without SETUP task.
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
|
||||
static inline bool nrf_drv_usbd_errata_166(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#else /* NRF_DRV_USBD_ERRATA_ENABLE */
|
||||
|
||||
static inline bool nrf_drv_usbd_errata_104(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool nrf_drv_usbd_errata_154(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool nrf_drv_usbd_errata_166(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* NRF_DRV_USBD_ERRATA_ENABLE */
|
||||
/** @} */
|
||||
#endif /* NRF_DRV_USBD_ERRATA_H__ */
|
||||
+1065
File diff suppressed because it is too large
Load Diff
+184
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* 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_SYSTICK_H__
|
||||
#define NRF_SYSTICK_H__
|
||||
|
||||
#include "nrf.h"
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @defgroup nrf_systick_hal SYSTICK HAL
|
||||
* @{
|
||||
* @ingroup nrf_systick
|
||||
*
|
||||
* @brief Hardware access layer for accessing the SYSTICK peripheral.
|
||||
*
|
||||
* SYSTICK is ARM peripheral, not Nordic design.
|
||||
* It means that it has no Nordic-typical interface with Tasks and Events.
|
||||
*
|
||||
* Its usage is limited here to implement simple delays.
|
||||
* Also keep in mind that this timer would be stopped when CPU is sleeping
|
||||
* (WFE/WFI instruction is successfully executed).
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Mask of usable bits in the SysTick value
|
||||
*/
|
||||
#define NRF_SYSTICK_VAL_MASK SysTick_VAL_CURRENT_Msk
|
||||
|
||||
/**
|
||||
* @brief Flags used by SysTick configuration.
|
||||
*
|
||||
* @sa nrf_systick_csr_set
|
||||
* @sa nrf_systick_csr_get
|
||||
*/
|
||||
typedef enum {
|
||||
NRF_SYSTICK_CSR_COUNTFLAG_MASK = SysTick_CTRL_COUNTFLAG_Msk, /**< Status flag: Returns 1 if timer counted to 0 since the last read of this register. */
|
||||
|
||||
NRF_SYSTICK_CSR_CLKSOURCE_MASK = SysTick_CTRL_CLKSOURCE_Msk, /**< Configuration bit: Select the SysTick clock source. */
|
||||
NRF_SYSTICK_CSR_CLKSOURCE_REF = 0U << SysTick_CTRL_CLKSOURCE_Pos, /**< Configuration value: Select reference clock. */
|
||||
NRF_SYSTICK_CSR_CLKSOURCE_CPU = 1U << SysTick_CTRL_CLKSOURCE_Pos, /**< Configuration value: Select CPU clock. */
|
||||
|
||||
NRF_SYSTICK_CSR_TICKINT_MASK = SysTick_CTRL_TICKINT_Msk, /**< Configuration bit: Enables SysTick exception request. */
|
||||
NRF_SYSTICK_CSR_TICKINT_ENABLE = 1U << SysTick_CTRL_TICKINT_Pos, /**< Configuration value: Counting down to zero does not assert the SysTick exception request. */
|
||||
NRF_SYSTICK_CSR_TICKINT_DISABLE = 0U << SysTick_CTRL_TICKINT_Pos, /**< Configuration value: Counting down to zero to asserts the SysTick exception request. */
|
||||
|
||||
NRF_SYSTICK_CSR_ENABLE_MASK = SysTick_CTRL_ENABLE_Msk, /**< Configuration bit: Enable the SysTick timer. */
|
||||
NRF_SYSTICK_CSR_ENABLE = 1U << SysTick_CTRL_ENABLE_Pos, /**< Configuration value: Counter enabled. */
|
||||
NRF_SYSTICK_CSR_DISABLE = 0U << SysTick_CTRL_ENABLE_Pos /**< Configuration value: Counter disabled. */
|
||||
} nrf_systick_csr_flags_t;
|
||||
|
||||
/**
|
||||
* @brief Get Configuration and Status Register
|
||||
*
|
||||
* @return Values composed by @ref nrf_systick_csr_flags_t.
|
||||
* @note The @ref NRF_SYSTICK_CSR_COUNTFLAG_MASK value is cleared when CSR register is read.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_systick_csr_get(void);
|
||||
|
||||
/**
|
||||
* @brief Set Configuration and Status Register
|
||||
*
|
||||
* @param[in] val The value composed from @ref nrf_systick_csr_flags_t.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_systick_csr_set(uint32_t val);
|
||||
|
||||
/**
|
||||
* @brief Get the current reload value.
|
||||
*
|
||||
* @return The reload register value.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_systick_load_get(void);
|
||||
|
||||
/**
|
||||
* @brief Configure the reload value.
|
||||
*
|
||||
* @param[in] val The value to set in the reload register.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_systick_load_set(uint32_t val);
|
||||
|
||||
/**
|
||||
* @brief Read the SysTick current value
|
||||
*
|
||||
* @return The current SysTick value
|
||||
* @sa NRF_SYSTICK_VAL_MASK
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_systick_val_get(void);
|
||||
|
||||
/**
|
||||
* @brief Clear the SysTick current value
|
||||
*
|
||||
* @note The SysTick does not allow setting current value.
|
||||
* Any write to VAL register would clear the timer.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_systick_val_clear(void);
|
||||
|
||||
/**
|
||||
* @brief Read the calibration register
|
||||
*
|
||||
* @return The calibration register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_systick_calib_get(void);
|
||||
|
||||
|
||||
|
||||
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
||||
|
||||
__STATIC_INLINE uint32_t nrf_systick_csr_get(void)
|
||||
{
|
||||
return SysTick->CTRL;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void nrf_systick_csr_set(uint32_t val)
|
||||
{
|
||||
SysTick->CTRL = val;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t nrf_systick_load_get(void)
|
||||
{
|
||||
return SysTick->LOAD;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void nrf_systick_load_set(uint32_t val)
|
||||
{
|
||||
SysTick->LOAD = val;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t nrf_systick_val_get(void)
|
||||
{
|
||||
return SysTick->VAL;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void nrf_systick_val_clear(void)
|
||||
{
|
||||
SysTick->VAL = 0;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t nrf_systick_calib_get(void)
|
||||
{
|
||||
return SysTick->CALIB;
|
||||
}
|
||||
|
||||
#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
|
||||
|
||||
/** @} */
|
||||
#endif /* NRF_SYSTICK_H__ */
|
||||
+1422
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "app_util.h"
|
||||
#include "nrf_atfifo.h"
|
||||
#include "nrf_atfifo_internal.h"
|
||||
|
||||
|
||||
/* Unions testing */
|
||||
STATIC_ASSERT(sizeof(nrf_atfifo_postag_t) == sizeof(uint32_t));
|
||||
|
||||
|
||||
ret_code_t nrf_atfifo_init(nrf_atfifo_t * const p_fifo, void * p_buf, uint16_t buf_size, uint16_t item_size)
|
||||
{
|
||||
if (NULL == p_buf)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
if (0 != (buf_size % item_size))
|
||||
{
|
||||
return NRF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
p_fifo->p_buf = p_buf;
|
||||
p_fifo->tail.tag = 0;
|
||||
p_fifo->head.tag = 0;
|
||||
p_fifo->buf_size = buf_size;
|
||||
p_fifo->item_size = item_size;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ret_code_t nrf_atfifo_clear(nrf_atfifo_t * const p_fifo)
|
||||
{
|
||||
bool released = nrf_atfifo_space_clear(p_fifo);
|
||||
return released ? NRF_SUCCESS : NRF_ERROR_BUSY;
|
||||
}
|
||||
|
||||
|
||||
ret_code_t nrf_atfifo_alloc_put(nrf_atfifo_t * const p_fifo, void const * p_var, size_t size, bool * const p_visible)
|
||||
{
|
||||
nrf_atfifo_item_put_t context;
|
||||
bool visible;
|
||||
void * p_data = nrf_atfifo_item_alloc(p_fifo, &context);
|
||||
if (NULL == p_data)
|
||||
{
|
||||
return NRF_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
memcpy(p_data, p_var, size);
|
||||
|
||||
visible = nrf_atfifo_item_put(p_fifo, &context);
|
||||
if (NULL != p_visible)
|
||||
{
|
||||
*p_visible = visible;
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void * nrf_atfifo_item_alloc(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t * p_context)
|
||||
{
|
||||
if (nrf_atfifo_wspace_req(p_fifo, &(p_context->last_tail)))
|
||||
{
|
||||
return ((uint8_t*)(p_fifo->p_buf)) + p_context->last_tail.pos.wr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool nrf_atfifo_item_put(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t * p_context)
|
||||
{
|
||||
if ((p_context->last_tail.pos.wr) == (p_context->last_tail.pos.rd))
|
||||
{
|
||||
nrf_atfifo_wspace_close(p_fifo);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ret_code_t nrf_atfifo_get_free(nrf_atfifo_t * const p_fifo, void * const p_var, size_t size, bool * p_released)
|
||||
{
|
||||
nrf_atfifo_item_get_t context;
|
||||
bool released;
|
||||
void const * p_s = nrf_atfifo_item_get(p_fifo, &context);
|
||||
if (NULL == p_s)
|
||||
{
|
||||
return NRF_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
memcpy(p_var, p_s, size);
|
||||
|
||||
released = nrf_atfifo_item_free(p_fifo, &context);
|
||||
if (NULL != p_released)
|
||||
{
|
||||
*p_released = released;
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void const * 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;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool nrf_atfifo_item_free(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context)
|
||||
{
|
||||
if ((p_context->last_head.pos.wr) == (p_context->last_head.pos.rd))
|
||||
{
|
||||
nrf_atfifo_rspace_close(p_fifo);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
/**
|
||||
* 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_ATFIFO_H__
|
||||
#define NRF_ATFIFO_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nordic_common.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "sdk_errors.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup nrf_atfifo Atomic FIFO
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief @tagAPI52 FIFO implementation that allows for making atomic transactions without
|
||||
* locking interrupts.
|
||||
*
|
||||
* @details There are two types of functions to prepare the FIFO writing:
|
||||
* - Single function for simple access:
|
||||
* @code
|
||||
* if (NRF_SUCCESS != nrf_atfifo_simple_put(my_fifo, &data, NULL))
|
||||
* {
|
||||
* // Error handling
|
||||
* }
|
||||
* @endcode
|
||||
* - Function pair to limit data copying:
|
||||
* @code
|
||||
* struct point3d
|
||||
* {
|
||||
* int x, y, z;
|
||||
* }point3d_t;
|
||||
* nrf_atfifo_context_t context;
|
||||
* point3d_t * point;
|
||||
*
|
||||
* if (NULL != (point = nrf_atfifo_item_alloc(my_fifo, &context)))
|
||||
* {
|
||||
* point->x = a;
|
||||
* point->y = b;
|
||||
* point->z = c;
|
||||
* if (nrf_atfifo_item_put(my_fifo, &context))
|
||||
* {
|
||||
* // Send information to the rest of the system
|
||||
* // that there is new data in the FIFO available for reading.
|
||||
* }
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // Error handling
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
* @note
|
||||
* This atomic FIFO implementation requires that the operation that is
|
||||
* opened last is finished (committed/flushed) first.
|
||||
* This is typical for operations performed from the interrupt runtime
|
||||
* when the other operation is performed from the main thread.
|
||||
*
|
||||
* This implementation does not support typical multithreading operating system
|
||||
* access where operations can be started and finished in totally unrelated order.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Read and write position structure.
|
||||
*
|
||||
* A structure that holds the read and write position used by the FIFO head and tail.
|
||||
*/
|
||||
typedef struct nrf_atfifo_postag_pos_s
|
||||
{
|
||||
uint16_t wr; //!< First free space to write the data
|
||||
uint16_t rd; //!< A place after the last data to read
|
||||
}nrf_atfifo_postag_pos_t;
|
||||
|
||||
/**
|
||||
* @brief End data index tag.
|
||||
*
|
||||
* A tag used to mark the end of data.
|
||||
* To properly realize atomic data committing, the whole variable has to be
|
||||
* accessed atomically.
|
||||
*/
|
||||
typedef union nrf_atfifo_postag_u
|
||||
{
|
||||
uint32_t tag; //!< Whole tag, used for atomic, 32-bit access
|
||||
nrf_atfifo_postag_pos_t pos; //!< Structure that holds reading and writing position separately
|
||||
}nrf_atfifo_postag_t;
|
||||
|
||||
/**
|
||||
* @brief The FIFO instance.
|
||||
*
|
||||
* The instance of atomic FIFO.
|
||||
* Used with all FIFO functions.
|
||||
*/
|
||||
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
|
||||
}nrf_atfifo_t;
|
||||
|
||||
/**
|
||||
* @brief FIFO write operation item context.
|
||||
*
|
||||
* Context structure used to mark an allocated space in FIFO that is ready for put.
|
||||
* All the data required to properly put allocated and written data.
|
||||
*/
|
||||
typedef struct nrf_atfifo_item_put_s
|
||||
{
|
||||
nrf_atfifo_postag_t last_tail; //!< Tail tag value that was here when opening the FIFO to write
|
||||
}nrf_atfifo_item_put_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief FIFO read operation item context.
|
||||
*
|
||||
* Context structure used to mark an opened get operation to properly free an item after reading.
|
||||
*/
|
||||
typedef struct nrf_atfifo_rcontext_s
|
||||
{
|
||||
nrf_atfifo_postag_t last_head; //!< Head tag value that was here when opening the FIFO to read
|
||||
}nrf_atfifo_item_get_t;
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup nrf_atfifo_instmacros FIFO instance macros
|
||||
*
|
||||
* A group of macros helpful for FIFO instance creation and initialization.
|
||||
* They may be used to create and initialize instances for most use cases.
|
||||
*
|
||||
* FIFO may also be created and initialized directly using
|
||||
* @ref nrf_atfifo_init function.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Macro for generating the name for a data buffer.
|
||||
*
|
||||
* The name of the data buffer that would be created by
|
||||
* @ref NRF_ATFIFO_DEF macro.
|
||||
*
|
||||
* @param[in] fifo_id Identifier of the FIFO object.
|
||||
*
|
||||
* @return Name of the buffer variable.
|
||||
*
|
||||
* @note This is auxiliary internal macro and in normal usage
|
||||
* it should not be called.
|
||||
*/
|
||||
#define NRF_ATFIFO_BUF_NAME(fifo_id) CONCAT_2(fifo_id, _data)
|
||||
|
||||
/**
|
||||
* @brief Macro for generating the name for a FIFO instance.
|
||||
*
|
||||
* The name of the instance variable that will be created by the
|
||||
* @ref NRF_ATFIFO_DEF macro.
|
||||
*
|
||||
* @param[in] fifo_id Identifier of the FIFO object.
|
||||
*
|
||||
* @return Name of the instance variable.
|
||||
*
|
||||
* @note This is auxiliary internal macro and in normal usage
|
||||
* it should not be called.
|
||||
*/
|
||||
#define NRF_ATFIFO_INST_NAME(fifo_id) CONCAT_2(fifo_id, _inst)
|
||||
|
||||
/**
|
||||
* @brief Macro for creating an instance.
|
||||
*
|
||||
* Creates the FIFO object variable itself.
|
||||
*
|
||||
* Usage example:
|
||||
* @code
|
||||
* NRF_ATFIFO_DEF(my_fifo, uint16_t, 12);
|
||||
* NRF_ATFIFO_INIT(my_fifo);
|
||||
*
|
||||
* uint16_t some_val = 45;
|
||||
* nrf_atfifo_item_put(my_fifo, &some_val, sizeof(some_val), NULL);
|
||||
* nrf_atfifo_item_get(my_fifo, &some_val, sizeof(some_val), NULL);
|
||||
* @endcode
|
||||
*
|
||||
* @param[in] fifo_id Identifier of a FIFO object.
|
||||
* This identifier will be a pointer to the instance.
|
||||
* It makes it possible to use this directly for the functions
|
||||
* that operate on the FIFO.
|
||||
* Because it is a static const object, it should be optimized by the compiler.
|
||||
* @param[in] storage_type Type of data that will be stored in the FIFO.
|
||||
* @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); \
|
||||
static nrf_atfifo_t * const fifo_id = &NRF_ATFIFO_INST_NAME(fifo_id)
|
||||
|
||||
/**
|
||||
* @brief Macro for initializing the FIFO that was previously declared by the macro.
|
||||
*
|
||||
* Use this macro to simplify FIFO initialization.
|
||||
*
|
||||
* @note
|
||||
* This macro can be only used on a FIFO object defined by @ref NRF_ATFIFO_DEF macro.
|
||||
*
|
||||
* @param[in] fifo_id Identifier of the FIFO object.
|
||||
*
|
||||
* @return Value from the @ref nrf_atfifo_init function.
|
||||
*/
|
||||
#define NRF_ATFIFO_INIT(fifo_id) \
|
||||
nrf_atfifo_init( \
|
||||
fifo_id, \
|
||||
NRF_ATFIFO_BUF_NAME(fifo_id), \
|
||||
sizeof(NRF_ATFIFO_BUF_NAME(fifo_id)), \
|
||||
sizeof(NRF_ATFIFO_BUF_NAME(fifo_id)[0]) \
|
||||
)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Function for initializing the FIFO.
|
||||
*
|
||||
* Preparing the FIFO instance to work.
|
||||
*
|
||||
* @param[out] p_fifo FIFO object to initialize.
|
||||
* @param[in,out] p_buf FIFO buffer for storing data.
|
||||
* @param[in] buf_size Total buffer size (has to be divisible by @c item_size).
|
||||
* @param[in] item_size Size of a single item held inside the FIFO.
|
||||
*
|
||||
* @retval NRF_SUCCESS If initialization was successful.
|
||||
* @retval NRF_ERROR_NULL If a NULL pointer is provided as the buffer.
|
||||
* @retval NRF_ERROR_INVALID_LENGTH If size of the buffer provided is not divisible by @c item_size.
|
||||
*
|
||||
* @note
|
||||
* Buffer size must be able to hold one element more than the designed FIFO capacity.
|
||||
* This one, empty element is used for overflow checking.
|
||||
*/
|
||||
ret_code_t nrf_atfifo_init(nrf_atfifo_t * const p_fifo, void * p_buf, uint16_t buf_size, uint16_t item_size);
|
||||
|
||||
/**
|
||||
* @brief Function for clearing the FIFO.
|
||||
*
|
||||
* Function for clearing the FIFO.
|
||||
*
|
||||
* If this function is called during an opened and uncommitted write operation,
|
||||
* the FIFO is cleared up to the currently ongoing commit.
|
||||
* There is no possibility to cancel an ongoing commit.
|
||||
*
|
||||
* If this function is called during an opened and unflushed read operation,
|
||||
* the read position in the head is set, but copying it into the write head position
|
||||
* is left to read closing operation.
|
||||
*
|
||||
* This way, there is no more data to read, but the memory is released
|
||||
* in the moment when it is safe.
|
||||
*
|
||||
* @param[in,out] p_fifo FIFO object.
|
||||
*
|
||||
* @retval NRF_SUCCESS FIFO totally cleared.
|
||||
* @retval NRF_ERROR_BUSY Function called in the middle of writing or reading operation.
|
||||
* If it is called in the middle of writing operation,
|
||||
* FIFO was cleared up to the already started and uncommitted write.
|
||||
* If it is called in the middle of reading operation,
|
||||
* write head was only moved. It will be copied into read tail when the reading operation
|
||||
* is flushed.
|
||||
*/
|
||||
ret_code_t nrf_atfifo_clear(nrf_atfifo_t * const p_fifo);
|
||||
|
||||
/**
|
||||
* @brief Function for atomically putting data into the FIFO.
|
||||
*
|
||||
* It uses memcpy function inside and in most situations, it is more suitable to
|
||||
* use @ref nrf_atfifo_item_alloc, write the data, and @ref nrf_atfifo_item_put to store a new value
|
||||
* in a FIFO.
|
||||
*
|
||||
* @param[in,out] p_fifo FIFO object.
|
||||
* @param[in] p_var Variable to copy.
|
||||
* @param[in] size Size of the variable to copy.
|
||||
* Can be smaller or equal to the FIFO item size.
|
||||
* @param[out] p_visible See value returned by @ref nrf_atfifo_item_put.
|
||||
* It may be NULL if the caller does not require the current operation status.
|
||||
*
|
||||
* @retval NRF_SUCCESS If an element has been successfully added to the FIFO.
|
||||
* @retval NRF_ERROR_NO_MEM If the FIFO is full.
|
||||
*
|
||||
* @note
|
||||
* To avoid data copying, you can use the @ref nrf_atfifo_item_alloc and @ref nrf_atfifo_item_put
|
||||
* functions pair.
|
||||
*/
|
||||
ret_code_t nrf_atfifo_alloc_put(nrf_atfifo_t * const p_fifo, void const * const p_var, size_t size, bool * const p_visible);
|
||||
|
||||
/**
|
||||
* @brief Function for opening the FIFO for writing.
|
||||
*
|
||||
* Function called to start the FIFO write operation and access the given FIFO buffer directly.
|
||||
*
|
||||
* @param[in,out] p_fifo FIFO object.
|
||||
* @param[out] p_context Operation context, required by @ref nrf_atfifo_item_put.
|
||||
*
|
||||
* @return Pointer to the space where variable data can be stored.
|
||||
* NULL if there is no space in the buffer.
|
||||
*/
|
||||
void * nrf_atfifo_item_alloc(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t * p_context);
|
||||
|
||||
/**
|
||||
* @brief Function for closing the writing operation.
|
||||
*
|
||||
* Puts a previously allocated context into FIFO.
|
||||
* This function must be called to commit an opened write operation.
|
||||
* It sets all the buffers and marks the data, so that it is visible to read.
|
||||
*
|
||||
* @param[in,out] p_fifo FIFO object.
|
||||
* @param[in] p_context Operation context, filled by the @ref nrf_atfifo_item_alloc function.
|
||||
*
|
||||
* @retval true Data is currently ready and will be visible to read.
|
||||
* @retval false The internal commit was marked, but the writing operation interrupted another writing operation.
|
||||
* The data will be available to read when the interrupted operation is committed.
|
||||
*/
|
||||
bool nrf_atfifo_item_put(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t * p_context);
|
||||
|
||||
/**
|
||||
* @brief Function for getting a single value from the FIFO.
|
||||
*
|
||||
* This function gets the value from the top of the FIFO.
|
||||
* The value is removed from the FIFO memory.
|
||||
*
|
||||
* @param[in,out] p_fifo FIFO object.
|
||||
* @param[out] p_var Pointer to the variable to store the data.
|
||||
* @param[in] size Size of the data to be loaded.
|
||||
* @param[out] p_released See the values returned by @ref nrf_atfifo_item_free.
|
||||
*
|
||||
* @retval NRF_SUCCESS Element was successfully copied from the FIFO memory.
|
||||
* @retval NRF_ERROR_NOT_FOUND No data in the FIFO.
|
||||
*/
|
||||
ret_code_t nrf_atfifo_get_free(nrf_atfifo_t * const p_fifo, void * const p_var, size_t size, bool * p_released);
|
||||
|
||||
/**
|
||||
* @brief Function for opening the FIFO for reading.
|
||||
*
|
||||
* Function called to start the FIFO read operation and access the given FIFO buffer directly.
|
||||
*
|
||||
* @param[in,out] p_fifo FIFO object.
|
||||
* @param[out] p_context The operation context, required by @ref nrf_atfifo_item_free
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief Function for closing the reading operation.
|
||||
*
|
||||
* Function used to finish the reading operation.
|
||||
* If this reading operation does not interrupt another reading operation, the head write buffer is moved.
|
||||
* If this reading operation is placed in the middle of another reading, only the new read pointer is written.
|
||||
*
|
||||
* @param[in,out] p_fifo FIFO object.
|
||||
* @param[in] p_context Context of the reading operation to be closed.
|
||||
*
|
||||
* @retval true This operation is not generated in the middle of another read operation and the write head will be updated to the read head (space is released).
|
||||
* @retval false This operation was performed in the middle of another read operation and the write buffer head was not moved (no space is released).
|
||||
*/
|
||||
bool nrf_atfifo_item_free(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context);
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NRF_ATFIFO_H__ */
|
||||
@@ -0,0 +1,577 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Atomic FIFO internal file
|
||||
*
|
||||
* This file should be included only by nrf_atfifo internally.
|
||||
* Needs nrf_atfifo.h included first.
|
||||
*/
|
||||
#ifndef NRF_ATFIFO_H__
|
||||
#error This is internal file. Do not include this file in your program.
|
||||
#endif
|
||||
|
||||
#ifndef NRF_ATFIFO_INTERNAL_H__
|
||||
#define NRF_ATFIFO_INTERNAL_H__
|
||||
#include <stddef.h>
|
||||
#include "nrf.h"
|
||||
#include "app_util.h"
|
||||
#include "nordic_common.h"
|
||||
|
||||
#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)) == 0
|
||||
#error Unsupported core version
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure that rd and wr pos in a tag are aligned like expected
|
||||
* Changing this would require changes inside assembly code!
|
||||
*/
|
||||
STATIC_ASSERT(offsetof(nrf_atfifo_postag_pos_t, wr) == 0);
|
||||
STATIC_ASSERT(offsetof(nrf_atfifo_postag_pos_t, rd) == 2);
|
||||
|
||||
/**
|
||||
* @brief Atomically reserve space for a new write.
|
||||
*
|
||||
* @param[in,out] p_fifo FIFO object.
|
||||
* @param[out] old_tail Tail position tag before new space is reserved.
|
||||
*
|
||||
* @retval true Space available.
|
||||
* @retval false Memory full.
|
||||
*
|
||||
* @sa nrf_atfifo_wspace_close
|
||||
*/
|
||||
static bool nrf_atfifo_wspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail);
|
||||
|
||||
/**
|
||||
* @brief Atomically mark all written data available.
|
||||
*
|
||||
* This function marks all data available for reading.
|
||||
* This marking is done by copying tail.pos.wr into tail.pos.rd.
|
||||
*
|
||||
* It must be called only when closing the first write.
|
||||
* It cannot be called if any write access was interrupted.
|
||||
* See the code below:
|
||||
* @code
|
||||
* if (old_tail.pos.wr == old_tail.pos.rd)
|
||||
* {
|
||||
* nrf_atfifo_wspace_close(my_fifo);
|
||||
* return true;
|
||||
* }
|
||||
* return false;
|
||||
* @endcode
|
||||
*
|
||||
* @param[in,out] p_fifo FIFO object.
|
||||
*
|
||||
* @sa nrf_atfifo_wspace_req
|
||||
*/
|
||||
static void nrf_atfifo_wspace_close(nrf_atfifo_t * const p_fifo);
|
||||
|
||||
/**
|
||||
* @brief Atomically get a part of a buffer to read data.
|
||||
*
|
||||
* @param[in,out] p_fifo FIFO object.
|
||||
* @param[out] old_head Head position tag before the data buffer is read.
|
||||
*
|
||||
* @retval true Data available for reading.
|
||||
* @retval false No data in the buffer.
|
||||
*
|
||||
* @sa nrf_atfifo_rspace_close
|
||||
*/
|
||||
static bool nrf_atfifo_rspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head);
|
||||
|
||||
/**
|
||||
* @brief Atomically release all read data.
|
||||
*
|
||||
* This function marks all data that was read as free space,
|
||||
* which is available for writing.
|
||||
* This marking is done by copying head.pos.rd into head.pos.wr.
|
||||
*
|
||||
* It must be called only when closing the first read.
|
||||
* It cannot be called when the current read access interrupted any other read access.
|
||||
* See code below:
|
||||
* @code
|
||||
* if (old_head.pos.wr == old_head.pos.rd)
|
||||
* {
|
||||
* nrf_atfifo_rspace_close(my_fifo);
|
||||
* return true;
|
||||
* }
|
||||
* return false;
|
||||
* @endcode
|
||||
*
|
||||
* @param[in,out] p_fifo FIFO object.
|
||||
*
|
||||
* @sa nrf_atfifo_rspace_req
|
||||
*/
|
||||
static void nrf_atfifo_rspace_close(nrf_atfifo_t * const p_fifo);
|
||||
|
||||
/**
|
||||
* @brief Safely clear the FIFO, internal function.
|
||||
*
|
||||
* This function realizes the functionality required by @ref nrf_atfifo_clear.
|
||||
*
|
||||
* @param[in,out] p_fifo FIFO object.
|
||||
*
|
||||
* @retval true All the data was released.
|
||||
* @retval false All the data available for releasing was released, but there is some pending transfer.
|
||||
*/
|
||||
static bool nrf_atfifo_space_clear(nrf_atfifo_t * const p_fifo);
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Implementation starts here
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
|
||||
|
||||
__ASM bool nrf_atfifo_wspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail)
|
||||
{
|
||||
/* Registry usage:
|
||||
* R0 - p_fifo
|
||||
* R1 - p_old_tail
|
||||
* R2 - internal variable old_tail (saved by caller)
|
||||
* R3 - internal variable new_tail (saved by caller)
|
||||
* R4 - internal temporary register (saved by this function)
|
||||
* R5 - not used stored to keep the stack aligned to 8 bytes
|
||||
* Returned value:
|
||||
* R0 (bool - 32 bits)
|
||||
*/
|
||||
push {r4, r5}
|
||||
nrf_atfifo_wspace_req_repeat
|
||||
/* Load tail tag and set memory monitor !!! R2 - old tail !!! */
|
||||
ldrex r2, [r0, #__cpp(offsetof(nrf_atfifo_t, tail))]
|
||||
/* Extract write position !!! R3 !!! */
|
||||
uxth r3, r2
|
||||
/* Increment address with overload support !!! R4 used temporary !!! */
|
||||
ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, item_size))]
|
||||
add r3, r4
|
||||
ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, buf_size))]
|
||||
cmp r3, r4
|
||||
it hs
|
||||
subhs r3, r3, r4
|
||||
|
||||
/* Check if FIFO would overload after making this increment !!! R4 used temporary !!! */
|
||||
ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, head) + offsetof(nrf_atfifo_postag_pos_t, wr))]
|
||||
cmp r3, r4
|
||||
ittt eq
|
||||
clrexeq
|
||||
moveq r0, #__cpp(false)
|
||||
beq nrf_atfifo_wspace_req_exit
|
||||
|
||||
/* Pack everything back !!! R3 - new tail !!! */
|
||||
/* Copy lower byte from new_tail, and higher byte is a value from the top of old_tail */
|
||||
pkhbt r3, r3, r2
|
||||
|
||||
/* Store new value clearing memory monitor !!! R4 used temporary !!! */
|
||||
strex r4, r3, [r0, #__cpp(offsetof(nrf_atfifo_t, tail))]
|
||||
cmp r4, #0
|
||||
bne nrf_atfifo_wspace_req_repeat
|
||||
|
||||
/* Return true */
|
||||
mov r0, #__cpp(true)
|
||||
nrf_atfifo_wspace_req_exit
|
||||
/* Save old tail */
|
||||
str r2, [r1]
|
||||
pop {r4, r5}
|
||||
bx lr
|
||||
}
|
||||
|
||||
|
||||
__ASM void nrf_atfifo_wspace_close(nrf_atfifo_t * const p_fifo)
|
||||
{
|
||||
/* Registry usage:
|
||||
* R0 - p_fifo
|
||||
* R1 - internal temporary register
|
||||
* R2 - new_tail
|
||||
*/
|
||||
nrf_atfifo_wspace_close_repeat
|
||||
ldrex r2, [r0, #__cpp(offsetof(nrf_atfifo_t, tail))]
|
||||
/* Copy from lower byte to higher */
|
||||
pkhbt r2, r2, r2, lsl #16
|
||||
|
||||
strex r1, r2, [r0, #__cpp(offsetof(nrf_atfifo_t, tail))]
|
||||
cmp r1, #0
|
||||
bne nrf_atfifo_wspace_close_repeat
|
||||
bx lr
|
||||
}
|
||||
|
||||
|
||||
__ASM bool nrf_atfifo_rspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head)
|
||||
{
|
||||
/* Registry usage:
|
||||
* R0 - p_fifo
|
||||
* R1 - p_old_head
|
||||
* R2 - internal variable old_head (saved by caller)
|
||||
* R3 - internal variable new_head (saved by caller)
|
||||
* R4 - internal temporary register (saved by this function)
|
||||
* R5 - not used stored to keep the stack aligned to 8 bytes
|
||||
* Returned value:
|
||||
* R0 (bool - 32 bits)
|
||||
*/
|
||||
push {r4, r5}
|
||||
nrf_atfifo_rspace_req_repeat
|
||||
/* Load tail tag and set memory monitor !!! R2 - old tail !!! */
|
||||
ldrex r2, [r0, #__cpp(offsetof(nrf_atfifo_t, head))]
|
||||
/* Extract read position !!! R3 !!! */
|
||||
uxth r3, r2, ror #16
|
||||
|
||||
/* Check if we have any data !!! R4 used temporary !!! */
|
||||
ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd))]
|
||||
cmp r3, r4
|
||||
ittt eq
|
||||
clrexeq
|
||||
moveq r0, #__cpp(false)
|
||||
beq nrf_atfifo_rspace_req_exit
|
||||
|
||||
/* Increment address with overload support !!! R4 used temporary !!! */
|
||||
ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, item_size))]
|
||||
add r3, r4
|
||||
ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, buf_size))]
|
||||
cmp r3, r4
|
||||
it hs
|
||||
subhs r3, r3, r4
|
||||
|
||||
/* Pack everything back !!! R3 - new tail !!! */
|
||||
/* Copy lower byte from old_head, and higher byte is a value from write_pos */
|
||||
pkhbt r3, r2, r3, lsl #16
|
||||
|
||||
/* Store new value clearing memory monitor !!! R4 used temporary !!! */
|
||||
strex r4, r3, [r0, #__cpp(offsetof(nrf_atfifo_t, head))]
|
||||
cmp r4, #0
|
||||
bne nrf_atfifo_rspace_req_repeat
|
||||
|
||||
/* Return true */
|
||||
mov r0, #__cpp(true)
|
||||
nrf_atfifo_rspace_req_exit
|
||||
/* Save old head */
|
||||
str r2, [r1]
|
||||
pop {r4, r5}
|
||||
bx lr
|
||||
}
|
||||
|
||||
|
||||
__ASM void nrf_atfifo_rspace_close(nrf_atfifo_t * const p_fifo)
|
||||
{
|
||||
/* Registry usage:
|
||||
* R0 - p_fifo
|
||||
* R1 - internal temporary register
|
||||
* R2 - new_tail
|
||||
*/
|
||||
nrf_atfifo_rspace_close_repeat
|
||||
ldrex r2, [r0, #__cpp(offsetof(nrf_atfifo_t, head))]
|
||||
/* Copy from higher byte to lower */
|
||||
pkhtb r2, r2, r2, asr #16
|
||||
|
||||
strex r1, r2, [r0, #__cpp(offsetof(nrf_atfifo_t, head))]
|
||||
cmp r1, #0
|
||||
bne nrf_atfifo_rspace_close_repeat
|
||||
bx lr
|
||||
}
|
||||
|
||||
|
||||
__ASM bool nrf_atfifo_space_clear(nrf_atfifo_t * const p_fifo)
|
||||
{
|
||||
/* Registry usage:
|
||||
* R0 - p_fifo as input, bool output after
|
||||
* R1 - tail, rd pointer, new_head
|
||||
* R2 - head_old, destroyed when creating new_head
|
||||
* R3 - p_fifo - copy
|
||||
*/
|
||||
mov r3, r0
|
||||
nrf_atfifo_space_clear_repeat
|
||||
/* Load old head in !!! R2 register !!! and read pointer of tail in !!! R1 register !!! */
|
||||
ldrex r2, [r3, #__cpp(offsetof(nrf_atfifo_t, head))]
|
||||
ldrh r1, [r3, #__cpp(offsetof(nrf_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd))]
|
||||
cmp r2, r2, ror #16
|
||||
/* Return false as default */
|
||||
mov r0, #__cpp(false)
|
||||
/* Create new head in !!! R1 register !!! Data in !!! R2 register broken !!! */
|
||||
itett ne
|
||||
uxthne r2, r2
|
||||
orreq r1, r1, r1, lsl #16
|
||||
orrne r1, r2, r1, lsl #16
|
||||
|
||||
/* Skip header test */
|
||||
bne nrf_atfifo_space_clear_head_test_skip
|
||||
|
||||
/* Load whole tail and test it !!! R2 used !!! */
|
||||
ldr r2, [r3, #__cpp(offsetof(nrf_atfifo_t, tail))]
|
||||
cmp r2, r2, ror #16
|
||||
/* Return true if equal */
|
||||
it eq
|
||||
moveq r0, #__cpp(true)
|
||||
|
||||
nrf_atfifo_space_clear_head_test_skip
|
||||
/* Store and test if success !!! R2 used temporary !!! */
|
||||
strex r2, r1, [r3, #__cpp(offsetof(nrf_atfifo_t, head))]
|
||||
cmp r2, #0
|
||||
bne nrf_atfifo_space_clear_repeat
|
||||
bx lr
|
||||
}
|
||||
|
||||
#elif defined ( __ICCARM__ ) || defined ( __GNUC__ )
|
||||
|
||||
bool nrf_atfifo_wspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail)
|
||||
{
|
||||
volatile bool ret;
|
||||
volatile uint32_t old_tail;
|
||||
uint32_t new_tail;
|
||||
uint32_t temp;
|
||||
|
||||
__ASM volatile(
|
||||
/* For more comments see Keil version above */
|
||||
"1: \n"
|
||||
" ldrex %[old_tail], [%[p_fifo], %[offset_tail]] \n"
|
||||
" uxth %[new_tail], %[old_tail] \n"
|
||||
" \n"
|
||||
" ldrh %[temp], [%[p_fifo], %[offset_item_size]] \n"
|
||||
" add %[new_tail], %[temp] \n"
|
||||
" ldrh %[temp], [%[p_fifo], %[offset_buf_size]] \n"
|
||||
" cmp %[new_tail], %[temp] \n"
|
||||
" it hs \n"
|
||||
" subhs %[new_tail], %[new_tail], %[temp] \n"
|
||||
" \n"
|
||||
" ldrh %[temp], [%[p_fifo], %[offset_head_wr]] \n"
|
||||
" cmp %[new_tail], %[temp] \n"
|
||||
" ittt eq \n"
|
||||
" clrexeq \n"
|
||||
" moveq %[ret], %[false_val] \n"
|
||||
" beq.n 2f \n"
|
||||
" \n"
|
||||
" pkhbt %[new_tail], %[new_tail], %[old_tail] \n"
|
||||
" \n"
|
||||
" strex %[temp], %[new_tail], [%[p_fifo], %[offset_tail]] \n"
|
||||
" cmp %[temp], #0 \n"
|
||||
" bne.n 1b \n"
|
||||
" \n"
|
||||
" mov %[ret], %[true_val] \n"
|
||||
"2: \n"
|
||||
: /* Output operands */
|
||||
[ret] "=r"(ret),
|
||||
[temp] "=&r"(temp),
|
||||
[old_tail]"=&r"(old_tail),
|
||||
[new_tail]"=&r"(new_tail)
|
||||
: /* Input operands */
|
||||
[p_fifo] "r"(p_fifo),
|
||||
[offset_tail] "J"(offsetof(nrf_atfifo_t, tail)),
|
||||
[offset_head_wr] "J"(offsetof(nrf_atfifo_t, head) + offsetof(nrf_atfifo_postag_pos_t, wr)),
|
||||
[offset_item_size]"J"(offsetof(nrf_atfifo_t, item_size)),
|
||||
[offset_buf_size] "J"(offsetof(nrf_atfifo_t, buf_size)),
|
||||
[true_val] "I"(true),
|
||||
[false_val] "I"(false)
|
||||
: /* Clobbers */
|
||||
"cc");
|
||||
|
||||
p_old_tail->tag = old_tail;
|
||||
UNUSED_VARIABLE(new_tail);
|
||||
UNUSED_VARIABLE(temp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void nrf_atfifo_wspace_close(nrf_atfifo_t * const p_fifo)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t new_tail;
|
||||
|
||||
__ASM volatile(
|
||||
/* For more comments see Keil version above */
|
||||
"1: \n"
|
||||
" ldrex %[new_tail], [%[p_fifo], %[offset_tail]] \n"
|
||||
" pkhbt %[new_tail],%[new_tail], %[new_tail], lsl #16 \n"
|
||||
" \n"
|
||||
" strex %[temp], %[new_tail], [%[p_fifo], %[offset_tail]] \n"
|
||||
" cmp %[temp], #0 \n"
|
||||
" bne.n 1b \n"
|
||||
: /* Output operands */
|
||||
[temp] "=&r"(temp),
|
||||
[new_tail] "=&r"(new_tail)
|
||||
: /* Input operands */
|
||||
[p_fifo] "r"(p_fifo),
|
||||
[offset_tail] "J"(offsetof(nrf_atfifo_t, tail))
|
||||
: /* Clobbers */
|
||||
"cc");
|
||||
|
||||
UNUSED_VARIABLE(temp);
|
||||
UNUSED_VARIABLE(new_tail);
|
||||
}
|
||||
|
||||
|
||||
bool nrf_atfifo_rspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head)
|
||||
{
|
||||
volatile bool ret;
|
||||
volatile uint32_t old_head;
|
||||
uint32_t new_head;
|
||||
uint32_t temp;
|
||||
|
||||
__ASM volatile(
|
||||
/* For more comments see Keil version above */
|
||||
"1: \n"
|
||||
" ldrex %[old_head], [%[p_fifo], %[offset_head]] \n"
|
||||
" uxth %[new_head], %[old_head], ror #16 \n"
|
||||
" \n"
|
||||
" ldrh %[temp], [%[p_fifo], %[offset_tail_rd]] \n"
|
||||
" cmp %[new_head], %[temp] \n"
|
||||
" ittt eq \n"
|
||||
" clrexeq \n"
|
||||
" moveq %[ret], %[false_val] \n"
|
||||
" beq.n 2f \n"
|
||||
" \n"
|
||||
" ldrh %[temp], [%[p_fifo], %[offset_item_size]] \n"
|
||||
" add %[new_head], %[temp] \n"
|
||||
" ldrh %[temp], [%[p_fifo], %[offset_buf_size]] \n"
|
||||
" cmp %[new_head], %[temp] \n"
|
||||
" it hs \n"
|
||||
" subhs %[new_head], %[new_head], %[temp] \n"
|
||||
" \n"
|
||||
" pkhbt %[new_head], %[old_head], %[new_head], lsl #16 \n"
|
||||
" \n"
|
||||
" strex %[temp], %[new_head], [%[p_fifo], %[offset_head]] \n"
|
||||
" cmp %[temp], #0 \n"
|
||||
" bne.n 1b \n"
|
||||
" \n"
|
||||
" mov %[ret], %[true_val] \n"
|
||||
"2: \n"
|
||||
: /* Output operands */
|
||||
[ret] "=r"(ret),
|
||||
[temp] "=&r"(temp),
|
||||
[old_head]"=&r"(old_head),
|
||||
[new_head]"=&r"(new_head)
|
||||
: /* Input operands */
|
||||
[p_fifo] "r"(p_fifo),
|
||||
[offset_head] "J"(offsetof(nrf_atfifo_t, head)),
|
||||
[offset_tail_rd] "J"(offsetof(nrf_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd)),
|
||||
[offset_item_size]"J"(offsetof(nrf_atfifo_t, item_size)),
|
||||
[offset_buf_size] "J"(offsetof(nrf_atfifo_t, buf_size)),
|
||||
[true_val] "I"(true),
|
||||
[false_val] "I"(false)
|
||||
: /* Clobbers */
|
||||
"cc");
|
||||
|
||||
p_old_head->tag = old_head;
|
||||
UNUSED_VARIABLE(new_head);
|
||||
UNUSED_VARIABLE(temp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void nrf_atfifo_rspace_close(nrf_atfifo_t * const p_fifo)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t new_head;
|
||||
|
||||
__ASM volatile(
|
||||
/* For more comments see Keil version above */
|
||||
"1: \n"
|
||||
" ldrex %[new_head], [%[p_fifo], %[offset_head]] \n"
|
||||
" pkhtb %[new_head],%[new_head], %[new_head], asr #16 \n"
|
||||
" \n"
|
||||
" strex %[temp], %[new_head], [%[p_fifo], %[offset_head]] \n"
|
||||
" cmp %[temp], #0 \n"
|
||||
" bne.n 1b \n"
|
||||
: /* Output operands */
|
||||
[temp] "=&r"(temp),
|
||||
[new_head] "=&r"(new_head)
|
||||
: /* Input operands */
|
||||
[p_fifo] "r"(p_fifo),
|
||||
[offset_head] "J"(offsetof(nrf_atfifo_t, head))
|
||||
: /* Clobbers */
|
||||
"cc");
|
||||
|
||||
UNUSED_VARIABLE(temp);
|
||||
UNUSED_VARIABLE(new_head);
|
||||
}
|
||||
|
||||
|
||||
bool nrf_atfifo_space_clear(nrf_atfifo_t * const p_fifo)
|
||||
{
|
||||
volatile bool ret;
|
||||
uint32_t old_head; /* This variable is left broken after assembly code finishes */
|
||||
uint32_t new_head;
|
||||
|
||||
__ASM volatile(
|
||||
"1: \n"
|
||||
" ldrex %[old_head], [%[p_fifo], %[offset_head]] \n"
|
||||
" ldrh %[new_head], [%[p_fifo], %[offset_tail_rd]] \n"
|
||||
" cmp %[old_head], %[old_head], ror #16 \n"
|
||||
" \n"
|
||||
" mov %[ret], %[false_val] \n"
|
||||
" \n"
|
||||
" itett ne \n"
|
||||
" uxthne %[old_head], %[old_head] \n"
|
||||
" orreq %[new_head], %[new_head], %[new_head], lsl #16 \n"
|
||||
" orrne %[new_head], %[old_head], %[new_head], lsl #16 \n"
|
||||
" \n"
|
||||
" bne.n 2f \n"
|
||||
" \n"
|
||||
" ldr %[old_head], [%[p_fifo], %[offset_tail]] \n"
|
||||
" cmp %[old_head], %[old_head], ror #16 \n"
|
||||
" it eq \n"
|
||||
" moveq %[ret], %[true_val] \n"
|
||||
" \n"
|
||||
"2: \n"
|
||||
" strex %[old_head], %[new_head], [%[p_fifo], %[offset_head]] \n"
|
||||
" cmp %[old_head], #0 \n"
|
||||
" bne.n 1b \n"
|
||||
: /* Output operands */
|
||||
[ret] "=&r"(ret),
|
||||
[old_head] "=&r"(old_head),
|
||||
[new_head] "=&r"(new_head)
|
||||
: /* Input operands */
|
||||
[p_fifo] "r"(p_fifo),
|
||||
[offset_head] "J"(offsetof(nrf_atfifo_t, head)),
|
||||
[offset_tail] "J"(offsetof(nrf_atfifo_t, tail)),
|
||||
[offset_tail_rd] "J"(offsetof(nrf_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd)),
|
||||
[true_val] "I"(true),
|
||||
[false_val] "I"(false)
|
||||
: /* Clobbers */
|
||||
"cc");
|
||||
|
||||
UNUSED_VARIABLE(old_head);
|
||||
UNUSED_VARIABLE(new_head);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
#error Unsupported compiler
|
||||
#endif
|
||||
|
||||
#endif /* NRF_ATFIFO_INTERNAL_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,563 @@
|
||||
/**
|
||||
* 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_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"
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd USB Device high level library
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief @tagAPI52840 Module for easy support for any USB device configuration.
|
||||
*
|
||||
* This module manages class instances that would create the USB device,
|
||||
* manages endpoints and interfaces transactions.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configuration passed to @ref app_usbd_init.
|
||||
*/
|
||||
typedef struct {
|
||||
#if (!(APP_USBD_EVENT_QUEUE_ENABLE)) || defined(__SDK_DOXYGEN__)
|
||||
/**
|
||||
* @brief User defined event handler.
|
||||
*
|
||||
* This function is called on every event from the interrupt.
|
||||
* It is prepared for external user function that would queue events to be processed
|
||||
* from the main context.
|
||||
* It should be used with operating systems with its own implementation of the queue.
|
||||
*
|
||||
* @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).
|
||||
*/
|
||||
void (*ev_handler)(app_usbd_internal_evt_t const * const p_event);
|
||||
#endif
|
||||
|
||||
#if (APP_USBD_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
|
||||
/**
|
||||
* @brief User defined event handler.
|
||||
*
|
||||
* This function is called on every event from the interrupt.
|
||||
*
|
||||
* @param p_event The event structure pointer.
|
||||
* @param queued The event is visible in the queue.
|
||||
* If queue conflict is detected the event might not be accessible inside queue
|
||||
* until all write operations finish.
|
||||
* 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).
|
||||
*
|
||||
* @note If is set to NULL no event would be called from interrupt.
|
||||
* @note This function is called before event is processed.
|
||||
* It means that if the event type is @ref APP_USBD_EVT_DRV_SETUP,
|
||||
* there would not be setup field present in the event structure.
|
||||
*/
|
||||
void (*ev_isr_handler)(app_usbd_internal_evt_t const * const p_event, bool queued);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief User defined event processor
|
||||
*
|
||||
* 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).
|
||||
*
|
||||
* @param event Event type.
|
||||
* Only following events are sent into this function:
|
||||
* - APP_USBD_EVT_DRV_SOF
|
||||
* - APP_USBD_EVT_DRV_RESET - Note that it also exits suspend
|
||||
* - APP_USBD_EVT_DRV_SUSPEND
|
||||
* - APP_USBD_EVT_DRV_RESUME - It is also generated when remote wakeup is generated
|
||||
* - APP_USBD_EVT_START
|
||||
* - APP_USBD_EVT_STOP
|
||||
*/
|
||||
void (*ev_state_proc)(app_usbd_event_type_t event);
|
||||
|
||||
/**
|
||||
* @brief SOF processing required by the user event processing
|
||||
*
|
||||
* This flag would enable SOF processing for the user events regardless of the fact if any
|
||||
* of the implemented class requires SOF event.
|
||||
*
|
||||
* @note SOF event would be enabled anyway if any of the appended class requires SOF processing.
|
||||
*/
|
||||
bool enable_sof;
|
||||
} app_usbd_config_t;
|
||||
|
||||
/**
|
||||
* @brief USB library initialization.
|
||||
*
|
||||
* Call this function before any configuration or class attachment.
|
||||
* USBD peripheral would be ready to accept commands, and library would be ready,
|
||||
* but it would not be connected to the bus.
|
||||
* Call @ref app_usbd_enable to enable USBD communication with the host.
|
||||
*
|
||||
* @param p_config Configuration. NULL pointer might be passed here and default
|
||||
* configuration will be applied then.
|
||||
*/
|
||||
ret_code_t app_usbd_init(app_usbd_config_t const * p_config);
|
||||
|
||||
/**
|
||||
* @brief USB library un-initialization
|
||||
*
|
||||
* @note Currently not supported
|
||||
*/
|
||||
ret_code_t app_usbd_uninit(void);
|
||||
|
||||
/**
|
||||
* @brief Enable USBD
|
||||
*
|
||||
* USBD is enabled.
|
||||
* Since now the high frequency clock may be requested when USB RESET would be detected.
|
||||
*/
|
||||
void app_usbd_enable(void);
|
||||
|
||||
/**
|
||||
* @brief Disable USBD
|
||||
*
|
||||
* Disabled USDB peripheral cannot be accessed but also stops requesting
|
||||
* High Frequency clock and releases power regulator.
|
||||
*
|
||||
* @note This function cannot be called when USB is started. Stop it first.
|
||||
*/
|
||||
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
|
||||
* 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
|
||||
* higher than USB interrupt.
|
||||
*
|
||||
* When start is processed it would:
|
||||
* 1. Start library.
|
||||
* 2. Enable interrupts.
|
||||
* 3. Enable USB pull-ups.
|
||||
*
|
||||
* @note
|
||||
* In some specific circumstances the library can be left not started and this function would
|
||||
* silently exit.
|
||||
* This may happen if some glitches appears on USB power line or if the plug was disconnected before
|
||||
* whole starting process finishes.
|
||||
* User would get the event from POWER peripheral then.
|
||||
* Also no @ref APP_USBD_EVT_STARTED event would be generated to the classes and user event handler.
|
||||
* For the safe code it is recommended to wait for @ref APP_USBD_EVT_STARTED event if anything
|
||||
* has to be initialized after USB driver is started (just before enabling the interrupts).
|
||||
* If library is properly started the @ref APP_USBD_EVT_STARTED event passed to the user handler
|
||||
* from this function body.
|
||||
*/
|
||||
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
|
||||
* 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
|
||||
* higher than USB interrupt.
|
||||
*
|
||||
* When the event is processed interrupts and USB pull-ups are disabled.
|
||||
* The peripheral itself is left enabled so it can be programmed,
|
||||
* but a HOST sees it as a peripheral disconnection.
|
||||
*
|
||||
* @note
|
||||
* If the library is not started when this function is called it exits silently - also
|
||||
* no @ref APP_USBD_EVT_STOPPED is generated.
|
||||
*/
|
||||
void app_usbd_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Request library to suspend
|
||||
*
|
||||
* This function send suspend request to the event queue.
|
||||
*
|
||||
* @note This function should only be called after @ref APP_USBD_EVT_DRV_SUSPEND os received.
|
||||
* Internal suspend request processing would give no effect if the bus is not in suspend state.
|
||||
*/
|
||||
void app_usbd_suspend_req(void);
|
||||
|
||||
/**
|
||||
* @brief Request library to wake-up
|
||||
*
|
||||
* This function send wakeup request to the event queue.
|
||||
*
|
||||
* @note Calling this function does not mean that peripheral is active - the wakeup request is sent
|
||||
* into message queue and needs to be processed.
|
||||
*
|
||||
* @retval true Wakeup generation has been started.
|
||||
* @retval false No wakeup would be generated becouse it is disabled by the host.
|
||||
*/
|
||||
bool app_usbd_wakeup_req(void);
|
||||
|
||||
/**
|
||||
* @brief USBD event processor
|
||||
*
|
||||
* Function to be called on each event to be processed by the library.
|
||||
*/
|
||||
void app_usbd_event_execute(app_usbd_internal_evt_t const * const p_event);
|
||||
|
||||
|
||||
#if (APP_USBD_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
|
||||
/**
|
||||
* @brief Function that process events from the queue
|
||||
*
|
||||
* @note This function calls @ref app_usbd_event_execute internally.
|
||||
*
|
||||
* @retval true Event was processed
|
||||
* @retval false The event queue is empty
|
||||
*/
|
||||
bool app_usbd_event_queue_process(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Add class instance
|
||||
*
|
||||
* This function connects given instance into internal class instance chain and
|
||||
* into all required endpoints.
|
||||
* The instance event handler would be connected into endpoint by default,
|
||||
* but this can be overwritten by @ref app_usbd_ep_handler_set.
|
||||
*
|
||||
* After successful attachment @ref APP_USBD_EVT_INST_APPEND would be passed to class instance.
|
||||
*
|
||||
* @note This function can only be called after USBD library is initialized but still disabled.
|
||||
* Assertion would be generated otherwise.
|
||||
*
|
||||
* @param[in,out] p_cinst Instance to connect. Chain data would be written into writable instance data.
|
||||
*/
|
||||
ret_code_t app_usbd_class_append(app_usbd_class_inst_t const * p_cinst);
|
||||
|
||||
/**
|
||||
* @brief Remove class instance
|
||||
*
|
||||
* Instance is removed from instance chain.
|
||||
* Instance and event handlers are removed also from endpoints.
|
||||
* Endpoints used by by the class instance are left disabled.
|
||||
*
|
||||
* @note This function can only be called after USBD library is initialized but still disabled.
|
||||
* Assertion would be generated otherwise.
|
||||
*
|
||||
* @param p_cinst Instance pointer to remove.
|
||||
*
|
||||
* @retval NRF_SUCCESS Instance successfully removed.
|
||||
* @retval NRF_ERROR_NOT_FOUND Instance not found in the instance chain.
|
||||
*/
|
||||
ret_code_t app_usbd_class_remove(app_usbd_class_inst_t const * p_cinst);
|
||||
|
||||
/**
|
||||
* @brief Remove all class instances
|
||||
*
|
||||
* This function basically calls @ref app_usbd_class_remove
|
||||
* on instances chain as long as there is any element left.
|
||||
*
|
||||
* @note This function can only be called after USBD library is initialized but still disabled.
|
||||
* Assertion would be generated otherwise.
|
||||
*
|
||||
* @sa app_usbd_class_remove
|
||||
*
|
||||
* @return Is should always return @ref NRF_SUCCESS.
|
||||
* Any error value returned would mean there is an error inside the library.
|
||||
*/
|
||||
ret_code_t app_usbd_class_remove_all(void);
|
||||
|
||||
/**
|
||||
* @brief Change endpoint handler
|
||||
*
|
||||
* This function may be called for the endpoint only if the class instance is
|
||||
* already properly attached by the @ref app_usbd_class_append function.
|
||||
*
|
||||
* The endpoint event handler function can be only overwritten by the class instance
|
||||
* that was connected into the endpoint.
|
||||
*
|
||||
* @note This function can only be called after USBD library is initialized but still disabled.
|
||||
* Assertion would be generated otherwise.
|
||||
*
|
||||
* @param[in] p_cinst Instance of a class that wish to set new event handler.
|
||||
* It has to match currently configured instance for the selected endpoint.
|
||||
* In other situation error would be returned.
|
||||
* @param[in] ep Endpoint address to configure.
|
||||
* @param[in] handler Event handler function to set.
|
||||
*
|
||||
* @retval NRF_SUCCESS New handler successfully set
|
||||
* @retval NRF_ERROR_INVALID_PARAM p_cinst is not the same as currently set for the endpoint
|
||||
*/
|
||||
ret_code_t app_usbd_ep_handler_set(app_usbd_class_inst_t const * p_cinst,
|
||||
nrf_drv_usbd_ep_t ep,
|
||||
app_usbd_ep_event_handler_t handler);
|
||||
|
||||
/**
|
||||
* @brief Register class instance as the one that requires SOF events
|
||||
*
|
||||
* This function should be called in reaction on APP_USBD_EVT_INST_APPEND event.
|
||||
* Connect the class instance to the list of instances that requires SOF processing.
|
||||
* If none of the appended instances requires SOF event - it is disabled.
|
||||
*
|
||||
* @param p_cinst Instance that requires SOF event.
|
||||
*
|
||||
* @retval NRF_SUCCESS Instance linked into SOF processing list.
|
||||
*
|
||||
* @sa app_usbd_class_sof_unregister
|
||||
*/
|
||||
ret_code_t app_usbd_class_sof_register(app_usbd_class_inst_t const * p_cinst);
|
||||
|
||||
/**
|
||||
* @brief Unregister class instance from SOF processing instances list
|
||||
*
|
||||
* Every class that calls @ref app_usbd_class_sof_register have to call also unregistering function
|
||||
* in reaction to @ref APP_USBD_EVT_INST_REMOVE event.
|
||||
*
|
||||
* @param p_cinst Instance to be unregistered from SOF event processing list.
|
||||
*
|
||||
* @retval NRF_SUCCESS Instance linked into SOF processing list.
|
||||
* @retval NRF_ERROR_NOT_FOUND Instance not found in the SOF processing list.
|
||||
*
|
||||
* @sa app_usbd_class_sof_register
|
||||
*/
|
||||
ret_code_t app_usbd_class_sof_unregister(app_usbd_class_inst_t const * p_cinst);
|
||||
|
||||
/**
|
||||
* @brief Register class on remote wake-up feature
|
||||
*
|
||||
* @param[in] p_inst Instance of the class
|
||||
*
|
||||
* @retval NRF_SUCCESS Instance that requires remote wake-up registered
|
||||
*/
|
||||
ret_code_t app_usbd_class_rwu_register(app_usbd_class_inst_t const * const p_inst);
|
||||
|
||||
/**
|
||||
* @brief Unregister class from remote wake-up feature
|
||||
*
|
||||
* @param[in] p_inst Instance of the class
|
||||
*
|
||||
* @retval NRF_SUCCESS Instance that requires remote wake-up removed
|
||||
*/
|
||||
ret_code_t app_usbd_class_rwu_unregister(app_usbd_class_inst_t const * const p_inst);
|
||||
|
||||
/**
|
||||
* @brief Check if there is any class with remote wakeup
|
||||
*
|
||||
* The function checks internal registered class with remote wakeup counter.
|
||||
*
|
||||
* @sa app_usbd_class_rwu_register, app_usbd_class_rwu_unregister
|
||||
*
|
||||
* @retval true The remote wakeup functionality is required by some class instance
|
||||
* @retval false There is no class instance that requires wakeup functionality
|
||||
*/
|
||||
bool app_usbd_class_rwu_enabled_check(void);
|
||||
|
||||
/**
|
||||
* @brief Function finds a given descriptor type in class descriptors payload
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @return Address of the descriptor (NULL if 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);
|
||||
|
||||
/**
|
||||
* @brief Standard interface request handle
|
||||
*
|
||||
* @param[in] p_setup_ev Setup event
|
||||
*
|
||||
* @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
|
||||
* */
|
||||
ret_code_t app_usbd_endpoint_std_req_handle(app_usbd_setup_evt_t const * p_setup_ev);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Standard interface set request handle
|
||||
*
|
||||
* @param[in] p_cinst Instance of a class
|
||||
* @param[in] p_setup_ev Setup event
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @name Iterate through classes lists
|
||||
*
|
||||
* Functions that helps to iterate through internally chained classes.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Get first class instance in the list
|
||||
*
|
||||
* Get first instance from the list of active class instances.
|
||||
* That instance may be used then in @ref app_usbd_class_next_get function.
|
||||
*
|
||||
* @return First instance in the list or NULL if there are no instances available.
|
||||
*/
|
||||
app_usbd_class_inst_t const * app_usbd_class_first_get(void);
|
||||
|
||||
/**
|
||||
* @brief Get next instance in the list
|
||||
*
|
||||
* Get the next instance from the list of active instances.
|
||||
* Used to iterate through all instances.
|
||||
*
|
||||
* @param[in] p_cinst The current instance from with next one is required.
|
||||
*
|
||||
* @return Next instance to the given one or NULL if there is no more instances in the list.
|
||||
*/
|
||||
static inline app_usbd_class_inst_t const * app_usbd_class_next_get(
|
||||
app_usbd_class_inst_t const * const p_cinst)
|
||||
{
|
||||
ASSERT(NULL != p_cinst);
|
||||
return app_usbd_class_data_access(p_cinst)->p_next;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get first instance in SOF list
|
||||
*
|
||||
* Start iteration through the list of instances that requires SOF event processing.
|
||||
*
|
||||
* @return First instance in the list or NULL if the list is empty
|
||||
*
|
||||
* @sa app_usbd_class_first_get
|
||||
*/
|
||||
app_usbd_class_inst_t const * app_usbd_class_sof_first_get(void);
|
||||
|
||||
/**
|
||||
* @brief Get next instance in the SOF list
|
||||
*
|
||||
* Get the next instance from the list of instances requiring SOF event processing.
|
||||
* Used to iterate through all SOF instances.
|
||||
*
|
||||
* @param p_cinst The current instance from with next one is required.
|
||||
*
|
||||
* @return Next instance to the given one or NULL if there is no more instances in the list.
|
||||
*/
|
||||
static inline app_usbd_class_inst_t const * app_usbd_class_sof_next_get(
|
||||
app_usbd_class_inst_t const * const p_cinst)
|
||||
{
|
||||
ASSERT(NULL != p_cinst);
|
||||
return app_usbd_class_data_access(p_cinst)->p_sof_next;
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Communicate with interfaces, endpoints and instances inside usbd library
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
* @return Operation status
|
||||
*/
|
||||
ret_code_t app_usbd_iface_call(uint8_t iface, app_usbd_complex_evt_t const * const p_event);
|
||||
|
||||
/**
|
||||
* @brief Call endpoint event handler
|
||||
*
|
||||
* Call event handler for the selected endpoint.
|
||||
* @param[in] ep Endpoint number
|
||||
* @param[in] p_event Event structure to send
|
||||
*
|
||||
* @return Operation status
|
||||
*/
|
||||
ret_code_t app_usbd_ep_call(nrf_drv_usbd_ep_t ep, app_usbd_complex_evt_t const * const p_event);
|
||||
|
||||
/**
|
||||
* @brief Auxiliary function that process event by every instance in the list
|
||||
*
|
||||
* This function ignores the result of called handler.
|
||||
*
|
||||
* @param p_event Event to pass to every instance
|
||||
*/
|
||||
void app_usbd_all_call(app_usbd_complex_evt_t const * const p_event);
|
||||
|
||||
/**
|
||||
* @brief Call interface event handlers and stop when served
|
||||
*
|
||||
* Call event handlers from instances as long as we get result different than @ref NRF_ERROR_NOT_SUPPORTED
|
||||
* @param[in] p_event Event structure to send
|
||||
*
|
||||
* @return Operation status or @ref NRF_ERROR_NOT_SUPPORTED if none of instances in the list can support given event.
|
||||
*/
|
||||
ret_code_t app_usbd_all_until_served_call(app_usbd_complex_evt_t const * const p_event);
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APP_USBD_H__ */
|
||||
@@ -0,0 +1,841 @@
|
||||
/**
|
||||
* 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_USBD_CLASS_BASE_H__
|
||||
#define APP_USBD_CLASS_BASE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "app_usbd_types.h"
|
||||
#include "nrf_drv_usbd.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "app_util.h"
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd_class_base USBD Class Base module
|
||||
* @ingroup app_usbd
|
||||
*
|
||||
* @brief @tagAPI52840 The base for any class instance is defined in this module.
|
||||
*
|
||||
* @details Any class instance must start from base class instance structure.
|
||||
* This makes them compatible with USBD library independently of the
|
||||
* implementation details.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Endpoint configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
nrf_drv_usbd_ep_t address; //!< Endpoint address
|
||||
} app_usbd_class_ep_conf_t;
|
||||
|
||||
/**
|
||||
* @brief Interface configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t number; //!< Interface number
|
||||
uint8_t ep_cnt; //!< Endpoint number
|
||||
uint8_t ep_offset; //!< Offset of the first endpoint
|
||||
/**< Offset in bytes of the first endpoint.
|
||||
* The offset is calculated from the address of this interface structure
|
||||
*/
|
||||
} app_usbd_class_iface_conf_t;
|
||||
|
||||
/**
|
||||
* @brief Instance variable data
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
app_usbd_class_inst_t const * p_next; //!< Pointer to the next instance
|
||||
app_usbd_class_inst_t const * p_sof_next; //!< Pointer to the next SOF event requiring instance
|
||||
} app_usbd_class_data_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Class interface function set
|
||||
* */
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Instance callback function
|
||||
*
|
||||
* The function used by every class instance.
|
||||
* @param[in,out] p_inst Instance of the class
|
||||
* @param[in] p_event Event to process
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief Instance get descriptors
|
||||
*
|
||||
* The function used by every class instance.
|
||||
* @param[in,out] p_inst Instance of the class
|
||||
* @param[out] p_size Descriptor size
|
||||
*
|
||||
* @return Class descriptors start address
|
||||
*/
|
||||
const void * (* get_descriptors)(app_usbd_class_inst_t const * const p_inst,
|
||||
size_t * p_size);
|
||||
} app_usbd_class_methods_t;
|
||||
|
||||
/**
|
||||
* @brief The instance structure itself
|
||||
*
|
||||
* The structure of base class instance
|
||||
*/
|
||||
struct app_usbd_class_inst_s
|
||||
{
|
||||
app_usbd_class_data_t * p_data; //!< Pointer to non-constant data
|
||||
app_usbd_class_methods_t const * p_class_methods; //!< Class interface methods
|
||||
struct
|
||||
{
|
||||
uint8_t cnt; //!< Number of defined interfaces
|
||||
uint8_t config[]; //!< Interface configuration data followed by endpoint data
|
||||
} iface; //!< Interface structure
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get total number of interfaces
|
||||
*
|
||||
*
|
||||
*/
|
||||
static inline uint8_t app_usbd_class_iface_count_get(app_usbd_class_inst_t const * const p_inst)
|
||||
{
|
||||
return p_inst->iface.cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Interface accessing function
|
||||
*
|
||||
* Get interface pointer.
|
||||
* Interfaces creates continuous array in the memory so it is possible to get
|
||||
* interface with index 0 and the just iterate to the next one.
|
||||
*
|
||||
* @param p_inst Pointer to the class instance
|
||||
* @param iface_idx Index of the instance to get.
|
||||
* This is not the interface identifier.
|
||||
* Technically it is the index of the interface in the class description array.
|
||||
* @return Pointer to the interface configuration parameters or NULL if given index is out of interface scope for given class.
|
||||
*/
|
||||
static inline app_usbd_class_iface_conf_t const * app_usbd_class_iface_get(
|
||||
app_usbd_class_inst_t const * const p_inst,
|
||||
uint8_t iface_idx)
|
||||
{
|
||||
ASSERT(NULL != p_inst);
|
||||
if (iface_idx >= (app_usbd_class_iface_count_get(p_inst)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
app_usbd_class_iface_conf_t const * p_interface =
|
||||
(app_usbd_class_iface_conf_t const * )(p_inst->iface.config);
|
||||
return &(p_interface[iface_idx]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get interface number
|
||||
*
|
||||
* @param p_iface Pointer to interface structure
|
||||
*
|
||||
* @return Interface number from interface configuration structure
|
||||
*/
|
||||
static inline uint8_t app_usbd_class_iface_number_get(
|
||||
app_usbd_class_iface_conf_t const * const p_iface)
|
||||
{
|
||||
return p_iface->number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of endpoints in interface
|
||||
*
|
||||
* @param p_iface Pointer to interface structure
|
||||
*
|
||||
* @return Number of endpoints used by given interface
|
||||
*/
|
||||
static inline uint8_t app_usbd_class_iface_ep_count_get(
|
||||
app_usbd_class_iface_conf_t const * const p_iface)
|
||||
{
|
||||
return p_iface->ep_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Interface Endpoint accessing function
|
||||
*
|
||||
* @param p_iface Interface configuration pointer
|
||||
* @param ep_idx Endpoint index
|
||||
*
|
||||
* @return Endpoint information structure pointer or NULL if given index is outside of endpoints for selected interface.
|
||||
*
|
||||
* @sa app_usbd_class_iface_get
|
||||
*/
|
||||
static inline app_usbd_class_ep_conf_t const * app_usbd_class_iface_ep_get(
|
||||
app_usbd_class_iface_conf_t const * const p_iface,
|
||||
uint8_t ep_idx)
|
||||
{
|
||||
ASSERT(NULL != p_iface);
|
||||
if (ep_idx >= p_iface->ep_cnt)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
app_usbd_class_ep_conf_t const * p_ep =
|
||||
(app_usbd_class_ep_conf_t const * )(((uint8_t const *)p_iface) + p_iface->ep_offset);
|
||||
return &(p_ep[ep_idx]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Translate endpoint address to class index
|
||||
*
|
||||
* @param p_iface Interface configuration pointer
|
||||
* @param ep_address Endpoint address
|
||||
*
|
||||
* @return Endpoint index or number of endpoints if not found
|
||||
*
|
||||
*/
|
||||
static inline uint8_t app_usbd_class_iface_ep_idx_get(
|
||||
app_usbd_class_iface_conf_t const * const p_iface,
|
||||
nrf_drv_usbd_ep_t ep_address)
|
||||
{
|
||||
ASSERT(NULL != p_iface);
|
||||
app_usbd_class_ep_conf_t const * p_ep =
|
||||
(app_usbd_class_ep_conf_t const * )(((uint8_t const *)p_iface) + p_iface->ep_offset);
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; i < p_iface->ep_cnt; ++i)
|
||||
{
|
||||
if (ep_address == p_ep[i].address)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the selected endpoint address
|
||||
*
|
||||
* @param p_ep Endpoint configuration structure
|
||||
*
|
||||
* @return Endpoint address
|
||||
*/
|
||||
static inline nrf_drv_usbd_ep_t app_usbd_class_ep_address_get(app_usbd_class_ep_conf_t const * p_ep)
|
||||
{
|
||||
return (nrf_drv_usbd_ep_t)p_ep->address;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the pointer to the writable instance data
|
||||
*
|
||||
* @param p_inst Instance pointer
|
||||
* @return Pointer to writable instance data
|
||||
*/
|
||||
static inline app_usbd_class_data_t * app_usbd_class_data_access(
|
||||
app_usbd_class_inst_t const * const p_inst)
|
||||
{
|
||||
return p_inst->p_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Internal macros for argument mapping
|
||||
*
|
||||
* Functions to be used as a mapping macro for @ref MACRO_MAP, @ref MACRO_MAP_FOR or @ref MACRO_MAP_FOR_PARAM
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Count the number of endpoints in given configuration
|
||||
*
|
||||
* Config should be given as a interface configuration in a brackets:
|
||||
* @code
|
||||
* (interface_nr, ep1, ep2, ep3)
|
||||
* @endcode
|
||||
* Number of endpoints may vary from 0 to a few (technically up to 16, but it seems not to make sense to use more than 4).
|
||||
* Interface number is always present.
|
||||
*
|
||||
* @param iface_config Single interface configuration (in brackets)
|
||||
*
|
||||
* @return Number of endpoints in interface. This is computed value - can be used by compiler but not by preprocessor.
|
||||
*/
|
||||
#define APP_USBD_CLASS_CONF_IFACE_EP_COUNT_(iface_config) \
|
||||
(NUM_VA_ARGS(BRACKET_EXTRACT(iface_config)) - 1)
|
||||
|
||||
/**
|
||||
* @brief Adds the number of endpoints in given config to the current value
|
||||
*
|
||||
* This is basically @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_ with plus sign added.
|
||||
*
|
||||
* @param iface_config See parameters documentation in @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_
|
||||
*
|
||||
* @return Plus sign followed by number of endpoints in interface.
|
||||
*
|
||||
* @sa APP_USBD_CLASS_CONF_IFACE_EP_COUNT_
|
||||
*/
|
||||
#define APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_(iface_config) \
|
||||
+ APP_USBD_CLASS_CONF_IFACE_EP_COUNT_(iface_config)
|
||||
|
||||
/**
|
||||
* @brief Create variable for endpoint
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Extract endpoints given interface configuration
|
||||
*
|
||||
* This macro gets single endpoint configuration and extracts all the endpoints.
|
||||
* It also adds comma on the end of extracted endpoints.
|
||||
* This way when this macro is called few times it generates nice list of all endpoints
|
||||
* that may be used to array initialization.
|
||||
*
|
||||
* @param iface_config Single interface configuration in brackets.
|
||||
* The format should be similar like described in @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_.
|
||||
*/
|
||||
#define APP_USBD_CLASS_IFACE_EP_EXTRACT_(iface_config) \
|
||||
CONCAT_2(APP_USBD_CLASS_IFACE_EP_EXTRACT_, \
|
||||
NUM_VA_ARGS_IS_MORE_THAN_1(BRACKET_EXTRACT(iface_config))) \
|
||||
(BRACKET_EXTRACT(iface_config))
|
||||
|
||||
/**
|
||||
* @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_EP_EXTRACT_
|
||||
*
|
||||
* This macro is called when interface has no endpoints
|
||||
*/
|
||||
#define APP_USBD_CLASS_IFACE_EP_EXTRACT_0(iface_nr)
|
||||
|
||||
/**
|
||||
* @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_EP_EXTRACT_
|
||||
*
|
||||
* This macro is called when interface has at least one endpoint
|
||||
*/
|
||||
#define APP_USBD_CLASS_IFACE_EP_EXTRACT_1(...) \
|
||||
APP_USBD_CLASS_IFACE_EP_EXTRACT_1_(__VA_ARGS__)
|
||||
|
||||
#define APP_USBD_CLASS_IFACE_EP_EXTRACT_1_(iface_nr, ...) \
|
||||
MACRO_MAP_REC(PARAM_CBRACE, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Generate configuration for single interface
|
||||
*
|
||||
* This macro extract configuration for single interface.
|
||||
* The configuration is inside curly brackets and comma is added on the end.
|
||||
* This mean it can be directly used to init array of interface configurations.
|
||||
*
|
||||
* @param iface_config Single interface configuration
|
||||
* @param N Currently processed configuration
|
||||
* @param iface_configs All interfaces configuration in brackets
|
||||
*/
|
||||
#define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_(iface_config, N, iface_configs) \
|
||||
CONCAT_2(APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_, \
|
||||
NUM_VA_ARGS_IS_MORE_THAN_1(BRACKET_EXTRACT(iface_config))) \
|
||||
(N, iface_configs, BRACKET_EXTRACT(iface_config))
|
||||
|
||||
#define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_x(iface_config, N, iface_configs) \
|
||||
[N] = !!!iface_config!!!
|
||||
/**
|
||||
* @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_
|
||||
*
|
||||
* This macro is called when interface has no endpoints
|
||||
*/
|
||||
#define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0(N, iface_configs, iface_nr) \
|
||||
APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0_(N, iface_configs, iface_nr)
|
||||
#define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0_(N, iface_configs, iface_nr) \
|
||||
{ .number = iface_nr, .ep_cnt = 0, .ep_offset = 0 },
|
||||
|
||||
/**
|
||||
* @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_
|
||||
*
|
||||
* This macro is called when interface has at last one endpoint
|
||||
*/
|
||||
#define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1(N, iface_configs, ...) \
|
||||
APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1_(N, iface_configs, __VA_ARGS__)
|
||||
#define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1_(N, iface_configs, iface_nr, ...) \
|
||||
{ .number = iface_nr, .ep_cnt = NUM_VA_ARGS(__VA_ARGS__), \
|
||||
.ep_offset = APP_USBD_CLASS_CONF_TOTAL_EP_COUNT_N(N, iface_configs) * \
|
||||
sizeof(app_usbd_class_ep_conf_t) \
|
||||
+ ((NUM_VA_ARGS(BRACKET_EXTRACT(iface_configs)) - N) * \
|
||||
sizeof(app_usbd_class_iface_conf_t)) \
|
||||
},
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name Macros that uses mapping macros internally
|
||||
*
|
||||
* Auxiliary macros that uses mapping macros to make some calculations or realize other functionality.
|
||||
* Mapped here for easier unit testing and to hide complex mapping functions calling.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Count total number of endpoints
|
||||
*
|
||||
* @param iface_configs List of interface configurations like explained
|
||||
* in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
|
||||
*
|
||||
* @return The equation to calculate the number of endpoints by compiler.
|
||||
*/
|
||||
#define APP_USBD_CLASS_CONF_TOTAL_EP_COUNT(iface_configs) \
|
||||
(0 MACRO_MAP(APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_, BRACKET_EXTRACT(iface_configs)))
|
||||
|
||||
/**
|
||||
* @brief Count total number of endpoint up-to interface index
|
||||
*
|
||||
* The version of @ref APP_USBD_CLASS_CONF_TOTAL_EP_COUNT macro which takes the
|
||||
* number of interfaces to analyze.
|
||||
*
|
||||
* @param N Number of interfaces to analyze
|
||||
* @param iface_configs List of interface configurations like explained
|
||||
* in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
|
||||
*
|
||||
* @return The equation to calculate the number of endpoints by compiler.
|
||||
*/
|
||||
#define APP_USBD_CLASS_CONF_TOTAL_EP_COUNT_N(N, iface_configs) \
|
||||
(0 MACRO_MAP_N(N, APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_, BRACKET_EXTRACT(iface_configs)))
|
||||
|
||||
/**
|
||||
* @brief Extract configurations for interfaces
|
||||
*
|
||||
* This macro extracts the configurations for every interface.
|
||||
* Basically uses the @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_ macro on every
|
||||
* configuration found.
|
||||
*
|
||||
* This should generate interface configuration initialization data
|
||||
* in comma separated initializers in curly braces.
|
||||
*
|
||||
* @param iface_configs List of interface configurations like explained
|
||||
* in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
|
||||
*
|
||||
* @return Comma separated initialization data for all interfaces.
|
||||
*/
|
||||
/*lint -emacro( (40), APP_USBD_CLASS_IFACES_CONFIG_EXTRACT) */
|
||||
#define APP_USBD_CLASS_IFACES_CONFIG_EXTRACT(iface_configs) \
|
||||
MACRO_MAP_FOR_PARAM(iface_configs, \
|
||||
APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_, \
|
||||
BRACKET_EXTRACT(iface_configs))
|
||||
|
||||
/**
|
||||
* @brief Extract all endpoints
|
||||
*
|
||||
* Macro that extracts all endpoints from every interface
|
||||
*
|
||||
* @param iface_configs List of interface configurations like explained
|
||||
* in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
|
||||
*
|
||||
* @return Comma separated list of endpoints
|
||||
*/
|
||||
/*lint -emacro( (40), APP_USBD_CLASS_IFACES_EP_EXTRACT) */
|
||||
#define APP_USBD_CLASS_IFACES_EP_EXTRACT(iface_configs) \
|
||||
MACRO_MAP(APP_USBD_CLASS_IFACE_EP_EXTRACT_, BRACKET_EXTRACT(iface_configs))
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBD instance of class mnemonic
|
||||
*
|
||||
* Macro that generates mnemonic for the name of the structure that describes instance for selected class.
|
||||
*
|
||||
* @param type_name The name of the instance without _t postfix
|
||||
*
|
||||
* @return The name with the right postfix to create the name for the type for the class.
|
||||
*/
|
||||
#define APP_USBD_CLASS_INSTANCE_TYPE(type_name) CONCAT_2(type_name, _t)
|
||||
|
||||
/**
|
||||
* @brief USBD data for instance class mnemonic
|
||||
*
|
||||
* The mnemonic of the variable type that holds writable part of the class instance.
|
||||
*
|
||||
* @param type_name The name of the instance without _t postfix
|
||||
*
|
||||
* @return The name with the right postfix to create the name for the data type for the class.
|
||||
*/
|
||||
#define APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(type_name, _data_t)
|
||||
|
||||
/**
|
||||
* @brief Declare class specific member of class instance
|
||||
*
|
||||
* @param type Type of the attached class configuration.
|
||||
*
|
||||
* @sa APP_USBD_CLASS_INSTANCE_TYPEDEF
|
||||
*/
|
||||
#define APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC(type) type class_part;
|
||||
|
||||
/**
|
||||
* @brief Used if there is no class specific configuration
|
||||
*
|
||||
* This constant can be used if there is no specific configuration inside created instance
|
||||
*
|
||||
* @sa APP_USBD_CLASS_INSTANCE_TYPEDEF
|
||||
*/
|
||||
#define APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE
|
||||
|
||||
/**
|
||||
* @brief Declare class specific member of class data
|
||||
*
|
||||
* @param type Type of the attached class data.
|
||||
*
|
||||
* @sa APP_USBD_CLASS_DATA_TYPEDEF
|
||||
*/
|
||||
#define APP_USBD_CLASS_DATA_SPECIFIC_DEC(type) APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC(type)
|
||||
|
||||
/**
|
||||
* @brief Used if there is no class specific data
|
||||
*
|
||||
* This constant can be used if there is no specific writable data inside created instance
|
||||
*
|
||||
* @sa APP_USBD_CLASS_DATA_TYPEDEF
|
||||
*/
|
||||
#define APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Instance structure declaration
|
||||
*
|
||||
* The macro that declares a variable type that would be used to store given class instance.
|
||||
* Class instance stores all the data from @ref app_usbd_class_inst_t and overlaid data for specified class.
|
||||
*
|
||||
* The structure of interface configuration data:
|
||||
* @code
|
||||
* (
|
||||
* (iface1_nr, (ep1, ep2, ep3)),
|
||||
(iface2_nr),
|
||||
(iface3_nr, (ep4))
|
||||
* )
|
||||
* @endcode
|
||||
*
|
||||
* @param type_name The name of the instance without _t postfix.
|
||||
* @param interfaces_configs List of interface configurations like explained above.
|
||||
* @param class_config_dec Result of the macro
|
||||
* @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC or
|
||||
* @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE
|
||||
*
|
||||
* @return The definition of the structure type that holds all the required data.
|
||||
*
|
||||
* @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_DATA_TYPEDEF instead.
|
||||
*
|
||||
* @note APP_USBD_CLASS_DATA_TYPEDEF has to be called first for the compilation to success.
|
||||
*
|
||||
* @sa APP_USBD_CLASS_TYPEDEF
|
||||
*/
|
||||
#define APP_USBD_CLASS_INSTANCE_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))]; \
|
||||
app_usbd_class_ep_conf_t \
|
||||
ep[APP_USBD_CLASS_CONF_TOTAL_EP_COUNT(interfaces_configs)]; \
|
||||
} iface; \
|
||||
class_config_dec \
|
||||
} specific; \
|
||||
} APP_USBD_CLASS_INSTANCE_TYPE(type_name)
|
||||
|
||||
/**
|
||||
* @brief Writable data structure declaration
|
||||
*
|
||||
* The macro that declares a variable type that would be used to store given class writable data.
|
||||
* Writable data contains base part of the type @ref app_usbd_class_data_t followed by
|
||||
* class specific data.
|
||||
*
|
||||
* @param type_name The name of the type without _t postfix.
|
||||
* @param class_data_dec Result of the macro
|
||||
* @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC or
|
||||
* @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE
|
||||
*
|
||||
* @return The definition of the structure type that holds all the required writable data
|
||||
*
|
||||
* @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_DATA_TYPEDEF instead.
|
||||
*
|
||||
* @sa APP_USBD_CLASS_TYPEDEF
|
||||
*/
|
||||
#define APP_USBD_CLASS_DATA_TYPEDEF(type_name, class_data_dec) \
|
||||
typedef struct \
|
||||
{ \
|
||||
app_usbd_class_data_t base; \
|
||||
class_data_dec \
|
||||
}APP_USBD_CLASS_DATA_TYPE(type_name)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Declare all data types required by the class instance
|
||||
*
|
||||
* Macro that declares data type first and then instance type.
|
||||
*
|
||||
* @param type_name The name of the type without _t postfix.
|
||||
* @param interface_configs List of interface configurations like in @ref APP_USBD_CLASS_INSTANCE_TYPEDEF.
|
||||
* @param class_config_dec Result of the macro
|
||||
* @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC or
|
||||
* @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE
|
||||
* @param class_data_dec Result of the macro
|
||||
* @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC or
|
||||
* @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE
|
||||
*
|
||||
* @return Declaration of the data type for the instance and instance itself.
|
||||
*
|
||||
* @sa APP_USBD_CLASS_DATA_TYPEDEF
|
||||
* @sa APP_USBD_CLASS_INSTANCE_TYPEDEF
|
||||
*/
|
||||
#define APP_USBD_CLASS_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_TYPEDEF(type_name, interface_configs, class_config_dec)
|
||||
|
||||
/**
|
||||
* @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF
|
||||
*
|
||||
* @param type_name The name of the type without _t postfix.
|
||||
* */
|
||||
#define APP_USBD_CLASS_FORWARD(type_name) union CONCAT_2(type_name, _u)
|
||||
|
||||
/**
|
||||
* @brief Generate the initialization data for
|
||||
*
|
||||
* Macro that generates the initialization data for instance.
|
||||
*
|
||||
* @param p_ram_data Pointer to writable instance data structure
|
||||
* @param class_methods Class methods
|
||||
* @param interfaces_configs Exactly the same interface config data that in @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
|
||||
* @param class_config_part Configuration part. The data should be inside brackets.
|
||||
* Any data here would be removed from brackets and then put as an initialization
|
||||
* data for class_part member of instance structure.
|
||||
*
|
||||
* @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_INST_DEF instead.
|
||||
*/
|
||||
#define APP_USBD_CLASS_INSTANCE_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) }, \
|
||||
.ep = { APP_USBD_CLASS_IFACES_EP_EXTRACT(interfaces_configs) } \
|
||||
}, \
|
||||
BRACKET_EXTRACT(class_config_part) \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Define the base class instance
|
||||
*
|
||||
* Macro that defines whole instance variable and fill it with initialization data.
|
||||
*
|
||||
* 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.
|
||||
* @code
|
||||
* APP_USBD_CLASS_TYPEDEF(
|
||||
* some_base_class,
|
||||
* CLASS_BASE_CONFIGURATION,
|
||||
* APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE,
|
||||
* APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE
|
||||
* );
|
||||
* APP_USBD_CLASS_INST_DEF(
|
||||
* some_base_class_inst,
|
||||
* some_base_class,
|
||||
* base_class_event_handler,
|
||||
* CLASS_BASE_CONFIGURATION,
|
||||
* () // Empty configuration
|
||||
* );
|
||||
* @endcode
|
||||
*
|
||||
* If the type of instance configuration is simple type, just provide initialization value:
|
||||
* @code
|
||||
* APP_USBD_CLASS_TYPEDEF(
|
||||
* some_base_class,
|
||||
* CLASS_BASE_CONFIGURATION,
|
||||
* APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE,
|
||||
* APP_USBD_CLASS_DATA_SPECIFIC_DEC(uint8_t)
|
||||
* );
|
||||
* APP_USBD_CLASS_INST_DEF(
|
||||
* some_base_class_inst,
|
||||
* some_base_class,
|
||||
* base_class_event_handler,
|
||||
* CLASS_BASE_CONFIGURATION,
|
||||
* (12) // Example values
|
||||
* );
|
||||
* @endcode
|
||||
*
|
||||
* If the type of instance configuration is structure, provide initialization value for the whole structure:
|
||||
* @code
|
||||
* typedef structure
|
||||
* {
|
||||
* uint32_t p1;
|
||||
* uint8_t p2;
|
||||
* }my_config_t;
|
||||
*
|
||||
* APP_USBD_CLASS_TYPEDEF(
|
||||
* some_base_class,
|
||||
* CLASS_BASE_CONFIGURATION,
|
||||
* APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE,
|
||||
* APP_USBD_CLASS_DATA_SPECIFIC_DEC(my_config_t)
|
||||
* );
|
||||
* APP_USBD_CLASS_INST_DEF(
|
||||
* some_base_class_inst,
|
||||
* some_base_class,
|
||||
* base_class_event_handler,
|
||||
* CLASS_BASE_CONFIGURATION,
|
||||
* ({12, 3}) // Example values
|
||||
* );
|
||||
* @endcode
|
||||
*
|
||||
* @param instance_name The name of created instance variable.
|
||||
* It would be constant variable and its type would be app_usbd_class_inst_t.
|
||||
* @param type_name The name of the variable type. It has to be the same type that was passed to
|
||||
* @ref APP_USBD_CLASS_TYPEDEF
|
||||
* @param class_methods Class unified interface.
|
||||
* @param interfaces_configs The same configuration data that the one passed to @ref APP_USBD_CLASS_TYPEDEF
|
||||
* @param class_config_part Configuration data to the type that was declared by class_data_dec when calling
|
||||
* @ref APP_USBD_CLASS_TYPEDEF.
|
||||
* Configuration data has to be provided in brackets.
|
||||
* It would be extracted from brackets and placed in initialization part of configuration structure.
|
||||
* See detailed description of this macro for more informations.
|
||||
*/
|
||||
#define APP_USBD_CLASS_INST_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); \
|
||||
static const APP_USBD_CLASS_INSTANCE_TYPE(type_name) instance_name = \
|
||||
APP_USBD_CLASS_INSTANCE_INITVAL( \
|
||||
&CONCAT_2(instance_name, _data), \
|
||||
class_methods, \
|
||||
interfaces_configs, \
|
||||
class_config_part)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Define the base class instance in global scope
|
||||
*
|
||||
* This is the same macro like @ref APP_USBD_CLASS_INST_DEF but it creates the instance
|
||||
* without static keyword.
|
||||
*
|
||||
* @param instance_name See documentation for @ref APP_USBD_CLASS_INST_DEF
|
||||
* @param type_name See documentation for @ref APP_USBD_CLASS_INST_DEF
|
||||
* @param class_methods See documentation for @ref APP_USBD_CLASS_INST_DEF
|
||||
* @param interfaces_configs See documentation for @ref APP_USBD_CLASS_INST_DEF
|
||||
* @param class_config_part See documentation for @ref APP_USBD_CLASS_INST_DEF
|
||||
*/
|
||||
#define APP_USBD_CLASS_INST_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_INITVAL( \
|
||||
&CONCAT_2(instance_name, _data), \
|
||||
class_methods, \
|
||||
interfaces_configs, \
|
||||
class_config_part)
|
||||
|
||||
/**
|
||||
* @brief Access class specific configuration
|
||||
*
|
||||
* Macro that returns class specific configuration.
|
||||
*
|
||||
* @param[in] p_inst Instance pointer
|
||||
*
|
||||
* @return A pointer for class specific part of the instance
|
||||
*
|
||||
* @note If macro is used on the instance that has no class specific configuration
|
||||
* an error would be generated during compilation.
|
||||
*/
|
||||
#define APP_USBD_CLASS_GET_SPECIFIC_CONFIG(p_inst) (&((p_inst)->specific.class_part))
|
||||
|
||||
/**
|
||||
* @brief Access class specific data
|
||||
*
|
||||
* @param[in] p_inst Instance pointer
|
||||
*
|
||||
* @return A pointer for class specific part of writable data
|
||||
*
|
||||
* @note If macro is used on the instance that has no class specific data
|
||||
* an error would be generated during compilation.
|
||||
*/
|
||||
#define APP_USBD_CLASS_GET_SPECIFIC_DATA(p_inst) (&(((p_inst)->specific.p_data)->class_part))
|
||||
|
||||
/**
|
||||
* @brief Macro to get base instance from class specific instance
|
||||
*
|
||||
* This macro may be used on class specific instance to get base instance that
|
||||
* can be processed by base instance access functions.
|
||||
* Class specific instance can be just casted to class base instance,
|
||||
* 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
|
||||
* and would generate also error if this base member is wrong type.
|
||||
*/
|
||||
#define APP_USBD_CLASS_BASE_INSTANCE(p_inst) (&((p_inst)->base))
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APP_USBD_CLASS_BASE_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,297 @@
|
||||
/**
|
||||
* 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_USBD_CORE_H__
|
||||
#define APP_USBD_CORE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sdk_common.h"
|
||||
#include "nrf_drv_usbd.h"
|
||||
#include "app_usbd_types.h"
|
||||
#include "app_usbd_class_base.h"
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd_core USB Device high level library core module
|
||||
* @ingroup app_usbd
|
||||
*
|
||||
* @brief @tagAPI52840 Core module that manages current USB state and process device requests.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Core interface configuration
|
||||
*
|
||||
* Core instance would have 2 endpoints (IN0 and OUT0).
|
||||
* The interface number does not matter because it is not used.
|
||||
*/
|
||||
#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
|
||||
*
|
||||
* Possible USB Device states according to specification.
|
||||
*/
|
||||
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_t;
|
||||
|
||||
/**
|
||||
* @brief EP0 handler function pointer
|
||||
*
|
||||
* Type of the variable that would hold the pointer to the handler for
|
||||
* endpoint 0 messages processing.
|
||||
*
|
||||
* @param p_contex Context variable configured with the transmission request.
|
||||
*/
|
||||
typedef ret_code_t (*app_usbd_core_setup_data_handler_t)(nrf_drv_usbd_ep_status_t status,
|
||||
void * p_context);
|
||||
|
||||
/**
|
||||
* @brief Variable type used to register EP0 transfer handler
|
||||
*
|
||||
* EP0 messages are processed by core instance.
|
||||
* Another class can register itself to receive messages from EP0 when requesting
|
||||
* for Setup data transfer.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
app_usbd_core_setup_data_handler_t handler; //!< Event handler to be called when transmission is ready
|
||||
void * p_context; //!< Context pointer to be send to every called event.
|
||||
} app_usbd_core_setup_data_handler_desc_t;
|
||||
|
||||
/*lint -save -e10 -e26 -e93 -e123 -e505 */
|
||||
/**
|
||||
* @brief Declare Core instance type
|
||||
*
|
||||
* USBD core instance type definition.
|
||||
*/
|
||||
APP_USBD_CLASS_TYPEDEF(app_usbd_core,
|
||||
APP_USBD_CORE_CLASS_CONFIGURATION,
|
||||
APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE,
|
||||
APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE);
|
||||
/*lint -restore*/
|
||||
|
||||
/**
|
||||
* @brief Access to core instance
|
||||
*
|
||||
* Function that returns pointer to the USBD core instance.
|
||||
*
|
||||
* @return pointer to the core instance
|
||||
*/
|
||||
static inline app_usbd_class_inst_t const * app_usbd_core_instance_access(void)
|
||||
{
|
||||
extern const APP_USBD_CLASS_INSTANCE_TYPE(app_usbd_core) app_usbd_core_inst;
|
||||
return (app_usbd_class_inst_t const *)&app_usbd_core_inst;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default simple response to setup command
|
||||
*
|
||||
* This function generates default simple response.
|
||||
* It sends ZLP when required and on takes care on allowing status stage when
|
||||
* transfer is finished.
|
||||
*
|
||||
* @param p_setup Pointer to original setup message
|
||||
* @param p_data Pointer to the response. This has to be globaly aviable data.
|
||||
* @param size Total size of the answer - The function takes care about
|
||||
* limiting the size of transfered data to the size required
|
||||
* by setup command.
|
||||
*/
|
||||
ret_code_t app_usbd_core_setup_rsp(app_usbd_setup_t const * p_setup,
|
||||
void const * p_data,
|
||||
size_t size);
|
||||
|
||||
/**
|
||||
* @brief Configure the handler for the nearest setup data endpoint transfer
|
||||
*
|
||||
* This function would be called on incomming setup data.
|
||||
* The correct place to set the handler for a data is when SETUP command
|
||||
* was received.
|
||||
*
|
||||
* @param ep Endpoint number (only IN0 and OUT0) are supported.
|
||||
* @param p_handler_desc Descriptor of the handler to be called.
|
||||
*
|
||||
* @retval NRF_SUCCESS Successfully configured
|
||||
* @retval NRF_ERROR_INVALID_ADDR Last received setup direction does not match
|
||||
* configured endpoint.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* Returns special internal buffer that can be used in setup transfer.
|
||||
* @return Internal buffer pointer
|
||||
*/
|
||||
void * app_usbd_core_setup_transfer_buff_get(size_t * p_size);
|
||||
|
||||
|
||||
/**@brief Return internal USBD core state
|
||||
*
|
||||
* @return Check @ref app_usbd_state_t to find possible USBD core states
|
||||
*/
|
||||
app_usbd_state_t app_usbd_core_state_get(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check current feature state
|
||||
*
|
||||
* Function checks the state of the selected feature that was configured by the host.
|
||||
*
|
||||
* @param feature Feature to check.
|
||||
* Only features related to the device should be checked by this function.
|
||||
*
|
||||
* @retval true Selected feature is set
|
||||
* @retval false Selected feature is cleared
|
||||
*/
|
||||
bool app_usbd_core_feature_state_get(app_usbd_setup_stdfeature_t feature);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APP_USBD_CORE_H__ */
|
||||
@@ -0,0 +1,335 @@
|
||||
/**
|
||||
* 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_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"
|
||||
|
||||
/* Compiler support for anonymous unions */
|
||||
ANON_UNIONS_ENABLE
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd_descriptor USB standard descriptors
|
||||
* @ingroup app_usbd
|
||||
*
|
||||
* @brief @tagAPI52840 Module with types definitions used for standard descriptors.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Helper macro for translating unsigned 24 bit value to 2 byte raw descriptor
|
||||
* */
|
||||
#define APP_USBD_U16_TO_RAW_DSC(val) (uint8_t)(val), \
|
||||
(uint8_t)(((val) / (256)))
|
||||
|
||||
/**
|
||||
* @brief Helper macro for translating unsigned 24 bit value to 3 byte raw descriptor
|
||||
* */
|
||||
#define APP_USBD_U24_TO_RAW_DSC(val) (uint8_t)(val), \
|
||||
(uint8_t)(((val) / (256))), \
|
||||
(uint8_t)(((val) / (256 * 256)))
|
||||
|
||||
/**
|
||||
* @brief Helper macro for translating unsigned 32 bit value to 4 byte raw descriptor
|
||||
* */
|
||||
#define APP_USBD_U32_TO_RAW_DSC(val) (uint8_t)(val), \
|
||||
(uint8_t)(((val) / (256))), \
|
||||
(uint8_t)(((val) / (256 * 256))) \
|
||||
(uint8_t)(((val) / (256 * 256 * 256)))
|
||||
/**
|
||||
* @brief Descriptor types
|
||||
*
|
||||
* Descriptor types used in two situations:
|
||||
* - when processing @ref APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR SETUP request,
|
||||
* the required descriptor type may be placed in wValue in HighByte.
|
||||
* - As a descriptor identifier itself inside descriptor stream.
|
||||
*
|
||||
* According to chapter 9.6 of USB 2.0 specification, following descriptors may
|
||||
* be requested directly by GetDescriptor method:
|
||||
* - @ref APP_USBD_DESCRIPTOR_DEVICE
|
||||
* - @ref APP_USBD_DESCRIPTOR_DEVICE_QUALIFIER (not used for FullSpeed only device)
|
||||
* - @ref APP_USBD_DESCRIPTOR_CONFIGURATION
|
||||
* - @ref APP_USBD_DESCRIPTOR_STRING
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
APP_USBD_DESCRIPTOR_DEVICE = 1, /**< Device descriptor. */
|
||||
APP_USBD_DESCRIPTOR_CONFIGURATION = 2, /**<
|
||||
* Specific configuration descriptor.
|
||||
* Configuration descriptor is always followed by all the related interface
|
||||
* and endpoints descriptors.
|
||||
*/
|
||||
APP_USBD_DESCRIPTOR_STRING = 3, /**< String descriptor. */
|
||||
APP_USBD_DESCRIPTOR_INTERFACE = 4, /**<
|
||||
* Interface descriptor followed by all the related endpoints descriptors.
|
||||
*
|
||||
* @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION.
|
||||
* Cannot be accessed by GetDescriptor or SetDescriptor
|
||||
*/
|
||||
APP_USBD_DESCRIPTOR_ENDPOINT = 5, /**<
|
||||
* Endpoint descriptor.
|
||||
*
|
||||
* @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION.
|
||||
* Cannot be accessed by GetDescriptor or SetDescriptor
|
||||
*/
|
||||
APP_USBD_DESCRIPTOR_DEVICE_QUALIFIER = 6, /**< @note Not supported - used only in HighSpeed capable devices. */
|
||||
APP_USBD_DESCRIPTOR_OTHER_SPEED_CONFIGURATION = 7, /**< @note Not supported - our USB implementation supports only one speed. */
|
||||
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 /**<
|
||||
* 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_t;
|
||||
|
||||
/* Make all descriptors packed */
|
||||
#pragma pack(push, 1)
|
||||
|
||||
/**
|
||||
* @brief Common descriptor header
|
||||
*
|
||||
* The header that we can find on the beginning of all descriptors that contains
|
||||
* the descriptor length and type.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; //!< Size of the descriptor in bytes.
|
||||
uint8_t bDescriptorType; //!< Should equal one of @ref app_usbd_descriptor_t.
|
||||
/** Class specific descriptors values are defined inside classes. */
|
||||
} app_usbd_descriptor_header_t;
|
||||
|
||||
/**
|
||||
* @brief Device descriptor
|
||||
*
|
||||
* Descriptor used for the whole device
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; //!< Size of the descriptor in bytes.
|
||||
uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_DEVICE.
|
||||
uint16_t bcdUSB; //!< USB Specification Release Number in Binary-Coded Decimal
|
||||
uint8_t bDeviceClass; //!< Device class code.
|
||||
/**< If 0, each interface specifies its own class information.
|
||||
* 0xFF for vendor-specific.
|
||||
*/
|
||||
uint8_t bDeviceSubClass; //!< Subclass code.
|
||||
/**< If bDevice Class is set to value other than 0xFF,
|
||||
* all values here are reserved for assignment by USB-IF.
|
||||
*/
|
||||
uint8_t bDeviceProtocol; //!< Subclass code.
|
||||
/**< If 0, no specific protocol is defined on device basis.
|
||||
* Each interface may define its own protocol then.
|
||||
* If set to 0xFF, vendor-specific protocol is used.
|
||||
*/
|
||||
uint8_t bMaxPacketSize0; //!< Maximum packet size for endpoint zero.
|
||||
uint16_t idVendor; //!< Vendor ID (Assigned by the USB-IF).
|
||||
uint16_t idProduct; //!< Product ID (assigned by manufacturer).
|
||||
uint16_t bcdDevice; //!< Device release number in binary-coded decimal.
|
||||
uint8_t iManufacturer; //!< Index of string descriptor in describing manufacturer.
|
||||
uint8_t iProduct; //!< Index of string descriptor in describing product.
|
||||
uint8_t iSerialNumber; //!< Index of string descriptor in describing the device's serial number.
|
||||
uint8_t bNumConfigurations; //!< Number of possible configurations.
|
||||
} app_usbd_descriptor_device_t;
|
||||
|
||||
/**
|
||||
* @brief Attributes masks
|
||||
*
|
||||
* Masks used for attributes in configuration.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/** This is reserved descriptor that has always to be set */
|
||||
APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_ALWAYS_SET_MASK = 1U << 7,
|
||||
/** Attribute that informs that device is self powered */
|
||||
APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK = 1U << 6,
|
||||
/** Attribute that informs that device has Remove Wakeup functionality */
|
||||
APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_REMOTE_WAKEUP_MASK = 1U << 5
|
||||
} app_usbd_descriptor_configuration_attributes_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration descriptor
|
||||
*
|
||||
* Descriptor used at the beginning of configuration response.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; //!< Size of the descriptor in bytes.
|
||||
uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_DEVICE.
|
||||
uint16_t wTotalLength; //!< Total length of configuration data, including all descriptors returned after configuration itself.
|
||||
uint8_t bNumInterfaces; //!< Number of interfaces supportedf by this configuration
|
||||
uint8_t bConfigurationValue; //!< Value to use as an argument to the SetConfiguration request.
|
||||
uint8_t iConfiguration; //!< Index of string descriptor describing this configuration.
|
||||
uint8_t bmAttributes; //!< Configuration characteristics.
|
||||
uint8_t bMaxPower; //!< Maximum power consumption. Expressed in 2 mA units.
|
||||
} app_usbd_descriptor_configuration_t;
|
||||
|
||||
/**
|
||||
* @brief Raw descriptor - String descriptor zero
|
||||
*
|
||||
* String descriptor sent only as a response for GetDescriptor.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; //!< Size of the descriptor in bytes.
|
||||
uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_STRING.
|
||||
uint16_t wLANGID[]; //!< The array of LANGID codes supported by the device.
|
||||
} app_usbd_descriptor_string0_t;
|
||||
|
||||
/**
|
||||
* @brief Raw descriptor - Any normal string
|
||||
*
|
||||
* String descriptor sent only as a response for GetDescriptor.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; //!< Size of the descriptor in bytes.
|
||||
uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_STRING.
|
||||
uint16_t bString[]; //!< UNICODE encoded string.
|
||||
} app_usbd_descriptor_string_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Interface descriptor
|
||||
*
|
||||
* Interface descriptor, returned as a part of configuration descriptor.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; //!< Size of the descriptor in bytes.
|
||||
uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_INTERFACE.
|
||||
uint8_t bInterfaceNumber; //!< Number of this interface.
|
||||
uint8_t bAlternateSetting; //!< Value used to select this alternate setting.
|
||||
uint8_t bNumEndpoints; //!< Number of endpoints used by this interface.
|
||||
uint8_t bInterfaceClass; //!< Class code (assigned by the USB-IF). 0xff for vendor specific.
|
||||
uint8_t bInterfaceSubClass; //!< Subclass code (assigned by the USB-IF).
|
||||
uint8_t bInterfaceProtocol; //!< Protocol code (assigned by the USB-IF). 0xff for vendor specific.
|
||||
uint8_t iInterface; //!< Index of string descriptor describing this interface.
|
||||
} app_usbd_descriptor_iface_t;
|
||||
|
||||
/** Offset of endpoint type attribute bits */
|
||||
#define APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET 0
|
||||
/** Mask of endpoint type attribute bits */
|
||||
#define APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET)
|
||||
|
||||
/** Offset of endpoint synchronization type attribute bits */
|
||||
#define APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET 2
|
||||
/** Mask of endpoint synchronization type attribute bits */
|
||||
#define APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET)
|
||||
|
||||
/** Offset of endpoint usage type attribute bits */
|
||||
#define APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET 4
|
||||
/** Mask of endpoint usage type attribute bits */
|
||||
#define APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET)
|
||||
|
||||
/**
|
||||
* @brief Endpoint attributes mnemonics
|
||||
*
|
||||
* @sa APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_MASK
|
||||
* @sa APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_MASK
|
||||
* @sa APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_MASK
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_CONTROL = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
|
||||
APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_ISOCHRONOUS = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
|
||||
APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
|
||||
APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT = 3 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
|
||||
|
||||
APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_NONE = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
|
||||
APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_ASYNCHRONOUS = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
|
||||
APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_ADAPTIVE = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
|
||||
APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_SYNCHRONOUS = 3 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
|
||||
|
||||
APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_DATA = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET,
|
||||
APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_FEEDBACK = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET,
|
||||
APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_IMPLICIT = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET
|
||||
} app_usbd_descriptor_ep_attr_bitmap_t;
|
||||
|
||||
/**
|
||||
* @brief Endpoint descriptor
|
||||
*
|
||||
* Endpoint descriptor, returned as a part of configuration descriptor.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; //!< Size of the descriptor in bytes.
|
||||
uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_ENDPOINT.
|
||||
uint8_t bEndpointAddress; //!< Endpoint address
|
||||
uint8_t bmAttributes; //!< Endpoint attributes
|
||||
uint16_t wMaxPacketSize; //!< Maximum packet size this endpoint is capable of handling.
|
||||
uint8_t bInterval; //!< Interval for pooling endpoint for data transfers.
|
||||
} app_usbd_descriptor_ep_t;
|
||||
|
||||
/**
|
||||
* @brief Interface association descriptor
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; //!< size of this descriptor in bytes
|
||||
uint8_t bDescriptorType; //!< INTERFACE descriptor type
|
||||
uint8_t bFirstInterface; //!< Number of interface
|
||||
uint8_t bInterfaceCount; //!< value to select alternate setting
|
||||
uint8_t bFunctionClass; //!< Class code assigned by the USB
|
||||
uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB
|
||||
uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB
|
||||
uint8_t iFunction; //!< Index of string descriptor
|
||||
} app_usbd_descriptor_iad_t;
|
||||
|
||||
#pragma pack(pop)
|
||||
ANON_UNIONS_DISABLE
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif /* APP_USBD_DESCRIPTOR_H__ */
|
||||
@@ -0,0 +1,286 @@
|
||||
/**
|
||||
* 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_USBD_LANGID_H__
|
||||
#define APP_USBD_LANGID_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief This file contains LANGID variable type with all defined values
|
||||
*
|
||||
* This file was created using Language Identifiers (LANGIDs) 3/29/00 Version 1.0,
|
||||
* available on USB web page:
|
||||
* http://www.usb.org/developers/docs/USB_LANGIDs.pdf
|
||||
*
|
||||
* @note
|
||||
* Do not include this file directly to the project.
|
||||
* It is included by @file app_usbd_request.h.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Offset of the lowest bit of primary language identifier
|
||||
* @sa app_usbd_langid_t
|
||||
*/
|
||||
#define APP_USB_LANG_OFFSET 0
|
||||
|
||||
/**
|
||||
* Bitmask for a primary language identifier
|
||||
* @sa app_usbd_langid_t
|
||||
*/
|
||||
#define APP_USB_LANG_MASK BF_MASK(10, APP_USB_LANG_OFFSET)
|
||||
|
||||
/**
|
||||
* Offset of the lowest bit of sub-language identifier
|
||||
* @sa app_usbd_langid_t
|
||||
*/
|
||||
#define APP_USB_SUBLANG_OFFSET 10
|
||||
|
||||
/**
|
||||
* Bitmask for a sub-language identifier
|
||||
* @sa app_usbd_langid_t
|
||||
*/
|
||||
#define APP_USB_SUBLANG_MASK BF_MASK(6, APP_USB_SUBLANG_OFFSET)
|
||||
|
||||
/**
|
||||
* @brief Primary language identifiers
|
||||
*
|
||||
* Mnemonics for primary language identifiers.
|
||||
* This mnemonics can be combined using logical OR operator with @ref app_usbd_langid_sub_t.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
APP_USBD_LANG_ARABIC = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Arabic */
|
||||
APP_USBD_LANG_BULGARIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Bulgarian */
|
||||
APP_USBD_LANG_CATALAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Catalan */
|
||||
APP_USBD_LANG_CHINESE = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Chinese */
|
||||
APP_USBD_LANG_CZECH = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Czech */
|
||||
APP_USBD_LANG_DANISH = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Danish */
|
||||
APP_USBD_LANG_GERMAN = 0x07U << ( APP_USB_LANG_OFFSET ), /**< German */
|
||||
APP_USBD_LANG_GREEK = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Greek */
|
||||
APP_USBD_LANG_ENGLISH = 0x09U << ( APP_USB_LANG_OFFSET ), /**< English */
|
||||
APP_USBD_LANG_SPANISH = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< Spanish */
|
||||
APP_USBD_LANG_FINNISH = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< Finnish */
|
||||
APP_USBD_LANG_FRENCH = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< French */
|
||||
APP_USBD_LANG_HEBREW = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< Hebrew */
|
||||
APP_USBD_LANG_HUNGARIAN = 0x0eU << ( APP_USB_LANG_OFFSET ), /**< Hungarian */
|
||||
APP_USBD_LANG_ICELANDIC = 0x0fU << ( APP_USB_LANG_OFFSET ), /**< Icelandic */
|
||||
APP_USBD_LANG_ITALIAN = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Italian */
|
||||
APP_USBD_LANG_JAPANESE = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Japanese */
|
||||
APP_USBD_LANG_KOREAN = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Korean */
|
||||
APP_USBD_LANG_DUTCH = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Dutch */
|
||||
APP_USBD_LANG_NORWEGIAN = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Norwegian */
|
||||
APP_USBD_LANG_POLISH = 0x15U << ( APP_USB_LANG_OFFSET ), /**< Polish */
|
||||
APP_USBD_LANG_PORTUGUESE = 0x16U << ( APP_USB_LANG_OFFSET ), /**< Portuguese */
|
||||
APP_USBD_LANG_ROMANIAN = 0x18U << ( APP_USB_LANG_OFFSET ), /**< Romanian */
|
||||
APP_USBD_LANG_RUSSIAN = 0x19U << ( APP_USB_LANG_OFFSET ), /**< Russian */
|
||||
APP_USBD_LANG_CROATIAN = 0x1aU << ( APP_USB_LANG_OFFSET ), /**< Croatian */
|
||||
APP_USBD_LANG_SERBIAN = 0x1aU << ( APP_USB_LANG_OFFSET ), /**< Serbian */
|
||||
APP_USBD_LANG_SLOVAK = 0x1bU << ( APP_USB_LANG_OFFSET ), /**< Slovak */
|
||||
APP_USBD_LANG_ALBANIAN = 0x1cU << ( APP_USB_LANG_OFFSET ), /**< Albanian */
|
||||
APP_USBD_LANG_SWEDISH = 0x1dU << ( APP_USB_LANG_OFFSET ), /**< Swedish */
|
||||
APP_USBD_LANG_THAI = 0x1eU << ( APP_USB_LANG_OFFSET ), /**< Thai */
|
||||
APP_USBD_LANG_TURKISH = 0x1fU << ( APP_USB_LANG_OFFSET ), /**< Turkish */
|
||||
APP_USBD_LANG_URDU = 0x20U << ( APP_USB_LANG_OFFSET ), /**< Urdu */
|
||||
APP_USBD_LANG_INDONESIAN = 0x21U << ( APP_USB_LANG_OFFSET ), /**< Indonesian */
|
||||
APP_USBD_LANG_UKRANIAN = 0x22U << ( APP_USB_LANG_OFFSET ), /**< Ukrainian */
|
||||
APP_USBD_LANG_BELARUSIAN = 0x23U << ( APP_USB_LANG_OFFSET ), /**< Belarusian */
|
||||
APP_USBD_LANG_SLOVENIAN = 0x24U << ( APP_USB_LANG_OFFSET ), /**< Slovenian */
|
||||
APP_USBD_LANG_ESTONIAN = 0x25U << ( APP_USB_LANG_OFFSET ), /**< Estonian */
|
||||
APP_USBD_LANG_LATVIAN = 0x26U << ( APP_USB_LANG_OFFSET ), /**< Latvian */
|
||||
APP_USBD_LANG_LITHUANIAN = 0x27U << ( APP_USB_LANG_OFFSET ), /**< Lithuanian */
|
||||
APP_USBD_LANG_FARSI = 0x29U << ( APP_USB_LANG_OFFSET ), /**< Farsi */
|
||||
APP_USBD_LANG_VIETNAMESE = 0x2aU << ( APP_USB_LANG_OFFSET ), /**< Vietnamese */
|
||||
APP_USBD_LANG_ARMENIAN = 0x2bU << ( APP_USB_LANG_OFFSET ), /**< Armenian */
|
||||
APP_USBD_LANG_AZERI = 0x2cU << ( APP_USB_LANG_OFFSET ), /**< Azeri */
|
||||
APP_USBD_LANG_BASQUE = 0x2dU << ( APP_USB_LANG_OFFSET ), /**< Basque */
|
||||
APP_USBD_LANG_MACEDONIAN = 0x2fU << ( APP_USB_LANG_OFFSET ), /**< Macedonian */
|
||||
APP_USBD_LANG_AFRIKAANS = 0x36U << ( APP_USB_LANG_OFFSET ), /**< Afrikaans */
|
||||
APP_USBD_LANG_GEORGIAN = 0x37U << ( APP_USB_LANG_OFFSET ), /**< Georgian */
|
||||
APP_USBD_LANG_FAEROESE = 0x38U << ( APP_USB_LANG_OFFSET ), /**< Faeroese */
|
||||
APP_USBD_LANG_HINDI = 0x39U << ( APP_USB_LANG_OFFSET ), /**< Hindi */
|
||||
APP_USBD_LANG_MALAY = 0x3eU << ( APP_USB_LANG_OFFSET ), /**< Malay */
|
||||
APP_USBD_LANG_KAZAK = 0x3fU << ( APP_USB_LANG_OFFSET ), /**< Kazak */
|
||||
APP_USBD_LANG_SWAHILI = 0x41U << ( APP_USB_LANG_OFFSET ), /**< Swahili */
|
||||
APP_USBD_LANG_UZBEK = 0x43U << ( APP_USB_LANG_OFFSET ), /**< Uzbek */
|
||||
APP_USBD_LANG_TATAR = 0x44U << ( APP_USB_LANG_OFFSET ), /**< Tatar */
|
||||
APP_USBD_LANG_BENGALI = 0x45U << ( APP_USB_LANG_OFFSET ), /**< Bengali */
|
||||
APP_USBD_LANG_PUNJABI = 0x46U << ( APP_USB_LANG_OFFSET ), /**< Punjabi */
|
||||
APP_USBD_LANG_GUJARATI = 0x47U << ( APP_USB_LANG_OFFSET ), /**< Gujarati */
|
||||
APP_USBD_LANG_ORIYA = 0x48U << ( APP_USB_LANG_OFFSET ), /**< Oriya */
|
||||
APP_USBD_LANG_TAMIL = 0x49U << ( APP_USB_LANG_OFFSET ), /**< Tamil */
|
||||
APP_USBD_LANG_TELUGU = 0x4aU << ( APP_USB_LANG_OFFSET ), /**< Telugu */
|
||||
APP_USBD_LANG_KANNADA = 0x4bU << ( APP_USB_LANG_OFFSET ), /**< Kannada */
|
||||
APP_USBD_LANG_MALAYALAM = 0x4cU << ( APP_USB_LANG_OFFSET ), /**< Malayalam */
|
||||
APP_USBD_LANG_ASSAMESE = 0x4dU << ( APP_USB_LANG_OFFSET ), /**< Assamese */
|
||||
APP_USBD_LANG_MARATHI = 0x4eU << ( APP_USB_LANG_OFFSET ), /**< Marathi */
|
||||
APP_USBD_LANG_SANSKRIT = 0x4fU << ( APP_USB_LANG_OFFSET ), /**< Sanskrit */
|
||||
APP_USBD_LANG_KONKANI = 0x57U << ( APP_USB_LANG_OFFSET ), /**< Konkani */
|
||||
APP_USBD_LANG_MANIPURI = 0x58U << ( APP_USB_LANG_OFFSET ), /**< Manipuri */
|
||||
APP_USBD_LANG_SINDHI = 0x59U << ( APP_USB_LANG_OFFSET ), /**< Sindhi */
|
||||
APP_USBD_LANG_KASHMIRI = 0x60U << ( APP_USB_LANG_OFFSET ), /**< Kashmiri */
|
||||
APP_USBD_LANG_NEPALI = 0x61U << ( APP_USB_LANG_OFFSET ), /**< Nepali */
|
||||
APP_USBD_LANG_HID = 0xffU << ( APP_USB_LANG_OFFSET ), /**< Reserved for USB HID Class use */
|
||||
}app_usbd_langid_primary_t;
|
||||
|
||||
/**
|
||||
* @brief Sublanguage identifiers
|
||||
*
|
||||
* Mnemonics with sublanguage values.
|
||||
* Use them in combination with @ref app_usbd_langid_primary_t.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
APP_USBD_SUBLANG_ARABIC_SAUDI_ARABIA = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Saudi Arabia) */
|
||||
APP_USBD_SUBLANG_ARABIC_IRAQ = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Iraq) */
|
||||
APP_USBD_SUBLANG_ARABIC_EGYPT = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Egypt) */
|
||||
APP_USBD_SUBLANG_ARABIC_LIBYA = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Libya) */
|
||||
APP_USBD_SUBLANG_ARABIC_ALGERIA = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Algeria) */
|
||||
APP_USBD_SUBLANG_ARABIC_MOROCCO = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Morocco) */
|
||||
APP_USBD_SUBLANG_ARABIC_TUNISIA = 0x07U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Tunisia) */
|
||||
APP_USBD_SUBLANG_ARABIC_OMAN = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Oman) */
|
||||
APP_USBD_SUBLANG_ARABIC_YEMEN = 0x09U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Yemen) */
|
||||
APP_USBD_SUBLANG_ARABIC_SYRIA = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Syria) */
|
||||
APP_USBD_SUBLANG_ARABIC_JORDAN = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Jordan) */
|
||||
APP_USBD_SUBLANG_ARABIC_LEBANON = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Lebanon) */
|
||||
APP_USBD_SUBLANG_ARABIC_KUWAIT = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Kuwait) */
|
||||
APP_USBD_SUBLANG_ARABIC_UAE = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Arabic (U.A.E.) */
|
||||
APP_USBD_SUBLANG_ARABIC_BAHRAIN = 0x15U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Bahrain) */
|
||||
APP_USBD_SUBLANG_ARABIC_QATAR = 0x16U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Qatar) */
|
||||
APP_USBD_SUBLANG_AZERI_CYRILLIC = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Azeri (Cyrillic) */
|
||||
APP_USBD_SUBLANG_AZERI_LATIN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Azeri (Latin) */
|
||||
APP_USBD_SUBLANG_CHINESE_TRADITIONAL = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Traditional) */
|
||||
APP_USBD_SUBLANG_CHINESE_SIMPLIFIED = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Simplified) */
|
||||
APP_USBD_SUBLANG_CHINESE_HONGKONG = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Hong Kong SAR, PRC) */
|
||||
APP_USBD_SUBLANG_CHINESE_SINGAPORE = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Singapore) */
|
||||
APP_USBD_SUBLANG_CHINESE_MACAU = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Macau SAR) */
|
||||
APP_USBD_SUBLANG_DUTCH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Dutch */
|
||||
APP_USBD_SUBLANG_DUTCH_BELGIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Dutch (Belgian) */
|
||||
APP_USBD_SUBLANG_ENGLISH_US = 0x01U << ( APP_USB_LANG_OFFSET ), /**< English (US) */
|
||||
APP_USBD_SUBLANG_ENGLISH_UK = 0x02U << ( APP_USB_LANG_OFFSET ), /**< English (UK) */
|
||||
APP_USBD_SUBLANG_ENGLISH_AUS = 0x03U << ( APP_USB_LANG_OFFSET ), /**< English (Australian) */
|
||||
APP_USBD_SUBLANG_ENGLISH_CAN = 0x04U << ( APP_USB_LANG_OFFSET ), /**< English (Canadian) */
|
||||
APP_USBD_SUBLANG_ENGLISH_NZ = 0x05U << ( APP_USB_LANG_OFFSET ), /**< English (New Zealand) */
|
||||
APP_USBD_SUBLANG_ENGLISH_EIRE = 0x06U << ( APP_USB_LANG_OFFSET ), /**< English (Ireland) */
|
||||
APP_USBD_SUBLANG_ENGLISH_SOUTH_AFRICA = 0x07U << ( APP_USB_LANG_OFFSET ), /**< English (South Africa) */
|
||||
APP_USBD_SUBLANG_ENGLISH_JAMAICA = 0x08U << ( APP_USB_LANG_OFFSET ), /**< English (Jamaica) */
|
||||
APP_USBD_SUBLANG_ENGLISH_CARIBBEAN = 0x09U << ( APP_USB_LANG_OFFSET ), /**< English (Caribbean) */
|
||||
APP_USBD_SUBLANG_ENGLISH_BELIZE = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< English (Belize) */
|
||||
APP_USBD_SUBLANG_ENGLISH_TRINIDAD = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< English (Trinidad) */
|
||||
APP_USBD_SUBLANG_ENGLISH_PHILIPPINES = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< English (Zimbabwe) */
|
||||
APP_USBD_SUBLANG_ENGLISH_ZIMBABWE = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< English (Philippines) */
|
||||
APP_USBD_SUBLANG_FRENCH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< French */
|
||||
APP_USBD_SUBLANG_FRENCH_BELGIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< French (Belgian) */
|
||||
APP_USBD_SUBLANG_FRENCH_CANADIAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< French (Canadian) */
|
||||
APP_USBD_SUBLANG_FRENCH_SWISS = 0x04U << ( APP_USB_LANG_OFFSET ), /**< French (Swiss) */
|
||||
APP_USBD_SUBLANG_FRENCH_LUXEMBOURG = 0x05U << ( APP_USB_LANG_OFFSET ), /**< French (Luxembourg) */
|
||||
APP_USBD_SUBLANG_FRENCH_MONACO = 0x06U << ( APP_USB_LANG_OFFSET ), /**< French (Monaco) */
|
||||
APP_USBD_SUBLANG_GERMAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< German */
|
||||
APP_USBD_SUBLANG_GERMAN_SWISS = 0x02U << ( APP_USB_LANG_OFFSET ), /**< German (Swiss) */
|
||||
APP_USBD_SUBLANG_GERMAN_AUSTRIAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< German (Austrian) */
|
||||
APP_USBD_SUBLANG_GERMAN_LUXEMBOURG = 0x04U << ( APP_USB_LANG_OFFSET ), /**< German (Luxembourg) */
|
||||
APP_USBD_SUBLANG_GERMAN_LIECHTENSTEIN = 0x05U << ( APP_USB_LANG_OFFSET ), /**< German (Liechtenstein) */
|
||||
APP_USBD_SUBLANG_ITALIAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Italian */
|
||||
APP_USBD_SUBLANG_ITALIAN_SWISS = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Italian (Swiss) */
|
||||
APP_USBD_SUBLANG_KASHMIRI_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Kashmiri (India) */
|
||||
APP_USBD_SUBLANG_KOREAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Korean */
|
||||
APP_USBD_SUBLANG_LITHUANIAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Lithuanian */
|
||||
APP_USBD_SUBLANG_MALAY_MALAYSIA = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Malay (Malaysia) */
|
||||
APP_USBD_SUBLANG_MALAY_BRUNEI_DARUSSALAM = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Malay (Brunei Darassalam) */
|
||||
APP_USBD_SUBLANG_NEPALI_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Nepali (India) */
|
||||
APP_USBD_SUBLANG_NORWEGIAN_BOKMAL = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Norwegian (Bokmal) */
|
||||
APP_USBD_SUBLANG_NORWEGIAN_NYNORSK = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Norwegian (Nynorsk) */
|
||||
APP_USBD_SUBLANG_PORTUGUESE = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Portuguese (Brazilian) */
|
||||
APP_USBD_SUBLANG_PORTUGUESE_BRAZILIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Portuguese */
|
||||
APP_USBD_SUBLANG_SERBIAN_LATIN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Serbian (Latin) */
|
||||
APP_USBD_SUBLANG_SERBIAN_CYRILLIC = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Serbian (Cyrillic) */
|
||||
APP_USBD_SUBLANG_SPANISH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Castilian) */
|
||||
APP_USBD_SUBLANG_SPANISH_MEXICAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Mexican) */
|
||||
APP_USBD_SUBLANG_SPANISH_MODERN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Modern) */
|
||||
APP_USBD_SUBLANG_SPANISH_GUATEMALA = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Guatemala) */
|
||||
APP_USBD_SUBLANG_SPANISH_COSTA_RICA = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Costa Rica) */
|
||||
APP_USBD_SUBLANG_SPANISH_PANAMA = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Panama) */
|
||||
APP_USBD_SUBLANG_SPANISH_DOMINICAN_REPUBLIC = 0x07U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Dominican Republic) */
|
||||
APP_USBD_SUBLANG_SPANISH_VENEZUELA = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Venezuela) */
|
||||
APP_USBD_SUBLANG_SPANISH_COLOMBIA = 0x09U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Colombia) */
|
||||
APP_USBD_SUBLANG_SPANISH_PERU = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Peru) */
|
||||
APP_USBD_SUBLANG_SPANISH_ARGENTINA = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Argentina) */
|
||||
APP_USBD_SUBLANG_SPANISH_ECUADOR = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Ecuador) */
|
||||
APP_USBD_SUBLANG_SPANISH_CHILE = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Chile) */
|
||||
APP_USBD_SUBLANG_SPANISH_URUGUAY = 0x0eU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Uruguay) */
|
||||
APP_USBD_SUBLANG_SPANISH_PARAGUAY = 0x0fU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Paraguay) */
|
||||
APP_USBD_SUBLANG_SPANISH_BOLIVIA = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Bolivia) */
|
||||
APP_USBD_SUBLANG_SPANISH_EL_SALVADOR = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Spanish (El Salvador) */
|
||||
APP_USBD_SUBLANG_SPANISH_HONDURAS = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Honduras) */
|
||||
APP_USBD_SUBLANG_SPANISH_NICARAGUA = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Nicaragua) */
|
||||
APP_USBD_SUBLANG_SPANISH_PUERTO_RICO = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Puerto Rico) */
|
||||
APP_USBD_SUBLANG_SWEDISH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Swedish */
|
||||
APP_USBD_SUBLANG_SWEDISH_FINLAND = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Swedish (Finland) */
|
||||
APP_USBD_SUBLANG_URDU_PAKISTAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Urdu (Pakistan) */
|
||||
APP_USBD_SUBLANG_URDU_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Urdu (India) */
|
||||
APP_USBD_SUBLANG_UZBEK_LATIN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Uzbek (Latin) */
|
||||
APP_USBD_SUBLANG_UZBEK_CYRILLIC = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Uzbek (Cyrillic) */
|
||||
APP_USBD_SUBLANG_HID_USAGE_DATA_DESCRIPTOR = 0x01U << ( APP_USB_LANG_OFFSET ), /**< HID (Usage Data Descriptor) */
|
||||
APP_USBD_SUBLANG_HID_VENDOR_DEFINED_1 = 0x3cU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 1) */
|
||||
APP_USBD_SUBLANG_HID_VENDOR_DEFINED_2 = 0x3dU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 2) */
|
||||
APP_USBD_SUBLANG_HID_VENDOR_DEFINED_3 = 0x3eU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 3) */
|
||||
APP_USBD_SUBLANG_HID_VENDOR_DEFINED_4 = 0x3fU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 4) */
|
||||
}app_usbd_langid_sub_t;
|
||||
|
||||
/**
|
||||
* @brief LANGID variable
|
||||
*
|
||||
* The LANGID value is composed from:
|
||||
* - 10-bit (9-0) of Primary Language Identifiers
|
||||
* - 6-bit (15-10) of Sublanguage Identifiers.
|
||||
*
|
||||
* @sa app_usbd_langid_primary_t
|
||||
* @sa app_usbd_langid_sub_t
|
||||
*/
|
||||
typedef uint16_t app_usbd_langid_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APP_USBD_LANGID_H__ */
|
||||
@@ -0,0 +1,355 @@
|
||||
/**
|
||||
* 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_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"
|
||||
|
||||
/* Compiler support for anonymous unions */
|
||||
ANON_UNIONS_ENABLE
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd_request USB standard requests
|
||||
* @ingroup app_usbd
|
||||
*
|
||||
* @brief @tagAPI52840 Module with types definitions used for standard requests processing.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Recipient bit-field in request type
|
||||
*
|
||||
* Bits 4...0
|
||||
*/
|
||||
#define APP_USBD_SETUP_REQ_BF_REC BF_CX(5, 0)
|
||||
|
||||
/**
|
||||
* @brief Type bit-field in request type
|
||||
*
|
||||
* Bits 6...5
|
||||
*/
|
||||
#define APP_USBD_SETUP_REQ_BF_TYP BF_CX(2, 5)
|
||||
|
||||
/**
|
||||
* @brief Direction bit-field in request type
|
||||
*
|
||||
* Bit 7
|
||||
*/
|
||||
#define APP_USBD_SETUP_REQ_BF_DIR BF_CX(1, 7)
|
||||
|
||||
/**
|
||||
* @brief Recipient enumerator.
|
||||
*
|
||||
* @note It is part of @ref app_usbd_setup_reqtype_t variable type.
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_SETUP_REQREC_DEVICE = 0x0, /**< The whole device is a request target */
|
||||
APP_USBD_SETUP_REQREC_INTERFACE = 0x1, /**< Selected interface is a request target */
|
||||
APP_USBD_SETUP_REQREC_ENDPOINT = 0x2, /**< Selected endpoint is a request target */
|
||||
APP_USBD_SETUP_REQREC_OTHER = 0x3 /**< Other element is a request target */
|
||||
} app_usbd_setup_reqrec_t;
|
||||
|
||||
/**
|
||||
* @brief Request type enumerator.
|
||||
*
|
||||
* @note It is part of @ref app_usbd_setup_reqtype_t variable type.
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_SETUP_REQTYPE_STD = 0x0, /**< Standard request */
|
||||
APP_USBD_SETUP_REQTYPE_CLASS = 0x1, /**< Class specific request */
|
||||
APP_USBD_SETUP_REQTYPE_VENDOR = 0x2 /**< Vendor specific request */
|
||||
} app_usbd_setup_reqtype_t;
|
||||
|
||||
/**
|
||||
* @brief Direction of setup command
|
||||
*
|
||||
* @note It is part of @ref app_usbd_setup_reqtype_t variable type.
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_SETUP_REQDIR_OUT = 0x0, /**< Host to device */
|
||||
APP_USBD_SETUP_REQDIR_IN = 0x1, /**< Device to host */
|
||||
} app_usbd_setup_reqdir_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Standard requests
|
||||
*
|
||||
* Enumerator for standard requests values
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_SETUP_STDREQ_GET_STATUS = 0x00, /**<
|
||||
* Targets: Device, Interface, Endpoint
|
||||
* Expected SETUP frame format:
|
||||
* - wValue: Zero
|
||||
* - wIndex: Zero, (lb): Interface or Endpoint
|
||||
* - wLength: 2
|
||||
* - Data:2 bytes of data, depending on targets
|
||||
* - Device:
|
||||
* - D15..D2: Reserved (Reset to zero)
|
||||
* - D1: Remove Wakeup
|
||||
* - D0: Self Powered
|
||||
* - Interface:
|
||||
* - D15..D0: Reserved (Reset to zero)
|
||||
* - Endpoint:
|
||||
* - D15..D1: Reserved (Reset to zero)
|
||||
* - D0: Halt
|
||||
*/
|
||||
APP_USBD_SETUP_STDREQ_CLEAR_FEATURE = 0x01, /**<
|
||||
* Targets: Device, Interface, Endpoint
|
||||
* Expected SETUP frame format:
|
||||
* - wValue: Feature selector (@ref app_usbd_setup_stdfeature_t)
|
||||
* - wIndex: Zero, Interface or Endpoint
|
||||
* - wLength: 0
|
||||
* - Data: None
|
||||
*/
|
||||
APP_USBD_SETUP_STDREQ_SET_FEATURE = 0x03, /**<
|
||||
* Targets: Device, Interface, Endpoint
|
||||
* Expected SETUP frame format:
|
||||
* - wValue: Feature selector (@ref app_usbd_setup_stdfeature_t)
|
||||
* - wIndex: Zero, Interface or Endpoint
|
||||
* - wLength: 0
|
||||
* - Data: None
|
||||
*/
|
||||
APP_USBD_SETUP_STDREQ_SET_ADDRESS = 0x05, /**<
|
||||
* @note This SETUP request is processed in hardware.
|
||||
* Use it only to mark current USB state.
|
||||
*
|
||||
* Targets: Device
|
||||
* Expected SETUP frame format:
|
||||
* - wValue: New device address
|
||||
* - wIndex: 0
|
||||
* - wLength: 0
|
||||
* - Data: None
|
||||
*/
|
||||
APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR = 0x06, /**<
|
||||
* Targets: Device
|
||||
* - wValue: (hb): Descriptor Type and (lb): Descriptor Index
|
||||
* - wIndex: Zero of Language ID
|
||||
* - wLength: Descriptor Length
|
||||
* - Data: Descriptor
|
||||
*/
|
||||
APP_USBD_SETUP_STDREQ_SET_DESCRIPTOR = 0x07, /**<
|
||||
* Not supported - Stall when called.
|
||||
*/
|
||||
APP_USBD_SETUP_STDREQ_GET_CONFIGURATION = 0x08, /**<
|
||||
* Target: Device
|
||||
* Expected SETUP frame format:
|
||||
* - wValue: 0
|
||||
* - wIndex: 0
|
||||
* - wLength: 1
|
||||
* - Data: Configuration value
|
||||
*/
|
||||
APP_USBD_SETUP_STDREQ_SET_CONFIGURATION = 0x09, /**<
|
||||
* Target: Device
|
||||
* Expected SETUP frame format:
|
||||
* - wValue: (lb): Configuration value
|
||||
* - wIndex: 0
|
||||
* - wLength: 0
|
||||
* - Data: None
|
||||
*/
|
||||
APP_USBD_SETUP_STDREQ_GET_INTERFACE = 0x0A, /**<
|
||||
* Target: Interface
|
||||
* Expected SETUP frame format:
|
||||
* - wValue: 0
|
||||
* - wIndex: Interface
|
||||
* - wLength: 1
|
||||
* - Data: Alternate setting
|
||||
*/
|
||||
APP_USBD_SETUP_STDREQ_SET_INTERFACE = 0x0B, /**<
|
||||
* Target: Interface
|
||||
* Expected SETUP frame format:
|
||||
* - wValue: Alternate setting
|
||||
* - wIndex: Interface
|
||||
* - wLength: 0
|
||||
* - Data: None
|
||||
*/
|
||||
APP_USBD_SETUP_STDREQ_SYNCH_FRAME = 0x0C /**<
|
||||
* Target: Endpoint
|
||||
* Expected SETUP frame format:
|
||||
* - wValue: 0
|
||||
* - wIndex: Endpoint
|
||||
* - wLength: 2
|
||||
* - Data: Frame Number
|
||||
*
|
||||
* @note
|
||||
* This request is used only in connection with isochronous endpoints.
|
||||
* This is rarely used and probably we would not need to support it.
|
||||
*/
|
||||
} app_usbd_setup_stdrequest_t;
|
||||
|
||||
/**
|
||||
* @brief Standard feature selectors
|
||||
*
|
||||
* Standard features that may be disabled or enabled by
|
||||
* @ref APP_USBD_SETUP_STDREQ_CLEAR_FEATURE or @ref APP_USBD_SETUP_STDREQ_SET_FEATURE
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP = 1, /**< Remote wakeup feature.
|
||||
*
|
||||
* Target: Device only
|
||||
*/
|
||||
APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT = 0, /**< Stall or clear the endpoint.
|
||||
*
|
||||
* Target: Endpoint different than default (0)
|
||||
*/
|
||||
APP_USBD_SETUP_STDFEATURE_TEST_MODE = 2 /**< Upstream port test mode.
|
||||
* Power has to be cycled to exit test mode.
|
||||
* This feature cannot be cleared.
|
||||
*
|
||||
* Target: Device only
|
||||
*
|
||||
* @note
|
||||
* It should only be supported by HighSpeed capable devices.
|
||||
* Not supported in this library.
|
||||
*/
|
||||
} app_usbd_setup_stdfeature_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Universal way to access 16 bit values and its parts
|
||||
*/
|
||||
typedef union {
|
||||
uint16_t w; //!< 16 bit access
|
||||
struct
|
||||
{
|
||||
uint8_t lb; //!< Low byte access
|
||||
uint8_t hb; //!< High byte access
|
||||
};
|
||||
} app_usbd_setup_w_t;
|
||||
|
||||
/**
|
||||
* @brief Internal redefinition of setup structure
|
||||
*
|
||||
* Redefinition of the structure to simplify changes in the future
|
||||
* if required - app_usbd API would present setup data using app_usbd_setup_t.
|
||||
*
|
||||
* The structure layout is always the same like @ref nrf_drv_usbd_setup_t
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t bmRequestType; //!< Setup type bitfield
|
||||
uint8_t bmRequest; //!< One of @ref app_usbd_setup_stdrequest_t values or class dependent one.
|
||||
app_usbd_setup_w_t wValue; //!< byte 2, 3
|
||||
app_usbd_setup_w_t wIndex; //!< byte 4, 5
|
||||
app_usbd_setup_w_t wLength; //!< byte 6, 7
|
||||
} app_usbd_setup_t;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Extract recipient from request type
|
||||
*
|
||||
* @param[in] bmRequestType
|
||||
*
|
||||
* @return Extracted recipient field from request type value
|
||||
*/
|
||||
static inline app_usbd_setup_reqrec_t app_usbd_setup_req_rec(uint8_t bmRequestType)
|
||||
{
|
||||
return (app_usbd_setup_reqrec_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_REC);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Extract type from request type
|
||||
*
|
||||
* @param[in] bmRequestType
|
||||
*
|
||||
* @return Extracted type field from request type value
|
||||
*/
|
||||
static inline app_usbd_setup_reqtype_t app_usbd_setup_req_typ(uint8_t bmRequestType)
|
||||
{
|
||||
return (app_usbd_setup_reqtype_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_TYP);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Extract direction from request type
|
||||
*
|
||||
* @param[in] bmRequestType
|
||||
*
|
||||
* @return Extracted direction field from request type value
|
||||
*/
|
||||
static inline app_usbd_setup_reqdir_t app_usbd_setup_req_dir(uint8_t bmRequestType)
|
||||
{
|
||||
return (app_usbd_setup_reqdir_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_DIR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Make request type value
|
||||
*
|
||||
* @param[in] rec Recipient
|
||||
* @param[in] typ Request type
|
||||
* @param[in] dir Direction
|
||||
*
|
||||
* @return Assembled request type value
|
||||
*/
|
||||
static inline uint8_t app_usbd_setup_req_val(app_usbd_setup_reqrec_t rec,
|
||||
app_usbd_setup_reqtype_t typ,
|
||||
app_usbd_setup_reqdir_t dir)
|
||||
{
|
||||
uint32_t bmRequestType = (
|
||||
BF_CX_VAL(rec, APP_USBD_SETUP_REQ_BF_REC) |
|
||||
BF_CX_VAL(typ, APP_USBD_SETUP_REQ_BF_TYP) |
|
||||
BF_CX_VAL(dir, APP_USBD_SETUP_REQ_BF_DIR)
|
||||
);
|
||||
|
||||
ASSERT(bmRequestType < 256U);
|
||||
return (uint8_t)bmRequestType;
|
||||
}
|
||||
|
||||
|
||||
ANON_UNIONS_DISABLE
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APP_USBD_REQUEST_H__ */
|
||||
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include "sdk_config.h"
|
||||
#if APP_USBD_ENABLED
|
||||
#include "app_usbd_string_desc.h"
|
||||
#include "app_usbd_langid.h"
|
||||
#include "app_usbd_core.h"
|
||||
#include "nordic_common.h"
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd_string_desc
|
||||
* @ingroup app_usbd
|
||||
*
|
||||
* USBD string descriptors management
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Array with language identifiers
|
||||
*
|
||||
* This array would be used to search the proper string for selected language.
|
||||
*/
|
||||
static const uint16_t m_langids[] = { APP_USBD_STRINGS_LANGIDS };
|
||||
|
||||
/**
|
||||
* @brief Language ID descriptor
|
||||
*
|
||||
* Language
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Mnemonics for the string positions in the array
|
||||
*
|
||||
* The mnemonics for the indexes of the strings inside the string array.
|
||||
*/
|
||||
enum {
|
||||
APP_USBD_STRING_ID_LANGIDS_ARRAY_POS = 0, /**< Supported language identifiers */
|
||||
APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS, /**< Manufacturer name */
|
||||
APP_USBD_STRING_ID_PRODUCT_ARRAY_POS, /**< Product name */
|
||||
APP_USBD_STRING_ID_SERIAL_ARRAY_POS, /**< Serial number */
|
||||
#define X(mnemonic, str_idx, ...) CONCAT_2(mnemonic, _ARRAY_POS),
|
||||
APP_USBD_STRINGS_USER
|
||||
#undef X
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief String index into internal array index conversion table
|
||||
*
|
||||
* The array that transforms the USB string indexes into internal array position.
|
||||
* @note Value 0 used to mark non-existing string.
|
||||
*/
|
||||
static const uint8_t m_string_translation[APP_USBD_STRING_ID_CNT] =
|
||||
{
|
||||
[APP_USBD_STRING_ID_LANGIDS ] = APP_USBD_STRING_ID_LANGIDS_ARRAY_POS,
|
||||
[APP_USBD_STRING_ID_MANUFACTURER] = APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS,
|
||||
[APP_USBD_STRING_ID_PRODUCT ] = APP_USBD_STRING_ID_PRODUCT_ARRAY_POS,
|
||||
[APP_USBD_STRING_ID_SERIAL ] = APP_USBD_STRING_ID_SERIAL_ARRAY_POS,
|
||||
#define X(mnemonic, str_idx, ...) [mnemonic] = CONCAT_2(mnemonic, _ARRAY_POS),
|
||||
APP_USBD_STRINGS_USER
|
||||
#undef X
|
||||
};
|
||||
|
||||
#ifndef APP_USBD_STRINGS_MANUFACTURER_EXTERN
|
||||
#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0
|
||||
#endif
|
||||
|
||||
#ifndef APP_USBD_STRINGS_PRODUCT_EXTERN
|
||||
#define APP_USBD_STRINGS_PRODUCT_EXTERN 0
|
||||
#endif
|
||||
|
||||
#ifndef APP_USBD_STRING_SERIAL_EXTERN
|
||||
#define APP_USBD_STRING_SERIAL_EXTERN 0
|
||||
#endif
|
||||
|
||||
#if APP_USBD_STRINGS_MANUFACTURER_EXTERN
|
||||
extern uint16_t APP_USBD_STRINGS_MANUFACTURER[];
|
||||
#endif
|
||||
|
||||
#if APP_USBD_STRINGS_PRODUCT_EXTERN
|
||||
extern uint16_t APP_USBD_STRINGS_PRODUCT[];
|
||||
#endif
|
||||
|
||||
#if APP_USBD_STRING_SERIAL_EXTERN
|
||||
extern uint16_t APP_USBD_STRING_SERIAL[];
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief String descriptors table
|
||||
* */
|
||||
static const uint16_t * m_string_dsc[APP_USBD_STRING_ID_CNT][ARRAY_SIZE(m_langids)] =
|
||||
{
|
||||
[APP_USBD_STRING_ID_LANGIDS_ARRAY_POS] = { APP_USBD_STRING_DESC(APP_USBD_STRINGS_LANGIDS) },
|
||||
[APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS] = { APP_USBD_STRINGS_MANUFACTURER },
|
||||
[APP_USBD_STRING_ID_PRODUCT_ARRAY_POS] = { APP_USBD_STRINGS_PRODUCT },
|
||||
[APP_USBD_STRING_ID_SERIAL_ARRAY_POS] = { APP_USBD_STRING_SERIAL },
|
||||
#define X(mnemonic, str_idx, ...) [CONCAT_2(mnemonic, _ARRAY_POS)] = { __VA_ARGS__ },
|
||||
APP_USBD_STRINGS_USER
|
||||
#undef X
|
||||
};
|
||||
|
||||
|
||||
|
||||
uint16_t const * app_usbd_string_desc_get(app_usbd_string_desc_idx_t idx, uint16_t langid)
|
||||
{
|
||||
/* LANGID string */
|
||||
if (APP_USBD_STRING_ID_LANGIDS == idx)
|
||||
{
|
||||
return m_string_dsc[APP_USBD_STRING_ID_LANGIDS_ARRAY_POS][0];
|
||||
}
|
||||
|
||||
/* Searching for the language */
|
||||
uint8_t lang_idx = 0;
|
||||
if (ARRAY_SIZE(m_langids) > 1)
|
||||
{
|
||||
while (m_langids[lang_idx] != langid)
|
||||
{
|
||||
if (++lang_idx >= ARRAY_SIZE(m_langids))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the string index in array */
|
||||
if (idx >= ARRAY_SIZE(m_string_translation))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t str_pos = m_string_translation[idx];
|
||||
if (str_pos == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint16_t const * p_str = m_string_dsc[str_pos][lang_idx];
|
||||
if ((ARRAY_SIZE(m_langids) > 1) && (lang_idx != 0))
|
||||
{
|
||||
if (p_str == NULL)
|
||||
{
|
||||
p_str = m_string_dsc[str_pos][0];
|
||||
}
|
||||
}
|
||||
|
||||
return p_str;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
#endif // APP_USBD_ENABLED
|
||||
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* 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_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"
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd_string_desc USBD string descriptors
|
||||
* @ingroup app_usbd
|
||||
*
|
||||
* @brief @tagAPI52840 USBD string descriptors management.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USB string initialization
|
||||
*
|
||||
* Macro that creates initialization values for USB string.
|
||||
* The format contains header and string itself.
|
||||
* The string should be declared as an array of uint16_t type.
|
||||
*
|
||||
* @param[in] ... Comma separated string letters or language ID.
|
||||
* @return String descriptor initialization data.
|
||||
*/
|
||||
#define APP_USBD_STRING_DESC(...) (const uint16_t[]){ \
|
||||
(0xff & (sizeof((uint16_t[]){__VA_ARGS__}) + 2)) | \
|
||||
((uint16_t)APP_USBD_DESCRIPTOR_STRING) << 8, \
|
||||
__VA_ARGS__ }
|
||||
|
||||
/**
|
||||
* @brief USB string descriptors ID's
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_STRING_ID_LANGIDS = 0, /**< Supported language identifiers */
|
||||
APP_USBD_STRING_ID_MANUFACTURER, /**< Manufacturer name */
|
||||
APP_USBD_STRING_ID_PRODUCT, /**< Product name */
|
||||
APP_USBD_STRING_ID_SERIAL, /**< Serial number */
|
||||
|
||||
#define X(mnemonic, str_idx, ...) mnemonic str_idx,
|
||||
APP_USBD_STRINGS_USER
|
||||
#undef X
|
||||
|
||||
APP_USBD_STRING_ID_CNT /**< Total number of identifiers */
|
||||
} app_usbd_string_desc_idx_t;
|
||||
|
||||
/**
|
||||
* @brief Get string descriptor
|
||||
*
|
||||
* @param[in] idx String descriptor index
|
||||
* @param[in] langid Selected language for the string
|
||||
* @return String descriptor or NULL if not exist
|
||||
* */
|
||||
uint16_t const * app_usbd_string_desc_get(app_usbd_string_desc_idx_t idx, uint16_t langid);
|
||||
|
||||
/**
|
||||
* @brief Get string length
|
||||
*
|
||||
* Function to get string length from descriptor (descriptor returned by @ref app_usbd_string_desc_get)
|
||||
*
|
||||
* @param[in] p_str String descriptor pointer
|
||||
* @return Total descriptor length in bytes
|
||||
*/
|
||||
static inline size_t app_usbd_string_desc_length(uint16_t const * p_str)
|
||||
{
|
||||
return ((const app_usbd_descriptor_string_t *)p_str)->bLength;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APP_USBD_STRING_DESC_H__ */
|
||||
@@ -0,0 +1,232 @@
|
||||
/**
|
||||
* 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_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"
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd_types USB Device high level library variable types definition
|
||||
* @ingroup app_usbd
|
||||
*
|
||||
* @brief @tagAPI52840 All types used by @ref app_usbd are defined here.
|
||||
* This helps to avoid cross referencing into types in different files.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Change given value to 2 digits in BCD notation
|
||||
*
|
||||
* @param[in] val The decimal value to be converted in the range from 0 to 99.
|
||||
* @return Calculated BCD value.
|
||||
*/
|
||||
#define APP_USBD_BCD_2_MAKE(val) ( \
|
||||
((((val) % 100) / 10) * 0x10) + \
|
||||
((((val) % 10) / 1) * 0x1) \
|
||||
)
|
||||
|
||||
/**
|
||||
* @brief Change given decimal version values to 4 digits in BCD notation
|
||||
*
|
||||
* USB specification uses 4 digits BCD version notation in many descriptors.
|
||||
* This macro changes 2 values to 4 BCD digits (one 16 bit value)
|
||||
* that describes version in USB standard.
|
||||
*
|
||||
* @param[in] major Major version
|
||||
* @param[in] minor Minor version
|
||||
*
|
||||
* @return Calculated 16 bit value with BCD representation of the version
|
||||
*/
|
||||
#define APP_USBD_BCD_VER_MAKE(major, minor) \
|
||||
((APP_USBD_BCD_2_MAKE(major) << 8) | APP_USBD_BCD_2_MAKE(minor))
|
||||
|
||||
/**
|
||||
* @brief Events codes
|
||||
*
|
||||
* Redefined application event codes
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
APP_USBD_EVT_DRV_SOF = NRF_DRV_USBD_EVT_SOF, /**< See documentation for @ref NRF_DRV_USBD_EVT_SOF */
|
||||
APP_USBD_EVT_DRV_RESET = NRF_DRV_USBD_EVT_RESET, /**< See documentation for @ref NRF_DRV_USBD_EVT_RESET */
|
||||
APP_USBD_EVT_DRV_SUSPEND = NRF_DRV_USBD_EVT_SUSPEND, /**< See documentation for @ref NRF_DRV_USBD_EVT_SUSPEND */
|
||||
APP_USBD_EVT_DRV_RESUME = NRF_DRV_USBD_EVT_RESUME, /**< See documentation for @ref NRF_DRV_USBD_EVT_RESUME */
|
||||
APP_USBD_EVT_DRV_WUREQ = NRF_DRV_USBD_EVT_WUREQ, /**< See documentation for @ref NRF_DRV_USBD_EVT_WUREQ */
|
||||
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_APP, /**< First application event code - for internal static assert checking */
|
||||
|
||||
APP_USBD_EVT_INST_APPEND = APP_USBD_EVT_FIRST_APP, /**< The instance was attached to the library, any configuration action can be done now */
|
||||
APP_USBD_EVT_INST_REMOVE, /**< The instance is going to be removed, this event is called just before removing the instance.
|
||||
* This removing cannot be stopped. */
|
||||
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_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 */
|
||||
APP_USBD_EVT_START_REQ, /**< Start requested */
|
||||
APP_USBD_EVT_STOP_REQ, /**< Stop requested */
|
||||
APP_USBD_EVT_SUSPEND_REQ, /**< Suspend request - HFCLK would be released and USBD peripheral clock would be disconnected */
|
||||
APP_USBD_EVT_WAKEUP_REQ, /**< Wakeup request - start the whole wakeup generation. */
|
||||
|
||||
} app_usbd_event_type_t;
|
||||
|
||||
/**
|
||||
* @brief Specific application event structure
|
||||
*
|
||||
* All the data required by the events that comes from the application level
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
app_usbd_event_type_t type; //!< Event type
|
||||
} app_usbd_evt_t;
|
||||
|
||||
/**
|
||||
* @brief Specific application event structure with setup structure included
|
||||
*
|
||||
* This event structure would be used when @ref APP_USBD_EVT_DRV_SETUP
|
||||
* is passed to instance event handler
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
app_usbd_event_type_t type; //!< Event type
|
||||
app_usbd_setup_t setup; //!< Setup structure
|
||||
} app_usbd_setup_evt_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Complex event variable type
|
||||
*
|
||||
* A variable that can store any kind of event.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
app_usbd_event_type_t type; //!< Event type
|
||||
nrf_drv_usbd_evt_t drv_evt; //!< Events that comes directly from the driver.
|
||||
/**< Use this event structure only for event
|
||||
* type < @ref APP_USBD_EVT_FIRST_APP
|
||||
*/
|
||||
app_usbd_setup_evt_t setup_evt; //!< Event structure with SETUP structure included.
|
||||
/**< This structure is used in connection with
|
||||
* @ref APP_USBD_EVT_DRV_SETUP
|
||||
*/
|
||||
app_usbd_evt_t app_evt; //!< Events that comes from the application driver.
|
||||
/**< Use this event structure only for event
|
||||
* type >= @ref APP_USBD_EVT_FIRST_APP
|
||||
*/
|
||||
} app_usbd_complex_evt_t;
|
||||
|
||||
/**
|
||||
* @brief Internal event variable type
|
||||
*
|
||||
* The variable type used for internal event processing.
|
||||
* This kind of event is the one that goes into the event queue.
|
||||
*
|
||||
* @note There is no setup event structure.
|
||||
* This structure would be created when setup event is processed.
|
||||
* The reason for that is the fact that setup event structure has high memory printout.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
app_usbd_event_type_t type; //!< Event type
|
||||
nrf_drv_usbd_evt_t drv_evt; //!< Events that comes directly from the driver.
|
||||
/**< Use this event structure only for event
|
||||
* type < @ref APP_USBD_EVT_FIRST_APP
|
||||
*/
|
||||
app_usbd_evt_t app_evt; //!< Events that comes from the application driver.
|
||||
/**< Use this event structure only for event
|
||||
* type >= @ref APP_USBD_EVT_FIRST_APP
|
||||
*/
|
||||
} app_usbd_internal_evt_t;
|
||||
|
||||
#ifdef DOXYGEN
|
||||
/**
|
||||
* @brief Base instance of a USBD class
|
||||
*
|
||||
* Any USBD class instance have to begin with this instance.
|
||||
* This may then be followed by any implementation dependent data.
|
||||
*
|
||||
* For an instance it should be possible to put whole structure into FLASH.
|
||||
*
|
||||
* @note This type is early defined as incomplete type.
|
||||
* This is required for function declaration that takes the pointer
|
||||
* to this structure but in second hand - it is also placed inside
|
||||
* the instance structure.
|
||||
* @note The structure is defined in @file app_usbd_class_base.h.
|
||||
*/
|
||||
typedef struct {} app_usbd_class_inst_t;
|
||||
#else
|
||||
typedef struct app_usbd_class_inst_s app_usbd_class_inst_t;
|
||||
#endif
|
||||
/**
|
||||
* @brief Endpoint callback function
|
||||
*
|
||||
* The function used by every class instance.
|
||||
* @param[in,out] p_inst Instance of the class
|
||||
* @param[in] p_event Event to process
|
||||
*
|
||||
* @note If given event is not supported by class, return @ref NRF_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
typedef ret_code_t (*app_usbd_ep_event_handler_t)(
|
||||
app_usbd_class_inst_t const * const p_inst,
|
||||
app_usbd_complex_evt_t const * const p_event
|
||||
);
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APP_USBD_TYPES_H__ */
|
||||
|
||||
+735
@@ -0,0 +1,735 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include "sdk_config.h"
|
||||
#if APP_USBD_CLASS_CDC_ACM_ENABLED
|
||||
#include "app_usbd_cdc_acm.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd_cdc_acm_internal CDC ACM internals
|
||||
* @{
|
||||
* @ingroup app_usbd_cdc
|
||||
* @internal
|
||||
*/
|
||||
|
||||
|
||||
#define NRF_LOG_MODULE_NAME cdc_acm
|
||||
|
||||
#if APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
|
||||
#define NRF_LOG_LEVEL APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL
|
||||
#define NRF_LOG_INFO_COLOR APP_USBD_CDC_ACM_CONFIG_INFO_COLOR
|
||||
#define NRF_LOG_DEBUG_COLOR APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR
|
||||
#else //APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
|
||||
#define NRF_LOG_LEVEL 0
|
||||
#endif //APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
|
||||
#include "nrf_log.h"
|
||||
NRF_LOG_MODULE_REGISTER();
|
||||
|
||||
#define APP_USBD_CDC_ACM_COMM_IFACE_IDX 0 /**< CDC ACM class comm interface index. */
|
||||
#define APP_USBD_CDC_ACM_DATA_IFACE_IDX 1 /**< CDC ACM class data interface index. */
|
||||
|
||||
#define APP_USBD_CDC_ACM_COMM_EPIN_IDX 0 /**< CDC ACM comm class endpoint IN index. */
|
||||
#define APP_USBD_CDC_ACM_DATA_EPIN_IDX 0 /**< CDC ACM data class endpoint IN index. */
|
||||
#define APP_USBD_CDC_ACM_DATA_EPOUT_IDX 1 /**< CDC ACM data class endpoint OUT index. */
|
||||
|
||||
/**
|
||||
* @brief Auxiliary function to access cdc_acm class instance data.
|
||||
*
|
||||
* @param[in] p_inst Class instance data.
|
||||
*
|
||||
* @return CDC ACM class instance.
|
||||
*/
|
||||
static inline app_usbd_cdc_acm_t const * cdc_acm_get(app_usbd_class_inst_t const * p_inst)
|
||||
{
|
||||
ASSERT(p_inst != NULL);
|
||||
return (app_usbd_cdc_acm_t const *)p_inst;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Auxiliary function to access cdc_acm class context data.
|
||||
*
|
||||
* @param[in] p_cdc_acm CDC ACM class instance data.
|
||||
*
|
||||
* @return CDC ACM class instance context.
|
||||
*/
|
||||
static inline app_usbd_cdc_acm_ctx_t * cdc_acm_ctx_get(app_usbd_cdc_acm_t const * p_cdc_acm)
|
||||
{
|
||||
ASSERT(p_cdc_acm != NULL);
|
||||
ASSERT(p_cdc_acm->specific.p_data != NULL);
|
||||
return &p_cdc_acm->specific.p_data->ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief User event handler.
|
||||
*
|
||||
* @param[in] p_inst Class instance.
|
||||
* @param[in] event user Event type.
|
||||
*/
|
||||
static inline void user_event_handler(app_usbd_class_inst_t const * p_inst,
|
||||
app_usbd_cdc_acm_user_event_t event)
|
||||
{
|
||||
app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
|
||||
if (p_cdc_acm->specific.inst.user_ev_handler != NULL)
|
||||
{
|
||||
p_cdc_acm->specific.inst.user_ev_handler(p_inst, event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Auxiliary function to access CDC ACM COMM IN endpoint address.
|
||||
*
|
||||
* @param[in] p_inst Class instance data.
|
||||
*
|
||||
* @return IN endpoint address.
|
||||
*/
|
||||
static inline nrf_drv_usbd_ep_t comm_ep_in_addr_get(app_usbd_class_inst_t const * p_inst)
|
||||
{
|
||||
app_usbd_class_iface_conf_t const * class_iface;
|
||||
class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_COMM_IFACE_IDX);
|
||||
|
||||
app_usbd_class_ep_conf_t const * ep_cfg;
|
||||
ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_COMM_EPIN_IDX);
|
||||
|
||||
return app_usbd_class_ep_address_get(ep_cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Auxiliary function to access CDC ACM DATA IN endpoint address.
|
||||
*
|
||||
* @param[in] p_inst Class instance data.
|
||||
*
|
||||
* @return IN endpoint address.
|
||||
*/
|
||||
static inline nrf_drv_usbd_ep_t data_ep_in_addr_get(app_usbd_class_inst_t const * p_inst)
|
||||
{
|
||||
app_usbd_class_iface_conf_t const * class_iface;
|
||||
class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_DATA_IFACE_IDX);
|
||||
|
||||
app_usbd_class_ep_conf_t const * ep_cfg;
|
||||
ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_DATA_EPIN_IDX);
|
||||
|
||||
return app_usbd_class_ep_address_get(ep_cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Auxiliary function to access CDC ACM DATA OUT endpoint address.
|
||||
*
|
||||
* @param[in] p_inst Class instance data.
|
||||
*
|
||||
* @return OUT endpoint address.
|
||||
*/
|
||||
static inline nrf_drv_usbd_ep_t data_ep_out_addr_get(app_usbd_class_inst_t const * p_inst)
|
||||
{
|
||||
app_usbd_class_iface_conf_t const * class_iface;
|
||||
class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_DATA_IFACE_IDX);
|
||||
|
||||
app_usbd_class_ep_conf_t const * ep_cfg;
|
||||
ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_DATA_EPOUT_IDX);
|
||||
|
||||
return app_usbd_class_ep_address_get(ep_cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Internal SETUP standard IN request handler.
|
||||
*
|
||||
* @param[in] p_inst Generic class instance.
|
||||
* @param[in] p_setup_ev Setup event.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
case APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR:
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Internal SETUP standard OUT request handler
|
||||
*
|
||||
* @param[in] p_inst Generic class instance
|
||||
* @param[in] p_setup_ev Setup event
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst,
|
||||
app_usbd_setup_evt_t const * p_setup_ev)
|
||||
{
|
||||
|
||||
switch (p_setup_ev->setup.bmRequest)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Internal SETUP class IN request handler.
|
||||
*
|
||||
* @param[in] p_inst Generic class instance.
|
||||
* @param[in] p_setup_ev Setup event.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst,
|
||||
app_usbd_setup_evt_t const * p_setup_ev)
|
||||
{
|
||||
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);
|
||||
|
||||
switch (p_setup_ev->setup.bmRequest)
|
||||
{
|
||||
case APP_USBD_CDC_REQ_GET_LINE_CODING:
|
||||
{
|
||||
if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_cdc_line_coding_t))
|
||||
{
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return app_usbd_core_setup_rsp(&p_setup_ev->setup,
|
||||
&p_cdc_acm_ctx->line_coding,
|
||||
sizeof(app_usbd_cdc_line_coding_t));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Class specific OUT request data callback.
|
||||
*
|
||||
* @param status Endpoint status.
|
||||
* @param p_context Context of transfer (set by @ref app_usbd_core_setup_data_handler_set).
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
static ret_code_t cdc_acm_req_out_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context)
|
||||
{
|
||||
if (status != NRF_USBD_EP_OK)
|
||||
{
|
||||
return NRF_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
app_usbd_cdc_acm_t const * p_cdc_acm = p_context;
|
||||
app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
|
||||
|
||||
switch (p_cdc_acm_ctx->request.type)
|
||||
{
|
||||
case APP_USBD_CDC_REQ_SET_LINE_CODING:
|
||||
{
|
||||
memcpy(&p_cdc_acm_ctx->line_coding,
|
||||
&p_cdc_acm_ctx->request.payload.line_coding,
|
||||
sizeof(app_usbd_cdc_line_coding_t));
|
||||
|
||||
NRF_LOG_INFO("REQ_SET_LINE_CODING: baudrate: %"PRIu32", databits: %u, "
|
||||
"format: %u, parity: %u",
|
||||
uint32_decode(p_cdc_acm_ctx->line_coding.dwDTERate),
|
||||
p_cdc_acm_ctx->line_coding.bDataBits,
|
||||
p_cdc_acm_ctx->line_coding.bCharFormat,
|
||||
p_cdc_acm_ctx->line_coding.bParityType);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Class specific request data stage setup.
|
||||
*
|
||||
* @param[in] p_inst Generic class instance.
|
||||
* @param[in] p_setup_ev Setup event.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
static ret_code_t cdc_acm_req_out_datastage(app_usbd_class_inst_t const * p_inst,
|
||||
app_usbd_setup_evt_t const * p_setup_ev)
|
||||
{
|
||||
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->request.type = p_setup_ev->setup.bmRequest;
|
||||
p_cdc_acm_ctx->request.len = p_setup_ev->setup.wLength.w;
|
||||
|
||||
/*Request setup data*/
|
||||
NRF_DRV_USBD_TRANSFER_OUT(transfer,
|
||||
&p_cdc_acm_ctx->request.payload,
|
||||
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);
|
||||
if (ret == NRF_SUCCESS)
|
||||
{
|
||||
const app_usbd_core_setup_data_handler_desc_t desc = {
|
||||
.handler = cdc_acm_req_out_data_cb,
|
||||
.p_context = (void*)p_cdc_acm
|
||||
};
|
||||
|
||||
ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc);
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Internal SETUP class OUT request handler.
|
||||
*
|
||||
* @param[in] p_inst Generic class instance.
|
||||
* @param[in] p_setup_ev Setup event.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst,
|
||||
app_usbd_setup_evt_t const * p_setup_ev)
|
||||
{
|
||||
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);
|
||||
|
||||
switch (p_setup_ev->setup.bmRequest)
|
||||
{
|
||||
case APP_USBD_CDC_REQ_SET_LINE_CODING:
|
||||
{
|
||||
if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_cdc_line_coding_t))
|
||||
{
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return cdc_acm_req_out_datastage(p_inst, p_setup_ev);
|
||||
}
|
||||
case APP_USBD_CDC_REQ_SET_CONTROL_LINE_STATE:
|
||||
{
|
||||
if (p_setup_ev->setup.wLength.w != 0)
|
||||
{
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NRF_LOG_INFO("REQ_SET_CONTROL_LINE_STATE: 0x%x", p_setup_ev->setup.wValue.w);
|
||||
|
||||
bool old_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ?
|
||||
true : false;
|
||||
p_cdc_acm_ctx->line_state = p_setup_ev->setup.wValue.w;
|
||||
|
||||
bool new_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ?
|
||||
true : false;
|
||||
|
||||
if (old_dtr == new_dtr)
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
const app_usbd_cdc_acm_user_event_t ev = new_dtr ?
|
||||
APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN : APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE;
|
||||
|
||||
user_event_handler(p_inst, ev);
|
||||
|
||||
if (!new_dtr)
|
||||
{
|
||||
/*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);
|
||||
ep = data_ep_out_addr_get(p_inst);
|
||||
usbd_drv_ep_abort(ep);
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Control endpoint handler.
|
||||
*
|
||||
* @param[in] p_inst Generic class instance.
|
||||
* @param[in] p_setup_ev Setup event.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst,
|
||||
app_usbd_setup_evt_t const * p_setup_ev)
|
||||
{
|
||||
ASSERT(p_inst != NULL);
|
||||
ASSERT(p_setup_ev != NULL);
|
||||
|
||||
if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
|
||||
{
|
||||
switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
|
||||
{
|
||||
case APP_USBD_SETUP_REQTYPE_STD:
|
||||
return setup_req_std_in(p_inst, p_setup_ev);
|
||||
case APP_USBD_SETUP_REQTYPE_CLASS:
|
||||
return setup_req_class_in(p_inst, p_setup_ev);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else /*APP_USBD_SETUP_REQDIR_OUT*/
|
||||
{
|
||||
switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
|
||||
{
|
||||
case APP_USBD_SETUP_REQTYPE_STD:
|
||||
return setup_req_std_out(p_inst, p_setup_ev);
|
||||
case APP_USBD_SETUP_REQTYPE_CLASS:
|
||||
return setup_req_class_out(p_inst, p_setup_ev);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Class specific endpoint transfer handler.
|
||||
*
|
||||
* @param[in] p_inst Generic class instance.
|
||||
* @param[in] p_setup_ev Setup event.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
static ret_code_t cdc_acm_endpoint_ev(app_usbd_class_inst_t const * p_inst,
|
||||
app_usbd_complex_evt_t const * p_event)
|
||||
{
|
||||
if (comm_ep_in_addr_get(p_inst) == p_event->drv_evt.data.eptransfer.ep)
|
||||
{
|
||||
NRF_LOG_INFO("EPIN_COMM: notify");
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep))
|
||||
{
|
||||
switch (p_event->drv_evt.data.eptransfer.status)
|
||||
{
|
||||
case NRF_USBD_EP_OK:
|
||||
NRF_LOG_INFO("EPIN_DATA: %02x done", p_event->drv_evt.data.eptransfer.ep);
|
||||
user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_TX_DONE);
|
||||
return NRF_SUCCESS;
|
||||
case NRF_USBD_EP_ABORTED:
|
||||
return NRF_SUCCESS;
|
||||
default:
|
||||
return NRF_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (NRF_USBD_EPOUT_CHECK(p_event->drv_evt.data.eptransfer.ep))
|
||||
{
|
||||
switch (p_event->drv_evt.data.eptransfer.status)
|
||||
{
|
||||
case NRF_USBD_EP_OK:
|
||||
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;
|
||||
case NRF_USBD_EP_WAITING:
|
||||
case NRF_USBD_EP_ABORTED:
|
||||
return NRF_SUCCESS;
|
||||
default:
|
||||
return NRF_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief @ref app_usbd_class_methods_t::event_handler
|
||||
*/
|
||||
static ret_code_t cdc_acm_event_handler(app_usbd_class_inst_t const * p_inst,
|
||||
app_usbd_complex_evt_t const * p_event)
|
||||
{
|
||||
ASSERT(p_inst != NULL);
|
||||
ASSERT(p_event != NULL);
|
||||
|
||||
ret_code_t ret = NRF_SUCCESS;
|
||||
switch (p_event->app_evt.type)
|
||||
{
|
||||
case APP_USBD_EVT_DRV_SOF:
|
||||
break;
|
||||
case APP_USBD_EVT_DRV_RESET:
|
||||
break;
|
||||
case APP_USBD_EVT_DRV_SETUP:
|
||||
ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event);
|
||||
break;
|
||||
case APP_USBD_EVT_DRV_EPTRANSFER:
|
||||
ret = cdc_acm_endpoint_ev(p_inst, p_event);
|
||||
break;
|
||||
case APP_USBD_EVT_DRV_SUSPEND:
|
||||
break;
|
||||
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;
|
||||
default:
|
||||
ret = NRF_ERROR_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Public cdc_acm class interface
|
||||
*
|
||||
*/
|
||||
const app_usbd_class_methods_t app_usbd_cdc_acm_class_methods = {
|
||||
.event_handler = cdc_acm_event_handler,
|
||||
.get_descriptors = cdc_acm_get_descriptors,
|
||||
};
|
||||
|
||||
|
||||
ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm,
|
||||
const void * p_buf,
|
||||
size_t length)
|
||||
{
|
||||
app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm);
|
||||
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)
|
||||
{
|
||||
/*Port is not opened*/
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
size_t size;
|
||||
ret_code_t ret = nrf_drv_usbd_ep_status_get(ep, &size);
|
||||
if (ret != NRF_SUCCESS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
/*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);
|
||||
}
|
||||
|
||||
static ret_code_t cdc_acm_serial_state_notify(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);
|
||||
app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
|
||||
|
||||
nrf_drv_usbd_ep_t ep = comm_ep_in_addr_get(p_inst);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ret_code_t app_usbd_cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm,
|
||||
app_usbd_cdc_acm_serial_state_t serial_state,
|
||||
bool value)
|
||||
{
|
||||
app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
|
||||
|
||||
ret_code_t ret;
|
||||
CRITICAL_REGION_ENTER();
|
||||
ret = NRF_SUCCESS;
|
||||
switch (serial_state)
|
||||
{
|
||||
case APP_USBD_CDC_ACM_SERIAL_STATE_DCD:
|
||||
case APP_USBD_CDC_ACM_SERIAL_STATE_DSR:
|
||||
case APP_USBD_CDC_ACM_SERIAL_STATE_BREAK:
|
||||
case APP_USBD_CDC_ACM_SERIAL_STATE_RING:
|
||||
case APP_USBD_CDC_ACM_SERIAL_STATE_FRAMING:
|
||||
case APP_USBD_CDC_ACM_SERIAL_STATE_PARITY:
|
||||
case APP_USBD_CDC_ACM_SERIAL_STATE_OVERRUN:
|
||||
|
||||
if (value)
|
||||
{
|
||||
p_cdc_acm_ctx->serial_state |= serial_state;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_cdc_acm_ctx->serial_state &= ~serial_state;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
ret = NRF_ERROR_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == NRF_SUCCESS)
|
||||
{
|
||||
app_usbd_cdc_acm_notify_t * notify = &p_cdc_acm_ctx->request.payload.notify;
|
||||
notify->cdc_notify.bmRequestType = app_usbd_setup_req_val(APP_USBD_SETUP_REQREC_INTERFACE,
|
||||
APP_USBD_SETUP_REQTYPE_CLASS,
|
||||
APP_USBD_SETUP_REQDIR_IN);
|
||||
notify->cdc_notify.bmRequest = APP_USBD_CDC_NOTIF_SERIAL_STATE;
|
||||
notify->cdc_notify.wValue = 0;
|
||||
notify->cdc_notify.wIndex = 0;
|
||||
notify->cdc_notify.wLength = sizeof(notify->serial_state);
|
||||
|
||||
notify->serial_state = p_cdc_acm_ctx->serial_state;
|
||||
|
||||
ret = cdc_acm_serial_state_notify(p_cdc_acm);
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_code_t app_usbd_cdc_acm_line_state_get(app_usbd_cdc_acm_t const * p_cdc_acm,
|
||||
app_usbd_cdc_acm_line_state_t line_state,
|
||||
uint32_t * value)
|
||||
{
|
||||
app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
|
||||
|
||||
ret_code_t ret;
|
||||
CRITICAL_REGION_ENTER();
|
||||
ret = NRF_SUCCESS;
|
||||
switch (line_state)
|
||||
{
|
||||
case APP_USBD_CDC_ACM_LINE_STATE_DTR:
|
||||
case APP_USBD_CDC_ACM_LINE_STATE_RTS:
|
||||
*value = (p_cdc_acm_ctx->line_state & line_state) != 0;
|
||||
break;
|
||||
default:
|
||||
ret = NRF_ERROR_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* APP_USBD_CLASS_CDC_ACM_ENABLED */
|
||||
|
||||
/** @} */
|
||||
+295
@@ -0,0 +1,295 @@
|
||||
/**
|
||||
* 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_USBD_CDC_ACM_H__
|
||||
#define APP_USBD_CDC_ACM_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "nrf_drv_usbd.h"
|
||||
#include "app_usbd_class_base.h"
|
||||
#include "app_usbd.h"
|
||||
#include "app_usbd_core.h"
|
||||
#include "app_usbd_descriptor.h"
|
||||
|
||||
#include "app_usbd_cdc_desc.h"
|
||||
#include "app_usbd_cdc_types.h"
|
||||
#include "app_usbd_cdc_acm_internal.h"
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd_cdc_acm USB CDC ACM class
|
||||
* @ingroup app_usbd
|
||||
*
|
||||
* @brief @tagAPI52840 Module with types, definitions and API used by CDC ACM class.
|
||||
*
|
||||
* @details References:
|
||||
* - "Universal Serial Bus Class Definitions for Communications Devices"
|
||||
* Revision 1.2, November 3, 2010
|
||||
* - "Universal Serial Bus Communications Class Subclass Specification for PSTN Devices"
|
||||
* Revision 1.2, February 9, 2007
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef DOXYGEN
|
||||
/**
|
||||
* @brief CDC ACM class instance type
|
||||
*
|
||||
* @ref APP_USBD_CLASS_TYPEDEF
|
||||
*/
|
||||
typedef struct { } app_usbd_cdc_acm_t;
|
||||
#else
|
||||
/*lint -save -e10 -e26 -e123 -e505 */
|
||||
APP_USBD_CLASS_TYPEDEF(app_usbd_cdc_acm, \
|
||||
APP_USBD_CDC_ACM_CONFIG(0, 0, 0, 0, 0), \
|
||||
APP_USBD_CDC_ACM_INSTANCE_SPECIFIC_DEC, \
|
||||
APP_USBD_CDC_ACM_DATA_SPECIFIC_DEC \
|
||||
);
|
||||
/*lint -restore*/
|
||||
#endif
|
||||
|
||||
|
||||
/*lint -save -e407 */
|
||||
|
||||
/**
|
||||
* @brief Events passed to user event handler.
|
||||
*
|
||||
* @note Example prototype of user event handler:
|
||||
*
|
||||
* @code
|
||||
void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
|
||||
app_usbd_cdc_acm_user_event_t event);
|
||||
* @endcode
|
||||
*/
|
||||
typedef enum app_usbd_cdc_acm_user_event_e {
|
||||
APP_USBD_CDC_ACM_USER_EVT_RX_DONE, /**< User event RX_DONE. */
|
||||
APP_USBD_CDC_ACM_USER_EVT_TX_DONE, /**< User event TX_DONE. */
|
||||
|
||||
APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN, /**< User event PORT_OPEN. */
|
||||
APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE, /**< User event PORT_CLOSE. */
|
||||
} app_usbd_cdc_acm_user_event_t;
|
||||
|
||||
/*lint -restore*/
|
||||
|
||||
/**
|
||||
* @brief Default CDC ACM descriptors.
|
||||
*
|
||||
* @param comm_interface COMM interface number.
|
||||
* @param comm_epin COMM interface IN endpoint.
|
||||
* @param data_interface DATA interface number.
|
||||
* @param data_epin DATA interface IN endpoint.
|
||||
* @param data_epout DATA interface OUT endpoint.
|
||||
*/
|
||||
#define APP_USBD_CDC_ACM_DEFAULT_DESC(comm_interface, \
|
||||
comm_epin, \
|
||||
data_interface, \
|
||||
data_epin, \
|
||||
data_epout) \
|
||||
APP_USBD_CDC_IAD_DSC(comm_interface, \
|
||||
APP_USBD_CDC_SUBCLASS_ACM, \
|
||||
APP_USBD_CDC_COMM_PROTOCOL_AT_V250) \
|
||||
APP_USBD_CDC_COMM_INTERFACE_DSC(comm_interface, \
|
||||
APP_USBD_CDC_SUBCLASS_ACM, \
|
||||
APP_USBD_CDC_COMM_PROTOCOL_AT_V250) \
|
||||
APP_USBD_CDC_HEADER_DSC(0x0110) \
|
||||
APP_USBD_CDC_CALL_MGMT_DSC(0x03, data_interface) \
|
||||
APP_USBD_CDC_ACM_DSC(0x02) \
|
||||
APP_USBD_CDC_UNION_DSC(comm_interface, data_interface) \
|
||||
APP_USBD_CDC_COM_EP_DSC(comm_epin, NRF_DRV_USBD_EPSIZE) \
|
||||
APP_USBD_CDC_DATA_INTERFACE_DSC(data_interface, 0, 0) \
|
||||
APP_USBD_CDC_DATA_EP_DSC(data_epin, data_epout, NRF_DRV_USBD_EPSIZE)
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* @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)
|
||||
|
||||
/**
|
||||
* @brief Helper function to get class instance from CDC ACM class.
|
||||
*
|
||||
* @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
|
||||
*
|
||||
* @return Base class instance.
|
||||
*/
|
||||
static inline app_usbd_class_inst_t const *
|
||||
app_usbd_cdc_acm_class_inst_get(app_usbd_cdc_acm_t const * p_cdc_acm)
|
||||
{
|
||||
return &p_cdc_acm->base;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to get cdc_acm specific request from cdc_acm class.
|
||||
*
|
||||
* @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
|
||||
*
|
||||
* @return CDC ACM class specific request.
|
||||
*/
|
||||
static inline app_usbd_cdc_acm_req_t *
|
||||
app_usbd_cdc_acm_class_request_get(app_usbd_cdc_acm_t const * p_cdc_acm)
|
||||
{
|
||||
return &p_cdc_acm->specific.p_data->ctx.request;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to get cdc_acm from base class instance.
|
||||
*
|
||||
* @param[in] p_inst Base class instance.
|
||||
*
|
||||
* @return CDC ACM class handle.
|
||||
*/
|
||||
static inline app_usbd_cdc_acm_t const *
|
||||
app_usbd_cdc_acm_class_get(app_usbd_class_inst_t const * p_inst)
|
||||
{
|
||||
return (app_usbd_cdc_acm_t const *)p_inst;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Writes data to CDC ACM serial port.
|
||||
*
|
||||
* This is asynchronous call. User should wait for @ref APP_USBD_CDC_ACM_USER_EVT_TX_DONE event
|
||||
* to be sure that all data has been sent and input buffer could be accessed again.
|
||||
*
|
||||
* @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
|
||||
* @param[in] p_buf Input buffer.
|
||||
* @param[in] length Input buffer length.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm,
|
||||
const void * p_buf,
|
||||
size_t length);
|
||||
|
||||
/**
|
||||
* @brief Returns the amount of data to be 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.
|
||||
*
|
||||
* @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
|
||||
*
|
||||
* @return Amount of data transfered.
|
||||
*/
|
||||
size_t app_usbd_cdc_acm_rx_size(app_usbd_cdc_acm_t const * p_cdc_acm);
|
||||
|
||||
/**
|
||||
* @brief Reads data from CDC ACM serial port.
|
||||
*
|
||||
* @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).
|
||||
*
|
||||
* @return 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 Serial state notifications.
|
||||
* */
|
||||
typedef enum {
|
||||
APP_USBD_CDC_ACM_SERIAL_STATE_DCD = (1u << 0), /**< Notification bit DCD. */
|
||||
APP_USBD_CDC_ACM_SERIAL_STATE_DSR = (1u << 1), /**< Notification bit DSR. */
|
||||
APP_USBD_CDC_ACM_SERIAL_STATE_BREAK = (1u << 2), /**< Notification bit BREAK. */
|
||||
APP_USBD_CDC_ACM_SERIAL_STATE_RING = (1u << 3), /**< Notification bit RING. */
|
||||
APP_USBD_CDC_ACM_SERIAL_STATE_FRAMING = (1u << 4), /**< Notification bit FRAMING.*/
|
||||
APP_USBD_CDC_ACM_SERIAL_STATE_PARITY = (1u << 5), /**< Notification bit PARITY. */
|
||||
APP_USBD_CDC_ACM_SERIAL_STATE_OVERRUN = (1u << 6), /**< Notification bit OVERRUN.*/
|
||||
} app_usbd_cdc_acm_serial_state_t;
|
||||
|
||||
/**
|
||||
* @brief Serial line state.
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_CDC_ACM_LINE_STATE_DTR = (1u << 0), /**< Line state bit DTR.*/
|
||||
APP_USBD_CDC_ACM_LINE_STATE_RTS = (1u << 1), /**< Line state bit RTS.*/
|
||||
} app_usbd_cdc_acm_line_state_t;
|
||||
|
||||
/**
|
||||
* @brief Serial state notification via IN interrupt endpoint.
|
||||
*
|
||||
* @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
|
||||
* @param[in] serial_state Serial state notification type.
|
||||
* @param[in] value Serial state value.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
ret_code_t app_usbd_cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm,
|
||||
app_usbd_cdc_acm_serial_state_t serial_state,
|
||||
bool value);
|
||||
|
||||
/**
|
||||
* @brief Control line value get.
|
||||
*
|
||||
* @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
|
||||
* @param[in] line_state Line control value type.
|
||||
* @param[out] value Line control value.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
ret_code_t app_usbd_cdc_acm_line_state_get(app_usbd_cdc_acm_t const * p_cdc_acm,
|
||||
app_usbd_cdc_acm_line_state_t line_state,
|
||||
uint32_t * value);
|
||||
|
||||
/** @} */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APP_USBD_CDC_ACM_H__ */
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
/**
|
||||
* 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_USBD_CDC_ACM_INTERNAL_H__
|
||||
#define APP_USBD_CDC_ACM_INTERNAL_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include "app_util.h"
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd_cdc_acm_internal USB CDC ACM internals
|
||||
* @ingroup app_usbd_cdc_acm
|
||||
* @brief @tagAPI52840 Internals of the USB ACM class implementation.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF in cdc_acm class.
|
||||
*
|
||||
*/
|
||||
APP_USBD_CLASS_FORWARD(app_usbd_cdc_acm);
|
||||
|
||||
/*lint -save -e165*/
|
||||
/**
|
||||
* @brief Forward declaration of @ref app_usbd_cdc_acm_user_event_e.
|
||||
*
|
||||
*/
|
||||
enum app_usbd_cdc_acm_user_event_e;
|
||||
|
||||
/*lint -restore*/
|
||||
|
||||
/**
|
||||
* @brief User event handler.
|
||||
*
|
||||
* @param[in] p_inst Class instance.
|
||||
* @param[in] event User event.
|
||||
*
|
||||
*/
|
||||
typedef void (*app_usbd_cdc_acm_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst,
|
||||
enum app_usbd_cdc_acm_user_event_e event);
|
||||
|
||||
/**
|
||||
* @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.
|
||||
|
||||
app_usbd_cdc_acm_user_ev_handler_t user_ev_handler; //!< User event handler.
|
||||
} app_usbd_cdc_acm_inst_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief CDC ACM serial state class notify
|
||||
*/
|
||||
typedef struct {
|
||||
app_usbd_cdc_notify_t cdc_notify; //!< CDC notify.
|
||||
uint16_t serial_state; //!< Serial port state.
|
||||
} app_usbd_cdc_acm_notify_t;
|
||||
|
||||
/**
|
||||
* @brief CDC ACM class specific request handled via control endpoint.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t type; //!< Request type.
|
||||
uint8_t len; //!< Request length.
|
||||
|
||||
union {
|
||||
app_usbd_cdc_line_coding_t line_coding; //!< CDC ACM current line coding.
|
||||
app_usbd_cdc_acm_notify_t notify; //!< CDC ACM class notify.
|
||||
} payload;
|
||||
} app_usbd_cdc_acm_req_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.
|
||||
|
||||
uint16_t line_state; //!< CDC ACM line state bitmap, DTE side.
|
||||
uint16_t serial_state; //!< CDC ACM serial state bitmap, DCE side.
|
||||
} app_usbd_cdc_acm_ctx_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief CDC ACM class configuration macro.
|
||||
*
|
||||
* Used by @ref APP_USBD_CDC_ACM_GLOBAL_DEF
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
*/
|
||||
#define APP_USBD_CDC_ACM_CONFIG(iface_comm, epin_comm, iface_data, epin_data, epout_data) \
|
||||
((iface_comm, epin_comm), \
|
||||
(iface_data, epin_data, epout_data))
|
||||
|
||||
|
||||
/**
|
||||
* @brief Specific class constant data for cdc_acm class.
|
||||
*
|
||||
* @ref app_usbd_cdc_acm_inst_t
|
||||
*/
|
||||
#define APP_USBD_CDC_ACM_INSTANCE_SPECIFIC_DEC app_usbd_cdc_acm_inst_t inst;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configures cdc_acm class instance.
|
||||
*
|
||||
* @param descriptors Mass storage class descriptors (raw table).
|
||||
* @param user_event_handler User event handler.
|
||||
*/
|
||||
#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, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Specific class data for cdc_acm class.
|
||||
*
|
||||
* @ref app_usbd_cdc_acm_ctx_t
|
||||
*/
|
||||
#define APP_USBD_CDC_ACM_DATA_SPECIFIC_DEC app_usbd_cdc_acm_ctx_t ctx;
|
||||
|
||||
|
||||
/**
|
||||
* @brief CDC ACM class descriptors config macro.
|
||||
*
|
||||
* @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) \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Public cdc_acm class interface.
|
||||
*
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
#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)) \
|
||||
)
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APP_USBD_CDC_ACM_INTERNAL_H__ */
|
||||
@@ -0,0 +1,208 @@
|
||||
/**
|
||||
* 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_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"
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd_cdc_desc CDC class descriptors
|
||||
* @brief @tagAPI52840 Descriptors used in the USB CDC class implementation.
|
||||
* @ingroup app_usbd_cdc_acm
|
||||
*
|
||||
* A group of macros used to initialize CDC descriptors
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initializer of IAD descriptor for CDC class.
|
||||
*
|
||||
* @param interface_number Interface number.
|
||||
* @param subclass Subclass, @ref app_usbd_cdc_subclass_t.
|
||||
* @param protocol Protocol, @ref app_usbd_cdc_comm_protocol_t.
|
||||
*/
|
||||
#define APP_USBD_CDC_IAD_DSC(interface_number, subclass, protocol) \
|
||||
/*.bLength = */ sizeof(app_usbd_descriptor_iad_t), \
|
||||
/*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION, \
|
||||
/*.bFirstInterface = */ interface_number, \
|
||||
/*.bInterfaceCount = */ 2, \
|
||||
/*.bFunctionClass = */ APP_USBD_CDC_COMM_CLASS, \
|
||||
/*.bFunctionSubClass = */ subclass, \
|
||||
/*.bFunctionProtocol = */ protocol, \
|
||||
/*.iFunction = */ 0, \
|
||||
|
||||
/**
|
||||
* @brief Initializer of interface descriptor for CDC COMM class.
|
||||
*
|
||||
* @param interface_number Interface number.
|
||||
* @param subclass Subclass, @ref app_usbd_cdc_subclass_t.
|
||||
* @param protocol Protocol, @ref app_usbd_cdc_comm_protocol_t.
|
||||
*/
|
||||
#define APP_USBD_CDC_COMM_INTERFACE_DSC(interface_number, subclass, protocol) \
|
||||
/*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
|
||||
/*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
|
||||
/*.bInterfaceNumber = */ interface_number, \
|
||||
/*.bAlternateSetting = */ 0x00, \
|
||||
/*.bNumEndpoints = */ 1, \
|
||||
/*.bInterfaceClass = */ APP_USBD_CDC_COMM_CLASS, \
|
||||
/*.bInterfaceSubClass = */ subclass, \
|
||||
/*.bInterfaceProtocol = */ protocol, \
|
||||
/*.iInterface = 0, */ 0x00, \
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initializer of interface descriptor for CDC DATA class.
|
||||
*
|
||||
* @param interface_number Interface number.
|
||||
* @param subclass Subclass, @ref app_usbd_cdc_subclass_t.
|
||||
* @param protocol Protocol, @ref app_usbd_cdc_data_protocol_t.
|
||||
*/
|
||||
#define APP_USBD_CDC_DATA_INTERFACE_DSC(interface_number, subclass, protocol) \
|
||||
/*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
|
||||
/*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
|
||||
/*.bInterfaceNumber = */ interface_number, \
|
||||
/*.bAlternateSetting = */ 0x00, \
|
||||
/*.bNumEndpoints = */ 2, \
|
||||
/*.bInterfaceClass = */ APP_USBD_CDC_DATA_CLASS, \
|
||||
/*.bInterfaceSubClass = */ subclass, \
|
||||
/*.bInterfaceProtocol = */ protocol, \
|
||||
/*.iInterface = 0, */ 0x00, \
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initializer of endpoint descriptor for CDC COM class.
|
||||
*
|
||||
* @param endpoint_in IN endpoint.
|
||||
* @param ep_size Endpoint size.
|
||||
*/
|
||||
#define APP_USBD_CDC_COM_EP_DSC(endpoint_in, ep_size) \
|
||||
/*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
|
||||
/*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
|
||||
/*.bEndpointAddress = */ endpoint_in, \
|
||||
/*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT, \
|
||||
/*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
|
||||
/*.bInterval = */ 16, \
|
||||
|
||||
/**
|
||||
* @brief Initializer of endpoint descriptors for CDC DATA class.
|
||||
*
|
||||
* @param endpoint_in IN endpoint.
|
||||
* @param endpoint_out OUT endpoint.
|
||||
* @param ep_size Endpoint size.
|
||||
*/
|
||||
#define APP_USBD_CDC_DATA_EP_DSC(endpoint_in, endpoint_out, ep_size) \
|
||||
/*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
|
||||
/*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
|
||||
/*.bEndpointAddress = */ endpoint_in, \
|
||||
/*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \
|
||||
/*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
|
||||
/*.bInterval = */ 0, \
|
||||
/*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
|
||||
/*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
|
||||
/*.bEndpointAddress = */ endpoint_out, \
|
||||
/*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \
|
||||
/*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
|
||||
/*.bInterval = */ 0, \
|
||||
|
||||
/**
|
||||
* @brief Initializer of endpoint descriptors for CDC header descriptor.
|
||||
*
|
||||
* @param bcd_cdc BCD CDC version.
|
||||
*/
|
||||
#define APP_USBD_CDC_HEADER_DSC(bcd_cdc) \
|
||||
/*.bLength = */ sizeof(app_usbd_cdc_desc_header_t), \
|
||||
/*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
|
||||
/*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_HEADER, \
|
||||
/*.bcdCDC = */ APP_USBD_U16_TO_RAW_DSC(bcd_cdc), \
|
||||
|
||||
/**
|
||||
* @brief Initializer of endpoint descriptors for CDC call management descriptor.
|
||||
*
|
||||
* @param capabilities Capabilities.
|
||||
* @param data_interface Data interface.
|
||||
*/
|
||||
#define APP_USBD_CDC_CALL_MGMT_DSC(capabilities, data_interface) \
|
||||
/*.bLength = */ sizeof(app_usbd_cdc_desc_call_mgmt_t), \
|
||||
/*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
|
||||
/*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_CALL_MGMT, \
|
||||
/*.bmCapabilities = */ capabilities, \
|
||||
/*.bDataInterface = */ data_interface, \
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initializer of endpoint descriptors for CDC DATA class.
|
||||
*
|
||||
* @param capabilities Capabilities.
|
||||
*/
|
||||
#define APP_USBD_CDC_ACM_DSC(capabilities) \
|
||||
/*.bLength = */ sizeof(app_usbd_cdc_desc_acm_t), \
|
||||
/*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
|
||||
/*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_ACM, \
|
||||
/*.bmCapabilities = */ capabilities, \
|
||||
|
||||
/**
|
||||
* @brief Initializer of endpoint descriptors for CDC DATA class.
|
||||
*
|
||||
* @param control_interface Control interface.
|
||||
* @param ... Subordinate interfaces list.
|
||||
*/
|
||||
#define APP_USBD_CDC_UNION_DSC(control_interface, ...) \
|
||||
/*.bLength = */ sizeof(app_usbd_cdc_desc_union_t) + (NUM_VA_ARGS(__VA_ARGS__)), \
|
||||
/*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
|
||||
/*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_UNION, \
|
||||
/*.bControlInterface = */ control_interface, \
|
||||
/*.bSubordinateInterface = */ __VA_ARGS__, \
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APP_USBD_CDC_H__ */
|
||||
+360
@@ -0,0 +1,360 @@
|
||||
/**
|
||||
* 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_USBD_CDC_TYPES_H__
|
||||
#define APP_USBD_CDC_TYPES_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd_cdc_types CDC class types
|
||||
* @ingroup app_usbd_cdc_acm
|
||||
*
|
||||
* @brief @tagAPI52840 Variable types used by the CDC class implementation.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Communications Interface Class code.
|
||||
*
|
||||
* Used for control interface in communication class.
|
||||
* @ref app_usbd_descriptor_iface_t::bInterfaceClass
|
||||
*/
|
||||
#define APP_USBD_CDC_COMM_CLASS 0x02
|
||||
|
||||
/**
|
||||
* @brief Data Class Interface code.
|
||||
*
|
||||
* Used for data interface in communication class.
|
||||
* @ref app_usbd_descriptor_iface_t::bInterfaceClass
|
||||
*/
|
||||
#define APP_USBD_CDC_DATA_CLASS 0x0A
|
||||
|
||||
/**
|
||||
* @brief CDC subclass possible values.
|
||||
*
|
||||
* @ref app_usbd_descriptor_iface_t::bInterfaceSubClass
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_CDC_SUBCLASS_RESERVED = 0x00, /**< Reserved in documentation. */
|
||||
APP_USBD_CDC_SUBCLASS_DLCM = 0x01, /**< Direct Line Control Model. */
|
||||
APP_USBD_CDC_SUBCLASS_ACM = 0x02, /**< Abstract Control Model. */
|
||||
APP_USBD_CDC_SUBCLASS_TCM = 0x03, /**< Telephone Control Model. */
|
||||
APP_USBD_CDC_SUBCLASS_MCCM = 0x04, /**< Multi-Channel Control Model. */
|
||||
APP_USBD_CDC_SUBCLASS_CAPI = 0x05, /**< CAPI Control Model. */
|
||||
APP_USBD_CDC_SUBCLASS_ENCM = 0x06, /**< Ethernet Networking Control Model. */
|
||||
APP_USBD_CDC_SUBCLASS_ATM = 0x07, /**< ATM Networking Control Model. */
|
||||
APP_USBD_CDC_SUBCLASS_WHCM = 0x08, /**< Wireless Handset Control Model. */
|
||||
APP_USBD_CDC_SUBCLASS_DM = 0x09, /**< Device Management. */
|
||||
APP_USBD_CDC_SUBCLASS_MDLM = 0x0A, /**< Mobile Direct Line Model. */
|
||||
APP_USBD_CDC_SUBCLASS_OBEX = 0x0B, /**< OBEX. */
|
||||
APP_USBD_CDC_SUBCLASS_EEM = 0x0C, /**< Ethernet Emulation Model. */
|
||||
APP_USBD_CDC_SUBCLASS_NCM = 0x0D /**< Network Control Model. */
|
||||
} app_usbd_cdc_subclass_t;
|
||||
|
||||
/**
|
||||
* @brief CDC protocol possible values.
|
||||
*
|
||||
* @ref app_usbd_descriptor_iface_t::bInterfaceProtocol
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_CDC_COMM_PROTOCOL_NONE = 0x00, /**< No class specific protocol required. */
|
||||
APP_USBD_CDC_COMM_PROTOCOL_AT_V250 = 0x01, /**< AT Commands: V.250 etc. */
|
||||
APP_USBD_CDC_COMM_PROTOCOL_AT_PCCA101 = 0x02, /**< AT Commands defined by PCCA-101. */
|
||||
APP_USBD_CDC_COMM_PROTOCOL_AT_PCCA101_ANNEXO = 0x03, /**< AT Commands defined by PCCA-101 & Annex O. */
|
||||
APP_USBD_CDC_COMM_PROTOCOL_AT_GSM707 = 0x04, /**< AT Commands defined by GSM 07.07. */
|
||||
APP_USBD_CDC_COMM_PROTOCOL_AT_3GPP_27007 = 0x05, /**< AT Commands defined by 3GPP 27.007. */
|
||||
APP_USBD_CDC_COMM_PROTOCOL_AT_CDMA = 0x06, /**< AT Commands defined by TIA for CDMA. */
|
||||
APP_USBD_CDC_COMM_PROTOCOL_EEM = 0x07, /**< Ethernet Emulation Model. */
|
||||
APP_USBD_CDC_COMM_PROTOCOL_EXTERNAL = 0xFE, /**< External Protocol: Commands defined by Command Set Functional Descriptor. */
|
||||
APP_USBD_CDC_COMM_PROTOCOL_VENDOR = 0xFF /**< Vendor-specific. */
|
||||
} app_usbd_cdc_comm_protocol_t;
|
||||
|
||||
/**
|
||||
* @brief CDC data interface protocols possible values.
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_CDC_DATA_PROTOCOL_NONE = 0x00, /**< No class specific protocol required. */
|
||||
APP_USBD_CDC_DATA_PROTOCOL_NTB = 0x01, /**< Network Transfer Block. */
|
||||
APP_USBD_CDC_DATA_PROTOCOL_ISDN_BRI = 0x30, /**< Physical interface protocol for ISDN BRI. */
|
||||
APP_USBD_CDC_DATA_PROTOCOL_HDLC = 0x31, /**< HDLC. */
|
||||
APP_USBD_CDC_DATA_PROTOCOL_TRANSPARENT = 0x32, /**< Transparent. */
|
||||
APP_USBD_CDC_DATA_PROTOCOL_Q921M = 0x50, /**< Management protocol for Q.921 data link protocol. */
|
||||
APP_USBD_CDC_DATA_PROTOCOL_Q921 = 0x51, /**< Data link protocol for Q.921. */
|
||||
APP_USBD_CDC_DATA_PROTOCOL_Q921TM = 0x52, /**< TEI-multiplexor for Q.921 data link protocol. */
|
||||
APP_USBD_CDC_DATA_PROTOCOL_V42BIS = 0x90, /**< Data compression procedures. */
|
||||
APP_USBD_CDC_DATA_PROTOCOL_Q931 = 0x91, /**< Euro-ISDN protocol control. */
|
||||
APP_USBD_CDC_DATA_PROTOCOL_V120 = 0x92, /**< V.24 rate adaptation to ISDN. */
|
||||
APP_USBD_CDC_DATA_PROTOCOL_CAPI20 = 0x93, /**< CAPI Commands. */
|
||||
APP_USBD_CDC_DATA_PROTOCOL_HOST = 0xFD, /**< Host based driver.
|
||||
* @note This protocol code should only be used in messages
|
||||
* between host and device to identify the host driver portion
|
||||
* of a protocol stack.
|
||||
*/
|
||||
APP_USBD_CDC_DATA_PROTOCOL_EXTERNAL = 0xFE, /**< The protocol(s) are described using a Protocol Unit Functional
|
||||
* Descriptors on Communications Class Interface.
|
||||
*/
|
||||
APP_USBD_CDC_DATA_PROTOCOL_VENDOR = 0xFF /**< Vendor-specific. */
|
||||
} app_usbd_cdc_data_protocol_t;
|
||||
|
||||
/**
|
||||
* @brief CDC Functional Descriptor types.
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_CDC_CS_INTERFACE = 0x24, /**< Class specific interface descriptor type.*/
|
||||
APP_USBD_CDC_CS_ENDPOINT = 0x25 /**< Class specific endpoint descriptor type.*/
|
||||
} app_usbd_cdc_func_type_t;
|
||||
|
||||
/**
|
||||
* @brief CDC Functional Descriptor subtypes
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_CDC_SCS_HEADER = 0x00, /**< Header Functional Descriptor, which marks the beginning of the concatenated set of functional descriptors for the interface. */
|
||||
APP_USBD_CDC_SCS_CALL_MGMT = 0x01, /**< Call Management Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_ACM = 0x02, /**< Abstract Control Management Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_DLM = 0x03, /**< Direct Line Management Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_TEL_R = 0x04, /**< Telephone Ringer Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_TEL_CAP = 0x05, /**< Telephone Call and Line State Reporting Capabilities Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_UNION = 0x06, /**< Union Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_COUNTRY_SEL = 0x07, /**< Country Selection Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_TEL_OM = 0x08, /**< Telephone Operational Modes Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_USB_TERM = 0x09, /**< USB Terminal Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_NCT = 0x0A, /**< Network Channel Terminal Descriptor. */
|
||||
APP_USBD_CDC_SCS_PU = 0x0B, /**< Protocol Unit Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_EU = 0x0C, /**< Extension Unit Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_MCM = 0x0D, /**< Multi-Channel Management Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_CAPI = 0x0E, /**< CAPI Control Management Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_ETH = 0x0F, /**< Ethernet Networking Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_ATM = 0x10, /**< ATM Networking Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_WHCM = 0x11, /**< Wireless Handset Control Model Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_MDLM = 0x12, /**< Mobile Direct Line Model Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_MDLM_DET = 0x13, /**< MDLM Detail Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_DMM = 0x14, /**< Device Management Model Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_OBEX = 0x15, /**< OBEX Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_CS = 0x16, /**< Command Set Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_CS_DET = 0x17, /**< Command Set Detail Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_TEL_CM = 0x18, /**< Telephone Control Model Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_OBEX_SI = 0x19, /**< OBEX Service Identifier Functional Descriptor. */
|
||||
APP_USBD_CDC_SCS_NCM = 0x1A /**< NCM Functional Descriptor. */
|
||||
} app_usbd_cdc_func_subtype_t;
|
||||
|
||||
/* Make all descriptors packed */
|
||||
#pragma pack(push, 1)
|
||||
|
||||
/**
|
||||
* @brief Header Functional Descriptor
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t bFunctionLength; //!< Size of this descriptor in bytes.
|
||||
uint8_t bDescriptorType; //!< @ref APP_USBD_CDC_CS_INTERFACE descriptor type.
|
||||
uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_HEADER.
|
||||
uint8_t bcdCDC[2]; //!< USB Class Definitions for Communications Devices Specification release number in binary-coded decimal.
|
||||
} app_usbd_cdc_desc_header_t;
|
||||
|
||||
/**
|
||||
* @brief Call management capabilities.
|
||||
*
|
||||
* @ref app_usbd_cdc_desc_call_mgmt_t::bmCapabilities bit
|
||||
* */
|
||||
typedef enum {
|
||||
APP_USBD_CDC_CALL_MGMT_SUPPORTED = (1 << 0), /**< Call management capability bit 0.*/
|
||||
APP_USBD_CDC_CALL_MGMT_OVER_DCI = (1 << 1), /**< Call management capability bit 1.*/
|
||||
} app_subd_cdc_call_mgmt_cap_t;
|
||||
|
||||
/**
|
||||
* @brief CDC Call Management Functional Descriptor.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
|
||||
uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
|
||||
uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_CALL_MGMT.
|
||||
uint8_t bmCapabilities; //!< Capabilities @ref app_subd_cdc_call_mgmt_cap_t.
|
||||
uint8_t bDataInterface; //!< Data interface number.
|
||||
} app_usbd_cdc_desc_call_mgmt_t;
|
||||
|
||||
/**
|
||||
* @brief ACM capabilities.
|
||||
*
|
||||
* @ref app_usbd_cdc_desc_acm_t::bmCapabilities bit
|
||||
* */
|
||||
typedef enum {
|
||||
APP_USBD_CDC_ACM_FEATURE_REQUESTS = (1 << 0), /**< ACM capability bit FEATURE_REQUESTS. */
|
||||
APP_USBD_CDC_ACM_LINE_REQUESTS = (1 << 1), /**< ACM capability bit LINE_REQUESTS. */
|
||||
APP_USBD_CDC_ACM_SENDBREAK_REQUESTS = (1 << 2), /**< ACM capability bit SENDBREAK_REQUESTS.*/
|
||||
APP_USBD_CDC_ACM_NOTIFY_REQUESTS = (1 << 3), /**< ACM capability bit NOTIFY_REQUESTS. */
|
||||
} app_subd_cdc_acm_cap_t;
|
||||
|
||||
/**
|
||||
* @brief CDC ACM Functional Descriptor.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
|
||||
uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
|
||||
uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_ACM.
|
||||
uint8_t bmCapabilities; //!< Capabilities @ref app_subd_cdc_acm_cap_t.
|
||||
} app_usbd_cdc_desc_acm_t;
|
||||
|
||||
/**
|
||||
* @brief Union Functional Descriptor.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
|
||||
uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
|
||||
uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_UNION.
|
||||
uint8_t bControlInterface; //!< The interface number of the Communications or Data Class interface, designated as the controlling interface for the union.
|
||||
uint8_t bSubordinateInterface[]; //!< Interface number of subordinate interfaces in the union. Number of interfaced depends on descriptor size.
|
||||
} app_usbd_cdc_desc_union_t;
|
||||
|
||||
/**
|
||||
* @brief Country Selection Functional Descriptor.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
|
||||
uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
|
||||
uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_COUNTRY_SEL.
|
||||
uint8_t iCountryCodeRelDate; //!< Index of a string giving the release date for the implemented ISO 3166 Country Codes.
|
||||
} app_usbd_cdc_desc_country_sel_t;
|
||||
|
||||
/**
|
||||
* @brief CDC Requests
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
/* CDC General */
|
||||
APP_USBD_CDC_REQ_SEND_ENCAPSULATED_COMMAND = 0x00, /**< This request is used to issue a command in the format of the supported control protocol of the Communications Class interface. */
|
||||
APP_USBD_CDC_REQ_GET_ENCAPSULATED_RESPONSE = 0x01, /**< This request is used to request a response in the format of the supported control protocol of the Communications Class interface. */
|
||||
/* CDC PSTN */
|
||||
APP_USBD_CDC_REQ_SET_COMM_FEATURE = 0x02, /**< This request controls the settings for a particular communications feature of a particular target. */
|
||||
APP_USBD_CDC_REQ_GET_COMM_FEATURE = 0x03, /**< This request returns the current settings for the communications feature as selected. */
|
||||
APP_USBD_CDC_REQ_CLEAR_COMM_FEATURE = 0x04, /**< This request controls the settings for a particular communications feature of a particular target, setting the selected feature to its default state. */
|
||||
APP_USBD_CDC_REQ_SET_AUX_LINE_STATE = 0x10, /**< This request is used to connect or disconnect a secondary jack to POTS circuit or CODEC, depending on hook state. */
|
||||
APP_USBD_CDC_REQ_SET_HOOK_STATE = 0x11, /**< This request is used to set the necessary PSTN line relay code for on-hook, off-hook, and caller ID states. */
|
||||
APP_USBD_CDC_REQ_PULSE_SETUP = 0x12, /**< This request is used to prepare for a pulse-dialing cycle. */
|
||||
APP_USBD_CDC_REQ_SEND_PULSE = 0x13, /**< This request is used to generate a specified number of make/break pulse cycles. */
|
||||
APP_USBD_CDC_REQ_SET_PULSE_TIME = 0x14, /**< This request sets the timing of the make and break periods for pulse dialing. */
|
||||
APP_USBD_CDC_REQ_RING_AUX_JACK = 0x15, /**< This request is used to generate a ring signal on a secondary phone jack. */
|
||||
APP_USBD_CDC_REQ_SET_LINE_CODING = 0x20, /**< This request allows the host to specify typical asynchronous line-character formatting properties. */
|
||||
APP_USBD_CDC_REQ_GET_LINE_CODING = 0x21, /**< This request allows the host to find out the currently configured line coding. */
|
||||
APP_USBD_CDC_REQ_SET_CONTROL_LINE_STATE = 0x22, /**< This request generates RS-232/V.24 style control signals. */
|
||||
APP_USBD_CDC_REQ_SEND_BREAK = 0x23, /**< This request sends special carrier modulation that generates an RS-232 style break. */
|
||||
APP_USBD_CDC_REQ_SET_RINGER_PARMS = 0x30, /**< This request configures the ringer for the communications device. */
|
||||
APP_USBD_CDC_REQ_GET_RINGER_PARMS = 0x31, /**< This request returns the ringer capabilities of the device and the current status of the device’s ringer. */
|
||||
APP_USBD_CDC_REQ_SET_OPERATION_PARMS = 0x32, /**< Sets the operational mode for the device, between a simple mode, standalone mode and a host centric mode. */
|
||||
APP_USBD_CDC_REQ_GET_OPERATION_PARMS = 0x33, /**< This request gets the current operational mode for the device. */
|
||||
APP_USBD_CDC_REQ_SET_LINE_PARMS = 0x34, /**< This request is used to change the state of the line, corresponding to the interface or master interface of a union to which the command was sent. */
|
||||
APP_USBD_CDC_REQ_GET_LINE_PARMS = 0x35, /**< This request is used to report the state of the line that corresponds to the interface or master interface of a union to which the command was sent. */
|
||||
APP_USBD_CDC_REQ_DIAL_DIGITS = 0x36, /**< This request dials the DTMF digits over the specified line. */
|
||||
} app_usbd_cdc_req_id_t;
|
||||
|
||||
/**
|
||||
* @brief CDC Notifications.
|
||||
*/
|
||||
typedef enum {
|
||||
/* CDC General */
|
||||
APP_USBD_CDC_NOTIF_NETWORK_CONNECTION = 0x00, /**< This notification allows the device to notify the host about network connection status. */
|
||||
APP_USBD_CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, /**< This notification allows the device to notify the host that a response is available.
|
||||
* This response can be retrieved with a subsequent GetEncapsulatedResponse request.
|
||||
_ */
|
||||
APP_USBD_CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A, /**< This notification allows the device to inform the host-networking driver
|
||||
* that a change in either the up-link or the down-link bit rate of the connection has occurred.
|
||||
*/
|
||||
/* CDC PSTN */
|
||||
APP_USBD_CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, /**< (DLM) This notification indicates the loop has changed on the auxiliary phone interface of the USB device. */
|
||||
APP_USBD_CDC_NOTIF_RING_DETECT = 0x09, /**< (DLM) This notification indicates ring voltage on the POTS line interface of the USB device. */
|
||||
APP_USBD_CDC_NOTIF_SERIAL_STATE = 0x20, /**< (ACM) This notification sends asynchronous notification of UART status. */
|
||||
APP_USBD_CDC_NOTIF_CALL_STATE_CHANGE = 0x28, /**< (TCM) This notification identifies that a change has occurred to the state of a call on the line corresponding to the interface or union for the line. */
|
||||
APP_USBD_CDC_NOTIF_LINE_STATE_CHANGE = 0x29 /**< (TCM) This notification identifies that a change has occurred to the state of the line corresponding to the interface or master interface of a union sending the notification message. */
|
||||
} app_usbd_cdc_notify_id_t;
|
||||
|
||||
/**
|
||||
* @brief Notification sent via CDC COMM endpoint.
|
||||
* */
|
||||
typedef struct {
|
||||
uint8_t bmRequestType; //!< Request type.
|
||||
uint8_t bmRequest; //!< Request ID @ref app_usbd_cdc_req_id_t.
|
||||
uint16_t wValue; //!< Value field.
|
||||
uint16_t wIndex; //!< Index field.
|
||||
uint16_t wLength; //!< Length of payload following.
|
||||
} app_usbd_cdc_notify_t;
|
||||
|
||||
/**
|
||||
* @brief CDC line coding structure.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t dwDTERate[4]; //!< Line baudrate.
|
||||
uint8_t bCharFormat; //!< Character format @ref app_usbd_cdc_line_stopbit_t.
|
||||
uint8_t bParityType; //!< Parity bits @ref app_usbd_cdc_line_parity_t.
|
||||
uint8_t bDataBits; //!< Number of data bits.
|
||||
} app_usbd_cdc_line_coding_t;
|
||||
|
||||
/**
|
||||
* @brief Possible values of @ref app_usbd_cdc_line_coding_t::bCharFormat.
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_CDC_LINE_STOPBIT_1 = 0, /**< 1 stop bit. */
|
||||
APP_USBD_CDC_LINE_STOPBIT_1_5 = 1, /**< 1.5 stop bits. */
|
||||
APP_USBD_CDC_LINE_STOPBIT_2 = 2, /**< 2 stop bits. */
|
||||
} app_usbd_cdc_line_stopbit_t;
|
||||
|
||||
/**
|
||||
* @brief Possible values of @ref app_usbd_cdc_line_coding_t::bParityType.
|
||||
*/
|
||||
typedef enum {
|
||||
APP_USBD_CDC_LINE_PARITY_NONE = 0, /**< No parity. */
|
||||
APP_USBD_CDC_LINE_PARITY_ODD = 1, /**< Odd parity. */
|
||||
APP_USBD_CDC_LINE_PARITY_EVEN = 2, /**< Even parity. */
|
||||
APP_USBD_CDC_LINE_PARITY_MARK = 3, /**< Parity forced to 0 (space).*/
|
||||
APP_USBD_CDC_LINE_PARITY_SPACE = 4, /**< Parity forced to 1 (mark). */
|
||||
} app_usbd_cdc_line_parity_t;
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/** @} */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APP_USBD_TYPES_H__ */
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* 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_USBD_STRING_CONFIG_H
|
||||
#define APP_USBD_STRING_CONFIG_H
|
||||
|
||||
/**
|
||||
* @defgroup app_usbd_string_conf USBD string configuration
|
||||
* @ingroup app_usbd_string_desc
|
||||
*
|
||||
* @brief @tagAPI52840 Configuration of the string module that can be easily affected by the final
|
||||
* user.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Supported languages identifiers
|
||||
*
|
||||
* Comma separated list of supported languages.
|
||||
*/
|
||||
#define APP_USBD_STRINGS_LANGIDS \
|
||||
((uint16_t)APP_USBD_LANG_ENGLISH | (uint16_t)APP_USBD_SUBLANG_ENGLISH_US)
|
||||
|
||||
/**
|
||||
* @brief Manufacturer name string descriptor
|
||||
*
|
||||
* Comma separated list of manufacturer names for each defined language.
|
||||
* Use @ref APP_USBD_STRING_DESC macro to create string descriptor.
|
||||
*
|
||||
* The order of manufacturer names has to be the same like in
|
||||
* @ref APP_USBD_STRINGS_LANGIDS.
|
||||
*/
|
||||
#define APP_USBD_STRINGS_MANUFACTURER \
|
||||
APP_USBD_STRING_DESC('N', 'o', 'r', 'd', 'i', 'c', ' ', 'S', 'e', 'm', 'i', 'c', 'o', 'n', 'd', 'u', 'c', 't', 'o', 'r')
|
||||
|
||||
/**
|
||||
* @brief Define whether @ref APP_USBD_STRINGS_MANUFACTURER is created by @ref APP_USBD_STRING_DESC
|
||||
* or declared as global variable.
|
||||
* */
|
||||
#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0
|
||||
|
||||
/**
|
||||
* @brief Product name string descriptor
|
||||
*
|
||||
* List of product names defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER
|
||||
*/
|
||||
#define APP_USBD_STRINGS_PRODUCT \
|
||||
APP_USBD_STRING_DESC('n', 'R', 'F', '5', '2', '8', '4', '0', ' ', 'O', 'p', 'e', 'n', 'T', 'h', 'r', 'e', 'a', 'd', ' ', 'D', 'e', 'v', 'i', 'c', 'e')
|
||||
|
||||
|
||||
/**
|
||||
* @brief Define whether @ref APP_USBD_STRINGS_PRODUCT is created by @ref APP_USBD_STRING_DESC
|
||||
* or declared as global variable.
|
||||
* */
|
||||
#define APP_USBD_STRINGS_PRODUCT_EXTERN 0
|
||||
|
||||
/**
|
||||
* @brief Serial number string descriptor
|
||||
*
|
||||
* Create serial number string descriptor using @ref APP_USBD_STRING_DESC,
|
||||
* or configure it to point to any internal variable pointer filled with descriptor.
|
||||
*
|
||||
* @note
|
||||
* There is only one SERIAL number inside the library and it is Language independent.
|
||||
*/
|
||||
#define APP_USBD_STRING_SERIAL gExternSerialNumber
|
||||
|
||||
/**
|
||||
* @brief Define whether @ref APP_USBD_STRING_SERIAL is created by @ref APP_USBD_STRING_DESC
|
||||
* or declared as global variable.
|
||||
* */
|
||||
#define APP_USBD_STRING_SERIAL_EXTERN 1
|
||||
|
||||
/**
|
||||
* @brief User strings default values
|
||||
*
|
||||
* This value stores all application specific user strings with its default initialization.
|
||||
* The setup is done by X-macros.
|
||||
* Expected macro parameters:
|
||||
* @code
|
||||
* X(mnemonic, [=str_idx], ...)
|
||||
* @endcode
|
||||
* - @c mnemonic: Mnemonic of the string descriptor that would be added to
|
||||
* @ref app_usbd_string_desc_idx_t enumerator.
|
||||
* - @c str_idx : String index value, may be set or left empty.
|
||||
* For example WinUSB driver requires descriptor to be present on 0xEE index.
|
||||
* Then use X(USBD_STRING_WINUSB, =0xEE, (APP_USBD_STRING_DESC(...)))
|
||||
* - @c ... : List of string descriptors for each defined language.
|
||||
*/
|
||||
#define APP_USBD_STRINGS_USER \
|
||||
X(APP_USER_1, , APP_USBD_STRING_DESC('U', 's', 'e', 'r', ' ', '1'))
|
||||
|
||||
/** @} */
|
||||
#endif /* APP_USBD_STRING_CONFIG_H */
|
||||
@@ -0,0 +1,102 @@
|
||||
; Windows 2000, XP, Vista, 7 and 8 (x32 and x64) driver for Nordic CDC ACM OpenThread device
|
||||
|
||||
[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
|
||||
|
||||
;----------------------------------------------------------
|
||||
; Targets
|
||||
;----------------------------------------------------------
|
||||
[Manufacturer]
|
||||
%Manufacturer%=DeviceList, NTAMD64, NTIA64, NT
|
||||
|
||||
[DeviceList]
|
||||
%NORDIC_CDC_ACM_EXAMPLE%=DriverInstall, USB\VID_1915&PID_CAFE
|
||||
|
||||
|
||||
[DeviceList.NTAMD64]
|
||||
%NORDIC_CDC_ACM_EXAMPLE%=DriverInstall.NTamd64, USB\VID_1915&PID_CAFE
|
||||
|
||||
|
||||
[DeviceList.NTIA64]
|
||||
%NORDIC_CDC_ACM_EXAMPLE%=DriverInstall.NTamd64, USB\VID_1915&PID_CAFE
|
||||
|
||||
|
||||
[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
|
||||
DriverInstall.NT.Copy=12
|
||||
|
||||
[DriverInstall.NT]
|
||||
include=mdmcpq.inf
|
||||
CopyFiles=DriverInstall.NT.Copy
|
||||
AddReg=DriverInstall.NT.AddReg
|
||||
|
||||
[DriverInstall.NT.Copy]
|
||||
usbser.sys
|
||||
|
||||
[DriverInstall.NT.AddReg]
|
||||
HKR,,DevLoader,,*ntkern
|
||||
HKR,,NTMPDriver,,usbser.sys
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
|
||||
[DriverInstall.NT.Services]
|
||||
AddService = usbser, 0x00000002, DriverService.NT
|
||||
|
||||
[DriverService.NT]
|
||||
DisplayName = %Serial.SvcDesc%
|
||||
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
|
||||
StartType = 3 ; SERVICE_DEMAND_START
|
||||
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
|
||||
ServiceBinary = %12%\usbser.sys
|
||||
LoadOrderGroup = Base
|
||||
|
||||
;----------------------------------------------------------
|
||||
; Windows XP, Vista, Windows 7, Windows 8 - 64bit
|
||||
;----------------------------------------------------------
|
||||
|
||||
[DriverInstall.NTamd64]
|
||||
include=mdmcpq.inf
|
||||
CopyFiles=DriverCopyFiles.NTamd64
|
||||
AddReg=DriverInstall.NTamd64.AddReg
|
||||
|
||||
[DriverCopyFiles.NTamd64]
|
||||
usbser.sys,,,0x20
|
||||
|
||||
[DriverInstall.NTamd64.AddReg]
|
||||
HKR,,DevLoader,,*ntkern
|
||||
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
|
||||
|
||||
;----------------------------------------------------------
|
||||
; String
|
||||
;----------------------------------------------------------
|
||||
|
||||
[Strings]
|
||||
Manufacturer = "Nordic Semiconductor"
|
||||
NORDIC_CDC_ACM_EXAMPLE = "nRF52840 OpenThread Device"
|
||||
|
||||
Serial.SvcDesc = "USB Serial emulation driver"
|
||||
|
||||
Reference in New Issue
Block a user