diff --git a/examples/platforms/nrf52840/Makefile.am b/examples/platforms/nrf52840/Makefile.am index 9269fcd9e..769b3e281 100644 --- a/examples/platforms/nrf52840/Makefile.am +++ b/examples/platforms/nrf52840/Makefile.am @@ -50,6 +50,7 @@ COMMONCPPFLAGS -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/hal \ -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 \ @@ -134,8 +135,11 @@ RADIO_DRIVER_SOURCES @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_debug.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_fsm.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_pib.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_revision.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_rx_buffer.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_common.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_drv_radio802154_clock_sdk.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/platform/timer/nrf_drv_radio802154_timer_none.c \ $(NULL) NORDICSEMI_SOURCES = \ @@ -220,10 +224,14 @@ noinst_HEADERS $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_priority_drop.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_procedures_duration.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_request.h \ + $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_revision.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_rx_buffer.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_internal.h \ + $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/hal/nrf_radio.h \ + $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_drv_radio802154_clock.h \ + $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/timer/nrf_drv_radio802154_timer.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_api.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_config.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.h \ @@ -235,7 +243,6 @@ noinst_HEADERS $(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_nvmc.h \ $(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_peripherals.h \ $(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_ppi.h \ - $(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_radio.h \ $(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_rng.h \ $(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_uart.h \ $(top_srcdir)/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT.h \ diff --git a/examples/platforms/nrf52840/platform-config.h b/examples/platforms/nrf52840/platform-config.h index df7a6f6d8..46d886213 100644 --- a/examples/platforms/nrf52840/platform-config.h +++ b/examples/platforms/nrf52840/platform-config.h @@ -371,32 +371,4 @@ #define NRF_DRV_RADIO802154_PENDING_EXTENDED_ADDRESSES OPENTHREAD_CONFIG_MAX_CHILDREN #endif -/** - * @def NRF_RAAL_HFCLK_START - * - * Macro to request High Frequency Clock start. It may use external driver or OS function. - * - */ -#ifndef NRF_RAAL_HFCLK_START -#define NRF_RAAL_HFCLK_START() \ - do { \ - nrf_drv_clock_hfclk_request(NULL); \ - \ - while(NRF_CLOCK->HFCLKSTAT != (CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) {} \ - } while(0); -#endif - -/** - * @def NRF_RAAL_HFCLK_STOP - * - * Macro to release High Frequency Clock. It may use external driver or OS function. - * - */ -#ifndef NRF_RAAL_HFCLK_STOP -#define NRF_RAAL_HFCLK_STOP() \ - do { \ - nrf_drv_clock_hfclk_release(); \ - } while(0); -#endif - #endif // PLATFORM_CONFIG_H_ diff --git a/third_party/NordicSemiconductor/README.md b/third_party/NordicSemiconductor/README.md index e6696fcec..dc875b225 100644 --- a/third_party/NordicSemiconductor/README.md +++ b/third_party/NordicSemiconductor/README.md @@ -2,21 +2,12 @@ Description: This folder consists of selected components from the nRF5 SDK, that are used 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) - - /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 + - /cmsis - Core Peripheral Access Layer Headers files + - /dependencies - Dependencies for drivers and libraries from nrf5 SDK + - /device - MDK for the nRF52840 chip + - /drivers - Drivers for the nRF52840 that are used in the platform + - /hal - Hardware Access Layer for the nRF52840 chip + - /libraries - Libraries for the nRF52840 chip + - /segger_rtt - Library for the RTT communication + - /softdevice - SoftDevice s140 headers diff --git a/third_party/NordicSemiconductor/drivers/radio/README.md b/third_party/NordicSemiconductor/drivers/radio/README.md index 19d4952d7..ec3cb58e8 100644 --- a/third_party/NordicSemiconductor/drivers/radio/README.md +++ b/third_party/NordicSemiconductor/drivers/radio/README.md @@ -1,128 +1,3 @@ # nRF 802.15.4 radio driver. -This driver implements only __non-beacon mode__ of operation. -It supports following __features__: - * reception of unicast and broadcast frames (with filtering), - * automatic sending ACK frames, - * setting pending bit in ACK frame according to pending data for given - destination, - * transmission of unicast and broadcast frames, - * automatic CCA procedure before transmission, - * automatic receiving ACK frames, - * low power mode (sleep), - * energy detection, - * promiscuous mode. - -## Implementation details - -The driver is a FSM. From API perspective it has 4 states. Most of those states -contains sub-states in implementation. - -### FSM description - -``` - receive() transmit() - --------> --------> - Sleep Receive Transmit - <-------- | /|\<-------- - sleep() | | receive() / transmitted() / busy_channel() - | | - energy_detection() | | energy_detected() - \|/ | - Energy detection -``` - -#### Transitions - -The driver is initialized in the Sleep state. The higher layer should call -the receive() function to make the driver enter the Receive state and start -radio operations. - -In basic applications radio should be most time in a Receive state. In this -state the radio receives incoming frames. Changing to any other state should be -performed from Receive state. - -When a frame is received in Receive state the driver notifies the higher layer -by calling received() function. This function is called after reception of a -broadcast frame or after sending an ACK to a unicast frame. -In the promiscuous mode the higher layer is notified about all of the received -frames. Even if the frame was not destined to the receiving node. - -To transmit a frame the higher layer should call the transmit() function. If -channel is busy the driver goes back to the Receive state and notifies the -higher layer by calling the busy_channel() function. If a broadcast frame was -transmitted the driver goes back to the Receive state and notifies the higher -layer by calling the transmitted() function. If a unicast frame was transmitted -and an ACK was received the driver goes back to the Receive state and notifies -the higher layer by calling the transmitted() function. If a unicast frame was -transmitted and there was no expected ACK received the higher layer shall call -the receive() function after the ACK timeout to make the driver go back to the -Receive state. - -To perform an Energy Detection procedure the higher layer should call the -energy_detection() function. When the procedure is completed the driver goes -automatically back to the Receive state and notifies the higher layer with the -energy_detected() function. - -#### States - -##### Sleep -In this state the radio is in low power mode. It cannot transmit or receive any -frame. - -##### Receive -In this state the radio receives 802.15.4 frames. It filters out frames with -invalid CRC, length, type, destination address. -If the driver receives unicast frame destined to the receiving node it -automatically transmits an ACK frame. According to 802.15.4 standard, an ACK -frame should be delayed aTurnaroundTime (192 uS) after reception of the ACKed -frame. To perform this delay the driver uses the TIFS timer in the radio -peripheral. This timer requires 3 shorts to work correctly: -1. END -> DISABLE -2. DISABLE -> TXEN -3. READY -> START -The driver has limited time after receiving of a frame to decide if an ACK -should be transmitted. If ACK should not be transmitted the driver must abort -sending ACK by disabling those shorts and triggering DISABLE task. -To use this limited time most effective the driver uses the Bit Counter feature -of the radio peripheral to get notification when the Frame Control field is -received and when the destination address is received. Those fields are used to -filter the frame before whole frame is received. -If all 3 shorts used to send ACK automatically are enabled the radio peripheral -sends ACK frames in loop. To prevent this during debugging process there are -only 2 shorts enabled when waiting for frame (1. and 2.) and 2 other shorts are -enabled in DISABLED event handler (1. and 3.). The first short is still enabled -to automatically disable transmitter after transmission of the ACK frame. - -##### Transmit -In this state the radio performs the CCA procedure. If channel is free the radio -transmits requested frame. If an ACK was requested in the transmitted frame -the driver automatically receives the ACK frame in this state. -To prevent the TXIDLE peripheral state the driver uses 2 shorts in Transmit -state: -1. READY -> START -2. END -> DISABLE -Those shorts automatically start transmission of the frame when transmitter is -ready and disable transmitter when the frame was transmitted. - -##### Energy detection -In this state the radio performs the Energy Detection procedure. During this -procedure the radio is busy and cannot change state to any other. The end of -this procedure is notified to the higher layer by a function call. - -### Mutex and critical sections. - -State transitions in the FSM can be requested simultaneously by the higher layer -and the IRQ handler. To prevent race conditions in the driver there is a mutex. -The mutex is unlocked only in the *Receive* state (*WaitingRxFrame* substate). -If there is requested state transition, the procedure shall lock the mutex -before state is changed. If mutex cannot be locked, another procedure has locked -it and is going to change the state. -The mutex is unlocked when the driver enters *Receive* state. - -A race condition could also occur during handle of a requests from the higher -layer. Even if the receiver is stopped (TASK STOP) the END or DISABLED event can -be raised for a few uS after triggering the task. To prevent interrupt of the -higher layer request handler by IRQ handler, the higher layer request handlers -are performend in critical sections. The critical sections are implemented as -software interrupt requests with priority equal to the RADIO IRQ. +Copy of [the nRF52840 IEEE 802.15.4 radio driver](https://github.com/NordicSemiconductor/nRF-IEEE-802.15.4-radio-driver). \ No newline at end of file diff --git a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h index 40c042468..decd3cc54 100644 --- a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h +++ b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h @@ -142,6 +142,7 @@ void nrf_fem_control_time_latch(void); /**@brief Activate Power Amplifier (TX) pin of the Front End Module. * * @param[in] shorts_used Information if this operation is related to a task triggered by a short. + * @param[in] turnaround Information if TX mode is entered from RX mode (turnaround) or DISABLED (ramp up). * * This function will set up a timer to activate the pin 5 +/- 2.5 us before radio READY event is generated. * It will also set up a PPI to deactivate the pin on radio DISABLED event. @@ -149,7 +150,7 @@ void nrf_fem_control_time_latch(void); * @note This function shall always be called after @ref nrf_fem_control_time_latch function was called, * to enable precise time measurement. * */ -void nrf_fem_control_pa_set(bool shorts_used); +void nrf_fem_control_pa_set(bool shorts_used, bool turnaround); /**@brief Activate Low Noise Amplifier (RX) pin of the Front End Module. * diff --git a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_common.c b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_common.c index 6dcc154ae..8216d96ef 100644 --- a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_common.c +++ b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_common.c @@ -172,9 +172,13 @@ void nrf_fem_control_time_latch(void) } } -void nrf_fem_control_pa_set(bool shorts_used) +void nrf_fem_control_pa_set(bool shorts_used, bool turnaround) { uint32_t target_time; + uint32_t latency; + + latency = turnaround ? NRF_FEM_RADIO_TX_TURNAROUND_LATENCY_US : + NRF_FEM_RADIO_TX_STARTUP_LATENCY_US; if (m_nrf_fem_control_cfg.pa_cfg.enable) { @@ -184,8 +188,8 @@ void nrf_fem_control_pa_set(bool shorts_used) uint32_t tifs = nrf_radio_ifs_get(); - target_time = tifs <= NRF_FEM_RADIO_TX_STARTUP_LATENCY_US ? - m_time_latch + NRF_FEM_RADIO_TX_STARTUP_LATENCY_US - NRF_FEM_PA_TIME_IN_ADVANCE : + target_time = tifs <= latency ? + m_time_latch + latency - NRF_FEM_PA_TIME_IN_ADVANCE : m_time_latch + tifs - NRF_FEM_RADIO_TIFS_DRIFT_US - NRF_FEM_PA_TIME_IN_ADVANCE; if (shorts_used) diff --git a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h index 7546c9006..f964223f2 100644 --- a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h +++ b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h @@ -48,10 +48,16 @@ extern "C" { #ifdef NRF52840_XXAA /** Radio ramp-up time in TX mode, in us. */ -#define NRF_FEM_RADIO_TX_STARTUP_LATENCY_US 129 +#define NRF_FEM_RADIO_TX_STARTUP_LATENCY_US 40 /** Radio ramp-up time in RX mode, in us. */ -#define NRF_FEM_RADIO_RX_STARTUP_LATENCY_US 129 +#define NRF_FEM_RADIO_RX_STARTUP_LATENCY_US 40 + +/** Radio turnaround from RX to TX mode, in us. */ +#define NRF_FEM_RADIO_TX_TURNAROUND_LATENCY_US 20 + +/** Radio turnaround from TX to RX mode, in us. */ +#define NRF_FEM_RADIO_RX_TURNAROUND_LATENCY_US 20 /** Tifs drift measured, in us. */ #define NRF_FEM_RADIO_TIFS_DRIFT_US 20 diff --git a/third_party/NordicSemiconductor/hal/nrf_radio.h b/third_party/NordicSemiconductor/drivers/radio/hal/nrf_radio.h similarity index 95% rename from third_party/NordicSemiconductor/hal/nrf_radio.h rename to third_party/NordicSemiconductor/drivers/radio/hal/nrf_radio.h index 7a500b130..cff0540cb 100644 --- a/third_party/NordicSemiconductor/hal/nrf_radio.h +++ b/third_party/NordicSemiconductor/drivers/radio/hal/nrf_radio.h @@ -89,6 +89,7 @@ typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ NRF_RADIO_EVENT_FRAMESTART = offsetof(NRF_RADIO_Type, EVENTS_FRAMESTART), /**< IEEE 802.15.4 length field received. */ NRF_RADIO_EVENT_EDEND = offsetof(NRF_RADIO_Type, EVENTS_EDEND), /**< Energy Detection procedure ended. */ NRF_RADIO_EVENT_BCMATCH = offsetof(NRF_RADIO_Type, EVENTS_BCMATCH), /**< Bit counter reached bit count value. */ + NRF_RADIO_EVENT_PHYEND = offsetof(NRF_RADIO_Type, EVENTS_PHYEND), /**< Generated in Ble_LR125Kbit, Ble_LR500Kbit and Ieee802154_250Kbit modes when last bit is sent on air. */ } nrf_radio_event_t; /*lint -restore */ /** @@ -109,6 +110,7 @@ typedef enum NRF_RADIO_INT_FRAMESTART_MASK = RADIO_INTENSET_FRAMESTART_Msk, /**< Mask for enabling or disabling an interrupt on FRAMESTART event. */ NRF_RADIO_INT_EDEND_MASK = RADIO_INTENSET_EDEND_Msk, /**< Mask for enabling or disabling an interrupt on EDEND event. */ NRF_RADIO_INT_BCMATCH_MASK = RADIO_INTENSET_BCMATCH_Msk, /**< Mask for enabling or disabling an interrupt on BCMATCH event. */ + NRF_RADIO_INT_PHYEND_MASK = RADIO_INTENSET_PHYEND_Msk, /**< Mask for enabling or disabling an interrupt on PHYEND event. */ } nrf_radio_int_mask_t; /** @@ -124,6 +126,8 @@ typedef enum NRF_RADIO_SHORT_CCAIDLE_TXEN_MASK = RADIO_SHORTS_CCAIDLE_TXEN_Msk, /**< Mask for setting shortcut between EVENT_CCAIDLE and TASK_TXEN. */ NRF_RADIO_SHORT_DISABLED_TXEN_MASK = RADIO_SHORTS_DISABLED_TXEN_Msk, /**< Mask for setting shortcut between EVENT_DISABLED and TASK_TXEN. */ NRF_RADIO_SHORT_FRAMESTART_BCSTART_MASK = RADIO_SHORTS_FRAMESTART_BCSTART_Msk, /**< Mask for setting shortcut between EVENT_FRAMESTART and TASK_BCSTART. */ + NRF_RADIO_SHORT_PHYEND_DISABLE_MASK = RADIO_SHORTS_PHYEND_DISABLE_Msk, /**< Mask for setting shortcut between EVENT_PHYEND and TASK_DISABLE. */ + NRF_RADIO_SHORT_PHYEND_START_MASK = RADIO_SHORTS_PHYEND_START_Msk, /**< Mask for setting shortcut between EVENT_PHYEND and TASK_START. */ } nrf_radio_short_mask_t; /** diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154.c b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154.c index 99b396e88..6413919d8 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154.c @@ -51,8 +51,11 @@ #include "nrf_drv_radio802154_pib.h" #include "nrf_drv_radio802154_priority_drop.h" #include "nrf_drv_radio802154_request.h" +#include "nrf_drv_radio802154_revision.h" #include "nrf_drv_radio802154_rx_buffer.h" #include "hal/nrf_radio.h" +#include "platform/clock/nrf_drv_radio802154_clock.h" +#include "platform/timer/nrf_drv_radio802154_timer.h" #include "raal/nrf_raal_api.h" #include @@ -116,19 +119,24 @@ int8_t nrf_drv_radio802154_dbm_from_energy_level_calculate(uint8_t energy_level) void nrf_drv_radio802154_init(void) { nrf_drv_radio802154_ack_pending_bit_init(); + nrf_drv_radio802154_clock_init(); nrf_drv_radio802154_debug_init(); nrf_drv_radio802154_fsm_init(); nrf_drv_radio802154_notification_init(); nrf_drv_radio802154_pib_init(); nrf_drv_radio802154_priority_drop_init(); nrf_drv_radio802154_request_init(); + nrf_drv_radio802154_revision_init(); nrf_drv_radio802154_rx_buffer_init(); + nrf_drv_radio802154_timer_init(); nrf_raal_init(); } void nrf_drv_radio802154_deinit(void) { + nrf_drv_radio802154_timer_deinit(); nrf_drv_radio802154_fsm_deinit(); + nrf_drv_radio802154_clock_deinit(); } #if !NRF_DRV_RADIO802154_INTERNAL_IRQ_HANDLING diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_config.h b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_config.h index 7eaa400bc..ea6542a40 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_config.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_config.h @@ -175,6 +175,19 @@ extern "C" { #define NRF_DRV_RADIO802154_NOTIFICATION_SWI_PRIORITY 5 #endif +/** + * @def NRF_DRV_RADIO802154_CLOCK_IRQ_PRIORITY + * + * Priority of clock interrupt used in standalone clock driver implementation. + * + * @note This configuration is only applicable for Clock Abstraction Layer implementation + * in nrf_drv_radio802154_clock_nodrv.c. + * + */ +#ifndef NRF_DRV_RADIO802154_CLOCK_IRQ_PRIORITY +#define NRF_DRV_RADIO802154_CLOCK_IRQ_PRIORITY 10 +#endif + /** *@} **/ diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_critical_section.c b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_critical_section.c index e101c16e2..63e449a7d 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_critical_section.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_critical_section.c @@ -42,6 +42,7 @@ #include "nrf_drv_radio802154_debug.h" #include "nrf_drv_radio802154_fsm.h" #include "hal/nrf_radio.h" +#include "platform/timer/nrf_drv_radio802154_timer.h" #include "raal/nrf_raal_api.h" #include @@ -70,6 +71,7 @@ void nrf_drv_radio802154_critical_section_enter(void) m_in_critical_section = true; #endif // PREVENT_NESTED_CRIT_SECTIONS + nrf_drv_radio802154_timer_critical_section_enter(); nrf_raal_critical_section_enter(); state = nrf_drv_radio802154_fsm_state_get(); @@ -114,6 +116,8 @@ void nrf_drv_radio802154_critical_section_exit(void) NVIC_EnableIRQ(RADIO_IRQn); } + nrf_drv_radio802154_timer_critical_section_exit(); + nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_CRIT_SECT_EXIT); } diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_debug.c b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_debug.c index 778219f02..9a911d665 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_debug.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_debug.c @@ -61,30 +61,35 @@ static void radio_event_gpio_toggle_init(void) nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_READY); nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_FRAMESTART); nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_EDEND); + nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_PHYEND); nrf_gpiote_task_configure(0, PIN_DBG_RADIO_EVT_END, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); nrf_gpiote_task_configure(1, PIN_DBG_RADIO_EVT_DISABLED, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); nrf_gpiote_task_configure(2, PIN_DBG_RADIO_EVT_READY, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); nrf_gpiote_task_configure(3, PIN_DBG_RADIO_EVT_FRAMESTART, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); nrf_gpiote_task_configure(4, PIN_DBG_RADIO_EVT_EDEND, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); + nrf_gpiote_task_configure(5, PIN_DBG_RADIO_EVT_PHYEND, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); nrf_gpiote_task_enable(0); nrf_gpiote_task_enable(1); nrf_gpiote_task_enable(2); nrf_gpiote_task_enable(3); nrf_gpiote_task_enable(4); + nrf_gpiote_task_enable(5); nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL0, (uint32_t) &NRF_RADIO->EVENTS_END, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_0)); nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL1, (uint32_t) &NRF_RADIO->EVENTS_DISABLED, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_1)); nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL2, (uint32_t) &NRF_RADIO->EVENTS_READY, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_2)); nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL3, (uint32_t) &NRF_RADIO->EVENTS_FRAMESTART, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_3)); nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL4, (uint32_t) &NRF_RADIO->EVENTS_EDEND, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_4)); + nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL5, (uint32_t) &NRF_RADIO->EVENTS_PHYEND, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_5)); nrf_ppi_channel_enable(NRF_PPI_CHANNEL0); nrf_ppi_channel_enable(NRF_PPI_CHANNEL1); nrf_ppi_channel_enable(NRF_PPI_CHANNEL2); nrf_ppi_channel_enable(NRF_PPI_CHANNEL3); nrf_ppi_channel_enable(NRF_PPI_CHANNEL4); + nrf_ppi_channel_enable(NRF_PPI_CHANNEL5); } /** diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_debug.h b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_debug.h index ccd051fe1..374aa71a6 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_debug.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_debug.h @@ -68,6 +68,7 @@ extern "C" { #define FUNCTION_EVENT_CCAIDLE 0x0106UL #define FUNCTION_EVENT_CCABUSY 0x0107UL #define FUNCTION_EVENT_EDEND 0x0108UL +#define FUNCTION_EVENT_PHYEND 0x0109UL #define FUNCTION_AUTO_ACK_ABORT 0x0201UL #define FUNCTION_TIMESLOT_STARTED 0x0202UL @@ -94,6 +95,7 @@ extern "C" { #define PIN_DBG_RADIO_EVT_READY 13 #define PIN_DBG_RADIO_EVT_FRAMESTART 14 #define PIN_DBG_RADIO_EVT_EDEND 25 +#define PIN_DBG_RADIO_EVT_PHYEND 24 #define PIN_DBG_TIMESLOT_ACTIVE 3 #define PIN_DBG_TIMESLOT_EXTEND_REQ 4 diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_fsm.c b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_fsm.c index 0c6e5c4f9..21592d8ca 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_fsm.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_fsm.c @@ -50,28 +50,42 @@ #include "nrf_drv_radio802154_pib.h" #include "nrf_drv_radio802154_priority_drop.h" #include "nrf_drv_radio802154_procedures_duration.h" +#include "nrf_drv_radio802154_revision.h" #include "nrf_drv_radio802154_rx_buffer.h" #include "fem/nrf_fem_control_api.h" #include "hal/nrf_radio.h" #include "raal/nrf_raal_api.h" + +/// Workaround for missing PHYEND event in older chip revision. +static inline uint32_t short_phyend_disable_mask_get(void) +{ + if (nrf_drv_radio802154_revision_has_phyend_event()) + { + return NRF_RADIO_SHORT_PHYEND_DISABLE_MASK; + } + + return NRF_RADIO_SHORT_END_DISABLE_MASK; +} + /// Value set to SHORTS register when no shorts should be enabled. #define SHORTS_IDLE 0 /// Value set to SHORTS register when receiver is waiting for incoming frame. #define SHORTS_RX_INITIAL (NRF_RADIO_SHORT_END_DISABLE_MASK | NRF_RADIO_SHORT_DISABLED_TXEN_MASK | \ NRF_RADIO_SHORT_FRAMESTART_BCSTART_MASK) + /// Value set to SHORTS register when receiver started receiving a frame. -#define SHORTS_RX_FOLLOWING (NRF_RADIO_SHORT_END_DISABLE_MASK | NRF_RADIO_SHORT_READY_START_MASK | \ +#define SHORTS_RX_FOLLOWING (short_phyend_disable_mask_get() | NRF_RADIO_SHORT_READY_START_MASK | \ NRF_RADIO_SHORT_FRAMESTART_BCSTART_MASK) /// Value set to SHORTS register when received frame should be acknowledged. -#define SHORTS_TX_ACK (NRF_RADIO_SHORT_END_DISABLE_MASK) +#define SHORTS_TX_ACK (short_phyend_disable_mask_get()) #if NRF_DRV_RADIO802154_SHORT_CCAIDLE_TXEN /// Value set to SHORTS register during transmission of a frame -#define SHORTS_TX_FRAME (NRF_RADIO_SHORT_END_DISABLE_MASK | NRF_RADIO_SHORT_READY_START_MASK | \ +#define SHORTS_TX_FRAME (short_phyend_disable_mask_get() | NRF_RADIO_SHORT_READY_START_MASK | \ NRF_RADIO_SHORT_CCAIDLE_TXEN_MASK) #else /// Value set to SHORTS register during transmission of a frame -#define SHORTS_TX_FRAME (NRF_RADIO_SHORT_END_DISABLE_MASK | NRF_RADIO_SHORT_READY_START_MASK) +#define SHORTS_TX_FRAME (short_phyend_disable_mask_get() | NRF_RADIO_SHORT_READY_START_MASK) #endif /// Delay before sending ACK (12sym = 192uS) @@ -271,7 +285,7 @@ static void tx_enable(void) { nrf_fem_control_time_latch(); nrf_radio_task_trigger(NRF_RADIO_TASK_TXEN); - nrf_fem_control_pa_set(false); + nrf_fem_control_pa_set(false, false); } /*************************************************************************************************** @@ -299,6 +313,7 @@ static inline void shorts_disable(void) { nrf_radio_shorts_set(SHORTS_IDLE); nrf_radio_ifs_set(0); + nrf_radio_ramp_up_mode_set(NRF_RADIO_RAMP_UP_MODE_FAST); } /// Enable peripheral shorts used during data frame transmission. @@ -311,6 +326,7 @@ static inline void shorts_tx_frame_set(void) static inline void shorts_rx_initial_set(void) { nrf_radio_ifs_set(TIFS_ACK_US); + nrf_radio_ramp_up_mode_set(NRF_RADIO_RAMP_UP_MODE_DEFAULT); nrf_radio_bcc_set(BCC_INIT); nrf_radio_shorts_set(SHORTS_RX_INITIAL); @@ -325,12 +341,12 @@ static inline void shorts_rx_following_set(void) /// Disable peripheral shorts used during automatic ACK transmission when ACK is being transmitted static inline void shorts_tx_ack_set(void) { - // If ACK is sent END_DISABLE short should persist to disable transmitter automatically. + // If ACK is sent PHYEND_DISABLE short should persist to disable transmitter automatically. nrf_radio_shorts_set(SHORTS_TX_ACK); nrf_radio_ifs_set(0); + nrf_radio_ramp_up_mode_set(NRF_RADIO_RAMP_UP_MODE_FAST); } - /*************************************************************************************************** * @section ACK transmission management **************************************************************************************************/ @@ -453,7 +469,7 @@ static void nrf_radio_init(void) nrf_radio_config_preamble_length_set(NRF_RADIO_PREAMBLE_LENGTH_32BIT_ZERO); nrf_radio_config_crc_included_set(true); nrf_radio_config_max_length_set(MAX_PACKET_SIZE); - nrf_radio_ramp_up_mode_set(NRF_RADIO_RAMP_UP_MODE_DEFAULT); + nrf_radio_ramp_up_mode_set(NRF_RADIO_RAMP_UP_MODE_FAST); // Configure CRC nrf_radio_crc_length_set(CRC_LENGTH); @@ -475,6 +491,12 @@ static void nrf_radio_init(void) nrf_radio_int_enable(NRF_RADIO_INT_READY_MASK); nrf_radio_int_enable(NRF_RADIO_INT_BCMATCH_MASK); nrf_radio_int_enable(NRF_RADIO_INT_EDEND_MASK); + + /// Workaround for missing PHYEND event in older chip revision. + if (nrf_drv_radio802154_revision_has_phyend_event()) + { + nrf_radio_int_enable(NRF_RADIO_INT_PHYEND_MASK); + } } /// Reset radio peripheral @@ -682,6 +704,7 @@ static inline void irq_framestart_state_waiting_rx_frame(void) auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH); nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_INVALID_FRAME); } @@ -712,6 +735,7 @@ static inline void irq_framestart_state_waiting_rx_frame(void) auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH); nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_RUNTIME); break; @@ -733,6 +757,7 @@ static inline void irq_framestart_state_rx_ack(void) frame_rx_start_after_ack_rx(); nrf_radio_event_clear(NRF_RADIO_EVENT_END); // In case frame ended before task DISABLE + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); } else { @@ -791,6 +816,7 @@ static inline void irq_bcmatch_mhr(void) default: auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_INVALID_FRAME); } @@ -810,6 +836,7 @@ static inline void irq_bcmatch_mhr(void) { auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); // Do not count received ACK as an error. if (frame_type != FRAME_TYPE_ACK) @@ -849,6 +876,7 @@ static inline void irq_bcmatch_address(void) { auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_INVALID_DEST_ADDR); } @@ -892,6 +920,7 @@ static inline void irq_bcmatch_state_rx_header(void) // Something had stopped the CPU too long. Start receiving again. auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_RUNTIME); break; @@ -915,6 +944,7 @@ static inline void irq_end_state_waiting_rx_frame(void) assert(nrf_radio_shorts_get() == SHORTS_RX_INITIAL); auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); } } else @@ -929,6 +959,7 @@ static inline void irq_end_state_rx_header(void) // Frame ended before header was received. auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_INVALID_FRAME); } @@ -952,6 +983,7 @@ static inline void irq_end_state_rx_frame(void) { auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); received_frame_notify(); } else @@ -964,6 +996,7 @@ static inline void irq_end_state_rx_frame(void) { auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_INVALID_FCS); } @@ -973,6 +1006,7 @@ static inline void irq_end_state_rx_frame(void) // CPU was hold too long. auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_RUNTIME); break; @@ -982,16 +1016,17 @@ static inline void irq_end_state_rx_frame(void) } /// This event is generated when the radio ends transmission of ACK frame. -static inline void irq_end_state_tx_ack(void) +static inline void irq_phyend_state_tx_ack(void) { assert(nrf_radio_shorts_get() == SHORTS_TX_ACK || - nrf_radio_shorts_get() == SHORTS_RX_FOLLOWING); // In case END is handled before READY + nrf_radio_shorts_get() == SHORTS_RX_FOLLOWING); // In case PHYEND is handled before READY shorts_disable(); received_frame_notify(); - // Clear event READY in case CPU was halted and event END is handled before READY. + // Clear event READY in case CPU was halted and event PHYEND is handled before READY. nrf_radio_event_clear(NRF_RADIO_EVENT_READY); + nrf_radio_event_clear(NRF_RADIO_EVENT_END); state_set(RADIO_STATE_WAITING_RX_FRAME); // Receiver is enabled by shorts. @@ -1006,13 +1041,14 @@ static inline void irq_end_state_cca_before_tx(void) } /// This event is generated when the radio ends transmission of a frame. -static inline void irq_end_state_tx_frame(void) +static inline void irq_phyend_state_tx_frame(void) { shorts_disable(); assert(nrf_radio_shorts_get() == SHORTS_IDLE); - // Clear event READY in case CPU was halted and event END is handled before READY. + // Clear event READY in case CPU was halted and event PHYEND is handled before READY. nrf_radio_event_clear(NRF_RADIO_EVENT_READY); + nrf_radio_event_clear(NRF_RADIO_EVENT_END); if (!ack_is_requested(mp_tx_data)) { @@ -1097,6 +1133,7 @@ static inline void irq_disabled_state_rx_frame(void) auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); } @@ -1124,7 +1161,7 @@ static inline void irq_disabled_state_tx_ack(void) { // nrf_fem_control_time_latch was called at the beginning of the irq handler, // to capture the time as close to short occurence as possible - nrf_fem_control_pa_set(true); + nrf_fem_control_pa_set(true, false); } } @@ -1448,6 +1485,40 @@ static inline void irq_handler(void) nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_EVENT_BCMATCH); } + if (nrf_drv_radio802154_revision_has_phyend_event() && nrf_radio_event_get(NRF_RADIO_EVENT_PHYEND)) + { + nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_EVENT_PHYEND); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); + + switch (m_state) + { + case RADIO_STATE_WAITING_RX_FRAME: + case RADIO_STATE_RX_HEADER: + case RADIO_STATE_RX_FRAME: + break; + + case RADIO_STATE_TX_ACK: + irq_phyend_state_tx_ack(); + break; + + case RADIO_STATE_CCA_BEFORE_TX: + break; + + case RADIO_STATE_TX_FRAME: + irq_phyend_state_tx_frame(); + break; + + case RADIO_STATE_RX_ACK: + case RADIO_STATE_WAITING_TIMESLOT: + break; + + default: + assert(false); + } + + nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_EVENT_PHYEND); + } + if (nrf_radio_event_get(NRF_RADIO_EVENT_END)) { nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_EVENT_END); @@ -1468,7 +1539,11 @@ static inline void irq_handler(void) break; case RADIO_STATE_TX_ACK: - irq_end_state_tx_ack(); + if (!nrf_drv_radio802154_revision_has_phyend_event()) + { + irq_phyend_state_tx_ack(); + } + break; case RADIO_STATE_CCA_BEFORE_TX: // This could happen at the beginning of transmission @@ -1477,7 +1552,11 @@ static inline void irq_handler(void) break; case RADIO_STATE_TX_FRAME: - irq_end_state_tx_frame(); + if (!nrf_drv_radio802154_revision_has_phyend_event()) + { + irq_phyend_state_tx_frame(); + } + break; case RADIO_STATE_RX_ACK: // Ended receiving of ACK. @@ -1617,7 +1696,7 @@ static inline void irq_handler(void) #else // nrf_fem_control_time_latch was called at the beginning of the irq handler, // to capture the time as close to short occurence as possible - nrf_fem_control_pa_set(true); + nrf_fem_control_pa_set(true, true); #endif break; @@ -1723,6 +1802,7 @@ static inline void tx_procedure_abort(radio_state_t state) nrf_radio_event_clear(NRF_RADIO_EVENT_READY); nrf_radio_event_clear(NRF_RADIO_EVENT_FRAMESTART); nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); } @@ -1778,6 +1858,7 @@ bool nrf_drv_radio802154_fsm_sleep(void) nrf_radio_event_clear(NRF_RADIO_EVENT_FRAMESTART); nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH); nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); result = true; @@ -1824,11 +1905,18 @@ bool nrf_drv_radio802154_fsm_receive(void) break; case RADIO_STATE_SLEEP: - assert(mutex_lock()); - state_set(RADIO_STATE_WAITING_TIMESLOT); - nrf_raal_continuous_mode_enter(); + if (mutex_lock()) + { + state_set(RADIO_STATE_WAITING_TIMESLOT); + nrf_raal_continuous_mode_enter(); + + result = true; + } + else + { + assert(false); + } - result = true; break; case RADIO_STATE_CCA_BEFORE_TX: @@ -1870,6 +1958,7 @@ bool nrf_drv_radio802154_fsm_transmit(const uint8_t * p_data, bool cca) if (mutex_lock()) { if (nrf_raal_timeslot_request(nrf_drv_radio802154_tx_duration_get(p_data[0], + cca, ack_is_requested(p_data)))) { assert(m_state == RADIO_STATE_WAITING_RX_FRAME); @@ -1883,11 +1972,12 @@ bool nrf_drv_radio802154_fsm_transmit(const uint8_t * p_data, bool cca) nrf_radio_event_clear(NRF_RADIO_EVENT_FRAMESTART); nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH); nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); // Check 2nd time in case this procedure was interrupted. if (nrf_raal_timeslot_request( - nrf_drv_radio802154_tx_duration_get(p_data[0], ack_is_requested(p_data)))) + nrf_drv_radio802154_tx_duration_get(p_data[0], cca, ack_is_requested(p_data)))) { result = true; } @@ -1944,6 +2034,7 @@ bool nrf_drv_radio802154_fsm_energy_detection(uint32_t time_us) nrf_radio_event_clear(NRF_RADIO_EVENT_FRAMESTART); nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH); nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); } else @@ -2000,6 +2091,7 @@ bool nrf_drv_radio802154_fsm_cca(void) nrf_radio_event_clear(NRF_RADIO_EVENT_FRAMESTART); nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH); nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); } else @@ -2041,6 +2133,7 @@ bool nrf_drv_radio802154_fsm_continuous_carrier(void) nrf_radio_event_clear(NRF_RADIO_EVENT_FRAMESTART); nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH); nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO_EVENT_READY); result = true; @@ -2105,17 +2198,23 @@ void nrf_drv_radio802154_fsm_channel_update(void) switch (m_state) { case RADIO_STATE_WAITING_RX_FRAME: - assert(mutex_lock()); + if (mutex_lock()) + { + channel_set(nrf_drv_radio802154_pib_channel_get()); + auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); - channel_set(nrf_drv_radio802154_pib_channel_get()); - auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME); - - // Clear events that could have happened in critical section due to receiving - // frame or RX ramp up. - nrf_radio_event_clear(NRF_RADIO_EVENT_FRAMESTART); - nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH); - nrf_radio_event_clear(NRF_RADIO_EVENT_END); - nrf_radio_event_clear(NRF_RADIO_EVENT_READY); + // Clear events that could have happened in critical section due to receiving + // frame or RX ramp up. + nrf_radio_event_clear(NRF_RADIO_EVENT_FRAMESTART); + nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH); + nrf_radio_event_clear(NRF_RADIO_EVENT_END); + nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); + nrf_radio_event_clear(NRF_RADIO_EVENT_READY); + } + else + { + assert(false); + } break; diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_procedures_duration.h b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_procedures_duration.h index a378da9f5..b09ada37b 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_procedures_duration.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_procedures_duration.h @@ -39,27 +39,35 @@ #include #include -#define PHY_US_PER_SYMBOL 16 -#define PHY_SYMBOLS_PER_OCTET 2 -#define PHY_SHR_DURATION 10 +#define TX_RAMP_UP_TIME 40 // us +#define RX_RAMP_UP_TIME 40 // us +#define RX_RAMP_DOWN_TIME 0 // us +#define MAX_RAMP_DOWN_TIME 6 // us -#define A_CCA_DURATION 8 -#define A_TURNAROUND_TIME 12 -#define A_UNIT_BACKOFF_PERIOD 20 +#define PHY_US_PER_SYMBOL 16 // us/sym +#define PHY_SYMBOLS_PER_OCTET 2 // sym/byte +#define PHY_SHR_DURATION 10 // sym -#define NUM_OCTETS_IN_ACK 6 +#define A_CCA_DURATION 8 // sym +#define A_TURNAROUND_TIME 12 // sym +#define A_UNIT_BACKOFF_PERIOD 20 // sym + +#define NUM_OCTETS_IN_ACK 6 // bytes #define MAC_ACK_WAIT_DURATION (A_UNIT_BACKOFF_PERIOD + \ A_TURNAROUND_TIME + \ PHY_SHR_DURATION + \ (NUM_OCTETS_IN_ACK * PHY_SYMBOLS_PER_OCTET)) -static inline uint16_t nrf_drv_radio802154_tx_duration_get(uint8_t psdu_length, bool ack_requested) +static inline uint16_t nrf_drv_radio802154_tx_duration_get(uint8_t psdu_length, + bool cca, + bool ack_requested) { - // aTurnaroundTime + CCA + aTurnaroundTime + SHR + PHR + PSDU + // ramp down + // if CCA: + RX ramp up + CCA + RX ramp down + // + TX ramp up + SHR + PHR + PSDU // if ACK: + macAckWaitDuration - uint16_t result = A_TURNAROUND_TIME + A_CCA_DURATION + A_TURNAROUND_TIME + PHY_SHR_DURATION; - result += (psdu_length + 1) * PHY_SYMBOLS_PER_OCTET; + uint16_t result = PHY_SHR_DURATION + (psdu_length + 1) * PHY_SYMBOLS_PER_OCTET; if (ack_requested) { @@ -68,21 +76,27 @@ static inline uint16_t nrf_drv_radio802154_tx_duration_get(uint8_t psdu_length, result *= PHY_US_PER_SYMBOL; + result += MAX_RAMP_DOWN_TIME + TX_RAMP_UP_TIME; + + if (cca) + { + result += RX_RAMP_UP_TIME + (A_CCA_DURATION * PHY_US_PER_SYMBOL) + RX_RAMP_DOWN_TIME; + } + return result; } static inline uint16_t nrf_drv_radio802154_rx_duration_get(uint8_t psdu_length, bool ack_requested) { // SHR + PHR + PSDU - // if ACK: + aTurnaroundTime + ACK frame duration + aTurnaroundTime + // if ACK: + aTurnaroundTime + ACK frame duration uint16_t result = PHY_SHR_DURATION + (psdu_length + 1) * PHY_SYMBOLS_PER_OCTET; if (ack_requested) { result += A_TURNAROUND_TIME + PHY_SHR_DURATION + - (NUM_OCTETS_IN_ACK * PHY_SYMBOLS_PER_OCTET) + - A_TURNAROUND_TIME; + (NUM_OCTETS_IN_ACK * PHY_SYMBOLS_PER_OCTET); } result *= PHY_US_PER_SYMBOL; @@ -92,10 +106,8 @@ static inline uint16_t nrf_drv_radio802154_rx_duration_get(uint8_t psdu_length, static inline uint16_t nrf_drv_radio802154_cca_duration_get(void) { - // aTurnaroundTime + CCA - uint16_t result = A_TURNAROUND_TIME + A_CCA_DURATION; - - result *= PHY_US_PER_SYMBOL; + // ramp down + rx ramp up + CCA + uint16_t result = MAX_RAMP_DOWN_TIME + RX_RAMP_UP_TIME + A_CCA_DURATION * PHY_US_PER_SYMBOL; return result; } diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_revision.c b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_revision.c new file mode 100644 index 000000000..226d282bf --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_revision.c @@ -0,0 +1,133 @@ +/* Copyright (c) 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. + * + */ + +/** + * @file + * This file implements helpers for checking nRF SoC revision. + * + */ + +#include "nrf_drv_radio802154_revision.h" + +#include + +/** @breif Types of nRF52840 revisions. */ +typedef enum +{ + NRF52840_REVISION_AAAA, + NRF52840_REVISION_AABA, + NRF52840_REVISION_UNKNOWN, +} nrf_drv_radio802154_chip_revision; + +static nrf_drv_radio802154_chip_revision m_nrf52840_revision = NRF52840_REVISION_UNKNOWN; + +/** + * @brief Internal auxiliary function to check if the program is running on NRF52840 chip. + * + * @retval true If it is NRF52480 chip. + * @retval false If it is other chip. + */ +static inline bool nrf_revision_type_52840(void) +{ + return ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 0x08) && + (((*(uint32_t *)0xF0000FE4) & 0x0F) == 0x00)); +} + +/** + * @brief Internal auxiliary function to check if the program is running + * on the AAAA revision of the nRF52840 chip. + * + * @retval true If it is NRF52480_AAAA chip revision. + * @retval false It is other chip revision. + */ +static inline bool nrf_revision_type_52840_aaaa(void) +{ + return (nrf_revision_type_52840() && + (((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x00) && // revision + (((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00)); // sub-revision +} + +/** + * @brief Internal auxiliary function to check if the program is running + * on the AABA revision of the nRF52840 chip. + * + * @retval true If it is NRF52480_AAAA chip revision. + * @retval false It is other chip revision. + */ +static inline bool nrf_revision_type_52840_aaba(void) +{ + return (nrf_revision_type_52840() && + (((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x10) && // revision + (((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00)); // sub-revision +} + +void nrf_drv_radio802154_revision_init(void) +{ + if (nrf_revision_type_52840_aaaa()) + { + m_nrf52840_revision = NRF52840_REVISION_AAAA; + } + else if (nrf_revision_type_52840_aaba()) + { + m_nrf52840_revision = NRF52840_REVISION_AABA; + } + else + { + m_nrf52840_revision = NRF52840_REVISION_UNKNOWN; + } +} + +bool nrf_drv_radio802154_revision_has_phyend_event(void) +{ +#if NRF52840_AAAA + return false; +#elif NRF52840_AABA + return true; +#else + bool result; + + switch (m_nrf52840_revision) + { + case NRF52840_REVISION_AAAA: + result = false; + break; + + case NRF52840_REVISION_AABA: + case NRF52840_REVISION_UNKNOWN: + result = true; + break; + + default: + assert(false); + } + + return result; +#endif // NRF52840_AAAA +} diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_revision.h b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_revision.h new file mode 100644 index 000000000..c02b846ab --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_revision.h @@ -0,0 +1,67 @@ +/* Copyright (c) 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. + * + */ + +/** + * @brief This module contains helpers for checking nRF SoC revision. + * + */ + +#ifndef NRF_DRV_RADIO802154_REVISION_H_ +#define NRF_DRV_RADIO802154_REVISION_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief This function initializes the module by reading the nRF52840 revision + * from the registers and storing it for convenient access. + * + * @note If the chip revision is not recognized, this module assumes that it is running on a newer + * chip revision that has all of the features, that the most recent known revision has. + */ +void nrf_drv_radio802154_revision_init(void); + +/** + * @brief Function to check if the program is running on NRF52840 revision that supports PHYEND event. + * + * @retval true If PHYEND event is supported. + * @retval false If PHYEND event is not supported. + */ +bool nrf_drv_radio802154_revision_has_phyend_event(void); + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_DRV_RADIO802154_REVISION_H_ */ diff --git a/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_drv_radio802154_clock.h b/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_drv_radio802154_clock.h new file mode 100644 index 000000000..1e6c8f40e --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_drv_radio802154_clock.h @@ -0,0 +1,130 @@ +/* Copyright (c) 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. + * + */ + +/** + * @brief This module defines Clock Abstraction Layer for the 802.15.4 driver. + * + * Clock Abstraction Layer can be used by other modules to start and stop nRF52840 clocks. + * + * It is used by Radio Arbiter clients (RAAL) to start HF clock when entering continuous mode + * and stop HF clock after continuous mode exit. + * + * It is used by standalone Timer Abstraction Layer implementation to start LF clock during initialization. + * + */ + +#ifndef NRF_DRV_RADIO802154_CLOCK_H_ +#define NRF_DRV_RADIO802154_CLOCK_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_drv_radio802154_clock Clock Abstraction Layer for the 802.15.4 driver + * @{ + * @ingroup nrf_drv_radio802154_clock + * @brief Clock Abstraction Layer interface for the 802.15.4 driver. + * + */ + +/** + * @brief Initialize the clock driver. + */ +void nrf_drv_radio802154_clock_init(void); + +/** + * @brief Deinitialize the clock driver. + */ +void nrf_drv_radio802154_clock_deinit(void); + +/** + * @brief Start High Frequency Clock. + * + * This function is asynchronous. It should request ramping up of HF clock and exit. When HF clock + * is ready @sa nrf_drv_radio802154_hfclk_ready() should be called. + */ +void nrf_drv_radio802154_clock_hfclk_start(void); + +/** + * @brief Stop High Frequency Clock. + */ +void nrf_drv_radio802154_clock_hfclk_stop(void); + +/** + * @brief Check if High Frequency Clock is running. + * + * @retval true If High Frequency Clock is running. + * @retval false If High Frequency Clock is not running. + */ +bool nrf_drv_radio802154_clock_hfclk_is_running(void); + +/** + * @brief Start Low Frequency Clock. + * + * This function is asynchronous. It should request ramping up of LF clock and exit. When LF clock + * is ready @sa nrf_drv_radio802154_lfclk_ready() should be called. + */ +void nrf_drv_radio802154_clock_lfclk_start(void); + +/** + * @brief Stop Low Frequency Clock. + */ +void nrf_drv_radio802154_clock_lfclk_stop(void); + +/** + * @brief Check if Low Frequency Clock is running. + * + * @retval true If Low Frequency Clock is running. + * @retval false If Low Frequency Clock is not running. + */ +bool nrf_drv_radio802154_clock_lfclk_is_running(void); + +/** + * @brief Callback executed when High Frequency Clock is ready. + */ +extern void nrf_drv_radio802154_clock_hfclk_ready(void); + +/** + * @brief Callback executed when Low Frequency Clock is ready. + */ +extern void nrf_drv_radio802154_clock_lfclk_ready(void); + +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_DRV_RADIO802154_CLOCK_H_ */ diff --git a/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_drv_radio802154_clock_nodrv.c b/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_drv_radio802154_clock_nodrv.c new file mode 100644 index 000000000..2d791128a --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_drv_radio802154_clock_nodrv.c @@ -0,0 +1,121 @@ +/* Copyright (c) 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. + * + */ + +/** + * @file + * This file implements the nrf 802.15.4 Clock Abstraction Layer without any driver. + * + * This implementation uses directly CLOCK hardware registers. + */ + +#include "nrf_drv_radio802154_clock.h" + +#include +#include + +#include "nrf_drv_radio802154_config.h" + +void nrf_drv_radio802154_clock_init(void) +{ + NVIC_SetPriority(POWER_CLOCK_IRQn, NRF_DRV_RADIO802154_CLOCK_IRQ_PRIORITY); + NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn); + NVIC_EnableIRQ(POWER_CLOCK_IRQn); + + nrf_clock_int_enable(NRF_CLOCK_INT_HF_STARTED_MASK); + nrf_clock_int_enable(NRF_CLOCK_INT_LF_STARTED_MASK); +} + +void nrf_drv_radio802154_clock_deinit(void) +{ + NVIC_DisableIRQ(POWER_CLOCK_IRQn); + NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn); + + nrf_clock_int_disable(NRF_CLOCK_INT_HF_STARTED_MASK); + nrf_clock_int_disable(NRF_CLOCK_INT_LF_STARTED_MASK); +} + +void nrf_drv_radio802154_clock_hfclk_start(void) +{ + nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); + nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART); +} + +void nrf_drv_radio802154_clock_hfclk_stop(void) +{ + nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP); +} + +bool nrf_drv_radio802154_clock_hfclk_is_running(void) +{ + return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY); +} + +void nrf_drv_radio802154_clock_lfclk_start(void) +{ + nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); + nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART); +} + +void nrf_drv_radio802154_clock_lfclk_stop(void) +{ + nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTOP); +} + +bool nrf_drv_radio802154_clock_lfclk_is_running(void) +{ + return nrf_clock_lf_is_running(); +} + +void POWER_CLOCK_IRQHandler(void) +{ + if (nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED)) + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); + + nrf_drv_radio802154_clock_hfclk_ready(); + } + + if (nrf_clock_event_check(NRF_CLOCK_EVENT_LFCLKSTARTED)) + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); + + nrf_drv_radio802154_clock_lfclk_ready(); + } +} + +__WEAK void nrf_drv_radio802154_clock_hfclk_ready(void) +{ + // Intentionally empty. +} + +__WEAK void nrf_drv_radio802154_clock_lfclk_ready(void) +{ + // Intentionally empty. +} diff --git a/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_drv_radio802154_clock_sdk.c b/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_drv_radio802154_clock_sdk.c new file mode 100644 index 000000000..ff23df8b7 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_drv_radio802154_clock_sdk.c @@ -0,0 +1,114 @@ +/* Copyright (c) 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. + * + */ + +/** + * @file + * This file implements the nrf 802.15.4 HF Clock abstraction with SDK driver. + * + * This implementation uses clock driver implementation from SDK. + */ + +#include "nrf_drv_radio802154_clock.h" + +#include + +#include +#include + +static void clock_handler(nrf_drv_clock_evt_type_t event); + +static nrf_drv_clock_handler_item_t m_clock_handler = +{ + .p_next = NULL, + .event_handler = clock_handler, +}; + +static void clock_handler(nrf_drv_clock_evt_type_t event) +{ + if (event == NRF_DRV_CLOCK_EVT_HFCLK_STARTED) + { + nrf_drv_radio802154_clock_hfclk_ready(); + } + + if (event == NRF_DRV_CLOCK_EVT_LFCLK_STARTED) + { + nrf_drv_radio802154_clock_lfclk_ready(); + } +} + +void nrf_drv_radio802154_clock_init(void) +{ + nrf_drv_clock_init(); +} + +void nrf_drv_radio802154_clock_deinit(void) +{ + nrf_drv_clock_uninit(); +} + +void nrf_drv_radio802154_clock_hfclk_start(void) +{ + nrf_drv_clock_hfclk_request(&m_clock_handler); +} + +void nrf_drv_radio802154_clock_hfclk_stop(void) +{ + nrf_drv_clock_hfclk_release(); +} + +bool nrf_drv_radio802154_clock_hfclk_is_running(void) +{ + return nrf_drv_clock_hfclk_is_running(); +} + +void nrf_drv_radio802154_clock_lfclk_start(void) +{ + nrf_drv_clock_lfclk_request(&m_clock_handler); +} + +void nrf_drv_radio802154_clock_lfclk_stop(void) +{ + nrf_drv_clock_lfclk_release(); +} + +bool nrf_drv_radio802154_clock_lfclk_is_running(void) +{ + return nrf_drv_clock_lfclk_is_running(); +} + +__WEAK void nrf_drv_radio802154_clock_hfclk_ready(void) +{ + // Intentionally empty. +} + +__WEAK void nrf_drv_radio802154_clock_lfclk_ready(void) +{ + // Intentionally empty. +} diff --git a/third_party/NordicSemiconductor/drivers/radio/platform/timer/nrf_drv_radio802154_timer.h b/third_party/NordicSemiconductor/drivers/radio/platform/timer/nrf_drv_radio802154_timer.h new file mode 100644 index 000000000..ecd1a90c6 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/platform/timer/nrf_drv_radio802154_timer.h @@ -0,0 +1,160 @@ +/* Copyright (c) 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. + * + */ + +/** + * @brief This module defines Timer Abstraction Layer for the 802.15.4 driver. + * + */ + +#ifndef NRF_DRV_RADIO802154_TIMER_API_H_ +#define NRF_DRV_RADIO802154_TIMER_API_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_drv_radio802154_timer Timer Abstraction Layer for the 802.15.4 driver + * @{ + * @ingroup nrf_drv_radio802154_timer + * @brief Timer Abstraction Layer interface for the 802.15.4 driver. + * + * Timer Abstraction Layer is an abstraction layer of timer that is meant to be used by + * the nRF 802.15.4 driver. This timer should provide low latency (max 100 us) in order to allow + * implementation in the driver code features like: + * * Timing out waiting for ACK frame + * * SIFS and LIFS + * * CSMA/CA + * * CSL + * * Auto polling by rx-off-when-idle devices + * + * @note Most of Timer Abstraction Layer API should not be called directly by 802.15.4 driver + * modules. This API is used by the Timer Scheduler module included in the driver and other + * modules should use Timer Scheduler API. Exception from above rule are initialization and + * deinitialization functions @sa nrf_drv_radio802154_timer_init() + * @sa nrf_drv_radio802154_timer_deinit() and critical section management + * @sa nrf_drv_radio802154_timer_critical_section_enter() + * @sa nrf_drv_radio802154_timer_critical_section_exit() as these functions are called from + * nrf_drv_radio802154_critical_section module and from global initialization functions + * @sa nrf_drv_radio802154_init() @sa nrf_drv_radio802154_deinit(). + */ + +/** + * @brief Initialize Timer. + */ +void nrf_drv_radio802154_timer_init(void); + +/** + * @brief Uninitialize Timer. + */ +void nrf_drv_radio802154_timer_deinit(void); + +/** + * @brief Enter critical section of the timer. + * + * In critical section timer cannot execute @sa nrf_drv_radio802154_timer_fired() function. + * + * @note Critical section cannot be nested. + */ +void nrf_drv_radio802154_timer_critical_section_enter(void); + +/** + * @brief Exit critical section of the timer. + * + * In critical section timer cannot execute @sa nrf_drv_radio802154_timer_fired() function. + * + * @note Critical section cannot be nested. + */ +void nrf_drv_radio802154_timer_critical_section_exit(void); + +/** + * @brief Get current time. + * + * Prior to getting current time, Timer must be initialized @sa nrf_drv_radio802154_timer_init(). + * There are no other requirements that must be fulfilled before using this function. + * + * @return Current time in microseconds [us]. + */ +uint32_t nrf_drv_radio802154_timer_time_get(void); + +/** + * @brief Get granularity of currently used timer. + * + * This function may be used to round up/down time calculations. + * + * @return Timer granularity in microseconds [us]. + */ +uint32_t nrf_drv_radio802154_timer_granularity_get(void); + +/** + * @brief Start one-shot timer that expires at specified time. + * + * Start one-shot timer that will expire @p dt microseconds after @p t0 time. + * If timer is running when this function is called, previously running timer will be stopped + * automatically. + * + * On timer expiration @sa nrf_drv_radio802154_timer_fired function will be called. + * Timer automatically stops after expiration. + * + * @param[in] t0 Number of microseconds representing timer start time. + * @param[in] dt Time of timer expiration as time elapsed from @p t0 [us]. + */ +void nrf_drv_radio802154_timer_start(uint32_t t0, uint32_t dt); + +/** + * @brief Stop currently running timer. + */ +void nrf_drv_radio802154_timer_stop(void); + +/** + * @brief Check if timer is currently running. + * + * @retval true Timer is running. + * @retval false Timer is not running. + */ +bool nrf_drv_radio802154_timer_is_running(void); + +/** + * @brief Callback executed when timer expires. + */ +extern void nrf_drv_radio802154_timer_fired(void); + +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_DRV_RADIO802154_TIMER_API_H_ */ diff --git a/third_party/NordicSemiconductor/drivers/radio/platform/timer/nrf_drv_radio802154_timer_none.c b/third_party/NordicSemiconductor/drivers/radio/platform/timer/nrf_drv_radio802154_timer_none.c new file mode 100644 index 000000000..8171d9dc8 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/platform/timer/nrf_drv_radio802154_timer_none.c @@ -0,0 +1,62 @@ +/* Copyright (c) 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. + * + */ + +/** + * @file + * This file implements the nrf 802.15.4 timer abstraction in case timer is not used. + * + * This timer abstraction should be used only when none of driver features that use timer is enabled. + * + */ + +#include "nrf_drv_radio802154_timer.h" + +void nrf_drv_radio802154_timer_init(void) +{ + // Intentionally empty +} + +void nrf_drv_radio802154_timer_deinit(void) +{ + // Intentionally empty +} + +void nrf_drv_radio802154_timer_critical_section_enter(void) +{ + // Intentionally empty +} + +void nrf_drv_radio802154_timer_critical_section_exit(void) +{ + // Intentionally empty +} + +// Other functions from TimAL API are intentionally not implemented to detect build configuration +// problems compile-time. diff --git a/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_config.h b/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_config.h index 6224c91a3..52d894de0 100644 --- a/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_config.h +++ b/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_config.h @@ -59,34 +59,6 @@ extern "C" { #define NRF_RAAL_MAX_CLEAN_UP_TIME_US 91 #endif -/** - * @def NRF_RAAL_HFCLK_START - * - * Macro to request High Frequency Clock start. It may use external driver or OS function. - * - */ -#ifndef NRF_RAAL_HFCLK_START -#define NRF_RAAL_HFCLK_START() \ - do { \ - NRF_CLOCK->TASKS_HFCLKSTART = 1; \ - \ - while(NRF_CLOCK->HFCLKSTAT != (CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) {} \ - } while(0); -#endif - -/** - * @def NRF_RAAL_HFCLK_STOP - * - * Macro to release High Frequency Clock. It may use external driver or OS function. - * - */ -#ifndef NRF_RAAL_HFCLK_STOP -#define NRF_RAAL_HFCLK_STOP() \ - do { \ - NRF_CLOCK->TASKS_HFCLKSTOP = 1; \ - } while(0); -#endif - /** *@} **/ diff --git a/third_party/NordicSemiconductor/drivers/radio/raal/single_phy/single_phy.c b/third_party/NordicSemiconductor/drivers/radio/raal/single_phy/single_phy.c index 69828070a..b188c74d4 100644 --- a/third_party/NordicSemiconductor/drivers/radio/raal/single_phy/single_phy.c +++ b/third_party/NordicSemiconductor/drivers/radio/raal/single_phy/single_phy.c @@ -42,7 +42,7 @@ #include #include -#include "nrf_raal_config.h" +#include "platform/clock/nrf_drv_radio802154_clock.h" static bool m_continuous; @@ -60,10 +60,8 @@ void nrf_raal_continuous_mode_enter(void) { assert(!m_continuous); - NRF_RAAL_HFCLK_START(); + nrf_drv_radio802154_clock_hfclk_start(); m_continuous = true; - - nrf_raal_timeslot_started(); } void nrf_raal_continuous_mode_exit(void) @@ -71,7 +69,7 @@ void nrf_raal_continuous_mode_exit(void) assert(m_continuous); m_continuous = false; - NRF_RAAL_HFCLK_STOP(); + nrf_drv_radio802154_clock_hfclk_stop(); } bool nrf_raal_timeslot_request(uint32_t length_us) @@ -97,3 +95,8 @@ void nrf_raal_critical_section_exit(void) { // Intentionally empty. } + +void nrf_drv_radio802154_clock_hfclk_ready(void) +{ + nrf_raal_timeslot_started(); +} diff --git a/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.c b/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.c index bdbb0a63a..c9be1799d 100644 --- a/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.c +++ b/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.c @@ -42,12 +42,24 @@ #include #include +#include #include #include #include -#include -#include -#include +#include + +#if defined(__GNUC__) + _Pragma("GCC diagnostic push") + _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") + _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") + _Pragma("GCC diagnostic ignored \"-Wpedantic\"") +#endif + +#include + +#if defined(__GNUC__) + _Pragma("GCC diagnostic pop") +#endif /**@brief Enable Request and End on timeslot safety interrupt. */ #define ENABLE_REQUEST_AND_END_ON_TIMESLOT_END 0 @@ -189,8 +201,6 @@ static void timeslot_request_prepare(void) /**@brief Request earliest timeslot. */ static void timeslot_request(void) { - assert(!m_in_timeslot); - timeslot_request_prepare(); sd_radio_request(&m_request); } @@ -517,14 +527,6 @@ void nrf_raal_softdevice_soc_evt_handler(uint32_t evt_id) { switch (evt_id) { - case NRF_EVT_HFCLKSTARTED: - if (m_continuous) - { - timeslot_request(); - } - - break; - case NRF_EVT_RADIO_BLOCKED: case NRF_EVT_RADIO_CANCELED: { @@ -591,7 +593,8 @@ void nrf_raal_init(void) m_config.timeslot_max_length = NRF_RAAL_TIMESLOT_DEFAULT_MAX_LENGTH; m_config.timeslot_timeout = NRF_RAAL_TIMESLOT_DEFAULT_TIMEOUT; - assert(sd_radio_session_open(signal_handler) == NRF_SUCCESS); + uint32_t err_code = sd_radio_session_open(signal_handler); + assert(err_code == NRF_SUCCESS); m_initialize = true; } @@ -599,7 +602,9 @@ void nrf_raal_init(void) void nrf_raal_uninit(void) { assert(m_initialize); - assert(sd_radio_session_close() == NRF_SUCCESS); + + uint32_t err_code = sd_radio_session_close(); + assert(err_code == NRF_SUCCESS); m_continuous = false; m_in_timeslot = false; @@ -618,12 +623,7 @@ void nrf_raal_continuous_mode_enter(void) m_timeslot_length = m_config.timeslot_length; m_continuous = true; - nrf_drv_clock_hfclk_request(NULL); - - if (NRF_CLOCK->HFCLKSTAT == (CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) - { - timeslot_request(); - } + nrf_drv_radio802154_clock_hfclk_start(); nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CONTINUOUS_ENTER); } @@ -643,7 +643,7 @@ void nrf_raal_continuous_mode_exit(void) NVIC_SetPendingIRQ(RAAL_TIMER_IRQn); } - nrf_drv_clock_hfclk_release(); + nrf_drv_radio802154_clock_hfclk_stop(); nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CONTINUOUS_EXIT); } @@ -707,3 +707,11 @@ void nrf_raal_critical_section_exit(void) nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CRIT_SECT_EXIT); } + +void nrf_drv_radio802154_clock_hfclk_ready(void) +{ + if (m_continuous && !m_in_timeslot) + { + timeslot_request(); + } +} diff --git a/third_party/NordicSemiconductor/hal/nrf_clock.h b/third_party/NordicSemiconductor/hal/nrf_clock.h index 695d6848d..0379f9f10 100644 --- a/third_party/NordicSemiconductor/hal/nrf_clock.h +++ b/third_party/NordicSemiconductor/hal/nrf_clock.h @@ -1,33 +1,42 @@ -/* Copyright (c) 2016, Nordic Semiconductor ASA +/** + * 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 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_CLOCK_H__ #define NRF_CLOCK_H__ @@ -291,7 +300,7 @@ __STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask) __STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task) { - return ((uint32_t)NRF_CLOCK + task); + return ((uint32_t )NRF_CLOCK + task); } __STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task) @@ -315,7 +324,7 @@ __STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event) __STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event) { - return (bool) * ((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)); + return (bool)*((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)); } __STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lfclk_t source) @@ -364,7 +373,7 @@ __STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(void) __STATIC_INLINE bool nrf_clock_hf_is_running(nrf_clock_hfclk_t clk_src) { return (NRF_CLOCK->HFCLKSTAT & (CLOCK_HFCLKSTAT_STATE_Msk | CLOCK_HFCLKSTAT_SRC_Msk)) == - (CLOCK_HFCLKSTAT_STATE_Msk | (clk_src << CLOCK_HFCLKSTAT_SRC_Pos)); + (CLOCK_HFCLKSTAT_STATE_Msk | (clk_src << CLOCK_HFCLKSTAT_SRC_Pos)); } __STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void) diff --git a/third_party/NordicSemiconductor/hal/nrf_egu.h b/third_party/NordicSemiconductor/hal/nrf_egu.h index 7c1c17295..ec30679bd 100644 --- a/third_party/NordicSemiconductor/hal/nrf_egu.h +++ b/third_party/NordicSemiconductor/hal/nrf_egu.h @@ -1,342 +1,367 @@ -/* 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 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. - * - */ -#ifndef NRF_EGU_H__ -#define NRF_EGU_H__ - -/** -* @defgroup nrf_egu EGU (Event Generator Unit) abstraction -* @{ -* @ingroup nrf_drivers -* @brief @tagAPI52 EGU (Event Generator Unit) module functions. -* -*/ - -#include -#include -#include -#include -#include "nrf.h" -#include "nrf_peripherals.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @enum nrf_egu_task_t - * @brief EGU tasks. - */ -typedef enum -{ - /*lint -save -e30 -esym(628,__INTADDR__)*/ - NRF_EGU_TASK_TRIGGER0 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[0]), /**< Trigger 0 for triggering the corresponding TRIGGERED[0] event. */ - NRF_EGU_TASK_TRIGGER1 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[1]), /**< Trigger 1 for triggering the corresponding TRIGGERED[1] event. */ - NRF_EGU_TASK_TRIGGER2 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[2]), /**< Trigger 2 for triggering the corresponding TRIGGERED[2] event. */ - NRF_EGU_TASK_TRIGGER3 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[3]), /**< Trigger 3 for triggering the corresponding TRIGGERED[3] event. */ - NRF_EGU_TASK_TRIGGER4 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[4]), /**< Trigger 4 for triggering the corresponding TRIGGERED[4] event. */ - NRF_EGU_TASK_TRIGGER5 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[5]), /**< Trigger 5 for triggering the corresponding TRIGGERED[5] event. */ - NRF_EGU_TASK_TRIGGER6 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[6]), /**< Trigger 6 for triggering the corresponding TRIGGERED[6] event. */ - NRF_EGU_TASK_TRIGGER7 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[7]), /**< Trigger 7 for triggering the corresponding TRIGGERED[7] event. */ - NRF_EGU_TASK_TRIGGER8 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[8]), /**< Trigger 8 for triggering the corresponding TRIGGERED[8] event. */ - NRF_EGU_TASK_TRIGGER9 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[9]), /**< Trigger 9 for triggering the corresponding TRIGGERED[9] event. */ - NRF_EGU_TASK_TRIGGER10 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[10]), /**< Trigger 10 for triggering the corresponding TRIGGERED[10] event. */ - NRF_EGU_TASK_TRIGGER11 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[11]), /**< Trigger 11 for triggering the corresponding TRIGGERED[11] event. */ - NRF_EGU_TASK_TRIGGER12 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[12]), /**< Trigger 12 for triggering the corresponding TRIGGERED[12] event. */ - NRF_EGU_TASK_TRIGGER13 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[13]), /**< Trigger 13 for triggering the corresponding TRIGGERED[13] event. */ - NRF_EGU_TASK_TRIGGER14 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[14]), /**< Trigger 14 for triggering the corresponding TRIGGERED[14] event. */ - NRF_EGU_TASK_TRIGGER15 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[15]) /**< Trigger 15 for triggering the corresponding TRIGGERED[15] event. */ - /*lint -restore*/ -} nrf_egu_task_t; - - -/** - * @enum nrf_egu_event_t - * @brief EGU events. - */ -typedef enum -{ - /*lint -save -e30 -esym(628,__INTADDR__)*/ - NRF_EGU_EVENT_TRIGGERED0 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[0]), /**< Event number 0 generated by triggering the corresponding TRIGGER[0] task. */ - NRF_EGU_EVENT_TRIGGERED1 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[1]), /**< Event number 1 generated by triggering the corresponding TRIGGER[1] task. */ - NRF_EGU_EVENT_TRIGGERED2 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[2]), /**< Event number 2 generated by triggering the corresponding TRIGGER[2] task. */ - NRF_EGU_EVENT_TRIGGERED3 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[3]), /**< Event number 3 generated by triggering the corresponding TRIGGER[3] task. */ - NRF_EGU_EVENT_TRIGGERED4 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[4]), /**< Event number 4 generated by triggering the corresponding TRIGGER[4] task. */ - NRF_EGU_EVENT_TRIGGERED5 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[5]), /**< Event number 5 generated by triggering the corresponding TRIGGER[5] task. */ - NRF_EGU_EVENT_TRIGGERED6 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[6]), /**< Event number 6 generated by triggering the corresponding TRIGGER[6] task. */ - NRF_EGU_EVENT_TRIGGERED7 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[7]), /**< Event number 7 generated by triggering the corresponding TRIGGER[7] task. */ - NRF_EGU_EVENT_TRIGGERED8 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[8]), /**< Event number 8 generated by triggering the corresponding TRIGGER[8] task. */ - NRF_EGU_EVENT_TRIGGERED9 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[9]), /**< Event number 9 generated by triggering the corresponding TRIGGER[9] task. */ - NRF_EGU_EVENT_TRIGGERED10 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[10]), /**< Event number 10 generated by triggering the corresponding TRIGGER[10] task. */ - NRF_EGU_EVENT_TRIGGERED11 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[11]), /**< Event number 11 generated by triggering the corresponding TRIGGER[11] task. */ - NRF_EGU_EVENT_TRIGGERED12 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[12]), /**< Event number 12 generated by triggering the corresponding TRIGGER[12] task. */ - NRF_EGU_EVENT_TRIGGERED13 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[13]), /**< Event number 13 generated by triggering the corresponding TRIGGER[13] task. */ - NRF_EGU_EVENT_TRIGGERED14 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[14]), /**< Event number 14 generated by triggering the corresponding TRIGGER[14] task. */ - NRF_EGU_EVENT_TRIGGERED15 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[15]) /**< Event number 15 generated by triggering the corresponding TRIGGER[15] task. */ - /*lint -restore*/ -} nrf_egu_event_t; - - -/** - * @enum nrf_egu_int_mask_t - * @brief EGU interrupts. - */ -typedef enum -{ - NRF_EGU_INT_TRIGGERED0 = EGU_INTENSET_TRIGGERED0_Msk, /**< Interrupt on EVENTS_TRIGGERED[0] event. */ - NRF_EGU_INT_TRIGGERED1 = EGU_INTENSET_TRIGGERED1_Msk, /**< Interrupt on EVENTS_TRIGGERED[1] event. */ - NRF_EGU_INT_TRIGGERED2 = EGU_INTENSET_TRIGGERED2_Msk, /**< Interrupt on EVENTS_TRIGGERED[2] event. */ - NRF_EGU_INT_TRIGGERED3 = EGU_INTENSET_TRIGGERED3_Msk, /**< Interrupt on EVENTS_TRIGGERED[3] event. */ - NRF_EGU_INT_TRIGGERED4 = EGU_INTENSET_TRIGGERED4_Msk, /**< Interrupt on EVENTS_TRIGGERED[4] event. */ - NRF_EGU_INT_TRIGGERED5 = EGU_INTENSET_TRIGGERED5_Msk, /**< Interrupt on EVENTS_TRIGGERED[5] event. */ - NRF_EGU_INT_TRIGGERED6 = EGU_INTENSET_TRIGGERED6_Msk, /**< Interrupt on EVENTS_TRIGGERED[6] event. */ - NRF_EGU_INT_TRIGGERED7 = EGU_INTENSET_TRIGGERED7_Msk, /**< Interrupt on EVENTS_TRIGGERED[7] event. */ - NRF_EGU_INT_TRIGGERED8 = EGU_INTENSET_TRIGGERED8_Msk, /**< Interrupt on EVENTS_TRIGGERED[8] event. */ - NRF_EGU_INT_TRIGGERED9 = EGU_INTENSET_TRIGGERED9_Msk, /**< Interrupt on EVENTS_TRIGGERED[9] event. */ - NRF_EGU_INT_TRIGGERED10 = EGU_INTENSET_TRIGGERED10_Msk, /**< Interrupt on EVENTS_TRIGGERED[10] event. */ - NRF_EGU_INT_TRIGGERED11 = EGU_INTENSET_TRIGGERED11_Msk, /**< Interrupt on EVENTS_TRIGGERED[11] event. */ - NRF_EGU_INT_TRIGGERED12 = EGU_INTENSET_TRIGGERED12_Msk, /**< Interrupt on EVENTS_TRIGGERED[12] event. */ - NRF_EGU_INT_TRIGGERED13 = EGU_INTENSET_TRIGGERED13_Msk, /**< Interrupt on EVENTS_TRIGGERED[13] event. */ - NRF_EGU_INT_TRIGGERED14 = EGU_INTENSET_TRIGGERED14_Msk, /**< Interrupt on EVENTS_TRIGGERED[14] event. */ - NRF_EGU_INT_TRIGGERED15 = EGU_INTENSET_TRIGGERED15_Msk, /**< Interrupt on EVENTS_TRIGGERED[15] event. */ - NRF_EGU_INT_ALL = 0xFFFFuL -} nrf_egu_int_mask_t; - -/**@brief Function for getting max channel number of given EGU. - * - * @param NRF_EGUx EGU instance. - * - * @returns number of available channels. - */ -__STATIC_INLINE uint32_t nrf_egu_channel_count(NRF_EGU_Type * NRF_EGUx) -{ - if (NRF_EGUx == NRF_EGU0){ - return EGU0_CH_NUM; - } - if (NRF_EGUx == NRF_EGU1){ - return EGU1_CH_NUM; - } - if (NRF_EGUx == NRF_EGU2){ - return EGU2_CH_NUM; - } - if (NRF_EGUx == NRF_EGU3){ - return EGU3_CH_NUM; - } - if (NRF_EGUx == NRF_EGU4){ - return EGU4_CH_NUM; - } - if (NRF_EGUx == NRF_EGU5){ - return EGU5_CH_NUM; - } - return 0; -} - -/** - * @brief Function for triggering a specific EGU task. - * - * @param NRF_EGUx EGU instance. - * @param egu_task EGU task. - */ -__STATIC_INLINE void nrf_egu_task_trigger(NRF_EGU_Type * NRF_EGUx, nrf_egu_task_t egu_task) -{ - *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task)) = 0x1UL; -} - - -/** - * @brief Function for returning the address of a specific EGU task register. - * - * @param NRF_EGUx EGU instance. - * @param egu_task EGU task. - */ -__STATIC_INLINE uint32_t * nrf_egu_task_address_get(NRF_EGU_Type * NRF_EGUx, - nrf_egu_task_t egu_task) -{ - return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task); -} - - -/** - * @brief Function for returning the address of a specific EGU TRIGGER task register. - * - * @param NRF_EGUx EGU instance. - * @param channel Channel number. - */ -__STATIC_INLINE uint32_t * nrf_egu_task_trigger_address_get(NRF_EGU_Type * NRF_EGUx, - uint8_t channel) -{ - ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); - return (uint32_t*)&NRF_EGUx->TASKS_TRIGGER[channel]; -} - - -/** - * @brief Function for returning the specific EGU TRIGGER task. - * - * @param NRF_EGUx EGU instance. - * @param channel Channel number. - */ -__STATIC_INLINE nrf_egu_task_t nrf_egu_task_trigger_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel) -{ - ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); - return (nrf_egu_task_t)((uint32_t) NRF_EGU_TASK_TRIGGER0 + (channel * sizeof(uint32_t))); -} - - -/** - * @brief Function for returning the state of a specific EGU event. - * - * @param NRF_EGUx EGU instance. - * @param egu_event EGU event to check. - */ -__STATIC_INLINE bool nrf_egu_event_check(NRF_EGU_Type * NRF_EGUx, - nrf_egu_event_t egu_event) -{ - return (bool)*(volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event); -} - - -/** - * @brief Function for clearing a specific EGU event. - * - * @param NRF_EGUx EGU instance. - * @param egu_event EGU event to clear. - */ -__STATIC_INLINE void nrf_egu_event_clear(NRF_EGU_Type * NRF_EGUx, - nrf_egu_event_t egu_event) -{ - *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event)) = 0x0UL; -#if __CORTEX_M == 0x04 - volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event)); - (void)dummy; -#endif -} - - -/** - * @brief Function for returning the address of a specific EGU event register. - * - * @param NRF_EGUx EGU instance. - * @param egu_event EGU event. - */ -__STATIC_INLINE uint32_t * nrf_egu_event_address_get(NRF_EGU_Type * NRF_EGUx, - nrf_egu_event_t egu_event) -{ - return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event); -} - - -/** - * @brief Function for returning the address of a specific EGU TRIGGERED event register. - * - * @param NRF_EGUx EGU instance. - * @param channel Channel number. - */ -__STATIC_INLINE uint32_t * nrf_egu_event_triggered_address_get(NRF_EGU_Type * NRF_EGUx, - uint8_t channel) -{ - ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); - return (uint32_t*)&NRF_EGUx->EVENTS_TRIGGERED[channel]; -} - - -/** - * @brief Function for returning the specific EGU TRIGGERED event. - * - * @param NRF_EGUx EGU instance. - * @param channel Channel number. - */ -__STATIC_INLINE nrf_egu_event_t nrf_egu_event_triggered_get(NRF_EGU_Type * NRF_EGUx, - uint8_t channel) -{ - ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); - return (nrf_egu_event_t)((uint32_t) NRF_EGU_EVENT_TRIGGERED0 + (channel * sizeof(uint32_t))); -} - - -/** - * @brief Function for enabling one or more specific EGU interrupts. - * - * @param NRF_EGUx EGU instance. - * @param egu_int_mask Interrupts to enable. - */ -__STATIC_INLINE void nrf_egu_int_enable(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask) -{ - NRF_EGUx->INTENSET = egu_int_mask; -} - - -/** - * @brief Function for retrieving the state of one or more EGU interrupts. - * - * @param NRF_EGUx EGU instance. - * @param egu_int_mask Interrupts to check. - * - * @retval true If all of the specified interrupts are enabled. - * @retval false If at least one of the specified interrupts is disabled. - */ -__STATIC_INLINE bool nrf_egu_int_enable_check(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask) -{ - return (bool)(NRF_EGUx->INTENSET & egu_int_mask); -} - - -/** - * @brief Function for disabling one or more specific EGU interrupts. - * - * @param NRF_EGUx EGU instance. - * @param egu_int_mask Interrupts to disable. - */ -__STATIC_INLINE void nrf_egu_int_disable(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask) -{ - NRF_EGUx->INTENCLR = egu_int_mask; -} - -/** - * @brief Function for retrieving one or more specific EGU interrupts. - * - * @param NRF_EGUx EGU instance. - * @param channel Channel number. - * - * @returns EGU interrupt mask. - */ -__STATIC_INLINE nrf_egu_int_mask_t nrf_egu_int_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel) -{ - ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); - return (nrf_egu_int_mask_t)((uint32_t) (EGU_INTENSET_TRIGGERED0_Msk << channel)); -} - -/** @} */ - - -#ifdef __cplusplus -} -#endif - -#endif +/** + * 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_EGU_H__ +#define NRF_EGU_H__ + +/** +* @defgroup nrf_egu EGU (Event Generator Unit) abstraction +* @{ +* @ingroup nrf_drivers +* @brief @tagAPI52 EGU (Event Generator Unit) module functions. +* +*/ + +#include +#include +#include +#include "nrf_assert.h" +#include "nrf.h" +#include "nrf_peripherals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @enum nrf_egu_task_t + * @brief EGU tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_EGU_TASK_TRIGGER0 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[0]), /**< Trigger 0 for triggering the corresponding TRIGGERED[0] event. */ + NRF_EGU_TASK_TRIGGER1 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[1]), /**< Trigger 1 for triggering the corresponding TRIGGERED[1] event. */ + NRF_EGU_TASK_TRIGGER2 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[2]), /**< Trigger 2 for triggering the corresponding TRIGGERED[2] event. */ + NRF_EGU_TASK_TRIGGER3 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[3]), /**< Trigger 3 for triggering the corresponding TRIGGERED[3] event. */ + NRF_EGU_TASK_TRIGGER4 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[4]), /**< Trigger 4 for triggering the corresponding TRIGGERED[4] event. */ + NRF_EGU_TASK_TRIGGER5 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[5]), /**< Trigger 5 for triggering the corresponding TRIGGERED[5] event. */ + NRF_EGU_TASK_TRIGGER6 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[6]), /**< Trigger 6 for triggering the corresponding TRIGGERED[6] event. */ + NRF_EGU_TASK_TRIGGER7 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[7]), /**< Trigger 7 for triggering the corresponding TRIGGERED[7] event. */ + NRF_EGU_TASK_TRIGGER8 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[8]), /**< Trigger 8 for triggering the corresponding TRIGGERED[8] event. */ + NRF_EGU_TASK_TRIGGER9 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[9]), /**< Trigger 9 for triggering the corresponding TRIGGERED[9] event. */ + NRF_EGU_TASK_TRIGGER10 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[10]), /**< Trigger 10 for triggering the corresponding TRIGGERED[10] event. */ + NRF_EGU_TASK_TRIGGER11 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[11]), /**< Trigger 11 for triggering the corresponding TRIGGERED[11] event. */ + NRF_EGU_TASK_TRIGGER12 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[12]), /**< Trigger 12 for triggering the corresponding TRIGGERED[12] event. */ + NRF_EGU_TASK_TRIGGER13 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[13]), /**< Trigger 13 for triggering the corresponding TRIGGERED[13] event. */ + NRF_EGU_TASK_TRIGGER14 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[14]), /**< Trigger 14 for triggering the corresponding TRIGGERED[14] event. */ + NRF_EGU_TASK_TRIGGER15 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[15]) /**< Trigger 15 for triggering the corresponding TRIGGERED[15] event. */ + /*lint -restore*/ +} nrf_egu_task_t; + + +/** + * @enum nrf_egu_event_t + * @brief EGU events. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_EGU_EVENT_TRIGGERED0 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[0]), /**< Event number 0 generated by triggering the corresponding TRIGGER[0] task. */ + NRF_EGU_EVENT_TRIGGERED1 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[1]), /**< Event number 1 generated by triggering the corresponding TRIGGER[1] task. */ + NRF_EGU_EVENT_TRIGGERED2 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[2]), /**< Event number 2 generated by triggering the corresponding TRIGGER[2] task. */ + NRF_EGU_EVENT_TRIGGERED3 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[3]), /**< Event number 3 generated by triggering the corresponding TRIGGER[3] task. */ + NRF_EGU_EVENT_TRIGGERED4 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[4]), /**< Event number 4 generated by triggering the corresponding TRIGGER[4] task. */ + NRF_EGU_EVENT_TRIGGERED5 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[5]), /**< Event number 5 generated by triggering the corresponding TRIGGER[5] task. */ + NRF_EGU_EVENT_TRIGGERED6 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[6]), /**< Event number 6 generated by triggering the corresponding TRIGGER[6] task. */ + NRF_EGU_EVENT_TRIGGERED7 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[7]), /**< Event number 7 generated by triggering the corresponding TRIGGER[7] task. */ + NRF_EGU_EVENT_TRIGGERED8 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[8]), /**< Event number 8 generated by triggering the corresponding TRIGGER[8] task. */ + NRF_EGU_EVENT_TRIGGERED9 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[9]), /**< Event number 9 generated by triggering the corresponding TRIGGER[9] task. */ + NRF_EGU_EVENT_TRIGGERED10 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[10]), /**< Event number 10 generated by triggering the corresponding TRIGGER[10] task. */ + NRF_EGU_EVENT_TRIGGERED11 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[11]), /**< Event number 11 generated by triggering the corresponding TRIGGER[11] task. */ + NRF_EGU_EVENT_TRIGGERED12 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[12]), /**< Event number 12 generated by triggering the corresponding TRIGGER[12] task. */ + NRF_EGU_EVENT_TRIGGERED13 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[13]), /**< Event number 13 generated by triggering the corresponding TRIGGER[13] task. */ + NRF_EGU_EVENT_TRIGGERED14 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[14]), /**< Event number 14 generated by triggering the corresponding TRIGGER[14] task. */ + NRF_EGU_EVENT_TRIGGERED15 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[15]) /**< Event number 15 generated by triggering the corresponding TRIGGER[15] task. */ + /*lint -restore*/ +} nrf_egu_event_t; + + +/** + * @enum nrf_egu_int_mask_t + * @brief EGU interrupts. + */ +typedef enum +{ + NRF_EGU_INT_TRIGGERED0 = EGU_INTENSET_TRIGGERED0_Msk, /**< Interrupt on EVENTS_TRIGGERED[0] event. */ + NRF_EGU_INT_TRIGGERED1 = EGU_INTENSET_TRIGGERED1_Msk, /**< Interrupt on EVENTS_TRIGGERED[1] event. */ + NRF_EGU_INT_TRIGGERED2 = EGU_INTENSET_TRIGGERED2_Msk, /**< Interrupt on EVENTS_TRIGGERED[2] event. */ + NRF_EGU_INT_TRIGGERED3 = EGU_INTENSET_TRIGGERED3_Msk, /**< Interrupt on EVENTS_TRIGGERED[3] event. */ + NRF_EGU_INT_TRIGGERED4 = EGU_INTENSET_TRIGGERED4_Msk, /**< Interrupt on EVENTS_TRIGGERED[4] event. */ + NRF_EGU_INT_TRIGGERED5 = EGU_INTENSET_TRIGGERED5_Msk, /**< Interrupt on EVENTS_TRIGGERED[5] event. */ + NRF_EGU_INT_TRIGGERED6 = EGU_INTENSET_TRIGGERED6_Msk, /**< Interrupt on EVENTS_TRIGGERED[6] event. */ + NRF_EGU_INT_TRIGGERED7 = EGU_INTENSET_TRIGGERED7_Msk, /**< Interrupt on EVENTS_TRIGGERED[7] event. */ + NRF_EGU_INT_TRIGGERED8 = EGU_INTENSET_TRIGGERED8_Msk, /**< Interrupt on EVENTS_TRIGGERED[8] event. */ + NRF_EGU_INT_TRIGGERED9 = EGU_INTENSET_TRIGGERED9_Msk, /**< Interrupt on EVENTS_TRIGGERED[9] event. */ + NRF_EGU_INT_TRIGGERED10 = EGU_INTENSET_TRIGGERED10_Msk, /**< Interrupt on EVENTS_TRIGGERED[10] event. */ + NRF_EGU_INT_TRIGGERED11 = EGU_INTENSET_TRIGGERED11_Msk, /**< Interrupt on EVENTS_TRIGGERED[11] event. */ + NRF_EGU_INT_TRIGGERED12 = EGU_INTENSET_TRIGGERED12_Msk, /**< Interrupt on EVENTS_TRIGGERED[12] event. */ + NRF_EGU_INT_TRIGGERED13 = EGU_INTENSET_TRIGGERED13_Msk, /**< Interrupt on EVENTS_TRIGGERED[13] event. */ + NRF_EGU_INT_TRIGGERED14 = EGU_INTENSET_TRIGGERED14_Msk, /**< Interrupt on EVENTS_TRIGGERED[14] event. */ + NRF_EGU_INT_TRIGGERED15 = EGU_INTENSET_TRIGGERED15_Msk, /**< Interrupt on EVENTS_TRIGGERED[15] event. */ + NRF_EGU_INT_ALL = 0xFFFFuL +} nrf_egu_int_mask_t; + +/**@brief Function for getting max channel number of given EGU. + * + * @param NRF_EGUx EGU instance. + * + * @returns number of available channels. + */ +__STATIC_INLINE uint32_t nrf_egu_channel_count(NRF_EGU_Type * NRF_EGUx) +{ + if (NRF_EGUx == NRF_EGU0){ + return EGU0_CH_NUM; + } + if (NRF_EGUx == NRF_EGU1){ + return EGU1_CH_NUM; + } +#if EGU_COUNT > 2 + if (NRF_EGUx == NRF_EGU2){ + return EGU2_CH_NUM; + } + if (NRF_EGUx == NRF_EGU3){ + return EGU3_CH_NUM; + } + if (NRF_EGUx == NRF_EGU4){ + return EGU4_CH_NUM; + } + if (NRF_EGUx == NRF_EGU5){ + return EGU5_CH_NUM; + } +#endif + return 0; +} + +/** + * @brief Function for triggering a specific EGU task. + * + * @param NRF_EGUx EGU instance. + * @param egu_task EGU task. + */ +__STATIC_INLINE void nrf_egu_task_trigger(NRF_EGU_Type * NRF_EGUx, nrf_egu_task_t egu_task) +{ + ASSERT(NRF_EGUx); + *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task)) = 0x1UL; +} + + +/** + * @brief Function for returning the address of a specific EGU task register. + * + * @param NRF_EGUx EGU instance. + * @param egu_task EGU task. + */ +__STATIC_INLINE uint32_t * nrf_egu_task_address_get(NRF_EGU_Type * NRF_EGUx, + nrf_egu_task_t egu_task) +{ + ASSERT(NRF_EGUx); + return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task); +} + + +/** + * @brief Function for returning the address of a specific EGU TRIGGER task register. + * + * @param NRF_EGUx EGU instance. + * @param channel Channel number. + */ +__STATIC_INLINE uint32_t * nrf_egu_task_trigger_address_get(NRF_EGU_Type * NRF_EGUx, + uint8_t channel) +{ + ASSERT(NRF_EGUx); + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); + return (uint32_t*)&NRF_EGUx->TASKS_TRIGGER[channel]; +} + + +/** + * @brief Function for returning the specific EGU TRIGGER task. + * + * @param NRF_EGUx EGU instance. + * @param channel Channel number. + */ +__STATIC_INLINE nrf_egu_task_t nrf_egu_task_trigger_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel) +{ + ASSERT(NRF_EGUx); + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); + return (nrf_egu_task_t)((uint32_t) NRF_EGU_TASK_TRIGGER0 + (channel * sizeof(uint32_t))); +} + + +/** + * @brief Function for returning the state of a specific EGU event. + * + * @param NRF_EGUx EGU instance. + * @param egu_event EGU event to check. + */ +__STATIC_INLINE bool nrf_egu_event_check(NRF_EGU_Type * NRF_EGUx, + nrf_egu_event_t egu_event) +{ + ASSERT(NRF_EGUx); + return (bool)*(volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event); +} + + +/** + * @brief Function for clearing a specific EGU event. + * + * @param NRF_EGUx EGU instance. + * @param egu_event EGU event to clear. + */ +__STATIC_INLINE void nrf_egu_event_clear(NRF_EGU_Type * NRF_EGUx, + nrf_egu_event_t egu_event) +{ + ASSERT(NRF_EGUx); + *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event)); + (void)dummy; +#endif +} + + +/** + * @brief Function for returning the address of a specific EGU event register. + * + * @param NRF_EGUx EGU instance. + * @param egu_event EGU event. + */ +__STATIC_INLINE uint32_t * nrf_egu_event_address_get(NRF_EGU_Type * NRF_EGUx, + nrf_egu_event_t egu_event) +{ + ASSERT(NRF_EGUx); + return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event); +} + + +/** + * @brief Function for returning the address of a specific EGU TRIGGERED event register. + * + * @param NRF_EGUx EGU instance. + * @param channel Channel number. + */ +__STATIC_INLINE uint32_t * nrf_egu_event_triggered_address_get(NRF_EGU_Type * NRF_EGUx, + uint8_t channel) +{ + ASSERT(NRF_EGUx); + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); + return (uint32_t*)&NRF_EGUx->EVENTS_TRIGGERED[channel]; +} + + +/** + * @brief Function for returning the specific EGU TRIGGERED event. + * + * @param NRF_EGUx EGU instance. + * @param channel Channel number. + */ +__STATIC_INLINE nrf_egu_event_t nrf_egu_event_triggered_get(NRF_EGU_Type * NRF_EGUx, + uint8_t channel) +{ + ASSERT(NRF_EGUx); + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); + return (nrf_egu_event_t)((uint32_t) NRF_EGU_EVENT_TRIGGERED0 + (channel * sizeof(uint32_t))); +} + + +/** + * @brief Function for enabling one or more specific EGU interrupts. + * + * @param NRF_EGUx EGU instance. + * @param egu_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_egu_int_enable(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask) +{ + ASSERT(NRF_EGUx); + NRF_EGUx->INTENSET = egu_int_mask; +} + + +/** + * @brief Function for retrieving the state of one or more EGU interrupts. + * + * @param NRF_EGUx EGU instance. + * @param egu_int_mask Interrupts to check. + * + * @retval true If all of the specified interrupts are enabled. + * @retval false If at least one of the specified interrupts is disabled. + */ +__STATIC_INLINE bool nrf_egu_int_enable_check(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask) +{ + ASSERT(NRF_EGUx); + return (bool)(NRF_EGUx->INTENSET & egu_int_mask); +} + + +/** + * @brief Function for disabling one or more specific EGU interrupts. + * + * @param NRF_EGUx EGU instance. + * @param egu_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_egu_int_disable(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask) +{ + ASSERT(NRF_EGUx); + NRF_EGUx->INTENCLR = egu_int_mask; +} + +/** + * @brief Function for retrieving one or more specific EGU interrupts. + * + * @param NRF_EGUx EGU instance. + * @param channel Channel number. + * + * @returns EGU interrupt mask. + */ +__STATIC_INLINE nrf_egu_int_mask_t nrf_egu_int_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel) +{ + ASSERT(NRF_EGUx); + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); + return (nrf_egu_int_mask_t)((uint32_t) (EGU_INTENSET_TRIGGERED0_Msk << channel)); +} + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/third_party/NordicSemiconductor/hal/nrf_gpio.h b/third_party/NordicSemiconductor/hal/nrf_gpio.h index 7fb8d7886..56e12df53 100644 --- a/third_party/NordicSemiconductor/hal/nrf_gpio.h +++ b/third_party/NordicSemiconductor/hal/nrf_gpio.h @@ -1,19 +1,48 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRANTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * +/** + * 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_GPIO_H__ #define NRF_GPIO_H__ #include "nrf.h" #include "nrf_peripherals.h" +#include "nrf_assert.h" #include #include @@ -432,7 +461,7 @@ __STATIC_INLINE void nrf_gpio_pin_latch_clear(uint32_t pin_number); */ __STATIC_INLINE NRF_GPIO_Type * nrf_gpio_pin_port_decode(uint32_t * p_pin) { - //ASSERT(*p_pin < NUMBER_OF_PINS); + ASSERT(*p_pin < NUMBER_OF_PINS); #if (GPIO_COUNT == 1) // The oldest definition case return NRF_GPIO; @@ -712,7 +741,7 @@ __STATIC_INLINE void nrf_gpio_ports_read(uint32_t start_port, uint32_t length, u { NRF_GPIO_Type * gpio_regs[GPIO_COUNT] = GPIO_REG_LIST; - //ASSERT(start_port + length <= GPIO_COUNT); + ASSERT(start_port + length <= GPIO_COUNT); uint32_t i; for (i = start_port; i < (start_port + length); i++) diff --git a/third_party/NordicSemiconductor/hal/nrf_gpiote.h b/third_party/NordicSemiconductor/hal/nrf_gpiote.h index 8f1dfb9a5..a86d73350 100644 --- a/third_party/NordicSemiconductor/hal/nrf_gpiote.h +++ b/third_party/NordicSemiconductor/hal/nrf_gpiote.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRANTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * +/** + * 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_GPIOTE_H__ #define NRF_GPIOTE_H__ diff --git a/third_party/NordicSemiconductor/hal/nrf_nvmc.c b/third_party/NordicSemiconductor/hal/nrf_nvmc.c index cbd757469..e535ed60c 100644 --- a/third_party/NordicSemiconductor/hal/nrf_nvmc.c +++ b/third_party/NordicSemiconductor/hal/nrf_nvmc.c @@ -1,33 +1,42 @@ -/* Copyright (c) 2016, Nordic Semiconductor ASA +/** + * 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 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. + * */ - /** *@file *@brief NMVC driver implementation @@ -38,27 +47,26 @@ #include "nrf_nvmc.h" +static inline void wait_for_flash_ready(void) +{ + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {;} +} + + void nrf_nvmc_page_erase(uint32_t address) { // Enable erase. NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een; - - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } + __ISB(); + __DSB(); // Erase the page NRF_NVMC->ERASEPAGE = address; - - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } + wait_for_flash_ready(); NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; - - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } + __ISB(); + __DSB(); } @@ -66,82 +74,63 @@ void nrf_nvmc_write_byte(uint32_t address, uint8_t value) { uint32_t byte_shift = address & (uint32_t)0x03; uint32_t address32 = address & ~byte_shift; // Address to the word this byte is in. - uint32_t value32 = (*(uint32_t *)address32 & ~((uint32_t)0xFF << (byte_shift << (uint32_t)3))); + uint32_t value32 = (*(uint32_t*)address32 & ~((uint32_t)0xFF << (byte_shift << (uint32_t)3))); value32 = value32 + ((uint32_t)value << (byte_shift << 3)); // Enable write. - NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos); + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen; + __ISB(); + __DSB(); - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } + *(uint32_t*)address32 = value32; + wait_for_flash_ready(); - *(uint32_t *)address32 = value32; - - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } - - NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos); - { - } + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; + __ISB(); + __DSB(); } + void nrf_nvmc_write_word(uint32_t address, uint32_t value) { // Enable write. NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen; + __ISB(); + __DSB(); - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } - - *(uint32_t *)address = value; - - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } + *(uint32_t*)address = value; + wait_for_flash_ready(); NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; + __ISB(); + __DSB(); +} - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + +void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes) +{ + for (uint32_t i = 0; i < num_bytes; i++) { + nrf_nvmc_write_byte(address + i, src[i]); } } -void nrf_nvmc_write_bytes(uint32_t address, const uint8_t *src, uint32_t num_bytes) + +void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words) { - uint32_t i; - - for (i = 0; i < num_bytes; i++) - { - nrf_nvmc_write_byte(address + i, src[i]); - } -} - -void nrf_nvmc_write_words(uint32_t address, const uint32_t *src, uint32_t num_words) -{ - uint32_t i; - // Enable write. NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen; + __ISB(); + __DSB(); - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + for (uint32_t i = 0; i < num_words; i++) { - } - - for (i = 0; i < num_words; i++) - { - ((uint32_t *)address)[i] = src[i]; - - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } + ((uint32_t*)address)[i] = src[i]; + wait_for_flash_ready(); } NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; - - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } + __ISB(); + __DSB(); } + diff --git a/third_party/NordicSemiconductor/hal/nrf_nvmc.h b/third_party/NordicSemiconductor/hal/nrf_nvmc.h index 22afe1bd2..c2ec89e61 100644 --- a/third_party/NordicSemiconductor/hal/nrf_nvmc.h +++ b/third_party/NordicSemiconductor/hal/nrf_nvmc.h @@ -1,33 +1,42 @@ -/* Copyright (c) 2016, Nordic Semiconductor ASA +/** + * 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 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. + * */ - /** * @file * @brief NMVC driver API. @@ -92,7 +101,7 @@ void nrf_nvmc_write_word(uint32_t address, uint32_t value); * @param src Pointer to data to copy from. * @param num_bytes Number of bytes in src to write. */ -void nrf_nvmc_write_bytes(uint32_t address, const uint8_t *src, uint32_t num_bytes); +void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes); /** @@ -100,9 +109,9 @@ void nrf_nvmc_write_bytes(uint32_t address, const uint8_t *src, uint32_t num_by * * @param address Address to write to. * @param src Pointer to data to copy from. - * @param num_words Number of bytes in src to write. + * @param num_words Number of words in src to write. */ -void nrf_nvmc_write_words(uint32_t address, const uint32_t *src, uint32_t num_words); +void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words); @@ -112,3 +121,5 @@ void nrf_nvmc_write_words(uint32_t address, const uint32_t *src, uint32_t num_wo #endif // NRF_NVMC_H__ /** @} */ + + diff --git a/third_party/NordicSemiconductor/hal/nrf_peripherals.h b/third_party/NordicSemiconductor/hal/nrf_peripherals.h index 25339f52a..3e45850d9 100644 --- a/third_party/NordicSemiconductor/hal/nrf_peripherals.h +++ b/third_party/NordicSemiconductor/hal/nrf_peripherals.h @@ -1,33 +1,42 @@ -/* 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: - * - * * 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. - * + * + * 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_PERIPHERALS_H #define NRF_PERIPHERALS_H @@ -45,6 +54,10 @@ #include "nrf51822_peripherals.h" #endif +#ifdef NRF52810_XXAA +#include "nrf52810_peripherals.h" +#endif + #ifdef NRF52832_XXAA #include "nrf52832_peripherals.h" #endif diff --git a/third_party/NordicSemiconductor/hal/nrf_ppi.h b/third_party/NordicSemiconductor/hal/nrf_ppi.h index d217d0a8e..e101254fc 100644 --- a/third_party/NordicSemiconductor/hal/nrf_ppi.h +++ b/third_party/NordicSemiconductor/hal/nrf_ppi.h @@ -1,15 +1,42 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRANTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * +/** + * 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_PPI_H__ #define NRF_PPI_H__ diff --git a/third_party/NordicSemiconductor/hal/nrf_rng.h b/third_party/NordicSemiconductor/hal/nrf_rng.h index b65bd047d..791670cbc 100644 --- a/third_party/NordicSemiconductor/hal/nrf_rng.h +++ b/third_party/NordicSemiconductor/hal/nrf_rng.h @@ -1,33 +1,42 @@ -/* Copyright (c) 2016, Nordic Semiconductor ASA +/** + * 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 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. + * */ - /** * @file * @brief RNG HAL API. @@ -95,20 +104,14 @@ typedef enum * * @param[in] rng_int_mask Mask of interrupts. */ -__STATIC_INLINE void nrf_rng_int_enable(uint32_t rng_int_mask) -{ - NRF_RNG->INTENSET = rng_int_mask; -} +__STATIC_INLINE void nrf_rng_int_enable(uint32_t rng_int_mask); /** * @brief Function for disabling interrupts. * * @param[in] rng_int_mask Mask of interrupts. */ -__STATIC_INLINE void nrf_rng_int_disable(uint32_t rng_int_mask) -{ - NRF_RNG->INTENCLR = rng_int_mask; -} +__STATIC_INLINE void nrf_rng_int_disable(uint32_t rng_int_mask); /** * @brief Function for getting the state of a specific interrupt. @@ -118,10 +121,7 @@ __STATIC_INLINE void nrf_rng_int_disable(uint32_t rng_int_mask) * @retval true If the interrupt is not enabled. * @retval false If the interrupt is enabled. */ -__STATIC_INLINE bool nrf_rng_int_get(nrf_rng_int_mask_t rng_int_mask) -{ - return (bool)(NRF_RNG->INTENCLR & rng_int_mask); -} +__STATIC_INLINE bool nrf_rng_int_get(nrf_rng_int_mask_t rng_int_mask); /** * @brief Function for getting the address of a specific task. @@ -130,20 +130,14 @@ __STATIC_INLINE bool nrf_rng_int_get(nrf_rng_int_mask_t rng_int_mask) * * @param[in] rng_task Task. */ -__STATIC_INLINE uint32_t *nrf_rng_task_address_get(nrf_rng_task_t rng_task) -{ - return (uint32_t *)((uint8_t *)NRF_RNG + rng_task); -} +__STATIC_INLINE uint32_t * nrf_rng_task_address_get(nrf_rng_task_t rng_task); /** * @brief Function for setting a specific task. * * @param[in] rng_task Task. */ -__STATIC_INLINE void nrf_rng_task_trigger(nrf_rng_task_t rng_task) -{ - *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_task)) = NRF_RNG_TASK_SET; -} +__STATIC_INLINE void nrf_rng_task_trigger(nrf_rng_task_t rng_task); /** * @brief Function for getting address of a specific event. @@ -152,24 +146,14 @@ __STATIC_INLINE void nrf_rng_task_trigger(nrf_rng_task_t rng_task) * * @param[in] rng_event Event. */ -__STATIC_INLINE uint32_t *nrf_rng_event_address_get(nrf_rng_event_t rng_event) -{ - return (uint32_t *)((uint8_t *)NRF_RNG + rng_event); -} +__STATIC_INLINE uint32_t * nrf_rng_event_address_get(nrf_rng_event_t rng_event); /** * @brief Function for clearing a specific event. * * @param[in] rng_event Event. */ -__STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event) -{ - *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)) = NRF_RNG_EVENT_CLEAR; -#if __CORTEX_M == 0x04 - volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)); - (void)dummy; -#endif -} +__STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event); /** * @brief Function for getting the state of a specific event. @@ -179,10 +163,7 @@ __STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event) * @retval true If the event is not set. * @retval false If the event is set. */ -__STATIC_INLINE bool nrf_rng_event_get(nrf_rng_event_t rng_event) -{ - return (bool) * ((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)); -} +__STATIC_INLINE bool nrf_rng_event_get(nrf_rng_event_t rng_event); /** * @brief Function for setting shortcuts. @@ -190,10 +171,7 @@ __STATIC_INLINE bool nrf_rng_event_get(nrf_rng_event_t rng_event) * @param[in] rng_short_mask Mask of shortcuts. * */ -__STATIC_INLINE void nrf_rng_shorts_enable(uint32_t rng_short_mask) -{ - NRF_RNG->SHORTS |= rng_short_mask; -} +__STATIC_INLINE void nrf_rng_shorts_enable(uint32_t rng_short_mask); /** * @brief Function for clearing shortcuts. @@ -201,39 +179,101 @@ __STATIC_INLINE void nrf_rng_shorts_enable(uint32_t rng_short_mask) * @param[in] rng_short_mask Mask of shortcuts. * */ -__STATIC_INLINE void nrf_rng_shorts_disable(uint32_t rng_short_mask) -{ - NRF_RNG->SHORTS &= ~rng_short_mask; -} +__STATIC_INLINE void nrf_rng_shorts_disable(uint32_t rng_short_mask); /** * @brief Function for getting the previously generated random value. * * @return Previously generated random value. */ +__STATIC_INLINE uint8_t nrf_rng_random_value_get(void); + +/** + * @brief Function for enabling digital error correction. + */ +__STATIC_INLINE void nrf_rng_error_correction_enable(void); + +/** + * @brief Function for disabling digital error correction. + */ +__STATIC_INLINE void nrf_rng_error_correction_disable(void); + +/** + *@} + **/ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_rng_int_enable(uint32_t rng_int_mask) +{ + NRF_RNG->INTENSET = rng_int_mask; +} + +__STATIC_INLINE void nrf_rng_int_disable(uint32_t rng_int_mask) +{ + NRF_RNG->INTENCLR = rng_int_mask; +} + +__STATIC_INLINE bool nrf_rng_int_get(nrf_rng_int_mask_t rng_int_mask) +{ + return (bool)(NRF_RNG->INTENCLR & rng_int_mask); +} + +__STATIC_INLINE uint32_t * nrf_rng_task_address_get(nrf_rng_task_t rng_task) +{ + return (uint32_t *)((uint8_t *)NRF_RNG + rng_task); +} + +__STATIC_INLINE void nrf_rng_task_trigger(nrf_rng_task_t rng_task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_task)) = NRF_RNG_TASK_SET; +} + +__STATIC_INLINE uint32_t * nrf_rng_event_address_get(nrf_rng_event_t rng_event) +{ + return (uint32_t *)((uint8_t *)NRF_RNG + rng_event); +} + +__STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)) = NRF_RNG_EVENT_CLEAR; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_rng_event_get(nrf_rng_event_t rng_event) +{ + return (bool) * ((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)); +} + +__STATIC_INLINE void nrf_rng_shorts_enable(uint32_t rng_short_mask) +{ + NRF_RNG->SHORTS |= rng_short_mask; +} + +__STATIC_INLINE void nrf_rng_shorts_disable(uint32_t rng_short_mask) +{ + NRF_RNG->SHORTS &= ~rng_short_mask; +} + __STATIC_INLINE uint8_t nrf_rng_random_value_get(void) { return (uint8_t)(NRF_RNG->VALUE & RNG_VALUE_VALUE_Msk); } -/** - * @brief Function for enabling digital error correction. - */ __STATIC_INLINE void nrf_rng_error_correction_enable(void) { NRF_RNG->CONFIG |= RNG_CONFIG_DERCEN_Msk; } -/** - * @brief Function for disabling digital error correction. - */ __STATIC_INLINE void nrf_rng_error_correction_disable(void) { NRF_RNG->CONFIG &= ~RNG_CONFIG_DERCEN_Msk; } -/** - *@} - **/ + +#endif #ifdef __cplusplus } diff --git a/third_party/NordicSemiconductor/hal/nrf_rtc.h b/third_party/NordicSemiconductor/hal/nrf_rtc.h index 2802acebf..2ed996d1d 100644 --- a/third_party/NordicSemiconductor/hal/nrf_rtc.h +++ b/third_party/NordicSemiconductor/hal/nrf_rtc.h @@ -1,33 +1,42 @@ -/* Copyright (c) 2016, Nordic Semiconductor ASA +/** + * 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 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. + * */ - /** * @file * @brief RTC HAL API. @@ -66,13 +75,13 @@ extern "C" { /** * @brief Macro for converting expected frequency to prescaler setting. */ -#define RTC_FREQ_TO_PRESCALER(FREQ) (uint16_t)((RTC_INPUT_FREQ / (FREQ)) - 1) +#define RTC_FREQ_TO_PRESCALER(FREQ) (uint16_t)(((RTC_INPUT_FREQ) / (FREQ)) - 1) /**< Macro for wrapping values to RTC capacity. */ -#define RTC_WRAP(val) (val & RTC_COUNTER_COUNTER_Msk) +#define RTC_WRAP(val) ((val) & RTC_COUNTER_COUNTER_Msk) -#define RTC_CHANNEL_INT_MASK(ch) ((uint32_t)NRF_RTC_INT_COMPARE0_MASK << ch) -#define RTC_CHANNEL_EVENT_ADDR(ch) (nrf_rtc_event_t)(NRF_RTC_EVENT_COMPARE_0 + ch * sizeof(uint32_t)) +#define RTC_CHANNEL_INT_MASK(ch) ((uint32_t)(NRF_RTC_INT_COMPARE0_MASK) << (ch)) +#define RTC_CHANNEL_EVENT_ADDR(ch) (nrf_rtc_event_t)((NRF_RTC_EVENT_COMPARE_0) + (ch) * sizeof(uint32_t)) /** * @enum nrf_rtc_task_t * @brief RTC tasks. diff --git a/third_party/NordicSemiconductor/hal/nrf_systick.h b/third_party/NordicSemiconductor/hal/nrf_systick.h index 26fbf37e3..840fda896 100644 --- a/third_party/NordicSemiconductor/hal/nrf_systick.h +++ b/third_party/NordicSemiconductor/hal/nrf_systick.h @@ -1,184 +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 -#include -#include - -/** - * @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__ */ +/** + * 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 +#include +#include + +/** + * @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__ */ diff --git a/third_party/NordicSemiconductor/hal/nrf_temp.h b/third_party/NordicSemiconductor/hal/nrf_temp.h index fbac882dc..1e728d215 100644 --- a/third_party/NordicSemiconductor/hal/nrf_temp.h +++ b/third_party/NordicSemiconductor/hal/nrf_temp.h @@ -1,81 +1,91 @@ -/* Copyright (c) 2012, 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. - * - */ -#ifndef NRF_TEMP_H__ -#define NRF_TEMP_H__ - -#include "nrf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** -* @defgroup nrf_temperature TEMP (temperature) abstraction -* @{ -* @ingroup nrf_drivers temperature_example -* @brief Temperature module init and read functions. -* -*/ - -/**@cond NO_DOXYGEN */ -#define MASK_SIGN (0x00000200UL) -#define MASK_SIGN_EXTENSION (0xFFFFFC00UL) - -/** - * @brief Function for preparing the temp module for temperature measurement. - * - * This function initializes the TEMP module and writes to the hidden configuration register. - */ -static __INLINE void nrf_temp_init(void) -{ - /**@note Workaround for PAN_028 rev2.0A anomaly 31 - TEMP: Temperature offset value has to be manually loaded to the TEMP module */ - *(uint32_t *) 0x4000C504 = 0; -} - -/** - * @brief Function for reading temperature measurement. - * - * The function reads the 10 bit 2's complement value and transforms it to a 32 bit 2's complement value. - */ -static __INLINE int32_t nrf_temp_read(void) -{ - /**@note Workaround for PAN_028 rev2.0A anomaly 28 - TEMP: Negative measured values are not represented correctly */ - return ((NRF_TEMP->TEMP & MASK_SIGN) != 0) ? (int32_t)(NRF_TEMP->TEMP | MASK_SIGN_EXTENSION) : (int32_t)(NRF_TEMP->TEMP); -} -/**@endcond */ - -/** @} */ - - -#ifdef __cplusplus -} -#endif - -#endif +/** + * 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. + * + */ +#ifndef NRF_TEMP_H__ +#define NRF_TEMP_H__ + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @defgroup nrf_temperature TEMP (temperature) abstraction +* @{ +* @ingroup nrf_drivers temperature_example +* @brief Temperature module init and read functions. +* +*/ + +/**@cond NO_DOXYGEN */ +#define MASK_SIGN (0x00000200UL) +#define MASK_SIGN_EXTENSION (0xFFFFFC00UL) + +/** + * @brief Function for preparing the temp module for temperature measurement. + * + * This function initializes the TEMP module and writes to the hidden configuration register. + */ +static __INLINE void nrf_temp_init(void) +{ + /**@note Workaround for PAN_028 rev2.0A anomaly 31 - TEMP: Temperature offset value has to be manually loaded to the TEMP module */ + *(uint32_t *) 0x4000C504 = 0; +} + +/** + * @brief Function for reading temperature measurement. + * + * The function reads the 10 bit 2's complement value and transforms it to a 32 bit 2's complement value. + */ +static __INLINE int32_t nrf_temp_read(void) +{ + /**@note Workaround for PAN_028 rev2.0A anomaly 28 - TEMP: Negative measured values are not represented correctly */ + return ((NRF_TEMP->TEMP & MASK_SIGN) != 0) ? (int32_t)(NRF_TEMP->TEMP | MASK_SIGN_EXTENSION) : (NRF_TEMP->TEMP); +} +/**@endcond */ + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/third_party/NordicSemiconductor/hal/nrf_timer.h b/third_party/NordicSemiconductor/hal/nrf_timer.h index 942fbc6f9..65671edde 100644 --- a/third_party/NordicSemiconductor/hal/nrf_timer.h +++ b/third_party/NordicSemiconductor/hal/nrf_timer.h @@ -1,589 +1,630 @@ -/*$$$LICENCE_NORDIC_STANDARD<2014>$$$*/ -/** - * @defgroup nrf_timer_hal Timer HAL - * @{ - * @ingroup nrf_timer - * - * @brief Hardware access layer for accessing the timer peripheral. - */ - -#ifndef NRF_TIMER_H__ -#define NRF_TIMER_H__ - -#include -#include -#include - -#include "nrf_peripherals.h" -#include "nrf.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * @brief Macro for validating the correctness of the BIT_WIDTH setting. - */ - -#define TIMER_MAX_SIZE(id) CONCAT_3(TIMER, id, _MAX_SIZE) - -#define TIMER_BIT_WIDTH_MAX(id, bit_width) \ - (TIMER_MAX_SIZE(id) == 8 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) : \ - (TIMER_MAX_SIZE(id) == 16 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \ - (bit_width == NRF_TIMER_BIT_WIDTH_16) : \ - (TIMER_MAX_SIZE(id) == 24 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \ - (bit_width == NRF_TIMER_BIT_WIDTH_16) || \ - (bit_width == NRF_TIMER_BIT_WIDTH_24) : \ - (TIMER_MAX_SIZE(id) == 32 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \ - (bit_width == NRF_TIMER_BIT_WIDTH_16) || \ - (bit_width == NRF_TIMER_BIT_WIDTH_24) || \ - (bit_width == NRF_TIMER_BIT_WIDTH_32) : \ - false)))) - -#if TIMER_COUNT > 3 -#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \ - ((p_reg == NRF_TIMER0) && (TIMER_BIT_WIDTH_MAX(0, bit_width))) \ - || ((p_reg == NRF_TIMER1) && (TIMER_BIT_WIDTH_MAX(1, bit_width))) \ - || ((p_reg == NRF_TIMER2) && (TIMER_BIT_WIDTH_MAX(2, bit_width))) \ - || ((p_reg == NRF_TIMER3) && (TIMER_BIT_WIDTH_MAX(3, bit_width))) \ - || ((p_reg == NRF_TIMER4) && (TIMER_BIT_WIDTH_MAX(4, bit_width))) ) - -#else -#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \ - ((p_reg == NRF_TIMER0) && TIMER_BIT_WIDTH_MAX(0, bit_width)) \ - || ((p_reg == NRF_TIMER1) && TIMER_BIT_WIDTH_MAX(1, bit_width)) \ - || ((p_reg == NRF_TIMER2) && TIMER_BIT_WIDTH_MAX(2, bit_width)) ) - -#endif - -/** - * @brief Macro for getting the number of capture/compare channels available - * in a given timer instance. - */ -#define NRF_TIMER_CC_CHANNEL_COUNT(id) CONCAT_3(TIMER, id, _CC_NUM) - -/** - * @brief Timer tasks. - */ -typedef enum -{ - /*lint -save -e30 -esym(628,__INTADDR__)*/ - NRF_TIMER_TASK_START = offsetof(NRF_TIMER_Type, TASKS_START), ///< Task for starting the timer. - NRF_TIMER_TASK_STOP = offsetof(NRF_TIMER_Type, TASKS_STOP), ///< Task for stopping the timer. - NRF_TIMER_TASK_COUNT = offsetof(NRF_TIMER_Type, TASKS_COUNT), ///< Task for incrementing the timer (in counter mode). - NRF_TIMER_TASK_CLEAR = offsetof(NRF_TIMER_Type, TASKS_CLEAR), ///< Task for resetting the timer value. - NRF_TIMER_TASK_SHUTDOWN = offsetof(NRF_TIMER_Type, TASKS_SHUTDOWN), ///< Task for powering off the timer. - NRF_TIMER_TASK_CAPTURE0 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[0]), ///< Task for capturing the timer value on channel 0. - NRF_TIMER_TASK_CAPTURE1 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[1]), ///< Task for capturing the timer value on channel 1. - NRF_TIMER_TASK_CAPTURE2 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[2]), ///< Task for capturing the timer value on channel 2. - NRF_TIMER_TASK_CAPTURE3 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[3]), ///< Task for capturing the timer value on channel 3. -#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) - NRF_TIMER_TASK_CAPTURE4 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[4]), ///< Task for capturing the timer value on channel 4. - NRF_TIMER_TASK_CAPTURE5 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[5]), ///< Task for capturing the timer value on channel 5. -#endif - /*lint -restore*/ -} nrf_timer_task_t; - -/** - * @brief Timer events. - */ -typedef enum -{ - /*lint -save -e30*/ - NRF_TIMER_EVENT_COMPARE0 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[0]), ///< Event from compare channel 0. - NRF_TIMER_EVENT_COMPARE1 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[1]), ///< Event from compare channel 1. - NRF_TIMER_EVENT_COMPARE2 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[2]), ///< Event from compare channel 2. - NRF_TIMER_EVENT_COMPARE3 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[3]), ///< Event from compare channel 3. -#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) - NRF_TIMER_EVENT_COMPARE4 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[4]), ///< Event from compare channel 4. - NRF_TIMER_EVENT_COMPARE5 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[5]), ///< Event from compare channel 5. -#endif - /*lint -restore*/ -} nrf_timer_event_t; - -/** - * @brief Types of timer shortcuts. - */ -typedef enum -{ - NRF_TIMER_SHORT_COMPARE0_STOP_MASK = TIMER_SHORTS_COMPARE0_STOP_Msk, ///< Shortcut for stopping the timer based on compare 0. - NRF_TIMER_SHORT_COMPARE1_STOP_MASK = TIMER_SHORTS_COMPARE1_STOP_Msk, ///< Shortcut for stopping the timer based on compare 1. - NRF_TIMER_SHORT_COMPARE2_STOP_MASK = TIMER_SHORTS_COMPARE2_STOP_Msk, ///< Shortcut for stopping the timer based on compare 2. - NRF_TIMER_SHORT_COMPARE3_STOP_MASK = TIMER_SHORTS_COMPARE3_STOP_Msk, ///< Shortcut for stopping the timer based on compare 3. -#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) - NRF_TIMER_SHORT_COMPARE4_STOP_MASK = TIMER_SHORTS_COMPARE4_STOP_Msk, ///< Shortcut for stopping the timer based on compare 4. - NRF_TIMER_SHORT_COMPARE5_STOP_MASK = TIMER_SHORTS_COMPARE5_STOP_Msk, ///< Shortcut for stopping the timer based on compare 5. -#endif - NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK = TIMER_SHORTS_COMPARE0_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 0. - NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK = TIMER_SHORTS_COMPARE1_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 1. - NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK = TIMER_SHORTS_COMPARE2_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 2. - NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK = TIMER_SHORTS_COMPARE3_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 3. -#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) - NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK = TIMER_SHORTS_COMPARE4_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 4. - NRF_TIMER_SHORT_COMPARE5_CLEAR_MASK = TIMER_SHORTS_COMPARE5_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 5. -#endif -} nrf_timer_short_mask_t; - -/** - * @brief Timer modes. - */ -typedef enum -{ - NRF_TIMER_MODE_TIMER = TIMER_MODE_MODE_Timer, ///< Timer mode: timer. - NRF_TIMER_MODE_COUNTER = TIMER_MODE_MODE_Counter, ///< Timer mode: counter. -#if defined(TIMER_MODE_MODE_LowPowerCounter) || defined(__SDK_DOXYGEN__) - NRF_TIMER_MODE_LOW_POWER_COUNTER = TIMER_MODE_MODE_LowPowerCounter, ///< Timer mode: low-power counter. -#endif -} nrf_timer_mode_t; - -/** - * @brief Timer bit width. - */ -typedef enum -{ - NRF_TIMER_BIT_WIDTH_8 = TIMER_BITMODE_BITMODE_08Bit, ///< Timer bit width 8 bit. - NRF_TIMER_BIT_WIDTH_16 = TIMER_BITMODE_BITMODE_16Bit, ///< Timer bit width 16 bit. - NRF_TIMER_BIT_WIDTH_24 = TIMER_BITMODE_BITMODE_24Bit, ///< Timer bit width 24 bit. - NRF_TIMER_BIT_WIDTH_32 = TIMER_BITMODE_BITMODE_32Bit ///< Timer bit width 32 bit. -} nrf_timer_bit_width_t; - -/** - * @brief Timer prescalers. - */ -typedef enum -{ - NRF_TIMER_FREQ_16MHz = 0, ///< Timer frequency 16 MHz. - NRF_TIMER_FREQ_8MHz, ///< Timer frequency 8 MHz. - NRF_TIMER_FREQ_4MHz, ///< Timer frequency 4 MHz. - NRF_TIMER_FREQ_2MHz, ///< Timer frequency 2 MHz. - NRF_TIMER_FREQ_1MHz, ///< Timer frequency 1 MHz. - NRF_TIMER_FREQ_500kHz, ///< Timer frequency 500 kHz. - NRF_TIMER_FREQ_250kHz, ///< Timer frequency 250 kHz. - NRF_TIMER_FREQ_125kHz, ///< Timer frequency 125 kHz. - NRF_TIMER_FREQ_62500Hz, ///< Timer frequency 62500 Hz. - NRF_TIMER_FREQ_31250Hz ///< Timer frequency 31250 Hz. -} nrf_timer_frequency_t; - -/** - * @brief Timer capture/compare channels. - */ -typedef enum -{ - NRF_TIMER_CC_CHANNEL0 = 0, ///< Timer capture/compare channel 0. - NRF_TIMER_CC_CHANNEL1, ///< Timer capture/compare channel 1. - NRF_TIMER_CC_CHANNEL2, ///< Timer capture/compare channel 2. - NRF_TIMER_CC_CHANNEL3, ///< Timer capture/compare channel 3. -#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) - NRF_TIMER_CC_CHANNEL4, ///< Timer capture/compare channel 4. - NRF_TIMER_CC_CHANNEL5, ///< Timer capture/compare channel 5. -#endif -} nrf_timer_cc_channel_t; - -/** - * @brief Timer interrupts. - */ -typedef enum -{ - NRF_TIMER_INT_COMPARE0_MASK = TIMER_INTENSET_COMPARE0_Msk, ///< Timer interrupt from compare event on channel 0. - NRF_TIMER_INT_COMPARE1_MASK = TIMER_INTENSET_COMPARE1_Msk, ///< Timer interrupt from compare event on channel 1. - NRF_TIMER_INT_COMPARE2_MASK = TIMER_INTENSET_COMPARE2_Msk, ///< Timer interrupt from compare event on channel 2. - NRF_TIMER_INT_COMPARE3_MASK = TIMER_INTENSET_COMPARE3_Msk, ///< Timer interrupt from compare event on channel 3. -#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) - NRF_TIMER_INT_COMPARE4_MASK = TIMER_INTENSET_COMPARE4_Msk, ///< Timer interrupt from compare event on channel 4. - NRF_TIMER_INT_COMPARE5_MASK = TIMER_INTENSET_COMPARE5_Msk, ///< Timer interrupt from compare event on channel 5. -#endif -} nrf_timer_int_mask_t; - - -/** - * @brief Function for activating a specific timer task. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] task Task to activate. - */ -__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg, - nrf_timer_task_t task); - -/** - * @brief Function for getting the address of a specific timer task register. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] task Requested task. - * - * @return Address of the specified task register. - */ -__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg, - nrf_timer_task_t task); - -/** - * @brief Function for clearing a specific timer event. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] event Event to clear. - */ -__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg, - nrf_timer_event_t event); - -/** - * @brief Function for checking the state of a specific timer event. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] event Event to check. - * - * @retval true If the event is set. - * @retval false If the event is not set. - */ -__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg, - nrf_timer_event_t event); - -/** - * @brief Function for getting the address of a specific timer event register. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] event Requested event. - * - * @return Address of the specified event register. - */ -__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg, - nrf_timer_event_t event); - -/** - * @brief Function for enabling specified shortcuts. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] timer_shorts_mask Shortcuts to enable. - */ -__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg, - uint32_t timer_shorts_mask); - -/** - * @brief Function for disabling specified shortcuts. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] timer_shorts_mask Shortcuts to disable. - */ -__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg, - uint32_t timer_shorts_mask); - -/** - * @brief Function for enabling specified interrupts. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] timer_int_mask Interrupts to enable. - */ -__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg, - uint32_t timer_int_mask); - -/** - * @brief Function for disabling specified interrupts. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] timer_int_mask Interrupts to disable. - */ -__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg, - uint32_t timer_int_mask); - -/** - * @brief Function for retrieving the state of a given interrupt. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] timer_int Interrupt to check. - * - * @retval true If the interrupt is enabled. - * @retval false If the interrupt is not enabled. - */ -__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg, - uint32_t timer_int); - -/** - * @brief Function for setting the timer mode. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] mode Timer mode. - */ -__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg, - nrf_timer_mode_t mode); - -/** - * @brief Function for retrieving the timer mode. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * - * @return Timer mode. - */ -__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_reg); - -/** - * @brief Function for setting the timer bit width. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] bit_width Timer bit width. - */ -__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg, - nrf_timer_bit_width_t bit_width); - -/** - * @brief Function for retrieving the timer bit width. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * - * @return Timer bit width. - */ -__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_reg); - -/** - * @brief Function for setting the timer frequency. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] frequency Timer frequency. - */ -__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg, - nrf_timer_frequency_t frequency); - -/** - * @brief Function for retrieving the timer frequency. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * - * @return Timer frequency. - */ -__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_reg); - -/** - * @brief Function for writing the capture/compare register for a specified channel. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] cc_channel Requested capture/compare channel. - * @param[in] cc_value Value to write to the capture/compare register. - */ -__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_reg, - nrf_timer_cc_channel_t cc_channel, - uint32_t cc_value); - -/** - * @brief Function for retrieving the capture/compare value for a specified channel. - * - * @param[in] p_reg Pointer to the peripheral registers structure. - * @param[in] cc_channel Requested capture/compare channel. - * - * @return Value from the requested capture/compare register. - */ -__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg, - nrf_timer_cc_channel_t cc_channel); - -/** - * @brief Function for getting a specific timer capture task. - * - * @param[in] channel Capture channel. - * - * @return Capture task. - */ -__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel); - -/** - * @brief Function for getting a specific timer compare event. - * - * @param[in] channel Compare channel. - * - * @return Compare event. - */ -__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel); - -/** - * @brief Function for getting a specific timer compare interrupt. - * - * @param[in] channel Compare channel. - * - * @return Compare interrupt. - */ -__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel); - -/** - * @brief Function for calculating the number of timer ticks for a given time - * (in microseconds) and timer frequency. - * - * @param[in] time_us Time in microseconds. - * @param[in] frequency Timer frequency. - * - * @return Number of timer ticks. - */ -__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us, - nrf_timer_frequency_t frequency); - -/** - * @brief Function for calculating the number of timer ticks for a given time - * (in milliseconds) and timer frequency. - * - * @param[in] time_ms Time in milliseconds. - * @param[in] frequency Timer frequency. - * - * @return Number of timer ticks. - */ -__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms, - nrf_timer_frequency_t frequency); - - -#ifndef SUPPRESS_INLINE_IMPLEMENTATION - -__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg, - nrf_timer_task_t task) -{ - *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; -} - -__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg, - nrf_timer_task_t task) -{ - return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task); -} - -__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg, - nrf_timer_event_t event) -{ - *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; -#if __CORTEX_M == 0x04 - volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); - (void)dummy; -#endif -} - -__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg, - nrf_timer_event_t event) -{ - return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); -} - -__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg, - nrf_timer_event_t event) -{ - return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event); -} - -__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg, - uint32_t timer_shorts_mask) -{ - p_reg->SHORTS |= timer_shorts_mask; -} - -__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg, - uint32_t timer_shorts_mask) -{ - p_reg->SHORTS &= ~(timer_shorts_mask); -} - -__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg, - uint32_t timer_int_mask) -{ - p_reg->INTENSET = timer_int_mask; -} - -__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg, - uint32_t timer_int_mask) -{ - p_reg->INTENCLR = timer_int_mask; -} - -__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg, - uint32_t timer_int) -{ - return (bool)(p_reg->INTENSET & timer_int); -} - -__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg, - nrf_timer_mode_t mode) -{ - p_reg->MODE = (p_reg->MODE & ~TIMER_MODE_MODE_Msk) | - ((mode << TIMER_MODE_MODE_Pos) & TIMER_MODE_MODE_Msk); -} - -__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_reg) -{ - return (nrf_timer_mode_t)(p_reg->MODE); -} - -__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg, - nrf_timer_bit_width_t bit_width) -{ - p_reg->BITMODE = (p_reg->BITMODE & ~TIMER_BITMODE_BITMODE_Msk) | - ((bit_width << TIMER_BITMODE_BITMODE_Pos) & - TIMER_BITMODE_BITMODE_Msk); -} - -__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_reg) -{ - return (nrf_timer_bit_width_t)(p_reg->BITMODE); -} - -__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg, - nrf_timer_frequency_t frequency) -{ - p_reg->PRESCALER = (p_reg->PRESCALER & ~TIMER_PRESCALER_PRESCALER_Msk) | - ((frequency << TIMER_PRESCALER_PRESCALER_Pos) & - TIMER_PRESCALER_PRESCALER_Msk); -} - -__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_reg) -{ - return (nrf_timer_frequency_t)(p_reg->PRESCALER); -} - -__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_reg, - nrf_timer_cc_channel_t cc_channel, - uint32_t cc_value) -{ - p_reg->CC[cc_channel] = cc_value; -} - -__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg, - nrf_timer_cc_channel_t cc_channel) -{ - return (uint32_t)p_reg->CC[cc_channel]; -} - -__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel) -{ - return (nrf_timer_task_t) - ((uint32_t)NRF_TIMER_TASK_CAPTURE0 + (channel * sizeof(uint32_t))); -} - -__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel) -{ - return (nrf_timer_event_t) - ((uint32_t)NRF_TIMER_EVENT_COMPARE0 + (channel * sizeof(uint32_t))); -} - -__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel) -{ - return (nrf_timer_int_mask_t) - ((uint32_t)NRF_TIMER_INT_COMPARE0_MASK << channel); -} - -__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us, - nrf_timer_frequency_t frequency) -{ - // The "frequency" parameter here is actually the prescaler value, and the - // timer runs at the following frequency: f = 16 MHz / 2^prescaler. - uint32_t prescaler = (uint32_t)frequency; - return ((time_us * 16UL) >> prescaler); -} - -__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms, - nrf_timer_frequency_t frequency) -{ - // The "frequency" parameter here is actually the prescaler value, and the - // timer runs at the following frequency: f = 16000 kHz / 2^prescaler. - uint32_t prescaler = (uint32_t)frequency; - return ((time_ms * 16000UL) >> prescaler); -} - -#endif // SUPPRESS_INLINE_IMPLEMENTATION - - -#ifdef __cplusplus -} -#endif - -#endif // NRF_TIMER_H__ - -/** @} */ +/** + * 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. + * + */ +/** + * @defgroup nrf_timer_hal Timer HAL + * @{ + * @ingroup nrf_timer + * + * @brief Hardware access layer for accessing the timer peripheral. + */ + +#ifndef NRF_TIMER_H__ +#define NRF_TIMER_H__ + +#include +#include +#include + +#include "nrf_peripherals.h" +#include "nrf.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Macro for validating the correctness of the BIT_WIDTH setting. + */ + +#define TIMER_MAX_SIZE(id) CONCAT_3(TIMER, id, _MAX_SIZE) + +#define TIMER_BIT_WIDTH_MAX(id, bit_width) \ + (TIMER_MAX_SIZE(id) == 8 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) : \ + (TIMER_MAX_SIZE(id) == 16 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_16) : \ + (TIMER_MAX_SIZE(id) == 24 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_16) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_24) : \ + (TIMER_MAX_SIZE(id) == 32 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_16) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_24) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_32) : \ + false)))) + +#if TIMER_COUNT > 3 +#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \ + ((p_reg == NRF_TIMER0) && (TIMER_BIT_WIDTH_MAX(0, bit_width))) \ + || ((p_reg == NRF_TIMER1) && (TIMER_BIT_WIDTH_MAX(1, bit_width))) \ + || ((p_reg == NRF_TIMER2) && (TIMER_BIT_WIDTH_MAX(2, bit_width))) \ + || ((p_reg == NRF_TIMER3) && (TIMER_BIT_WIDTH_MAX(3, bit_width))) \ + || ((p_reg == NRF_TIMER4) && (TIMER_BIT_WIDTH_MAX(4, bit_width))) ) + +#else +#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \ + ((p_reg == NRF_TIMER0) && TIMER_BIT_WIDTH_MAX(0, bit_width)) \ + || ((p_reg == NRF_TIMER1) && TIMER_BIT_WIDTH_MAX(1, bit_width)) \ + || ((p_reg == NRF_TIMER2) && TIMER_BIT_WIDTH_MAX(2, bit_width)) ) + +#endif + +/** + * @brief Macro for getting the number of capture/compare channels available + * in a given timer instance. + */ +#define NRF_TIMER_CC_CHANNEL_COUNT(id) CONCAT_3(TIMER, id, _CC_NUM) + +/** + * @brief Timer tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_TIMER_TASK_START = offsetof(NRF_TIMER_Type, TASKS_START), ///< Task for starting the timer. + NRF_TIMER_TASK_STOP = offsetof(NRF_TIMER_Type, TASKS_STOP), ///< Task for stopping the timer. + NRF_TIMER_TASK_COUNT = offsetof(NRF_TIMER_Type, TASKS_COUNT), ///< Task for incrementing the timer (in counter mode). + NRF_TIMER_TASK_CLEAR = offsetof(NRF_TIMER_Type, TASKS_CLEAR), ///< Task for resetting the timer value. + NRF_TIMER_TASK_SHUTDOWN = offsetof(NRF_TIMER_Type, TASKS_SHUTDOWN), ///< Task for powering off the timer. + NRF_TIMER_TASK_CAPTURE0 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[0]), ///< Task for capturing the timer value on channel 0. + NRF_TIMER_TASK_CAPTURE1 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[1]), ///< Task for capturing the timer value on channel 1. + NRF_TIMER_TASK_CAPTURE2 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[2]), ///< Task for capturing the timer value on channel 2. + NRF_TIMER_TASK_CAPTURE3 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[3]), ///< Task for capturing the timer value on channel 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_TASK_CAPTURE4 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[4]), ///< Task for capturing the timer value on channel 4. + NRF_TIMER_TASK_CAPTURE5 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[5]), ///< Task for capturing the timer value on channel 5. +#endif + /*lint -restore*/ +} nrf_timer_task_t; + +/** + * @brief Timer events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TIMER_EVENT_COMPARE0 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[0]), ///< Event from compare channel 0. + NRF_TIMER_EVENT_COMPARE1 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[1]), ///< Event from compare channel 1. + NRF_TIMER_EVENT_COMPARE2 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[2]), ///< Event from compare channel 2. + NRF_TIMER_EVENT_COMPARE3 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[3]), ///< Event from compare channel 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_EVENT_COMPARE4 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[4]), ///< Event from compare channel 4. + NRF_TIMER_EVENT_COMPARE5 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[5]), ///< Event from compare channel 5. +#endif + /*lint -restore*/ +} nrf_timer_event_t; + +/** + * @brief Types of timer shortcuts. + */ +typedef enum +{ + NRF_TIMER_SHORT_COMPARE0_STOP_MASK = TIMER_SHORTS_COMPARE0_STOP_Msk, ///< Shortcut for stopping the timer based on compare 0. + NRF_TIMER_SHORT_COMPARE1_STOP_MASK = TIMER_SHORTS_COMPARE1_STOP_Msk, ///< Shortcut for stopping the timer based on compare 1. + NRF_TIMER_SHORT_COMPARE2_STOP_MASK = TIMER_SHORTS_COMPARE2_STOP_Msk, ///< Shortcut for stopping the timer based on compare 2. + NRF_TIMER_SHORT_COMPARE3_STOP_MASK = TIMER_SHORTS_COMPARE3_STOP_Msk, ///< Shortcut for stopping the timer based on compare 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_SHORT_COMPARE4_STOP_MASK = TIMER_SHORTS_COMPARE4_STOP_Msk, ///< Shortcut for stopping the timer based on compare 4. + NRF_TIMER_SHORT_COMPARE5_STOP_MASK = TIMER_SHORTS_COMPARE5_STOP_Msk, ///< Shortcut for stopping the timer based on compare 5. +#endif + NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK = TIMER_SHORTS_COMPARE0_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 0. + NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK = TIMER_SHORTS_COMPARE1_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 1. + NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK = TIMER_SHORTS_COMPARE2_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 2. + NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK = TIMER_SHORTS_COMPARE3_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK = TIMER_SHORTS_COMPARE4_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 4. + NRF_TIMER_SHORT_COMPARE5_CLEAR_MASK = TIMER_SHORTS_COMPARE5_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 5. +#endif +} nrf_timer_short_mask_t; + +/** + * @brief Timer modes. + */ +typedef enum +{ + NRF_TIMER_MODE_TIMER = TIMER_MODE_MODE_Timer, ///< Timer mode: timer. + NRF_TIMER_MODE_COUNTER = TIMER_MODE_MODE_Counter, ///< Timer mode: counter. +#if defined(TIMER_MODE_MODE_LowPowerCounter) || defined(__SDK_DOXYGEN__) + NRF_TIMER_MODE_LOW_POWER_COUNTER = TIMER_MODE_MODE_LowPowerCounter, ///< Timer mode: low-power counter. +#endif +} nrf_timer_mode_t; + +/** + * @brief Timer bit width. + */ +typedef enum +{ + NRF_TIMER_BIT_WIDTH_8 = TIMER_BITMODE_BITMODE_08Bit, ///< Timer bit width 8 bit. + NRF_TIMER_BIT_WIDTH_16 = TIMER_BITMODE_BITMODE_16Bit, ///< Timer bit width 16 bit. + NRF_TIMER_BIT_WIDTH_24 = TIMER_BITMODE_BITMODE_24Bit, ///< Timer bit width 24 bit. + NRF_TIMER_BIT_WIDTH_32 = TIMER_BITMODE_BITMODE_32Bit ///< Timer bit width 32 bit. +} nrf_timer_bit_width_t; + +/** + * @brief Timer prescalers. + */ +typedef enum +{ + NRF_TIMER_FREQ_16MHz = 0, ///< Timer frequency 16 MHz. + NRF_TIMER_FREQ_8MHz, ///< Timer frequency 8 MHz. + NRF_TIMER_FREQ_4MHz, ///< Timer frequency 4 MHz. + NRF_TIMER_FREQ_2MHz, ///< Timer frequency 2 MHz. + NRF_TIMER_FREQ_1MHz, ///< Timer frequency 1 MHz. + NRF_TIMER_FREQ_500kHz, ///< Timer frequency 500 kHz. + NRF_TIMER_FREQ_250kHz, ///< Timer frequency 250 kHz. + NRF_TIMER_FREQ_125kHz, ///< Timer frequency 125 kHz. + NRF_TIMER_FREQ_62500Hz, ///< Timer frequency 62500 Hz. + NRF_TIMER_FREQ_31250Hz ///< Timer frequency 31250 Hz. +} nrf_timer_frequency_t; + +/** + * @brief Timer capture/compare channels. + */ +typedef enum +{ + NRF_TIMER_CC_CHANNEL0 = 0, ///< Timer capture/compare channel 0. + NRF_TIMER_CC_CHANNEL1, ///< Timer capture/compare channel 1. + NRF_TIMER_CC_CHANNEL2, ///< Timer capture/compare channel 2. + NRF_TIMER_CC_CHANNEL3, ///< Timer capture/compare channel 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_CC_CHANNEL4, ///< Timer capture/compare channel 4. + NRF_TIMER_CC_CHANNEL5, ///< Timer capture/compare channel 5. +#endif +} nrf_timer_cc_channel_t; + +/** + * @brief Timer interrupts. + */ +typedef enum +{ + NRF_TIMER_INT_COMPARE0_MASK = TIMER_INTENSET_COMPARE0_Msk, ///< Timer interrupt from compare event on channel 0. + NRF_TIMER_INT_COMPARE1_MASK = TIMER_INTENSET_COMPARE1_Msk, ///< Timer interrupt from compare event on channel 1. + NRF_TIMER_INT_COMPARE2_MASK = TIMER_INTENSET_COMPARE2_Msk, ///< Timer interrupt from compare event on channel 2. + NRF_TIMER_INT_COMPARE3_MASK = TIMER_INTENSET_COMPARE3_Msk, ///< Timer interrupt from compare event on channel 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_INT_COMPARE4_MASK = TIMER_INTENSET_COMPARE4_Msk, ///< Timer interrupt from compare event on channel 4. + NRF_TIMER_INT_COMPARE5_MASK = TIMER_INTENSET_COMPARE5_Msk, ///< Timer interrupt from compare event on channel 5. +#endif +} nrf_timer_int_mask_t; + + +/** + * @brief Function for activating a specific timer task. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg, + nrf_timer_task_t task); + +/** + * @brief Function for getting the address of a specific timer task register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg, + nrf_timer_task_t task); + +/** + * @brief Function for clearing a specific timer event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event); + +/** + * @brief Function for checking the state of a specific timer event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event); + +/** + * @brief Function for getting the address of a specific timer event register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event); + +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg, + uint32_t timer_shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg, + uint32_t timer_shorts_mask); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg, + uint32_t timer_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg, + uint32_t timer_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg, + uint32_t timer_int); + +/** + * @brief Function for setting the timer mode. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] mode Timer mode. + */ +__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg, + nrf_timer_mode_t mode); + +/** + * @brief Function for retrieving the timer mode. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return Timer mode. + */ +__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_reg); + +/** + * @brief Function for setting the timer bit width. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] bit_width Timer bit width. + */ +__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg, + nrf_timer_bit_width_t bit_width); + +/** + * @brief Function for retrieving the timer bit width. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return Timer bit width. + */ +__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_reg); + +/** + * @brief Function for setting the timer frequency. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] frequency Timer frequency. + */ +__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg, + nrf_timer_frequency_t frequency); + +/** + * @brief Function for retrieving the timer frequency. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return Timer frequency. + */ +__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_reg); + +/** + * @brief Function for writing the capture/compare register for a specified channel. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] cc_channel Requested capture/compare channel. + * @param[in] cc_value Value to write to the capture/compare register. + */ +__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_reg, + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value); + +/** + * @brief Function for retrieving the capture/compare value for a specified channel. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] cc_channel Requested capture/compare channel. + * + * @return Value from the requested capture/compare register. + */ +__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg, + nrf_timer_cc_channel_t cc_channel); + +/** + * @brief Function for getting a specific timer capture task. + * + * @param[in] channel Capture channel. + * + * @return Capture task. + */ +__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel); + +/** + * @brief Function for getting a specific timer compare event. + * + * @param[in] channel Compare channel. + * + * @return Compare event. + */ +__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel); + +/** + * @brief Function for getting a specific timer compare interrupt. + * + * @param[in] channel Compare channel. + * + * @return Compare interrupt. + */ +__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel); + +/** + * @brief Function for calculating the number of timer ticks for a given time + * (in microseconds) and timer frequency. + * + * @param[in] time_us Time in microseconds. + * @param[in] frequency Timer frequency. + * + * @return Number of timer ticks. + */ +__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us, + nrf_timer_frequency_t frequency); + +/** + * @brief Function for calculating the number of timer ticks for a given time + * (in milliseconds) and timer frequency. + * + * @param[in] time_ms Time in milliseconds. + * @param[in] frequency Timer frequency. + * + * @return Number of timer ticks. + */ +__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms, + nrf_timer_frequency_t frequency); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg, + nrf_timer_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg, + nrf_timer_task_t task) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task); +} + +__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg, + uint32_t timer_shorts_mask) +{ + p_reg->SHORTS |= timer_shorts_mask; +} + +__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg, + uint32_t timer_shorts_mask) +{ + p_reg->SHORTS &= ~(timer_shorts_mask); +} + +__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg, + uint32_t timer_int_mask) +{ + p_reg->INTENSET = timer_int_mask; +} + +__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg, + uint32_t timer_int_mask) +{ + p_reg->INTENCLR = timer_int_mask; +} + +__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg, + uint32_t timer_int) +{ + return (bool)(p_reg->INTENSET & timer_int); +} + +__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg, + nrf_timer_mode_t mode) +{ + p_reg->MODE = (p_reg->MODE & ~TIMER_MODE_MODE_Msk) | + ((mode << TIMER_MODE_MODE_Pos) & TIMER_MODE_MODE_Msk); +} + +__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_reg) +{ + return (nrf_timer_mode_t)(p_reg->MODE); +} + +__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg, + nrf_timer_bit_width_t bit_width) +{ + p_reg->BITMODE = (p_reg->BITMODE & ~TIMER_BITMODE_BITMODE_Msk) | + ((bit_width << TIMER_BITMODE_BITMODE_Pos) & + TIMER_BITMODE_BITMODE_Msk); +} + +__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_reg) +{ + return (nrf_timer_bit_width_t)(p_reg->BITMODE); +} + +__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg, + nrf_timer_frequency_t frequency) +{ + p_reg->PRESCALER = (p_reg->PRESCALER & ~TIMER_PRESCALER_PRESCALER_Msk) | + ((frequency << TIMER_PRESCALER_PRESCALER_Pos) & + TIMER_PRESCALER_PRESCALER_Msk); +} + +__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_reg) +{ + return (nrf_timer_frequency_t)(p_reg->PRESCALER); +} + +__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_reg, + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value) +{ + p_reg->CC[cc_channel] = cc_value; +} + +__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg, + nrf_timer_cc_channel_t cc_channel) +{ + return (uint32_t)p_reg->CC[cc_channel]; +} + +__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel) +{ + return (nrf_timer_task_t) + ((uint32_t)NRF_TIMER_TASK_CAPTURE0 + (channel * sizeof(uint32_t))); +} + +__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel) +{ + return (nrf_timer_event_t) + ((uint32_t)NRF_TIMER_EVENT_COMPARE0 + (channel * sizeof(uint32_t))); +} + +__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel) +{ + return (nrf_timer_int_mask_t) + ((uint32_t)NRF_TIMER_INT_COMPARE0_MASK << channel); +} + +__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us, + nrf_timer_frequency_t frequency) +{ + // The "frequency" parameter here is actually the prescaler value, and the + // timer runs at the following frequency: f = 16 MHz / 2^prescaler. + uint32_t prescaler = (uint32_t)frequency; + ASSERT(time_us <= (UINT32_MAX / 16UL)); + return ((time_us * 16UL) >> prescaler); +} + +__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms, + nrf_timer_frequency_t frequency) +{ + // The "frequency" parameter here is actually the prescaler value, and the + // timer runs at the following frequency: f = 16000 kHz / 2^prescaler. + uint32_t prescaler = (uint32_t)frequency; + ASSERT(time_ms <= (UINT32_MAX / 16000UL)); + return ((time_ms * 16000UL) >> prescaler); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_TIMER_H__ + +/** @} */ diff --git a/third_party/NordicSemiconductor/hal/nrf_uart.h b/third_party/NordicSemiconductor/hal/nrf_uart.h index 3df1de16f..e2e26996e 100644 --- a/third_party/NordicSemiconductor/hal/nrf_uart.h +++ b/third_party/NordicSemiconductor/hal/nrf_uart.h @@ -1,33 +1,42 @@ -/* Copyright (c) 2016, Nordic Semiconductor ASA +/** + * 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 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_UART_H__ #define NRF_UART_H__ @@ -82,7 +91,7 @@ typedef enum NRF_UART_EVENT_TXDRDY = offsetof(NRF_UART_Type, EVENTS_TXDRDY),/**< Event from data sent from TXD. */ NRF_UART_EVENT_ERROR = offsetof(NRF_UART_Type, EVENTS_ERROR), /**< Event from error detection. */ NRF_UART_EVENT_RXTO = offsetof(NRF_UART_Type, EVENTS_RXTO) /**< Event from receiver timeout. */ - /*lint -restore*/ + /*lint -restore*/ } nrf_uart_event_t; /** @@ -98,7 +107,7 @@ typedef enum NRF_UART_INT_MASK_TXDRDY = UART_INTENCLR_TXDRDY_Msk, /**< Data sent from TXD interrupt. */ NRF_UART_INT_MASK_ERROR = UART_INTENCLR_ERROR_Msk, /**< Error detection interrupt. */ NRF_UART_INT_MASK_RXTO = UART_INTENCLR_RXTO_Msk /**< Receiver timeout interrupt. */ - /*lint -restore*/ + /*lint -restore*/ } nrf_uart_int_mask_t; /** @@ -182,7 +191,7 @@ typedef enum * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] event Event to clear. */ -__STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type *p_reg, nrf_uart_event_t event); +__STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event); /** * @brief Function for checking the state of a specific UART event. @@ -192,7 +201,7 @@ __STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type *p_reg, nrf_uart_event_t * * @retval True if event is set, False otherwise. */ -__STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type *p_reg, nrf_uart_event_t event); +__STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type * p_reg, nrf_uart_event_t event); /** * @brief Function for returning the address of a specific UART event register. @@ -202,7 +211,7 @@ __STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type *p_reg, nrf_uart_event_t * * @retval Address of specified event register. */ -__STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type *p_reg, +__STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type * p_reg, nrf_uart_event_t event); /** @@ -211,7 +220,7 @@ __STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type *p_reg, * @param p_reg Pointer to the peripheral registers structure. * @param int_mask Interrupts to enable. */ -__STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type *p_reg, uint32_t int_mask); +__STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t int_mask); /** * @brief Function for retrieving the state of a given interrupt. @@ -222,7 +231,7 @@ __STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type *p_reg, uint32_t int_mask * @retval true If the interrupt is enabled. * @retval false If the interrupt is not enabled. */ -__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type *p_reg, uint32_t int_mask); +__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type * p_reg, uint32_t int_mask); /** * @brief Function for disabling specific interrupts. @@ -230,7 +239,7 @@ __STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type *p_reg, uint32_t in * @param p_reg Pointer to the peripheral registers structure. * @param int_mask Interrupts to disable. */ -__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type *p_reg, uint32_t int_mask); +__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t int_mask); /** * @brief Function for getting error source mask. Function is clearing error source flags after reading. @@ -238,21 +247,21 @@ __STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type *p_reg, uint32_t int_mas * @param p_reg Pointer to the peripheral registers structure. * @return Mask with error source flags. */ -__STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type *p_reg); +__STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg); /** * @brief Function for enabling UART. * * @param p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE void nrf_uart_enable(NRF_UART_Type *p_reg); +__STATIC_INLINE void nrf_uart_enable(NRF_UART_Type * p_reg); /** * @brief Function for disabling UART. * * @param p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE void nrf_uart_disable(NRF_UART_Type *p_reg); +__STATIC_INLINE void nrf_uart_disable(NRF_UART_Type * p_reg); /** * @brief Function for configuring TX/RX pins. @@ -261,42 +270,42 @@ __STATIC_INLINE void nrf_uart_disable(NRF_UART_Type *p_reg); * @param pseltxd TXD pin number. * @param pselrxd RXD pin number. */ -__STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type *p_reg, uint32_t pseltxd, uint32_t pselrxd); +__STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd); /** * @brief Function for disconnecting TX/RX pins. * * @param p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type *p_reg); +__STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg); /** * @brief Function for getting TX pin. * * @param p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type *p_reg); +__STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type * p_reg); /** * @brief Function for getting RX pin. * * @param p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type *p_reg); +__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg); /** * @brief Function for getting RTS pin. * * @param p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type *p_reg); +__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg); /** * @brief Function for getting CTS pin. * * @param p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type *p_reg); +__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg); /** @@ -306,7 +315,7 @@ __STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type *p_reg); * @param pselrts RTS pin number. * @param pselcts CTS pin number. */ -__STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type *p_reg, +__STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type * p_reg, uint32_t pselrts, uint32_t pselcts); @@ -315,7 +324,7 @@ __STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type *p_reg, * * @param p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type *p_reg); +__STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type * p_reg); /** * @brief Function for reading RX data. @@ -323,7 +332,7 @@ __STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type *p_reg); * @param p_reg Pointer to the peripheral registers structure. * @return Received byte. */ -__STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type *p_reg); +__STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type * p_reg); /** * @brief Function for setting Tx data. @@ -331,7 +340,7 @@ __STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type *p_reg); * @param p_reg Pointer to the peripheral registers structure. * @param txd Byte. */ -__STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type *p_reg, uint8_t txd); +__STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd); /** * @brief Function for starting an UART task. @@ -339,7 +348,7 @@ __STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type *p_reg, uint8_t txd); * @param p_reg Pointer to the peripheral registers structure. * @param task Task. */ -__STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type *p_reg, nrf_uart_task_t task); +__STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_t task); /** * @brief Function for returning the address of a specific task register. @@ -349,7 +358,7 @@ __STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type *p_reg, nrf_uart_task_t * * @return Task address. */ -__STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type *p_reg, nrf_uart_task_t task); +__STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type * p_reg, nrf_uart_task_t task); /** * @brief Function for configuring UART. @@ -358,9 +367,9 @@ __STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type *p_reg, nrf_uar * @param hwfc Hardware flow control. Enabled if true. * @param parity Parity. Included if true. */ -__STATIC_INLINE void nrf_uart_configure(NRF_UART_Type *p_reg, - nrf_uart_parity_t parity, - nrf_uart_hwfc_t hwfc); +__STATIC_INLINE void nrf_uart_configure(NRF_UART_Type * p_reg, + nrf_uart_parity_t parity, + nrf_uart_hwfc_t hwfc); /** * @brief Function for setting UART baudrate. @@ -368,10 +377,10 @@ __STATIC_INLINE void nrf_uart_configure(NRF_UART_Type *p_reg, * @param p_reg Pointer to the peripheral registers structure. * @param baudrate Baudrate. */ -__STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type *p_reg, nrf_uart_baudrate_t baudrate); +__STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type * p_reg, nrf_uart_baudrate_t baudrate); #ifndef SUPPRESS_INLINE_IMPLEMENTATION -__STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type *p_reg, nrf_uart_event_t event) +__STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event) { *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; #if __CORTEX_M == 0x04 @@ -381,50 +390,50 @@ __STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type *p_reg, nrf_uart_event_t } -__STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type *p_reg, nrf_uart_event_t event) +__STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type * p_reg, nrf_uart_event_t event) { - return (bool) * (volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); } -__STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type *p_reg, +__STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type * p_reg, nrf_uart_event_t event) { return (uint32_t)((uint8_t *)p_reg + (uint32_t)event); } -__STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type *p_reg, uint32_t int_mask) +__STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t int_mask) { p_reg->INTENSET = int_mask; } -__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type *p_reg, uint32_t int_mask) +__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type * p_reg, uint32_t int_mask) { return (bool)(p_reg->INTENSET & int_mask); } -__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type *p_reg, uint32_t int_mask) +__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t int_mask) { p_reg->INTENCLR = int_mask; } -__STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type *p_reg) +__STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg) { uint32_t errsrc_mask = p_reg->ERRORSRC; p_reg->ERRORSRC = errsrc_mask; return errsrc_mask; } -__STATIC_INLINE void nrf_uart_enable(NRF_UART_Type *p_reg) +__STATIC_INLINE void nrf_uart_enable(NRF_UART_Type * p_reg) { p_reg->ENABLE = UART_ENABLE_ENABLE_Enabled; } -__STATIC_INLINE void nrf_uart_disable(NRF_UART_Type *p_reg) +__STATIC_INLINE void nrf_uart_disable(NRF_UART_Type * p_reg) { p_reg->ENABLE = UART_ENABLE_ENABLE_Disabled; } -__STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type *p_reg, uint32_t pseltxd, uint32_t pselrxd) +__STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd) { #if defined(UART_PSEL_RXD_CONNECT_Pos) p_reg->PSEL.RXD = pselrxd; @@ -438,12 +447,12 @@ __STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type *p_reg, uint32_t pselt #endif } -__STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type *p_reg) +__STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg) { nrf_uart_txrx_pins_set(p_reg, NRF_UART_PSEL_DISCONNECTED, NRF_UART_PSEL_DISCONNECTED); } -__STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type *p_reg) +__STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type * p_reg) { #if defined(UART_PSEL_TXD_CONNECT_Pos) return p_reg->PSEL.TXD; @@ -452,7 +461,7 @@ __STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type *p_reg) #endif } -__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type *p_reg) +__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg) { #if defined(UART_PSEL_RXD_CONNECT_Pos) return p_reg->PSEL.RXD; @@ -461,7 +470,7 @@ __STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type *p_reg) #endif } -__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type *p_reg) +__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg) { #if defined(UART_PSEL_RTS_CONNECT_Pos) return p_reg->PSEL.RTS; @@ -470,7 +479,7 @@ __STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type *p_reg) #endif } -__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type *p_reg) +__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg) { #if defined(UART_PSEL_RTS_CONNECT_Pos) return p_reg->PSEL.CTS; @@ -479,7 +488,7 @@ __STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type *p_reg) #endif } -__STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type *p_reg, uint32_t pselrts, uint32_t pselcts) +__STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type * p_reg, uint32_t pselrts, uint32_t pselcts) { #if defined(UART_PSEL_RTS_CONNECT_Pos) p_reg->PSEL.RTS = pselrts; @@ -494,39 +503,39 @@ __STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type *p_reg, uint32_t pselr #endif } -__STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type *p_reg) +__STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type * p_reg) { nrf_uart_hwfc_pins_set(p_reg, NRF_UART_PSEL_DISCONNECTED, NRF_UART_PSEL_DISCONNECTED); } -__STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type *p_reg) +__STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type * p_reg) { return p_reg->RXD; } -__STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type *p_reg, uint8_t txd) +__STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd) { p_reg->TXD = txd; } -__STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type *p_reg, nrf_uart_task_t task) +__STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_t task) { *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; } -__STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type *p_reg, nrf_uart_task_t task) +__STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type * p_reg, nrf_uart_task_t task) { return (uint32_t)p_reg + (uint32_t)task; } -__STATIC_INLINE void nrf_uart_configure(NRF_UART_Type *p_reg, - nrf_uart_parity_t parity, - nrf_uart_hwfc_t hwfc) +__STATIC_INLINE void nrf_uart_configure(NRF_UART_Type * p_reg, + nrf_uart_parity_t parity, + nrf_uart_hwfc_t hwfc) { p_reg->CONFIG = (uint32_t)parity | (uint32_t)hwfc; } -__STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type *p_reg, nrf_uart_baudrate_t baudrate) +__STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type * p_reg, nrf_uart_baudrate_t baudrate) { p_reg->BAUDRATE = baudrate; } diff --git a/third_party/NordicSemiconductor/hal/nrf_usbd.h b/third_party/NordicSemiconductor/hal/nrf_usbd.h index c796e4ed2..ef6f4b4ef 100644 --- a/third_party/NordicSemiconductor/hal/nrf_usbd.h +++ b/third_party/NordicSemiconductor/hal/nrf_usbd.h @@ -56,6 +56,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief USBD tasks */ @@ -1229,6 +1233,10 @@ void nrf_usbd_dpdmvalue_set(nrf_usbd_dpdmvalue_t val) void nrf_usbd_dtoggle_set(uint8_t ep, nrf_usbd_dtoggle_t op) { + ASSERT(NRF_USBD_EP_VALIDATE(ep)); + ASSERT(!NRF_USBD_EPISO_CHECK(ep)); + NRF_USBD->DTOGGLE = ep | (NRF_USBD_DTOGGLE_NOP << USBD_DTOGGLE_VALUE_Pos); + __DSB(); NRF_USBD->DTOGGLE = ep | (op << USBD_DTOGGLE_VALUE_Pos); __ISB(); __DSB(); @@ -1238,7 +1246,7 @@ nrf_usbd_dtoggle_t nrf_usbd_dtoggle_get(uint8_t ep) { uint32_t retval; /* Select the endpoint to read */ - nrf_usbd_dtoggle_set(ep, NRF_USBD_DTOGGLE_NOP); + NRF_USBD->DTOGGLE = ep | (NRF_USBD_DTOGGLE_NOP << USBD_DTOGGLE_VALUE_Pos); retval = ((NRF_USBD->DTOGGLE) & USBD_DTOGGLE_VALUE_Msk) >> USBD_DTOGGLE_VALUE_Pos; return (nrf_usbd_dtoggle_t)retval; } @@ -1250,11 +1258,11 @@ bool nrf_usbd_ep_enable_check(uint8_t ep) if (NRF_USBD_EPIN_CHECK(ep)) { - return 0 != (NRF_USBD->EPINEN & (1UL<EPINEN & (1UL << epnr)); } else { - return 0 != (NRF_USBD->EPOUTEN & (1UL<EPOUTEN & (1UL << epnr)); } } @@ -1265,11 +1273,11 @@ void nrf_usbd_ep_enable(uint8_t ep) if (NRF_USBD_EPIN_CHECK(ep)) { - NRF_USBD->EPINEN |= 1UL<EPINEN |= 1UL << epnr; } else { - NRF_USBD->EPOUTEN |= 1UL<EPOUTEN |= 1UL << epnr; } __ISB(); __DSB(); @@ -1282,11 +1290,11 @@ void nrf_usbd_ep_disable(uint8_t ep) if (NRF_USBD_EPIN_CHECK(ep)) { - NRF_USBD->EPINEN &= ~(1UL<EPINEN &= ~(1UL << epnr); } else { - NRF_USBD->EPOUTEN &= ~(1UL<EPOUTEN &= ~(1UL << epnr); } __ISB(); __DSB(); @@ -1419,4 +1427,9 @@ uint32_t nrf_usbd_ep_amount_get(uint8_t ep) #endif /* SUPPRESS_INLINE_IMPLEMENTATION */ /** @} */ + +#ifdef __cplusplus +} +#endif + #endif /* NRF_USBD_H__ */