main.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. /**
  2. * Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. /** @file
  41. * @defgroup pwm_example_main main.c
  42. * @{
  43. * @ingroup pwm_example
  44. *
  45. * @brief PWM Example Application main file.
  46. *
  47. * This file contains the source code for a sample application using PWM.
  48. */
  49. #include <stdio.h>
  50. #include <string.h>
  51. #include "nrf_drv_pwm.h"
  52. #include "app_util_platform.h"
  53. #include "app_error.h"
  54. #include "boards.h"
  55. #include "bsp.h"
  56. #include "app_timer.h"
  57. #include "nrf_drv_clock.h"
  58. #include "nrf_log.h"
  59. #include "nrf_log_ctrl.h"
  60. #include "nrf_log_default_backends.h"
  61. static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0);
  62. static nrf_drv_pwm_t m_pwm1 = NRF_DRV_PWM_INSTANCE(1);
  63. static nrf_drv_pwm_t m_pwm2 = NRF_DRV_PWM_INSTANCE(2);
  64. // This is for tracking PWM instances being used, so we can unintialize only
  65. // the relevant ones when switching from one demo to another.
  66. #define USED_PWM(idx) (1UL << idx)
  67. static uint8_t m_used = 0;
  68. static uint16_t const m_demo1_top = 10000;
  69. static uint16_t const m_demo1_step = 200;
  70. static uint8_t m_demo1_phase;
  71. static nrf_pwm_values_individual_t m_demo1_seq_values;
  72. static nrf_pwm_sequence_t const m_demo1_seq =
  73. {
  74. .values.p_individual = &m_demo1_seq_values,
  75. .length = NRF_PWM_VALUES_LENGTH(m_demo1_seq_values),
  76. .repeats = 0,
  77. .end_delay = 0
  78. };
  79. static void demo1_handler(nrf_drv_pwm_evt_type_t event_type)
  80. {
  81. if (event_type == NRF_DRV_PWM_EVT_FINISHED)
  82. {
  83. uint8_t channel = m_demo1_phase >> 1;
  84. bool down = m_demo1_phase & 1;
  85. bool next_phase = false;
  86. uint16_t * p_channels = (uint16_t *)&m_demo1_seq_values;
  87. uint16_t value = p_channels[channel];
  88. if (down)
  89. {
  90. value -= m_demo1_step;
  91. if (value == 0)
  92. {
  93. next_phase = true;
  94. }
  95. }
  96. else
  97. {
  98. value += m_demo1_step;
  99. if (value >= m_demo1_top)
  100. {
  101. next_phase = true;
  102. }
  103. }
  104. p_channels[channel] = value;
  105. if (next_phase)
  106. {
  107. if (++m_demo1_phase >= 2 * NRF_PWM_CHANNEL_COUNT)
  108. {
  109. m_demo1_phase = 0;
  110. }
  111. }
  112. }
  113. }
  114. static void demo1(void)
  115. {
  116. NRF_LOG_INFO("Demo 1");
  117. /*
  118. * This demo plays back a sequence with different values for individual
  119. * channels (LED 1 - LED 4). Only four values are used (one per channel).
  120. * Every time the values are loaded into the compare registers, they are
  121. * updated in the provided event handler. The values are updated in such
  122. * a way that increase and decrease of the light intensity can be observed
  123. * continuously on succeeding channels (one second per channel).
  124. */
  125. nrf_drv_pwm_config_t const config0 =
  126. {
  127. .output_pins =
  128. {
  129. BSP_LED_0 | NRF_DRV_PWM_PIN_INVERTED, // channel 0
  130. BSP_LED_1 | NRF_DRV_PWM_PIN_INVERTED, // channel 1
  131. BSP_LED_3 | NRF_DRV_PWM_PIN_INVERTED, // channel 2
  132. BSP_LED_2 | NRF_DRV_PWM_PIN_INVERTED // channel 3
  133. },
  134. .irq_priority = APP_IRQ_PRIORITY_LOWEST,
  135. .base_clock = NRF_PWM_CLK_1MHz,
  136. .count_mode = NRF_PWM_MODE_UP,
  137. .top_value = m_demo1_top,
  138. .load_mode = NRF_PWM_LOAD_INDIVIDUAL,
  139. .step_mode = NRF_PWM_STEP_AUTO
  140. };
  141. APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, demo1_handler));
  142. m_used |= USED_PWM(0);
  143. m_demo1_seq_values.channel_0 = 0;
  144. m_demo1_seq_values.channel_1 = 0;
  145. m_demo1_seq_values.channel_2 = 0;
  146. m_demo1_seq_values.channel_3 = 0;
  147. m_demo1_phase = 0;
  148. (void)nrf_drv_pwm_simple_playback(&m_pwm0, &m_demo1_seq, 1,
  149. NRF_DRV_PWM_FLAG_LOOP);
  150. }
  151. static void demo2(void)
  152. {
  153. NRF_LOG_INFO("Demo 2");
  154. /*
  155. * This demo plays back two concatenated sequences:
  156. * - Sequence 0: Light intensity is increased in 25 steps during one second.
  157. * - Sequence 1: LED blinks twice (100 ms off, 100 ms on), then stays off
  158. * for 200 ms.
  159. * The same output is generated on all 4 channels (LED 1 - LED 4).
  160. * The playback is repeated in a loop.
  161. */
  162. enum { // [local constants]
  163. TOP = 10000,
  164. STEP_COUNT = 25
  165. };
  166. nrf_drv_pwm_config_t const config0 =
  167. {
  168. .output_pins =
  169. {
  170. BSP_LED_0 | NRF_DRV_PWM_PIN_INVERTED, // channel 0
  171. BSP_LED_1 | NRF_DRV_PWM_PIN_INVERTED, // channel 1
  172. BSP_LED_2 | NRF_DRV_PWM_PIN_INVERTED, // channel 2
  173. BSP_LED_3 | NRF_DRV_PWM_PIN_INVERTED // channel 3
  174. },
  175. .irq_priority = APP_IRQ_PRIORITY_LOWEST,
  176. .base_clock = NRF_PWM_CLK_500kHz,
  177. .count_mode = NRF_PWM_MODE_UP,
  178. .top_value = TOP,
  179. .load_mode = NRF_PWM_LOAD_COMMON,
  180. .step_mode = NRF_PWM_STEP_AUTO
  181. };
  182. APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL));
  183. m_used |= USED_PWM(0);
  184. // This array cannot be allocated on stack (hence "static") and it must
  185. // be in RAM.
  186. static nrf_pwm_values_common_t seq0_values[STEP_COUNT];
  187. uint16_t value = 0;
  188. uint16_t step = TOP / STEP_COUNT;
  189. uint8_t i;
  190. for (i = 0; i < STEP_COUNT; ++i)
  191. {
  192. value += step;
  193. seq0_values[i] = value;
  194. }
  195. nrf_pwm_sequence_t const seq0 =
  196. {
  197. .values.p_common = seq0_values,
  198. .length = NRF_PWM_VALUES_LENGTH(seq0_values),
  199. .repeats = 1,
  200. .end_delay = 0
  201. };
  202. // This array cannot be allocated on stack (hence "static") and it must
  203. // be in RAM (hence no "const", though its content is not changed).
  204. static nrf_pwm_values_common_t /*const*/ seq1_values[] =
  205. {
  206. 0,
  207. 0x8000,
  208. 0,
  209. 0x8000,
  210. 0,
  211. 0
  212. };
  213. nrf_pwm_sequence_t const seq1 =
  214. {
  215. .values.p_common = seq1_values,
  216. .length = NRF_PWM_VALUES_LENGTH(seq1_values),
  217. .repeats = 4,
  218. .end_delay = 0
  219. };
  220. (void)nrf_drv_pwm_complex_playback(&m_pwm0, &seq0, &seq1, 1,
  221. NRF_DRV_PWM_FLAG_LOOP);
  222. }
  223. static void demo3(void)
  224. {
  225. NRF_LOG_INFO("Demo 3");
  226. /*
  227. * This demo uses only one channel, which is reflected on LED 1.
  228. * The LED blinks three times (200 ms on, 200 ms off), then it stays off
  229. * for one second.
  230. * This scheme is performed three times before the peripheral is stopped.
  231. */
  232. nrf_drv_pwm_config_t const config0 =
  233. {
  234. .output_pins =
  235. {
  236. BSP_LED_0 | NRF_DRV_PWM_PIN_INVERTED, // channel 0
  237. NRF_DRV_PWM_PIN_NOT_USED, // channel 1
  238. NRF_DRV_PWM_PIN_NOT_USED, // channel 2
  239. NRF_DRV_PWM_PIN_NOT_USED, // channel 3
  240. },
  241. .irq_priority = APP_IRQ_PRIORITY_LOWEST,
  242. .base_clock = NRF_PWM_CLK_125kHz,
  243. .count_mode = NRF_PWM_MODE_UP,
  244. .top_value = 25000,
  245. .load_mode = NRF_PWM_LOAD_COMMON,
  246. .step_mode = NRF_PWM_STEP_AUTO
  247. };
  248. APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL));
  249. m_used |= USED_PWM(0);
  250. // This array cannot be allocated on stack (hence "static") and it must
  251. // be in RAM (hence no "const", though its content is not changed).
  252. static uint16_t /*const*/ seq_values[] =
  253. {
  254. 0x8000,
  255. 0,
  256. 0x8000,
  257. 0,
  258. 0x8000,
  259. 0
  260. };
  261. nrf_pwm_sequence_t const seq =
  262. {
  263. .values.p_common = seq_values,
  264. .length = NRF_PWM_VALUES_LENGTH(seq_values),
  265. .repeats = 0,
  266. .end_delay = 4
  267. };
  268. (void)nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 3, NRF_DRV_PWM_FLAG_STOP);
  269. }
  270. static void demo4(void)
  271. {
  272. NRF_LOG_INFO("Demo 4");
  273. /*
  274. * This demo uses all three PWM peripheral instances:
  275. * - PWM0 drives LED 1 and LED 2: Subsequent 2-bit binary values are
  276. * presented every 500 ms.
  277. * - PWM1 drives LED 3: During 500 ms, the LED increases and decreases
  278. * the light intensity, then it stays off for 1500 ms.
  279. * - PWM2 drives LED 4: For 500 ms, the LED stays off, then during 1500 ms
  280. * it increases and decreases the light intensity.
  281. * Simple playback with grouped loading mode is used for PWM0, and complex
  282. * playback with common loading mode is used for both PWM1 and PWM2.
  283. */
  284. nrf_drv_pwm_config_t config =
  285. {
  286. // These are the common configuration options we use for all PWM
  287. // instances.
  288. .irq_priority = APP_IRQ_PRIORITY_LOWEST,
  289. .count_mode = NRF_PWM_MODE_UP,
  290. .step_mode = NRF_PWM_STEP_AUTO,
  291. };
  292. ////////////////////////////////////////////////////////////////////////////
  293. // PWM0 initialization.
  294. config.output_pins[0] = BSP_LED_0 | NRF_DRV_PWM_PIN_INVERTED;
  295. config.output_pins[1] = NRF_DRV_PWM_PIN_NOT_USED;
  296. config.output_pins[2] = BSP_LED_1 | NRF_DRV_PWM_PIN_INVERTED;
  297. config.output_pins[3] = NRF_DRV_PWM_PIN_NOT_USED;
  298. config.base_clock = NRF_PWM_CLK_125kHz;
  299. config.top_value = 31250; // 250ms period
  300. config.load_mode = NRF_PWM_LOAD_GROUPED;
  301. APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config, NULL));
  302. m_used |= USED_PWM(0);
  303. // This array cannot be allocated on stack (hence "static") and it must
  304. // be in RAM (hence no "const", though its content is not changed).
  305. static nrf_pwm_values_grouped_t /*const*/ pwm0_seq_values[] =
  306. {
  307. { 0, 0 },
  308. { 0x8000, 0 },
  309. { 0, 0x8000 },
  310. { 0x8000, 0x8000 }
  311. };
  312. nrf_pwm_sequence_t const pwm0_seq =
  313. {
  314. .values.p_grouped = pwm0_seq_values,
  315. .length = NRF_PWM_VALUES_LENGTH(pwm0_seq_values),
  316. .repeats = 1,
  317. .end_delay = 0
  318. };
  319. ////////////////////////////////////////////////////////////////////////////
  320. // Common settings for PWM1 and PWM2.
  321. enum { // [local constants]
  322. TOP = 5000,
  323. STEP_COUNT = 50
  324. };
  325. config.base_clock = NRF_PWM_CLK_1MHz;
  326. config.top_value = TOP;
  327. config.load_mode = NRF_PWM_LOAD_COMMON;
  328. // This array cannot be allocated on stack (hence "static") and it must
  329. // be in RAM.
  330. static nrf_pwm_values_common_t fade_in_out_values[2 * STEP_COUNT];
  331. uint16_t value = 0;
  332. uint16_t step = TOP / STEP_COUNT;
  333. uint8_t i;
  334. for (i = 0; i < STEP_COUNT; ++i)
  335. {
  336. value += step;
  337. fade_in_out_values[i] = value;
  338. fade_in_out_values[STEP_COUNT + i] = TOP - value;
  339. }
  340. // This array cannot be allocated on stack (hence "static") and it must
  341. // be in RAM (hence no "const", though its content is not changed).
  342. static nrf_pwm_values_common_t /*const*/ stay_off_values[2] = { 0, 0 };
  343. ////////////////////////////////////////////////////////////////////////////
  344. // PWM1 initialization.
  345. config.output_pins[0] = NRF_DRV_PWM_PIN_NOT_USED;
  346. config.output_pins[1] = NRF_DRV_PWM_PIN_NOT_USED;
  347. config.output_pins[2] = BSP_LED_2 | NRF_DRV_PWM_PIN_INVERTED;
  348. config.output_pins[3] = NRF_DRV_PWM_PIN_NOT_USED;
  349. APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm1, &config, NULL));
  350. m_used |= USED_PWM(1);
  351. // Sequence 0 - fade-in/fade-out, duration: 500 ms.
  352. nrf_pwm_sequence_t const pwm1_seq0 =
  353. {
  354. .values.p_common = fade_in_out_values,
  355. .length = NRF_PWM_VALUES_LENGTH(fade_in_out_values),
  356. .repeats = 0,
  357. .end_delay = 0
  358. };
  359. // Sequence 1 - off, duration: 1500 ms.
  360. nrf_pwm_sequence_t const pwm1_seq1 =
  361. {
  362. .values.p_common = stay_off_values,
  363. .length = 2,
  364. .repeats = 149,
  365. .end_delay = 0
  366. };
  367. ////////////////////////////////////////////////////////////////////////////
  368. // PWM2 initialization.
  369. config.output_pins[0] = NRF_DRV_PWM_PIN_NOT_USED;
  370. config.output_pins[1] = NRF_DRV_PWM_PIN_NOT_USED;
  371. config.output_pins[2] = NRF_DRV_PWM_PIN_NOT_USED;
  372. config.output_pins[3] = BSP_LED_3 | NRF_DRV_PWM_PIN_INVERTED;
  373. APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm2, &config, NULL));
  374. m_used |= USED_PWM(2);
  375. // Sequence 0 - fade-in/fade-out, duration: 1500 ms.
  376. nrf_pwm_sequence_t const pwm2_seq0 =
  377. {
  378. .values.p_common = stay_off_values,
  379. .length = 2,
  380. .repeats = 49,
  381. .end_delay = 0
  382. };
  383. // Sequence 1 - off, duration: 500 ms.
  384. nrf_pwm_sequence_t const pwm2_seq1 =
  385. {
  386. .values.p_common = fade_in_out_values,
  387. .length = NRF_PWM_VALUES_LENGTH(fade_in_out_values),
  388. .repeats = 2,
  389. .end_delay = 0
  390. };
  391. (void)nrf_drv_pwm_simple_playback(&m_pwm0, &pwm0_seq, 1,
  392. NRF_DRV_PWM_FLAG_LOOP);
  393. (void)nrf_drv_pwm_complex_playback(&m_pwm1, &pwm1_seq0, &pwm1_seq1, 1,
  394. NRF_DRV_PWM_FLAG_LOOP);
  395. (void)nrf_drv_pwm_complex_playback(&m_pwm2, &pwm2_seq0, &pwm2_seq1, 1,
  396. NRF_DRV_PWM_FLAG_LOOP);
  397. }
  398. static void demo5(void)
  399. {
  400. NRF_LOG_INFO("Demo 5");
  401. /*
  402. * This demo, similarly to demo1, plays back a sequence with different
  403. * values for individual channels. Unlike demo 1, however, it does not use
  404. * an event handler. Therefore, the PWM peripheral does not use interrupts
  405. * and the CPU can stay in sleep mode.
  406. * The LEDs (1-4) blink separately. They are turned on for 125 ms each,
  407. * in counterclockwise order (looking at the board).
  408. */
  409. nrf_drv_pwm_config_t const config0 =
  410. {
  411. .output_pins =
  412. {
  413. BSP_LED_0 | NRF_DRV_PWM_PIN_INVERTED, // channel 0
  414. BSP_LED_2 | NRF_DRV_PWM_PIN_INVERTED, // channel 1
  415. BSP_LED_3 | NRF_DRV_PWM_PIN_INVERTED, // channel 2
  416. BSP_LED_1 | NRF_DRV_PWM_PIN_INVERTED // channel 3
  417. },
  418. .irq_priority = APP_IRQ_PRIORITY_LOWEST,
  419. .base_clock = NRF_PWM_CLK_125kHz,
  420. .count_mode = NRF_PWM_MODE_UP,
  421. .top_value = 15625,
  422. .load_mode = NRF_PWM_LOAD_INDIVIDUAL,
  423. .step_mode = NRF_PWM_STEP_AUTO
  424. };
  425. APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL));
  426. m_used |= USED_PWM(0);
  427. // This array cannot be allocated on stack (hence "static") and it must
  428. // be in RAM (hence no "const", though its content is not changed).
  429. static nrf_pwm_values_individual_t /*const*/ seq_values[] =
  430. {
  431. { 0x8000, 0, 0, 0 },
  432. { 0, 0x8000, 0, 0 },
  433. { 0, 0, 0x8000, 0 },
  434. { 0, 0, 0, 0x8000 }
  435. };
  436. nrf_pwm_sequence_t const seq =
  437. {
  438. .values.p_individual = seq_values,
  439. .length = NRF_PWM_VALUES_LENGTH(seq_values),
  440. .repeats = 0,
  441. .end_delay = 0
  442. };
  443. (void)nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 1, NRF_DRV_PWM_FLAG_LOOP);
  444. }
  445. static void bsp_evt_handler(bsp_event_t evt)
  446. {
  447. void (* const demos[])(void) =
  448. {
  449. demo1,
  450. demo2,
  451. demo3,
  452. demo4,
  453. demo5
  454. };
  455. uint8_t const demo_idx_max = (sizeof(demos) / sizeof(demos[0])) - 1;
  456. static uint8_t demo_idx = 0;
  457. switch (evt)
  458. {
  459. // Button 1 - switch to the previous demo.
  460. case BSP_EVENT_KEY_0:
  461. if (demo_idx > 0)
  462. {
  463. --demo_idx;
  464. }
  465. else
  466. {
  467. demo_idx = demo_idx_max;
  468. }
  469. break;
  470. // Button 2 - switch to the next demo.
  471. case BSP_EVENT_KEY_1:
  472. if (demo_idx < demo_idx_max)
  473. {
  474. ++demo_idx;
  475. }
  476. else
  477. {
  478. demo_idx = 0;
  479. }
  480. break;
  481. default:
  482. return;
  483. }
  484. if (m_used & USED_PWM(0))
  485. {
  486. nrf_drv_pwm_uninit(&m_pwm0);
  487. }
  488. if (m_used & USED_PWM(1))
  489. {
  490. nrf_drv_pwm_uninit(&m_pwm1);
  491. }
  492. if (m_used & USED_PWM(2))
  493. {
  494. nrf_drv_pwm_uninit(&m_pwm2);
  495. }
  496. m_used = 0;
  497. demos[demo_idx]();
  498. }
  499. static void init_bsp()
  500. {
  501. APP_ERROR_CHECK(nrf_drv_clock_init());
  502. nrf_drv_clock_lfclk_request(NULL);
  503. APP_ERROR_CHECK(app_timer_init());
  504. APP_ERROR_CHECK(bsp_init(BSP_INIT_BUTTONS, bsp_evt_handler));
  505. APP_ERROR_CHECK(bsp_buttons_enable());
  506. }
  507. void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
  508. {
  509. bsp_board_leds_on();
  510. app_error_save_and_stop(id, pc, info);
  511. }
  512. int main(void)
  513. {
  514. APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
  515. NRF_LOG_DEFAULT_BACKENDS_INIT();
  516. init_bsp();
  517. NRF_LOG_INFO("PWM example started.");
  518. // Start with Demo 1, then switch to another one when the user presses
  519. // button 1 or button 2 (see the 'bsp_evt_handler' function).
  520. demo1();
  521. for (;;)
  522. {
  523. // Wait for an event.
  524. __WFE();
  525. // Clear the event register.
  526. __SEV();
  527. __WFE();
  528. NRF_LOG_FLUSH();
  529. }
  530. }
  531. /** @} */