aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports/NRF5/NRF51822
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal/ports/NRF5/NRF51822')
-rw-r--r--os/hal/ports/NRF5/NRF51822/hal_adc_lld.c227
-rw-r--r--os/hal/ports/NRF5/NRF51822/hal_adc_lld.h229
-rw-r--r--os/hal/ports/NRF5/NRF51822/hal_ext_lld.c168
-rw-r--r--os/hal/ports/NRF5/NRF51822/hal_ext_lld.h139
-rw-r--r--os/hal/ports/NRF5/NRF51822/hal_ext_lld_isr.h79
-rw-r--r--os/hal/ports/NRF5/NRF51822/hal_lld.c2
-rw-r--r--os/hal/ports/NRF5/NRF51822/hal_lld.h2
-rw-r--r--os/hal/ports/NRF5/NRF51822/hal_pwm_lld.c492
-rw-r--r--os/hal/ports/NRF5/NRF51822/hal_pwm_lld.h334
-rw-r--r--os/hal/ports/NRF5/NRF51822/nrf51_isr.c (renamed from os/hal/ports/NRF5/NRF51822/hal_ext_lld_isr.c)56
-rw-r--r--os/hal/ports/NRF5/NRF51822/nrf51_isr.h44
-rw-r--r--os/hal/ports/NRF5/NRF51822/platform.mk88
12 files changed, 96 insertions, 1764 deletions
diff --git a/os/hal/ports/NRF5/NRF51822/hal_adc_lld.c b/os/hal/ports/NRF5/NRF51822/hal_adc_lld.c
deleted file mode 100644
index 6c0f2c6..0000000
--- a/os/hal/ports/NRF5/NRF51822/hal_adc_lld.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- Copyright (C) 2015 Stephen Caudle
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-/**
- * @file NRF51Fx22/adc_lld.c
- * @brief NRF51Fx22 ADC subsystem low level driver source.
- *
- * @addtogroup ADC
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-#define ADC_CHANNEL_MASK 0x7
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief ADC1 driver identifier.*/
-#if NRF5_ADC_USE_ADC1 || defined(__DOXYGEN__)
-ADCDriver ADCD1;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-static void adc_lld_config_next_channel(ADCDriver *adcp, uint32_t config) {
-
- /* Default to all analog input pins disabled */
- config &= ~ADC_CONFIG_PSEL_Msk;
-
- if (adcp->grpp->channel_mask) {
- /* Skip to the next channel */
- while (((1 << adcp->current_channel) & adcp->grpp->channel_mask) == 0)
- adcp->current_channel = (adcp->current_channel + 1) & ADC_CHANNEL_MASK;
- config |= (((1 << adcp->current_channel) << ADC_CONFIG_PSEL_Pos) & ADC_CONFIG_PSEL_Msk);
- }
-
- /* Setup analog input pin select and user config values */
- adcp->adc->CONFIG = config;
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if NRF5_ADC_USE_ADC1 || defined(__DOXYGEN__)
-/**
- * @brief ADC interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(Vector5C) {
-
- ADCDriver *adcp = &ADCD1;
- NRF_ADC_Type *adc = adcp->adc;
- bool more = true;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clear the ADC event */
- adc->EVENTS_END = 0;
-
- /* Read the sample into the buffer */
- adcp->samples[adcp->current_index++] = adc->RESULT;
-
- /* At the end of the buffer then we may be finished */
- if (adcp->current_index == adcp->number_of_samples) {
- _adc_isr_full_code(adcp);
-
- adcp->current_index = 0;
-
- /* We are never finished in circular mode */
- more = adcp->grpp->circular;
- }
-
- if (more) {
-
- /* Signal half completion in circular mode. */
- if (adcp->grpp->circular &&
- (adcp->current_index == (adcp->number_of_samples / 2))) {
-
- _adc_isr_half_code(adcp);
- }
-
- /* Skip to the next channel */
- adcp->current_channel = (adcp->current_channel + 1) & ADC_CHANNEL_MASK;
- adc_lld_config_next_channel(adcp, adcp->adc->CONFIG);
- adcp->adc->TASKS_START = 1;
- } else {
- adc_lld_stop_conversion(adcp);
- }
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level ADC driver initialization.
- *
- * @notapi
- */
-void adc_lld_init(void) {
-
-#if NRF5_ADC_USE_ADC1
- /* Driver initialization.*/
- adcObjectInit(&ADCD1);
- ADCD1.adc = NRF_ADC;
-#endif
-}
-
-/**
- * @brief Configures and activates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start(ADCDriver *adcp) {
-
- /* If in stopped state then configures and enables the ADC. */
- if (adcp->state == ADC_STOP) {
-#if NRF5_ADC_USE_ADC1
- if (&ADCD1 == adcp) {
-
- adcp->adc->INTENSET = ADC_INTENSET_END_Enabled << ADC_INTENSET_END_Pos;
- nvicEnableVector(ADC_IRQn, NRF5_ADC_IRQ_PRIORITY);
- }
-#endif /* NRF5_ADC_USE_ADC1 */
- }
-}
-
-/**
- * @brief Deactivates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop(ADCDriver *adcp) {
-
- /* If in ready state then disables the ADC clock and analog part.*/
- if (adcp->state == ADC_READY) {
-
-#if NRF5_ADC_USE_ADC1
- if (&ADCD1 == adcp) {
-
- nvicDisableVector(ADC_IRQn);
- adcp->adc->INTENCLR = ADC_INTENCLR_END_Clear << ADC_INTENCLR_END_Pos;
- adc_lld_stop_conversion(adcp);
- }
-#endif
- }
-}
-
-/**
- * @brief Starts an ADC conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start_conversion(ADCDriver *adcp) {
-
- NRF_ADC_Type *adc = adcp->adc;
-
- adcp->number_of_samples = adcp->depth * adcp->grpp->num_channels;
- adcp->current_index = 0;
-
- /* At least one sample must be configured */
- osalDbgAssert(adcp->number_of_samples, "must configure at least one sample");
-
- /* Skip to the next channel */
- adcp->current_channel = 0;
- adc_lld_config_next_channel(adcp, adcp->grpp->cfg);
-
- /* Enable and start the conversion */
- adc->ENABLE = ADC_ENABLE_ENABLE_Enabled << ADC_ENABLE_ENABLE_Pos;
- adc->TASKS_START = 1;
-}
-
-/**
- * @brief Stops an ongoing conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop_conversion(ADCDriver *adcp) {
-
- NRF_ADC_Type *adc = adcp->adc;
-
- adc->TASKS_STOP = 1;
- adc->ENABLE = ADC_ENABLE_ENABLE_Disabled << ADC_ENABLE_ENABLE_Pos;
-}
-
-#endif /* HAL_USE_ADC */
-
-/** @} */
diff --git a/os/hal/ports/NRF5/NRF51822/hal_adc_lld.h b/os/hal/ports/NRF5/NRF51822/hal_adc_lld.h
deleted file mode 100644
index 2ee30ac..0000000
--- a/os/hal/ports/NRF5/NRF51822/hal_adc_lld.h
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- Copyright (C) 2015 Stephen Caudle
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-/**
- * @file NRF51x22/adc_lld.h
- * @brief NRF51x22 ADC subsystem low level driver header.
- *
- * @addtogroup ADC
- * @{
- */
-
-#ifndef HAL_ADC_LLD_H
-#define HAL_ADC_LLD_H
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief ADC1 driver enable switch.
- * @details If set to @p TRUE the support for ADC1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(NRF5_ADC_USE_ADC1) || defined(__DOXYGEN__)
-#define NRF5_ADC_USE_ADC1 FALSE
-#endif
-
-/**
- * @brief ADC interrupt priority level setting.
- */
-#if !defined(NRF5_ADC_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define NRF5_ADC_IRQ_PRIORITY 2
-#endif
-
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !NRF5_ADC_USE_ADC1
-#error "ADC driver activated but no ADC peripheral assigned"
-#endif
-
-#if NRF5_ADC_USE_ADC1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(NRF5_ADC_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC1"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief ADC sample data type.
- */
-typedef uint16_t adcsample_t;
-
-/**
- * @brief Channels number in a conversion group.
- */
-typedef uint8_t adc_channels_num_t;
-
-/**
- * @brief Type of a structure representing an ADC driver.
- */
-typedef struct ADCDriver ADCDriver;
-
-/**
- * @brief ADC notification callback type.
- *
- * @param[in] adcp pointer to the @p ADCDriver object triggering the
- * callback
- * @param[in] buffer pointer to the most recent samples data
- * @param[in] n number of buffer rows available starting from @p buffer
- */
-typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n);
-
-/**
- * @brief Conversion group configuration structure.
- * @details This implementation-dependent structure describes a conversion
- * operation.
- * @note The use of this configuration structure requires knowledge of
- * STM32 ADC cell registers interface, please refer to the STM32
- * reference manual for details.
- */
-typedef struct {
- /**
- * @brief Enables the circular buffer mode for the group.
- */
- bool circular;
- /**
- * @brief Number of the analog channels belonging to the conversion group.
- */
- adc_channels_num_t num_channels;
- /**
- * @brief Callback function associated to the group or @p NULL.
- */
- adccallback_t end_cb;
- /* End of the mandatory fields.*/
- /**
- * @brief Bitmask of channels for ADC conversion.
- */
- uint32_t channel_mask;
- /**
- * @brief ADC CONFIG register details.
- * @note All the required bits must be defined into this field.
- */
- uint32_t cfg;
-} ADCConversionGroup;
-
-/**
- * @brief Driver configuration structure.
- * @note It could be empty on some architectures.
- */
-typedef struct {
- uint32_t dummy;
-} ADCConfig;
-
-/**
- * @brief Structure representing an ADC driver.
- */
-struct ADCDriver {
- /**
- * @brief Driver state.
- */
- adcstate_t state;
- /**
- * @brief Current configuration data.
- */
- const ADCConfig *config;
- /**
- * @brief Current samples buffer pointer or @p NULL.
- */
- adcsample_t *samples;
- /**
- * @brief Current samples buffer depth or @p 0.
- */
- size_t depth;
- /**
- * @brief Current conversion group pointer or @p NULL.
- */
- const ADCConversionGroup *grpp;
-#if ADC_USE_WAIT || defined(__DOXYGEN__)
- /**
- * @brief Waiting thread.
- */
- thread_reference_t thread;
-#endif
-#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
- /**
- * @brief Mutex protecting the peripheral.
- */
- mutex_t mutex;
-#endif /* ADC_USE_MUTUAL_EXCLUSION */
-#if defined(ADC_DRIVER_EXT_FIELDS)
- ADC_DRIVER_EXT_FIELDS
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Pointer to the ADCx registers block.
- */
- NRF_ADC_Type *adc;
- /**
- * @brief Number of samples expected.
- */
- size_t number_of_samples;
- /**
- * @brief Current position in the buffer.
- */
- size_t current_index;
- /**
- * @brief Current channel index into group channel_mask.
- */
- size_t current_channel;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if NRF5_ADC_USE_ADC1 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void adc_lld_init(void);
- void adc_lld_start(ADCDriver *adcp);
- void adc_lld_stop(ADCDriver *adcp);
- void adc_lld_start_conversion(ADCDriver *adcp);
- void adc_lld_stop_conversion(ADCDriver *adcp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_ADC */
-
-#endif /* HAL_ADC_LLD_H */
-
-/** @} */
diff --git a/os/hal/ports/NRF5/NRF51822/hal_ext_lld.c b/os/hal/ports/NRF5/NRF51822/hal_ext_lld.c
deleted file mode 100644
index 47736c7..0000000
--- a/os/hal/ports/NRF5/NRF51822/hal_ext_lld.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- Copyright (C) 2015 Stephen Caudle
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-/**
- * @file NRF51822/ext_lld.c
- * @brief NRF51822 EXT subsystem low level driver source.
- *
- * @addtogroup EXT
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_EXT || defined(__DOXYGEN__)
-
-#include "hal_ext_lld_isr.h"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief EXTD1 driver identifier.
- */
-EXTDriver EXTD1;
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level EXT driver initialization.
- *
- * @notapi
- */
-void ext_lld_init(void) {
-
- /* Driver initialization.*/
- extObjectInit(&EXTD1);
-}
-
-/**
- * @brief Configures and activates the EXT peripheral.
- *
- * @param[in] extp pointer to the @p EXTDriver object
- *
- * @notapi
- */
-void ext_lld_start(EXTDriver *extp) {
-
- unsigned i;
-
- ext_lld_exti_irq_enable();
-
- /* Configuration of automatic channels.*/
- for (i = 0; i < EXT_MAX_CHANNELS; i++) {
- uint32_t config = 0;
- uint32_t pad = (extp->config->channels[i].mode & EXT_MODE_GPIO_MASK)
- >> EXT_MODE_GPIO_OFFSET;
-
- if (extp->config->channels[i].mode & EXT_CH_MODE_BOTH_EDGES)
- config |= (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
- else if (extp->config->channels[i].mode & EXT_CH_MODE_RISING_EDGE)
- config |= (GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos);
- else
- config |= (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);
-
- config |= (pad << GPIOTE_CONFIG_PSEL_Pos);
-
- NRF_GPIOTE->CONFIG[i] = config;
- NRF_GPIOTE->EVENTS_PORT = 0;
- NRF_GPIOTE->EVENTS_IN[i] = 0;
-
- if (extp->config->channels[i].mode & EXT_CH_MODE_AUTOSTART)
- ext_lld_channel_enable(extp, i);
- else
- ext_lld_channel_disable(extp, i);
- }
-}
-
-/**
- * @brief Deactivates the EXT peripheral.
- *
- * @param[in] extp pointer to the @p EXTDriver object
- *
- * @notapi
- */
-void ext_lld_stop(EXTDriver *extp) {
-
- unsigned i;
-
- (void)extp;
- ext_lld_exti_irq_disable();
-
- for (i = 0; i < EXT_MAX_CHANNELS; i++)
- NRF_GPIOTE->CONFIG[i] = 0;
-
- NRF_GPIOTE->INTENCLR =
- (GPIOTE_INTENCLR_IN3_Msk | GPIOTE_INTENCLR_IN2_Msk |
- GPIOTE_INTENCLR_IN1_Msk | GPIOTE_INTENCLR_IN0_Msk);
-}
-
-/**
- * @brief Enables an EXT channel.
- *
- * @param[in] extp pointer to the @p EXTDriver object
- * @param[in] channel channel to be enabled
- *
- * @notapi
- */
-void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) {
-
- uint32_t config = NRF_GPIOTE->CONFIG[channel] & ~GPIOTE_CONFIG_MODE_Msk;
-
- (void)extp;
- config |= (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
-
- NRF_GPIOTE->CONFIG[channel] = config;
- NRF_GPIOTE->INTENSET = (1 << channel);
-}
-
-/**
- * @brief Disables an EXT channel.
- *
- * @param[in] extp pointer to the @p EXTDriver object
- * @param[in] channel channel to be disabled
- *
- * @notapi
- */
-void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel) {
-
- (void)extp;
- NRF_GPIOTE->CONFIG[channel] &= ~GPIOTE_CONFIG_MODE_Msk;
- NRF_GPIOTE->INTENCLR = (1 << channel);
-}
-
-#endif /* HAL_USE_EXT */
-
-/** @} */
diff --git a/os/hal/ports/NRF5/NRF51822/hal_ext_lld.h b/os/hal/ports/NRF5/NRF51822/hal_ext_lld.h
deleted file mode 100644
index 37ae721..0000000
--- a/os/hal/ports/NRF5/NRF51822/hal_ext_lld.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- Copyright (C) 2015 Stephen Caudle
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-/**
- * @file NRF51822/ext_lld.h
- * @brief NRF51822 GPIOTE subsystem low level driver header.
- *
- * @addtogroup EXT
- * @{
- */
-
-#ifndef HAL_EXT_LLD_H
-#define HAL_EXT_LLD_H
-
-#if HAL_USE_EXT || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief Available number of EXT channels.
- */
-#define EXT_MAX_CHANNELS 4
-#define EXT_MODE_GPIO_MASK 0xF8 /**< @brief Pad field mask. */
-#define EXT_MODE_GPIO_OFFSET 3 /**< @brief Pad field offset. */
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief EXT channel identifier.
- */
-typedef uint32_t expchannel_t;
-
-/**
- * @brief Type of an EXT generic notification callback.
- *
- * @param[in] extp pointer to the @p EXPDriver object triggering the
- * callback
- */
-typedef void (*extcallback_t)(EXTDriver *extp, expchannel_t channel);
-
-/**
- * @brief Channel configuration structure.
- */
-typedef struct {
- /**
- * @brief Channel mode.
- */
- uint32_t mode;
- /**
- * @brief Channel callback.
- * @details In the STM32 implementation a @p NULL callback pointer is
- * valid and configures the channel as an event sources instead
- * of an interrupt source.
- */
- extcallback_t cb;
-} EXTChannelConfig;
-
-/**
- * @brief Driver configuration structure.
- * @note It could be empty on some architectures.
- */
-typedef struct {
- /**
- * @brief Channel configurations.
- */
- EXTChannelConfig channels[EXT_MAX_CHANNELS];
- /* End of the mandatory fields.*/
-} EXTConfig;
-
-/**
- * @brief Structure representing an EXT driver.
- */
-struct EXTDriver {
- /**
- * @brief Driver state.
- */
- extstate_t state;
- /**
- * @brief Current configuration data.
- */
- const EXTConfig *config;
- /* End of the mandatory fields.*/
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if !defined(__DOXYGEN__)
-extern EXTDriver EXTD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void ext_lld_init(void);
- void ext_lld_start(EXTDriver *extp);
- void ext_lld_stop(EXTDriver *extp);
- void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel);
- void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_EXT */
-
-#endif /* HAL_EXT_LLD_H */
-
-/** @} */
diff --git a/os/hal/ports/NRF5/NRF51822/hal_ext_lld_isr.h b/os/hal/ports/NRF5/NRF51822/hal_ext_lld_isr.h
deleted file mode 100644
index d606866..0000000
--- a/os/hal/ports/NRF5/NRF51822/hal_ext_lld_isr.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- Copyright (C) 2015 Stephen Caudle
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-/**
- * @file NRF51x22/ext_lld_isr.h
- * @brief NRF51x22 EXT subsystem low level driver ISR header.
- *
- * @addtogroup EXT
- * @{
- */
-
-#ifndef HAL_EXT_LLD_ISR_H
-#define HAL_EXT_LLD_ISR_H
-
-#if HAL_USE_EXT || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief GPIOTE interrupt priority level setting.
- */
-#if !defined(NRF5_EXT_GPIOTE_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define NRF5_EXT_GPIOTE_IRQ_PRIORITY 3
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void ext_lld_exti_irq_enable(void);
- void ext_lld_exti_irq_disable(void);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_EXT */
-
-#endif /* HAL_EXT_LLD_ISR_H */
-
-/** @} */
diff --git a/os/hal/ports/NRF5/NRF51822/hal_lld.c b/os/hal/ports/NRF5/NRF51822/hal_lld.c
index f33fdda..412cfea 100644
--- a/os/hal/ports/NRF5/NRF51822/hal_lld.c
+++ b/os/hal/ports/NRF5/NRF51822/hal_lld.c
@@ -80,6 +80,8 @@ void hal_lld_init(void)
(NRF5_SYSTEM_TICKS == NRF5_SYSTEM_TICKS_AS_RTC)
NRF_CLOCK->TASKS_LFCLKSTART = 1;
#endif
+
+ irqInit();
}
/**
diff --git a/os/hal/ports/NRF5/NRF51822/hal_lld.h b/os/hal/ports/NRF5/NRF51822/hal_lld.h
index a1d2460..178bb42 100644
--- a/os/hal/ports/NRF5/NRF51822/hal_lld.h
+++ b/os/hal/ports/NRF5/NRF51822/hal_lld.h
@@ -94,7 +94,7 @@
/*===========================================================================*/
#include "nvic.h"
-
+#include "nrf51_isr.h"
#ifdef __cplusplus
extern "C" {
diff --git a/os/hal/ports/NRF5/NRF51822/hal_pwm_lld.c b/os/hal/ports/NRF5/NRF51822/hal_pwm_lld.c
deleted file mode 100644
index e2b4b6b..0000000
--- a/os/hal/ports/NRF5/NRF51822/hal_pwm_lld.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- ChibiOS/HAL - Copyright (C) 2016 Stéphane D'Alu
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-/**
- * @file hal_pwm_lld.c
- * @brief NRF51 PWM subsystem low level driver source.
- *
- * @note Using the method described in nrf51-pwm-library to correctly
- * handle toggling of the pin with GPIOTE when changing period.
- * It means it is generally unsafe to use GPIOTE with a period
- * less than (2 * PWM_GPIOTE_DECISION_TIME / 16MHz)
- *
- * @addtogroup PWM
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_PWM || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define PWM_GPIOTE_PPI_CC 3
-#define PWM_GPIOTE_DECISION_TIME 160
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief PWMD1 driver identifier.
- * @note The driver PWMD1 allocates the timer TIMER0 when enabled.
- */
-#if NRF5_PWM_USE_TIMER0 || defined(__DOXYGEN__)
-PWMDriver PWMD1;
-#endif
-
-/**
- * @brief PWMD2 driver identifier.
- * @note The driver PWMD2 allocates the timer TIMER1 when enabled.
- */
-#if NRF5_PWM_USE_TIMER1 || defined(__DOXYGEN__)
-PWMDriver PWMD2;
-#endif
-
-/**
- * @brief PWMD3 driver identifier.
- * @note The driver PWMD3 allocates the timer TIMER2 when enabled.
- */
-#if NRF5_PWM_USE_TIMER2 || defined(__DOXYGEN__)
-PWMDriver PWMD3;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static const uint8_t pwm_margin_by_prescaler[] = {
- (PWM_GPIOTE_DECISION_TIME + 0) >> 0,
- (PWM_GPIOTE_DECISION_TIME + 1) >> 1,
- (PWM_GPIOTE_DECISION_TIME + 3) >> 2,
- (PWM_GPIOTE_DECISION_TIME + 7) >> 3,
- (PWM_GPIOTE_DECISION_TIME + 15) >> 4,
- (PWM_GPIOTE_DECISION_TIME + 31) >> 5,
- (PWM_GPIOTE_DECISION_TIME + 63) >> 6,
- (PWM_GPIOTE_DECISION_TIME + 127) >> 7,
- (PWM_GPIOTE_DECISION_TIME + 255) >> 8,
- (PWM_GPIOTE_DECISION_TIME + 511) >> 9
-};
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-static void pwm_lld_serve_interrupt(PWMDriver *pwmp) {
- uint8_t channel;
- /* Deal with PWM channels
- */
- for (channel = 0 ; channel < pwmp->channels ; channel++) {
- if (pwmp->timer->EVENTS_COMPARE[channel]) {
- pwmp->timer->EVENTS_COMPARE[channel] = 0;
-
- if (pwmp->config->channels[channel].callback != NULL) {
- pwmp->config->channels[channel].callback(pwmp);
- }
- }
- }
-
- /* Deal with PWM period
- */
- if (pwmp->timer->EVENTS_COMPARE[pwmp->channels]) {
- pwmp->timer->EVENTS_COMPARE[pwmp->channels] = 0;
-
- if (pwmp->config->callback != NULL) {
- pwmp->config->callback(pwmp);
- }
- }
-}
-
-static inline
-bool pwm_within_safe_margins(PWMDriver *pwmp, uint32_t timer, uint32_t width) {
- const uint32_t margin = pwm_margin_by_prescaler[pwmp->timer->PRESCALER];
- return (width <= margin)
- ? ((width <= timer) && (timer < (pwmp->period + width - margin)))
- : ((width <= timer) || (timer < (width - margin)));
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if NRF5_PWM_USE_TIMER0
-/**
- * @brief TIMER0 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(Vector60) {
- OSAL_IRQ_PROLOGUE();
- pwm_lld_serve_interrupt(&PWMD1);
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* NRF5_PWM_USE_TIMER0 */
-
-#if NRF5_PWM_USE_TIMER1
-/**
- * @brief TIMER1 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(Vector64) {
- OSAL_IRQ_PROLOGUE();
- pwm_lld_serve_interrupt(&PWMD2);
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* NRF5_PWM_USE_TIMER1 */
-
-#if NRF5_PWM_USE_TIMER2
-/**
- * @brief TIMER2 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(Vector68) {
- OSAL_IRQ_PROLOGUE();
- pwm_lld_serve_interrupt(&PWMD3);
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* NRF5_PWM_USE_TIMER2 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level PWM driver initialization.
- *
- * @notapi
- */
-void pwm_lld_init(void) {
-
-#if NRF5_PWM_USE_TIMER0
- pwmObjectInit(&PWMD1);
- PWMD1.channels = PWM_CHANNELS;
- PWMD1.timer = NRF_TIMER0;
-#endif
-
-#if NRF5_PWM_USE_TIMER1
- pwmObjectInit(&PWMD2);
- PWMD2.channels = PWM_CHANNELS;
- PWMD2.timer = NRF_TIMER1;
-#endif
-
-#if NRF5_PWM_USE_TIMER2
- pwmObjectInit(&PWMD3);
- PWMD3.channels = PWM_CHANNELS;
- PWMD3.timer = NRF_TIMER2;
-#endif
-}
-
-/**
- * @brief Configures and activates the PWM peripheral.
- * @note Starting a driver that is already in the @p PWM_READY state
- * disables all the active channels.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- *
- * @notapi
- */
-void pwm_lld_start(PWMDriver *pwmp) {
- /* Prescaler value calculation: ftimer = 16MHz / 2^PRESCALER */
- uint16_t psc_ratio = NRF5_HFCLK_FREQUENCY / pwmp->config->frequency;
- /* Prescaler ratio must be between 1 and 512, and a power of two. */
- osalDbgAssert(psc_ratio <= 512 && !(psc_ratio & (psc_ratio - 1)),
- "invalid frequency");
- /* Prescaler value as a power of 2, must be 0..9 */
- uint32_t psc_value;
- for (psc_value = 0; psc_value < 10; psc_value++)
- if (psc_ratio == (unsigned)(1 << psc_value))
- break;
-
- /* Configure as 16bits timer (only TIMER0 support 32bits) */
- pwmp->timer->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
- pwmp->timer->MODE = TIMER_MODE_MODE_Timer;
-
- /* With clear shortcuts for period */
- pwmp->timer->SHORTS =
- 0x1UL << (TIMER_SHORTS_COMPARE0_CLEAR_Pos + pwmp->channels);
-
- /* Disable and reset interrupts for compare events */
- pwmp->timer->INTENCLR = (TIMER_INTENCLR_COMPARE0_Msk |
- TIMER_INTENCLR_COMPARE1_Msk |
- TIMER_INTENCLR_COMPARE2_Msk |
- TIMER_INTENCLR_COMPARE3_Msk );
- pwmp->timer->EVENTS_COMPARE[0] = 0;
- pwmp->timer->EVENTS_COMPARE[1] = 0;
- pwmp->timer->EVENTS_COMPARE[2] = 0;
- pwmp->timer->EVENTS_COMPARE[3] = 0;
-
- /* Set prescaler */
- pwmp->timer->PRESCALER = psc_value;
-
- /* Set period */
- pwmp->timer->CC[pwmp->channels] = pwmp->period;
-
- /* Clear everything */
- pwmp->timer->TASKS_CLEAR = 1;
-
- /* Enable interrupt */
-#if NRF5_PWM_USE_TIMER0
- if (&PWMD1 == pwmp) {
- nvicEnableVector(TIMER0_IRQn, NRF5_PWM_TIMER0_PRIORITY);
- }
-#endif
-
-#if NRF5_PWM_USE_TIMER1
- if (&PWMD2 == pwmp) {
- nvicEnableVector(TIMER1_IRQn, NRF5_PWM_TIMER1_PRIORITY);
- }
-#endif
-
-#if NRF5_PWM_USE_TIMER2
- if (&PWMD3 == pwmp) {
- nvicEnableVector(TIMER2_IRQn, NRF5_PWM_TIMER2_PRIORITY);
- }
-#endif
-
- /* Start timer */
- pwmp->timer->TASKS_START = 1;
-}
-
-/**
- * @brief Deactivates the PWM peripheral.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- *
- * @notapi
- */
-void pwm_lld_stop(PWMDriver *pwmp) {
- pwmp->timer->TASKS_SHUTDOWN = 1;
-
-#if NRF5_PWM_USE_TIMER0
- if (&PWMD1 == pwmp) {
- nvicDisableVector(TIMER0_IRQn);
- }
-#endif
-
-#if NRF5_PWM_USE_TIMER1
- if (&PWMD2 == pwmp) {
- nvicDisableVector(TIMER1_IRQn);
- }
-#endif
-
-#if NRF5_PWM_USE_TIMER2
- if (&PWMD3 == pwmp) {
- nvicDisableVector(TIMER2_IRQn);
- }
-#endif
-}
-
-/**
- * @brief Enables a PWM channel.
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @post The channel is active using the specified configuration.
- * @note The function has effect at the next cycle start.
- * @note Channel notification is not enabled.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...channels-1)
- * @param[in] width PWM pulse width as clock pulses number
- *
- * @notapi
- */
-void pwm_lld_enable_channel(PWMDriver *pwmp,
- pwmchannel_t channel,
- pwmcnt_t width) {
-#if NRF5_PWM_USE_GPIOTE_PPI
- const PWMChannelConfig *cfg_channel = &pwmp->config->channels[channel];
- const uint8_t gpiote_channel = cfg_channel->gpiote_channel;
- const uint8_t *ppi_channel = cfg_channel->ppi_channel;
-
- uint32_t outinit;
- switch(cfg_channel->mode & PWM_OUTPUT_MASK) {
- case PWM_OUTPUT_ACTIVE_LOW : outinit = GPIOTE_CONFIG_OUTINIT_Low; break;
- case PWM_OUTPUT_ACTIVE_HIGH: outinit = GPIOTE_CONFIG_OUTINIT_High; break;
- case PWM_OUTPUT_DISABLED : /* fall-through */
- default : goto no_output_config;
- }
-
- /* Deal with corner case: 0% and 100% */
- if ((width <= 0) || (width >= pwmp->period)) {
- /* Disable GPIOTE/PPI task */
- NRF_GPIOTE->CONFIG[gpiote_channel] = GPIOTE_CONFIG_MODE_Disabled;
- NRF_PPI->CHENCLR = ((1 << ppi_channel[0]) | (1 << ppi_channel[1]));
- /* Set Line */
- palWriteLine(cfg_channel->ioline,
- ((width <= 0) ^
- ((cfg_channel->mode & PWM_OUTPUT_MASK) == PWM_OUTPUT_ACTIVE_HIGH)));
-
- /* Really doing PWM */
- } else {
- const uint32_t gpio_pin = PAL_PAD(cfg_channel->ioline);
- const uint32_t polarity = GPIOTE_CONFIG_POLARITY_Toggle;
-
- /* Program tasks (one for duty cycle, one for periode) */
- NRF_PPI->CH[ppi_channel[0]].EEP =
- (uint32_t)&pwmp->timer->EVENTS_COMPARE[channel];
- NRF_PPI->CH[ppi_channel[0]].TEP =
- (uint32_t)&NRF_GPIOTE->TASKS_OUT[gpiote_channel];
- NRF_PPI->CH[ppi_channel[1]].EEP =
- (uint32_t)&pwmp->timer->EVENTS_COMPARE[pwmp->channels];
- NRF_PPI->CH[ppi_channel[1]].TEP =
- (uint32_t)&NRF_GPIOTE->TASKS_OUT[gpiote_channel];
- NRF_PPI->CHENSET = ((1 << ppi_channel[0]) | (1 << ppi_channel[1]));
-
- /* Something Old, something New */
- const uint32_t old_width = pwmp->timer->CC[channel];
- const uint32_t new_width = width;
-
- /* Check GPIOTE state */
- const bool gpiote = (NRF_GPIOTE->CONFIG[gpiote_channel] &
- GPIOTE_CONFIG_MODE_Msk) != GPIOTE_CONFIG_MODE_Disabled;
-
- /* GPIOTE is currently running */
- if (gpiote) {
- uint32_t current;
- while (true) {
- pwmp->timer->TASKS_CAPTURE[PWM_GPIOTE_PPI_CC] = 1;
- current = pwmp->timer->CC[PWM_GPIOTE_PPI_CC];
-
- if (pwm_within_safe_margins(pwmp, current, old_width) &&
- pwm_within_safe_margins(pwmp, current, new_width))
- break;
- }
- if (((old_width <= current) && (current < new_width)) ||
- ((new_width <= current) && (current < old_width))) {
- NRF_GPIOTE->TASKS_OUT[gpiote_channel] = 1;
- }
-
- /* GPIOTE need to be restarted */
- } else {
- /* Create GPIO Task */
- NRF_GPIOTE->CONFIG[gpiote_channel] =
- (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
- ((gpio_pin << GPIOTE_CONFIG_PSEL_Pos ) & GPIOTE_CONFIG_PSEL_Msk )|
- ((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk)|
- ((outinit << GPIOTE_CONFIG_OUTINIT_Pos ) & GPIOTE_CONFIG_OUTINIT_Msk );
-
- pwmp->timer->TASKS_CAPTURE[PWM_GPIOTE_PPI_CC] = 1;
- if (pwmp->timer->CC[PWM_GPIOTE_PPI_CC] > width)
- NRF_GPIOTE->TASKS_OUT[gpiote_channel] = 1;
- }
- }
-
- no_output_config:
-#endif
-
- pwmp->timer->CC[channel] = width;
-}
-
-/**
- * @brief Disables a PWM channel and its notification.
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @post The channel is disabled and its output line returned to the
- * idle state.
- * @note The function has effect at the next cycle start.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...channels-1)
- *
- * @notapi
- */
-void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
- pwmp->timer->CC[channel] = 0;
-#if NRF5_PWM_USE_GPIOTE_PPI
- const PWMChannelConfig *cfg_channel = &pwmp->config->channels[channel];
- switch(cfg_channel->mode & PWM_OUTPUT_MASK) {
- case PWM_OUTPUT_ACTIVE_LOW:
- case PWM_OUTPUT_ACTIVE_HIGH: {
- const uint8_t gpiote_channel = cfg_channel->gpiote_channel;
- const uint8_t *ppi_channel = cfg_channel->ppi_channel;
- NRF_PPI->CHENCLR = ((1 << ppi_channel[0]) | (1 << ppi_channel[1]));
- NRF_GPIOTE->CONFIG[gpiote_channel] = GPIOTE_CONFIG_MODE_Disabled;
- break;
- }
- case PWM_OUTPUT_DISABLED:
- default:
- break;
- }
-#endif
-}
-
-/**
- * @brief Enables the periodic activation edge notification.
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @note If the notification is already enabled then the call has no effect.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- *
- * @notapi
- */
-void pwm_lld_enable_periodic_notification(PWMDriver *pwmp) {
- pwmp->timer->INTENSET =
- 0x1UL << (TIMER_INTENSET_COMPARE0_Pos + pwmp->channels);
-}
-
-/**
- * @brief Disables the periodic activation edge notification.
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @note If the notification is already disabled then the call has no effect.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- *
- * @notapi
- */
-void pwm_lld_disable_periodic_notification(PWMDriver *pwmp) {
- pwmp->timer->INTENCLR =
- 0x1UL << (TIMER_INTENCLR_COMPARE0_Pos + pwmp->channels);
-}
-
-/**
- * @brief Enables a channel de-activation edge notification.
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @pre The channel must have been activated using @p pwmEnableChannel().
- * @note If the notification is already enabled then the call has no effect.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...channels-1)
- *
- * @notapi
- */
-void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
- pwmchannel_t channel) {
- pwmp->timer->INTENSET =
- 0x1UL << (TIMER_INTENSET_COMPARE0_Pos + channel);
-}
-
-/**
- * @brief Disables a channel de-activation edge notification.
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @pre The channel must have been activated using @p pwmEnableChannel().
- * @note If the notification is already disabled then the call has no effect.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...channels-1)
- *
- * @notapi
- */
-void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
- pwmchannel_t channel) {
- pwmp->timer->INTENCLR =
- 0x1UL << (TIMER_INTENCLR_COMPARE0_Pos + channel);
-}
-
-#endif /* HAL_USE_PWM */
-
-/** @} */
diff --git a/os/hal/ports/NRF5/NRF51822/hal_pwm_lld.h b/os/hal/ports/NRF5/NRF51822/hal_pwm_lld.h
deleted file mode 100644
index 2cad6e7..0000000
--- a/os/hal/ports/NRF5/NRF51822/hal_pwm_lld.h
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- ChibiOS/HAL - Copyright (C) 2016 Stéphane D'Alu
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-/**
- * @file hal_pwm_lld.h
- * @brief NRF51 PWM subsystem low level driver header.
- *
- * @addtogroup PWM
- * @{
- */
-
-#ifndef HAL_PWM_LLD_H_
-#define HAL_PWM_LLD_H_
-
-#if HAL_USE_PWM || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief Number of PWM channels per PWM driver.
- */
-#if NRF5_PWM_USE_GPIOTE_PPI
-#define PWM_CHANNELS 2
-#else
-#define PWM_CHANNELS 3
-#endif
-
-#define PWM_FREQUENCY_16MHZ 16000000 /** @brief 16MHz */
-#define PWM_FREQUENCY_8MHZ 8000000 /** @brief 8MHz */
-#define PWM_FREQUENCY_4MHZ 4000000 /** @brief 4MHz */
-#define PWM_FREQUENCY_2MHZ 2000000 /** @brief 2MHz */
-#define PWM_FREQUENCY_1MHZ 1000000 /** @brief 1MHz */
-#define PWM_FREQUENCY_500KHZ 500000 /** @brief 500kHz */
-#define PWM_FREQUENCY_250KHZ 250000 /** @brief 250kHz */
-#define PWM_FREQUENCY_125KHZ 125000 /** @brief 125kHz */
-#define PWM_FREQUENCY_62500HZ 62500 /** @brief 62500Hz */
-#define PWM_FREQUENCY_31250HZ 31250 /** @brief 31250Hz */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-
-/**
- * @brief TIMER0 as driver implementation
- */
-#if !defined(NRF5_PWM_USE_TIMER0)
-#define NRF5_PWM_USE_TIMER0 FALSE
-#endif
-
-/**
- * @brief TIMER1 as driver implementation
- */
-#if !defined(NRF5_PWM_USE_TIMER1)
-#define NRF5_PWM_USE_TIMER1 FALSE
-#endif
-
-/**
- * @brief TIMER2 as driver implementation
- */
-#if !defined(NRF5_PWM_USE_TIMER2)
-#define NRF5_PWM_USE_TIMER2 FALSE
-#endif
-
-/**
- * @brief TIMER0 interrupt priority level setting.
- */
-#if !defined(NRF5_PWM_TIMER0_PRIORITY) || defined(__DOXYGEN__)
-#define NRF5_PWM_TIMER0_PRIORITY 3
-#endif
-
-/**
- * @brief TIMER1 interrupt priority level setting.
- */
-#if !defined(NRF5_PWM_TIMER1_PRIORITY) || defined(__DOXYGEN__)
-#define NRF5_PWM_TIMER1_PRIORITY 3
-#endif
-
-/**
- * @brief TIMER2 interrupt priority level setting.
- */
-#if !defined(NRF5_PWM_TIMER2_PRIORITY) || defined(__DOXYGEN__)
-#define NRF5_PWM_TIMER2_PRIORITY 3
-#endif
-
-/**
- * @brief Allow driver to use GPIOTE/PPI to control PAL line
- */
-#if !defined(NRF5_PWM_USE_GPIOTE_PPI)
-#define NRF5_PWM_USE_GPIOTE_PPI TRUE
-#endif
-
-/** @} */
-
-/*===========================================================================*/
-/* Configuration checks. */
-/*===========================================================================*/
-
-#if !NRF5_PWM_USE_TIMER0 && !NRF5_PWM_USE_TIMER1 && !NRF5_PWM_USE_TIMER2
-#error "PWM driver activated but no TIMER peripheral assigned"
-#endif
-
-#if (NRF5_ST_USE_TIMER0 == TRUE) && (NRF5_PWM_USE_TIMER0 == TRUE)
-#error "TIMER0 used for ST and PWM"
-#endif
-
-#if NRF5_PWM_USE_TIMER0 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(NRF5_PWM_TIMER0_PRIORITY)
-#error "Invalid IRQ priority assigned to TIMER0"
-#endif
-
-#if NRF5_PWM_USE_TIMER1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(NRF5_PWM_TIMER1_PRIORITY)
-#error "Invalid IRQ priority assigned to TIMER1"
-#endif
-
-#if NRF5_PWM_USE_TIMER2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(NRF5_PWM_TIMER2_PRIORITY)
-#error "Invalid IRQ priority assigned to TIMER2"
-#endif
-
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of a PWM mode.
- */
-typedef uint32_t pwmmode_t;
-
-/**
- * @brief Type of a PWM channel.
- */
-typedef uint8_t pwmchannel_t;
-
-/**
- * @brief Type of a channels mask.
- */
-typedef uint32_t pwmchnmsk_t;
-
-/**
- * @brief Type of a PWM counter.
- */
-typedef uint16_t pwmcnt_t;
-
-/**
- * @brief Type of a PWM driver channel configuration structure.
- */
-typedef struct {
- /**
- * @brief Channel active logic level.
- */
- pwmmode_t mode;
-
- /**
- * @brief Channel callback pointer.
- * @note This callback is invoked on the channel compare event. If set to
- * @p NULL then the callback is disabled.
- */
- pwmcallback_t callback;
- /* End of the mandatory fields.*/
-
-#if NRF5_PWM_USE_GPIOTE_PPI || defined(__DOXYGEN__)
- /**
- * @brief PAL line to toggle.
- * @note Only used if mode is PWM_OUTPUT_HIGH or PWM_OUTPUT_LOW.
- * @note When NRF5_PWM_USE_GPIOTE_PPI is used and channel enabled,
- * it wont be possible to access this PAL line using the PAL
- * driver.
- */
- ioline_t ioline;
-
- /**
- * @brief Unique GPIOTE channel to use. (1 channel)
- * @note Only 4 GPIOTE channels are available on nRF51.
- */
- uint8_t gpiote_channel;
-
- /**
- * @brief Unique PPI channels to use. (2 channels)
- * @note Only 16 PPI channels are available on nRF51
- * (When Softdevice is enabled, only channels 0-7 are available)
- */
- uint8_t ppi_channel[2];
-#endif
-} PWMChannelConfig;
-
-/**
- * @brief Type of a PWM driver configuration structure.
- */
-typedef struct {
- /**
- * @brief Timer clock in Hz.
- * @note The low level can use assertions in order to catch invalid
- * frequency specifications.
- */
- uint32_t frequency;
- /**
- * @brief PWM period in ticks.
- * @note The low level can use assertions in order to catch invalid
- * period specifications.
- */
- pwmcnt_t period;
- /**
- * @brief Periodic callback pointer.
- * @note This callback is invoked on PWM counter reset. If set to
- * @p NULL then the callback is disabled.
- */
- pwmcallback_t callback;
- /**
- * @brief Channels configurations.
- */
- PWMChannelConfig channels[PWM_CHANNELS];
- /* End of the mandatory fields.*/
-} PWMConfig;
-
-/**
- * @brief Structure representing a PWM driver.
- */
-struct PWMDriver {
- /**
- * @brief Driver state.
- */
- pwmstate_t state;
- /**
- * @brief Current driver configuration data.
- */
- const PWMConfig *config;
- /**
- * @brief Current PWM period in ticks.
- */
- pwmcnt_t period;
- /**
- * @brief Mask of the enabled channels.
- */
- pwmchnmsk_t enabled;
- /**
- * @brief Number of channels in this instance.
- */
- pwmchannel_t channels;
-#if defined(PWM_DRIVER_EXT_FIELDS)
- PWM_DRIVER_EXT_FIELDS
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Pointer to the TIMER registers block.
- */
- NRF_TIMER_Type *timer;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Changes the period the PWM peripheral.
- * @details This function changes the period of a PWM unit that has already
- * been activated using @p pwmStart().
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @post The PWM unit period is changed to the new value.
- * @note The function has effect at the next cycle start.
- * @note If a period is specified that is shorter than the pulse width
- * programmed in one of the channels then the behavior is not
- * guaranteed.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] period new cycle time in ticks
- *
- * @notapi
- */
-#define pwm_lld_change_period(pwmp, period) \
- do { \
- (pwmp)->timer->CC[(pwmp)->channels] = ((period) - 1); \
- } while(0)
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if NRF5_PWM_USE_TIMER0 || defined(__DOXYGEN__)
-extern PWMDriver PWMD1;
-#endif
-#if NRF5_PWM_USE_TIMER1 || defined(__DOXYGEN__)
-extern PWMDriver PWMD2;
-#endif
-#if NRF5_PWM_USE_TIMER2 || defined(__DOXYGEN__)
-extern PWMDriver PWMD3;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void pwm_lld_init(void);
- void pwm_lld_start(PWMDriver *pwmp);
- void pwm_lld_stop(PWMDriver *pwmp);
- void pwm_lld_enable_channel(PWMDriver *pwmp,
- pwmchannel_t channel,
- pwmcnt_t width);
- void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
- void pwm_lld_enable_periodic_notification(PWMDriver *pwmp);
- void pwm_lld_disable_periodic_notification(PWMDriver *pwmp);
- void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
- pwmchannel_t channel);
- void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
- pwmchannel_t channel);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_PWM */
-
-#endif /* HAL_PWM_LLD_H_ */
-
-/** @} */
diff --git a/os/hal/ports/NRF5/NRF51822/hal_ext_lld_isr.c b/os/hal/ports/NRF5/NRF51822/nrf51_isr.c
index ca8e24d..9a2bd94 100644
--- a/os/hal/ports/NRF5/NRF51822/hal_ext_lld_isr.c
+++ b/os/hal/ports/NRF5/NRF51822/nrf51_isr.c
@@ -1,4 +1,5 @@
/*
+ Copyright (C) 2018 Konstantin Oblaukhov
Copyright (C) 2015 Stephen Caudle
Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,19 +16,15 @@
*/
/**
- * @file NRF51x22/ext_lld_isr.h
- * @brief NRF51x22 EXT subsystem low level driver ISR code.
+ * @file NRF51822/nrf51_isr.c
+ * @brief NRF51822 ISR handler code.
*
- * @addtogroup EXT
+ * @addtogroup NRF51822_ISR
* @{
*/
#include "hal.h"
-#if HAL_USE_EXT || defined(__DOXYGEN__)
-
-#include "hal_ext_lld_isr.h"
-
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
@@ -49,33 +46,21 @@
/*===========================================================================*/
/**
- * @brief EXTI[0]...EXTI[1] interrupt handler.
+ * @brief GPIOTE interrupt handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(Vector58) {
OSAL_IRQ_PROLOGUE();
-
- if (NRF_GPIOTE->EVENTS_IN[0])
+
+ for (int ch = 0; ch < NRF5_GPIOTE_NUM_CHANNELS; ch++)
{
- NRF_GPIOTE->EVENTS_IN[0] = 0;
- EXTD1.config->channels[0].cb(&EXTD1, 0);
- }
- if (NRF_GPIOTE->EVENTS_IN[1])
- {
- NRF_GPIOTE->EVENTS_IN[1] = 0;
- EXTD1.config->channels[1].cb(&EXTD1, 1);
- }
- if (NRF_GPIOTE->EVENTS_IN[2])
- {
- NRF_GPIOTE->EVENTS_IN[2] = 0;
- EXTD1.config->channels[2].cb(&EXTD1, 2);
- }
- if (NRF_GPIOTE->EVENTS_IN[3])
- {
- NRF_GPIOTE->EVENTS_IN[3] = 0;
- EXTD1.config->channels[3].cb(&EXTD1, 3);
+ if (NRF_GPIOTE->EVENTS_IN[ch])
+ {
+ NRF_GPIOTE->EVENTS_IN[ch] = 0;
+ _pal_isr_code(ch);
+ }
}
OSAL_IRQ_EPILOGUE();
@@ -84,27 +69,28 @@ OSAL_IRQ_HANDLER(Vector58) {
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
-
/**
- * @brief Enables EXTI IRQ sources.
+ * @brief Enables IRQ sources.
*
* @notapi
*/
-void ext_lld_exti_irq_enable(void) {
+void irqInit(void) {
- nvicEnableVector(GPIOTE_IRQn, NRF5_EXT_GPIOTE_IRQ_PRIORITY);
+#if HAL_USE_PAL
+ nvicEnableVector(GPIOTE_IRQn, NRF5_IRQ_GPIOTE_PRIORITY);
+#endif
}
/**
- * @brief Disables EXTI IRQ sources.
+ * @brief Disables IRQ sources.
*
* @notapi
*/
-void ext_lld_exti_irq_disable(void) {
+void irqDeinit(void) {
+#if HAL_USE_PAL
nvicDisableVector(GPIOTE_IRQn);
+#endif
}
-#endif /* HAL_USE_EXT */
-
/** @} */
diff --git a/os/hal/ports/NRF5/NRF51822/nrf51_isr.h b/os/hal/ports/NRF5/NRF51822/nrf51_isr.h
new file mode 100644
index 0000000..832d2c3
--- /dev/null
+++ b/os/hal/ports/NRF5/NRF51822/nrf51_isr.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (C) 2018 Konstantin Oblaukhov
+ Copyright (C) 2015 Stephen Caudle
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file NRF51822/nrf51_isr.h
+ * @brief NRF51822 ISR handler header.
+ *
+ * @addtogroup NRF51822_ISR
+ * @{
+ */
+
+#ifndef NRF51_ISR_H
+#define NRF51_ISR_H
+
+#if !defined(NRF5_IRQ_GPIOTE_PRIORITY) || defined(__DOXYGEN__)
+#define NRF5_IRQ_GPIOTE_PRIORITY 3
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void irqInit(void);
+ void irqDeinit(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF51_ISR_H */
+
+/** @} */
diff --git a/os/hal/ports/NRF5/NRF51822/platform.mk b/os/hal/ports/NRF5/NRF51822/platform.mk
index 7305acf..711a625 100644
--- a/os/hal/ports/NRF5/NRF51822/platform.mk
+++ b/os/hal/ports/NRF5/NRF51822/platform.mk
@@ -1,66 +1,34 @@
+PLATFORMSRC_CONTRIB := ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822/hal_lld.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822/nrf51_isr.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/TIMERv1/hal_st_lld.c
+
+PLATFORMINC_CONTRIB := ${CHIBIOS}/os/hal/ports/common/ARMCMx \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822
+
ifeq ($(USE_SMART_BUILD),yes)
-HALCONF := $(strip $(shell cat halconf.h halconf_community.h 2>/dev/null | egrep -e "define"))
-# List of all the NRF51x platform files.
-PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822/hal_lld.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_st_lld.c
-
-ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
-PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_pal_lld.c
-endif
-ifneq ($(findstring HAL_USE_SERIAL TRUE,$(HALCONF)),)
-PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_serial_lld.c
-endif
-ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),)
-PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_spi_lld.c
-endif
-ifneq ($(findstring HAL_USE_EXT TRUE,$(HALCONF)),)
-PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822/hal_ext_lld_isr.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822/hal_ext_lld.c
-endif
-ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
-PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_i2c_lld.c
-endif
-ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
-PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822/hal_adc_lld.c
-endif
-ifneq ($(findstring HAL_USE_GPT TRUE,$(HALCONF)),)
-PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_gpt_lld.c
-endif
-ifneq ($(findstring HAL_USE_WDG TRUE,$(HALCONF)),)
-PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_wdg_lld.c
-endif
-ifneq ($(findstring HAL_USE_RNG TRUE,$(HALCONF)),)
-PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_rng_lld.c
-endif
-ifneq ($(findstring HAL_USE_PWM TRUE,$(HALCONF)),)
-PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822/hal_pwm_lld.c
-endif
-ifneq ($(findstring HAL_USE_QEI TRUE,$(HALCONF)),)
-PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_qei_lld.c
-endif
-else
-PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822/hal_lld.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_pal_lld.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_serial_lld.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_st_lld.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_spi_lld.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822/hal_ext_lld_isr.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822/hal_ext_lld.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_i2c_lld.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822/hal_adc_lld.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_gpt_lld.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_wdg_lld.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_rng_lld.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822/hal_pwm_lld.c \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/hal_qei_lld.c
+# Configuration files directory
+ifeq ($(CONFDIR),)
+ CONFDIR = .
endif
-# Required include directories
-PLATFORMINC = ${CHIBIOS}/os/hal/ports/common/ARMCMx \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD \
- ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/NRF51822
+HALCONF := $(strip $(shell cat $(CONFDIR)/halconf.h $(CONFDIR)/halconf_community.h | egrep -e "\#define"))
+
+endif
+include ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/GPIOv1/driver.mk
+include ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/UARTv1/driver.mk
+include ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/SPIv1/driver.mk
+include ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/TWIv1/driver.mk
+include ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/ADCv1/driver.mk
+include ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/TIMERv1/driver.mk
+include ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/WDTv1/driver.mk
+include ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/RNGv1/driver.mk
+include ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/PWMv1/driver.mk
+include ${CHIBIOS_CONTRIB}/os/hal/ports/NRF5/LLD/QDECv1/driver.mk
+# Shared variables
+ALLCSRC += $(PLATFORMSRC_CONTRIB)
+ALLINC += $(PLATFORMINC_CONTRIB)