0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

nRF Connect SDK:タイマー(改版)

Posted at

以前の記事

以前にもタイマーに関連する記事を書きました。

ちなみにこの時にはnRFXタイマーは使えないと書いています。

nRFXタイマーは使える

でもふと疑問に思ったのです。その後PPIを使えるようにしたのですが、nRFXタイマーが使えないとしたらPPIをどうやって使えばいいんだ・・・?もちろんPPIはタイマー以外のペリフェラル結合でも使えますが、PPIで一番使いたいのはタイマーじゃないのかな、と。

以前はIRQ_CONNECTが足りていなかった

当時、何がダメでnRFXタイマーが動かないと判断したのか、実は覚えていません。調べた順番の前後も覚えていないのでもしかしたらタイマーの前にTWIMやSPIMを動かしているかも知れないのですが、当時足りていなかったのはおそらくIRQ_CONNECTではないかと思います。

改めて動作確認

せっかく動作確認するのだからタイマー0から4まで全部動かしてみようと思います。

main.c
/*
 * Copyright (c) 2012-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/zephyr.h>
#include <nrfx_timer.h>

static const nrfx_timer_t m_timer0 = NRFX_TIMER_INSTANCE(0);
static const nrfx_timer_t m_timer1 = NRFX_TIMER_INSTANCE(1);
static const nrfx_timer_t m_timer2 = NRFX_TIMER_INSTANCE(2);
static const nrfx_timer_t m_timer3 = NRFX_TIMER_INSTANCE(3);
static const nrfx_timer_t m_timer4 = NRFX_TIMER_INSTANCE(4);

static void timer_event_handler(nrf_timer_event_t event_type, void * context)
{
    switch (event_type)
    {
        case NRF_TIMER_EVENT_COMPARE0:
    		printk("timer 0\n");
            break;

        case NRF_TIMER_EVENT_COMPARE1:
    		printk("timer 1\n");
            break;

        case NRF_TIMER_EVENT_COMPARE2:
    		printk("timer 2\n");
            break;

        case NRF_TIMER_EVENT_COMPARE3:
    		printk("timer 3\n");
            break;

        case NRF_TIMER_EVENT_COMPARE4:
    		printk("timer 4\n");
            break;

        default:
    		printk("timer Other\n");
            break;
	}
}

void main(void)
{
	nrfx_err_t err;
    uint32_t time_ticks;
	nrfx_timer_config_t timer_cfg = {
		.frequency = NRF_TIMER_FREQ_16MHz,
		.mode      = NRF_TIMER_MODE_TIMER,
		.bit_width = NRF_TIMER_BIT_WIDTH_32,
	};

    // Configure timer driver
    err = nrfx_timer_init(&m_timer0, &timer_cfg, timer_event_handler);
	IRQ_CONNECT(TIMER0_IRQn, IRQ_PRIO_LOWEST, nrfx_timer_0_irq_handler, NULL, 0);
    time_ticks = nrfx_timer_ms_to_ticks(&m_timer0, 1000);
    nrfx_timer_extended_compare(&m_timer0, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);

    err = nrfx_timer_init(&m_timer1, &timer_cfg, timer_event_handler);
	IRQ_CONNECT(TIMER1_IRQn, IRQ_PRIO_LOWEST, nrfx_timer_1_irq_handler, NULL, 0);
    time_ticks = nrfx_timer_ms_to_ticks(&m_timer1, 2000);
    nrfx_timer_extended_compare(&m_timer1, NRF_TIMER_CC_CHANNEL1, time_ticks, NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK, true);

    err = nrfx_timer_init(&m_timer2, &timer_cfg, timer_event_handler);
	IRQ_CONNECT(TIMER2_IRQn, IRQ_PRIO_LOWEST, nrfx_timer_2_irq_handler, NULL, 0);
    time_ticks = nrfx_timer_ms_to_ticks(&m_timer2, 3000);
    nrfx_timer_extended_compare(&m_timer2, NRF_TIMER_CC_CHANNEL2, time_ticks, NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK, true);

    err = nrfx_timer_init(&m_timer3, &timer_cfg, timer_event_handler);
	IRQ_CONNECT(TIMER3_IRQn, IRQ_PRIO_LOWEST, nrfx_timer_3_irq_handler, NULL, 0);
    time_ticks = nrfx_timer_ms_to_ticks(&m_timer3, 4000);
    nrfx_timer_extended_compare(&m_timer3, NRF_TIMER_CC_CHANNEL3, time_ticks, NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK, true);

    err = nrfx_timer_init(&m_timer4, &timer_cfg, timer_event_handler);
	IRQ_CONNECT(TIMER4_IRQn, IRQ_PRIO_LOWEST, nrfx_timer_4_irq_handler, NULL, 0);
    time_ticks = nrfx_timer_ms_to_ticks(&m_timer4, 5000);
    nrfx_timer_extended_compare(&m_timer4, NRF_TIMER_CC_CHANNEL4, time_ticks, NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK, true);

    // Enable timer driver
	nrfx_timer_enable(&m_timer0);
	nrfx_timer_enable(&m_timer1);
	nrfx_timer_enable(&m_timer2);
	nrfx_timer_enable(&m_timer3);
	nrfx_timer_enable(&m_timer4);
}

コンフィギュレーション

prj.conf
CONFIG_NRFX_TIMER0=y
CONFIG_NRFX_TIMER1=y
CONFIG_NRFX_TIMER2=y
CONFIG_NRFX_TIMER3=y
CONFIG_NRFX_TIMER4=y
CONFIG_DEBUG_THREAD_INFO=y
CONFIG_DEBUG_OPTIMIZATIONS=y

余談ですが、VSCodeになってからはprj.confはKconfigの設定画面を使うと楽にできます。
image.png

タイマー0も使える

もしかしたらBluetoothを使っていないから解放されているだけかも知れませんが、タイマー0も普通に使えるみたいです。
ていうか、じゃあZephyrのタイムスライスっていったい誰がやっているんでしょう・・・?もしかしてLFCLKベースなのでしょうか?

nRF SDKではAPP TIMERと呼ばれていたタイマーのことです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?