Nordic Semiconductor nRF5 AirFuel SDK  version 2.2.0
common_hal_buttons.c
Go to the documentation of this file.
1 /* Copyright (c) Nordic Semiconductor. All Rights Reserved.
2  *
3  * The information contained herein is property of Nordic Semiconductor ASA.
4  * Terms and conditions of usage are described in detail in NORDIC
5  * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
6  *
7  * Licensees are granted free, non-transferable use of the information. NO
8  * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
9  * the file.
10  *
11  */
12 
18 #ifdef DFU_SUPPORT
19 
20 #include <stdbool.h>
21 #include <stdint.h>
22 #include "nrf_gpio.h"
23 #include "nrf_error.h"
24 #include "nrf_soc.h"
25 #include "nrf_gpiote.h"
26 #include "common_hal_buttons.h"
27 #include "app_timer.h"
28 #include "app_util_platform.h"
29 #include "wpt.h"
30 
31 #define GPIOTE_CHANNEL_NUMBER_BUTTON_PRESS 0
32 #define GPIOTE_CHANNEL_NUMBER_BUTTON_RELEASE 1
33 #define DFU_BUTTON_PIN 17
34 #define GPIOTE_IRQ_INTENCLR_ALL_VAL 0xffffffff
35 #define GPIOTE_IRQ_ENABLE_VAL 3
37 static uint32_t m_button_press_duration_ms;
38 static uint8_t m_app_timer_prescaler;
40 void common_hal_buttons_init(uint32_t button_press_duration_ms, uint8_t app_timer_prescaler)
41 {
42  m_button_press_duration_ms = button_press_duration_ms;
43  m_app_timer_prescaler = app_timer_prescaler;
44  nrf_gpio_cfg_input(DFU_BUTTON_PIN, NRF_GPIO_PIN_PULLUP);
45  nrf_gpiote_event_configure(GPIOTE_CHANNEL_NUMBER_BUTTON_PRESS, DFU_BUTTON_PIN, NRF_GPIOTE_POLARITY_HITOLO);
46  nrf_gpiote_event_configure(GPIOTE_CHANNEL_NUMBER_BUTTON_RELEASE, DFU_BUTTON_PIN, NRF_GPIOTE_POLARITY_LOTOHI);
47 
48  NRF_GPIOTE->INTENCLR = GPIOTE_IRQ_INTENCLR_ALL_VAL;
49  NRF_GPIOTE->INTENSET = GPIOTE_IRQ_ENABLE_VAL;
50  NVIC_ClearPendingIRQ(GPIOTE_IRQn);
51  NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_LOW);
52  NVIC_EnableIRQ(GPIOTE_IRQn);
53 }
54 
58 {
59  static uint32_t ticks_at_button_release, ticks_at_button_press;
60  uint32_t diff, err_code;
61 
62  if(NRF_GPIOTE->EVENTS_IN[GPIOTE_CHANNEL_NUMBER_BUTTON_PRESS] == 1)
63  {
64  // Button has been pressed down
65  err_code = app_timer_cnt_get(&ticks_at_button_press);
66  APP_ERROR_CHECK(err_code);
67 
68  NRF_GPIOTE->EVENTS_IN[GPIOTE_CHANNEL_NUMBER_BUTTON_PRESS] = 0;
69  }
70 
71  else if(NRF_GPIOTE->EVENTS_IN[GPIOTE_CHANNEL_NUMBER_BUTTON_RELEASE] == 1)
72  {
73  // Button has been released
74  err_code = app_timer_cnt_get(&ticks_at_button_release);
75  APP_ERROR_CHECK(err_code);
76 
77  diff = ticks_diff(ticks_at_button_release, ticks_at_button_press);
78 
79  // If enough time has passed, start bootloader in DFU mode
80  if(diff > APP_TIMER_TICKS(m_button_press_duration_ms, m_app_timer_prescaler))
81  {
82  if(dfu_check())
83  {
84  terminate();
85  dfu_start();
86  }
87  }
88 
89  NRF_GPIOTE->EVENTS_IN[GPIOTE_CHANNEL_NUMBER_BUTTON_RELEASE] = 0;
90  }
91 }
92 
93 #endif // DFU_SUPPORT
uint32_t ticks_diff(uint32_t ticks_now, uint32_t ticks_old)
Definition: common.c:78
#define GPIOTE_CHANNEL_NUMBER_BUTTON_PRESS
#define GPIOTE_IRQ_INTENCLR_ALL_VAL
#define GPIOTE_IRQ_ENABLE_VAL
void GPIOTE_IRQHandler(void)
Handler for GPIOTE interrupts.
#define DFU_BUTTON_PIN
bool dfu_check(void)
Needs to be implemented by application. Check if it is OK to jump to the DFU application.
Definition: pru.c:523
#define GPIOTE_CHANNEL_NUMBER_BUTTON_RELEASE
static uint8_t m_app_timer_prescaler
static uint32_t m_button_press_duration_ms
void dfu_start(void)
Starts DFU mode. The function writes a special value to retention register to tell bootloader to star...
Definition: common.c:93
void terminate(void)
Needs to be implemented by application. Perform all requried actions before jump to DFU application c...
Definition: pru.c:518