今日こそ頑張ります

危機感を抱きつつ、怠けるエンジニア。日記や備忘録。(以前のブログ:http://harupanda.blog.jp/)

nRF52833-DKの任意のGPIOでLチカをする

nRF52833-DK上にはLEDが実装されていて、SDKのサンプルではその中の4つのLEDを点滅させるようになっています。

今回は、それら既存のLEDとは異なるLEDを1つブレッドボード上に用意し、
さらに別のGPIOを操作してブレッドボード上のLEDを点滅させることにします。
(そっちの方が練習になるかと思い。)

GPIOの選択と接続

P0.23のGPIOに、LEDおよび3.3kオームの電流制限抵抗を介して、VDD_nRF(3.3V)に接続しています。
ちなみにnRF52833のGPIOのドライバビリティ(電流駆動能力)はデータシートに載っておらず。
DevZoneで検索してみると15mAという話みたい。結構流せるのね。
今回は3.3kを介して1mAなんで余裕です。

※なお、P1.01~08のGPIOも空いていて、はじめはそちら(P1.03)に接続していましたが、
うまく制御できず。(サンプルプログラムがP1.**を制御することが想定されていないのか??)
きちんと制御アドレスとかを解析すればできそうだけど、今回はそれはパスしてP0番台のGPIOを選択。

ソースコードの編集

nRF5_SDK_17.1.0_ddde560\examples\peripheral\blinky\pca10100e\blank\ses\blinky_pca10100e.emProject
をベースに編集していきます。

main.cのmain関数。

int main(void)
{
    /* Configure board. */
    bsp_board_init(BSP_INIT_LEDS);

    /* Toggle LEDs. */
    while (true)
    {
        for (int i = 0; i < LEDS_NUMBER; i++)
        {
            bsp_board_led_invert(i);
            nrf_delay_ms(500);
        }
    }
}

ここはそのままです。
bsp_board_initでは、GPIOを初期化をしているようです。
while文のループ内のbsp_board_led_invertでLEDを明滅させます。
簡単ですね。

bsp_board_initと、bsp_board_led_invertに
P0.23のGPIOの初期化、およびトグルの記述を追加しましょう。

それぞれ、board.cに記述があります。
まず、bsp_board_initから。

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
}

ここもそのままです。
今回、ポイントとなるのはbsp_board_leds_init()で、ここにさらに潜ると、

static void bsp_board_leds_init(void)
{
    #if defined(BOARD_PCA10059)
    // If nRF52 USB Dongle is powered from USB (high voltage mode),
    // GPIO output voltage is set to 1.8 V by default, which is not
    // enough to turn on green and blue LEDs. Therefore, GPIO voltage
    // needs to be increased to 3.0 V by configuring the UICR register.
    if (NRF_POWER->MAINREGSTATUS &
       (POWER_MAINREGSTATUS_MAINREGSTATUS_High << POWER_MAINREGSTATUS_MAINREGSTATUS_Pos))
    {
        gpio_output_voltage_setup();
    }
    #endif

    uint32_t i;
    for (i = 0; i < LEDS_NUMBER; ++i)
    {
        nrf_gpio_cfg_output(m_board_led_list[i]);
    }
    bsp_board_leds_off();

    //test
    uint8_t led_test_pin = LED_TEST;
    nrf_gpio_cfg_output(led_test_pin);
    nrf_gpio_pin_write(led_test_pin,0);
}

ここで、GPIOを出力に初期化し、さらに初期設定として消灯しています。
それぞれ、nrf_gpio_cfg_outputと、bsp_board_leds_offですね。

これを真似して追加します。testコメントから下3行です。
LED_TESTというdefineは、pca10100.hに以下のように追加しています。

#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_TEST       NRF_GPIO_PIN_MAP(0,23)

同じようなノリで、bsp_board_led_invertにも下記のように追記します。

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

    //test
    uint8_t led_test_pin = LED_TEST;
    nrf_gpio_pin_toggle(led_test_pin);
}

基本的にはこれでいけるはずなんですが、最後に1つ力業が必要です。
nrf_gpio_cfg_outputの先で呼び出されるnrf_gpio_pin_port_decodeの中の
NRF_ASSERTをコメントアウトします。
nrf_gpio_pin_present_checkの先では、エラッタ処理を通したりしているようですが
ここをそのまま通すとエラー処理側に落ちてしまいます。
趣味工作の範疇ではスキップしても問題ないだろ!所詮チェックだし!ということで
潔くコメントアウトしましょう。

__STATIC_INLINE NRF_GPIO_Type * nrf_gpio_pin_port_decode(uint32_t * p_pin)
{
    //test
    //NRFX_ASSERT(nrf_gpio_pin_present_check(*p_pin));

これでLチカの完成です。
次はBLEをいじりたいのですが、nRF52833-DKは技適を通していないので
BLEの電波を飛ばせません。

といわけで、ここらで本番環境であるISP1807をいじり始めたいと思います。
(nRF52833-DKはもともとオンボードJ-linkの目的で買っております)

次回は、ISP1807を利用してLチカさせたいと思います。