SEGGER + nRF52840 で Lチカ

SEGGER Embedded Studio を使って Nordic の Bluetooth の使える SOC である nRF52840 のLチカ（LEDの点滅プログラム） をします。

# 環境

- SEGGER Embedded Studio
- 開発ボード Raytac MDBT50Q-DB (nRF52840搭載)

MDBT50Q-DB は、台湾 Raitac 社の開発ボード。

今回の実験では、Nordicの公式の開発ボードである nRF52840 Development Kit(PCA10056) と論理的に同じものとして扱うことができます。

# 最初のプロジェクトを作る前の準備

「nRF52840 を Segger Embedded Studio 開発環境で First Try」
https://qiita.com/nanbuwks/items/dd20dc4619af1d994f2c

を見て、設定をしていきます。



# blinky

SDK 中の examples/peripheral/blinky

を使います。先の記事で、examplesはmyProjectsにコピーしていますので、
SDK 中の myProjects/peripheral/blinky/pca10056/mbr/ses
にある
「blinky_pca10056_mbr.emProject」
をダブルクリックしてSEGGERを起動します。


プロジェクトのプログラムは以下のようになっています（コード部のみ抜粋）。

```

#include <stdbool.h>
#include <stdint.h>
#include "nrf_delay.h"
#include "boards.h"
int main(void)
{
    bsp_board_init(BSP_INIT_LEDS);
    while (true)
    {
        for (int i = 0; i < LEDS_NUMBER; i++)
        {
            bsp_board_led_invert(i);
            nrf_delay_ms(500);
        }
    }
}
```
 bsp_board_init や bsp_board_led_invert は
「components/boards/boards.c 」
で定義されています。

```
static const uint8_t m_board_led_list[LEDS_NUMBER] = LEDS_LIST;

・・・

void bsp_board_led_invert(uint32_t led_idx)
{
    ASSERT(led_idx < LEDS_NUMBER);
    nrf_gpio_pin_toggle(m_board_led_list[led_idx]);
}

・・・

void bsp_board_init(uint32_t init_flags)
{
    #if defined(BOARDS_WITH_USB_DFU_TRIGGER) && defined(BOARD_PCA10059)
    (void) nrf_dfu_trigger_usb_init();
    #endif

    #if LEDS_NUMBER > 0
    if (init_flags & BSP_INIT_LEDS)
    {
        bsp_board_leds_init();
    }
    #endif //LEDS_NUMBER > 0

    #if BUTTONS_NUMBER > 0
    if (init_flags & BSP_INIT_BUTTONS)
    {
        bsp_board_buttons_init();
    }
    #endif //BUTTONS_NUMBER > 0
}
```
LEDS_NUMBERや、LEDS_LISTなどはSDK 中の
「components/boards/pca10056.h」
で定義されています。

```

#define LEDS_NUMBER    4

#define LED_1          NRF_GPIO_PIN_MAP(0,13)
#define LED_2          NRF_GPIO_PIN_MAP(0,14)
#define LED_3          NRF_GPIO_PIN_MAP(0,15)
#define LED_4          NRF_GPIO_PIN_MAP(0,16)
#define LED_START      LED_1
#define LED_STOP       LED_4

#define LEDS_ACTIVE_STATE 0

#define LEDS_LIST { LED_1, LED_2, LED_3, LED_4 }

#define LEDS_INV_MASK  LEDS_MASK

#define BSP_LED_0      13
#define BSP_LED_1      14
#define BSP_LED_2      15
#define BSP_LED_3      16
```

NRF_GPIO_PIN_MAP は、SDK中の
「modules/nrfx/hal/nrf_gpio.h」
で

```

#define NRF_GPIO_PIN_MAP(port, pin) (((port) << 5) | ((pin) & 0x1F))
```

のようになっています。

従って、
0.13
0.14
0.15
0.16
ポートにあるLEDが点灯／消灯することになります。

# 各ボードのLED割当

## nRF52840 Development Kit(PCA10056)
- LED 1 P0.13 Green (Active Low)
- LED 2 P0.14 Green (Active Low)
- LED 3 P0.15 Green (Active Low)
- LED 4 P0.16 Green (Active Low)

## MDBT50Q-DK

- LED 1 P0.13 Green (Active Low)
- LED 2 P0.14 Red (Active Low)
- LED 3 P0.15 Blue (Active Low)
- LED 4 P0.16 (実装せず)

## AONODON 20181113

- Red LED P1.09 (Active High)
- Green LED P0.10 (Active High)
- Blue LED P0.11 (Active High)


# AONODON でLチカ

AONODON 20181113のために、

「components/boards/pca10056.h」
を以下のように書き換えて、

- Red LED P1.09
- Green LED P0.10
- Blue LED P0.11

が点滅するかどうか調べてみます。

```

// LEDs definitions for AONODON20181113
#define LEDS_NUMBER    3

#define LED_1          NRF_GPIO_PIN_MAP(0,9)
#define LED_2          NRF_GPIO_PIN_MAP(0,10)
#define LED_3          NRF_GPIO_PIN_MAP(0,11)
#define LED_START      LED_1
#define LED_STOP       LED_3

#define LEDS_ACTIVE_STATE 0

#define LEDS_LIST { LED_1, LED_2, LED_3 }

#define LEDS_INV_MASK  LEDS_MASK

#define BSP_LED_0      9
#define BSP_LED_1      10
#define BSP_LED_2      11
```

さて、これで Build & Run してみましたが、BlueLED( GPIO 0.11 ) しか点滅しません。はて？

# GPIOを直接操作

GPIOを直接High/Lowとするには、

 nrf_gpio_cfg_output(NRF_GPIO_PIN_MAP(0,9));

でアウトプットモードにし、

 nrf_gpio_pin_write(NRF_GPIO_PIN_MAP(0,9),1);

で出力します。

ちなみに、nrf_gpio_pin_writeについては
「modules/nrfx/hal/nrf_gpio.h」
で以下のように定義されています。

```
__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value)
{
    if (value == 0)
    {
        nrf_gpio_pin_clear(pin_number);
    }
    else
    {
        nrf_gpio_pin_set(pin_number);
    }
}
```

ということで、blinkyをコピーして、gpio_ledというプロジェクトを作りました。

```

#include <stdbool.h>
#include <stdint.h>
#include "nrf_delay.h"
#include "boards.h"

int main(void)
{ 
    int counter=0;
    nrf_gpio_cfg_output(NRF_GPIO_PIN_MAP(0,11));
    while (true)
    {
            nrf_gpio_pin_write(NRF_GPIO_PIN_MAP(0,11),1);
            nrf_delay_ms(500);
            nrf_gpio_pin_write(NRF_GPIO_PIN_MAP(0,11),0);
            nrf_delay_ms(500);
            counter++;
    }
}
```


これで、GPIO0.11に接続しているLEDが点滅しました。