Перейти к содержанию

Регистры TIMER RP2350

Регистры двух системных таймеров RP2350 — TIMER0 и TIMER1: 64-битные счётчики с шагом от генератора тиков или от системной частоты, по четыре будильника, пауза при отладке и блокировка записи.

В RP2350 два одинаковых системных таймера — TIMER0 по адресу 0x400B 0000 и TIMER1 по адресу 0x400B 8000, — чтобы у разных доменов защиты было по своему. Каждый — 64-битный счётчик; при тике раз в микросекунду переполнения не наступит тысячи лет (даташит RP2350, раздел 12.8).

Отличия от RP2040: тик каждому таймеру даёт свой генератор в блоке TICKS, регистр SOURCE позволяет считать вместо тиков такты clk_sys, а LOCKED запрещает запись в таймер до сброса. Без запущенного генератора тиков таймер стоит — pico-sdk запускает его при инициализации.

Время читают парой TIMELR, затем TIMEHR, но с двух ядер так нельзя: защёлка старшей половины общая. Функция time_us_64 из pico-sdk читает TIMERAWH, TIMERAWL и снова TIMERAWH, пока старшая половина не совпадёт. Будильники ALARM0–ALARM3 сравнивают младшие 32 бита счётчика и срабатывают не дальше чем через 2³² мкс — около 72 минут; для более долгих интервалов есть таймер AON блока POWMAN.

ЭкземплярБазовый адрес
TIMER00x400B 0000
TIMER10x400B 8000

В RP2040 блок TIMER устроен иначе — регистры и поля отличаются, они описаны на странице «Регистры TIMER RP2040».

Регистры блока

РегистрСмещениеНазначениеПосле сброса
TIMER_TIMEHW0x00Запись старших 32 бит времени — после TIMELW0x0000 0000
TIMER_TIMELW0x04Запись младших 32 бит времени; в счётчик попадает после записи TIMEHW0x0000 0000
TIMER_TIMEHR0x08Чтение старших 32 бит времени — после TIMELR0x0000 0000
TIMER_TIMELR0x0CЧтение младших 32 бит времени; защёлкивает старшую половину0x0000 0000
TIMER_ALARMn0x10 + n · 0x04Будильник n: момент срабатывания по младшим 32 битам0x0000 0000
TIMER_ARMED0x20Взведённые будильники; запись 1 снимает будильник0x0000 0000
TIMER_TIMERAWH0x24Старшие 32 бита времени без защёлки0x0000 0000
TIMER_TIMERAWL0x28Младшие 32 бита времени без защёлки0x0000 0000
TIMER_DBGPAUSE0x2CПауза при отладке0x0000 0007
TIMER_PAUSE0x30Пауза таймера0x0000 0000
TIMER_LOCKED0x34Запрет записи в таймер; снимается только сбросом0x0000 0000
TIMER_SOURCE0x38Источник счёта: тик или clk_sys0x0000 0000
TIMER_INTR0x3CНеобработанные флаги прерываний0x0000 0000
TIMER_INTE0x40Разрешение прерываний0x0000 0000
TIMER_INTF0x44Принудительная установка прерываний0x0000 0000
TIMER_INTS0x48Флаги прерываний после маски и принуждения0x0000 0000

TIMER_TIMEHW — запись старших 32 бит времени — после TIMELW

Смещение 0x00, после сброса 0x0000 0000, запись с побочным действием. Макросы pico-sdk: TIMER_TIMEHW_…

Значение занимает регистр целиком, отдельных полей нет.

TIMER_TIMELW — запись младших 32 бит времени; в счётчик попадает после записи TIMEHW

Смещение 0x04, после сброса 0x0000 0000, запись с побочным действием. Макросы pico-sdk: TIMER_TIMELW_…

Значение занимает регистр целиком, отдельных полей нет.

TIMER_TIMEHR — чтение старших 32 бит времени — после TIMELR

Смещение 0x08, после сброса 0x0000 0000, только чтение. Макросы pico-sdk: TIMER_TIMEHR_…

Значение занимает регистр целиком, отдельных полей нет.

TIMER_TIMELR — чтение младших 32 бит времени; защёлкивает старшую половину

Смещение 0x0C, после сброса 0x0000 0000, только чтение. Макросы pico-sdk: TIMER_TIMELR_…

Значение занимает регистр целиком, отдельных полей нет.

TIMER_ALARMn — будильник n: момент срабатывания по младшим 32 битам

4 регистра, n = 0…3: смещение 0x10 + n · 0x04, после сброса 0x0000 0000, чтение и запись. Макросы pico-sdk: TIMER_ALARMn_…

Значение занимает регистр целиком, отдельных полей нет.

TIMER_ARMED — взведённые будильники; запись 1 снимает будильник

Смещение 0x20, после сброса 0x0000 0000, сброс записью 1. Макросы pico-sdk: TIMER_ARMED_…

Отдельных полей нет: значение занимает биты 3:0, остальные биты не используются.

TIMER_TIMERAWH — старшие 32 бита времени без защёлки

Смещение 0x24, после сброса 0x0000 0000, только чтение. Макросы pico-sdk: TIMER_TIMERAWH_…

Значение занимает регистр целиком, отдельных полей нет.

TIMER_TIMERAWL — младшие 32 бита времени без защёлки

Смещение 0x28, после сброса 0x0000 0000, только чтение. Макросы pico-sdk: TIMER_TIMERAWL_…

Значение занимает регистр целиком, отдельных полей нет.

TIMER_DBGPAUSE — пауза при отладке

Смещение 0x2C, после сброса 0x0000 0007. Макросы pico-sdk: TIMER_DBGPAUSE_…

1514131211109876543210
—DBG1DBG0—
  • DBG1 (бит 2, чтение и запись, после сброса 0x1) — Останавливать таймер, пока ядро 1 в режиме отладки.
  • DBG0 (бит 1, чтение и запись, после сброса 0x1) — Останавливать таймер, пока ядро 0 в режиме отладки.

TIMER_PAUSE — пауза таймера

Смещение 0x30, после сброса 0x0000 0000, чтение и запись. Макросы pico-sdk: TIMER_PAUSE_…

Отдельных полей нет: значение занимает бит 0, остальные биты не используются.

TIMER_LOCKED — запрет записи в таймер; снимается только сбросом

Смещение 0x34, после сброса 0x0000 0000, чтение и запись. Макросы pico-sdk: TIMER_LOCKED_…

Отдельных полей нет: значение занимает бит 0, остальные биты не используются.

TIMER_SOURCE — источник счёта: тик или clk_sys

Смещение 0x38, после сброса 0x0000 0000. Макросы pico-sdk: TIMER_SOURCE_…

  • CLK_SYS (бит 0, чтение и запись, после сброса 0x0) — 0 — тик из блока TICKS, 1 — такты clk_sys.

TIMER_INTR — необработанные флаги прерываний

Смещение 0x3C, после сброса 0x0000 0000. Макросы pico-sdk: TIMER_INTR_…

1514131211109876543210
—ALARM_3ALARM_2ALARM_1ALARM_0
  • ALARM_n, n = 0…3 (биты 0, 1, 2, 3; сброс записью 1, после сброса 0x0) — Сработал будильник n; сбрасывается записью 1.

TIMER_INTE — разрешение прерываний

Смещение 0x40, после сброса 0x0000 0000. Макросы pico-sdk: TIMER_INTE_…

1514131211109876543210
—ALARM_3ALARM_2ALARM_1ALARM_0
  • ALARM_n, n = 0…3 (биты 0, 1, 2, 3; чтение и запись, после сброса 0x0) — Разрешение прерывания будильника n.

TIMER_INTF — принудительная установка прерываний

Смещение 0x44, после сброса 0x0000 0000. Макросы pico-sdk: TIMER_INTF_…

1514131211109876543210
—ALARM_3ALARM_2ALARM_1ALARM_0
  • ALARM_n, n = 0…3 (биты 0, 1, 2, 3; чтение и запись, после сброса 0x0) — Принудительная установка прерывания будильника n.

TIMER_INTS — флаги прерываний после маски и принуждения

Смещение 0x48, после сброса 0x0000 0000. Макросы pico-sdk: TIMER_INTS_…

1514131211109876543210
—ALARM_3ALARM_2ALARM_1ALARM_0
  • ALARM_n, n = 0…3 (биты 0, 1, 2, 3; только чтение, после сброса 0x0) — Прерывание будильника n после маски и принуждения.

Частые вопросы

Зачем в RP2350 два системных таймера?

Чтобы защищённый и незащищённый код имели по собственному таймеру: TIMER0 и TIMER1 одинаковы, у каждого свой 64-битный счётчик, четыре будильника и свой генератор тиков в блоке TICKS. Права доступа к ним задают регистры TIMER0 и TIMER1 блока ACCESSCTRL.

Почему таймер RP2350 не считает?

Нужен запущенный генератор тиков: в блоке TICKS для TIMER0 или TIMER1 задают число тактов clk_ref на 1 мкс и включают ENABLE. Кроме того, таймер стоит, пока установлен PAUSE или пока ядро остановлено отладчиком при включённом DBGPAUSE.

Как считать таймером RP2350 такты процессора?

Запишите 1 в поле CLK_SYS регистра SOURCE: таймер будет увеличиваться с каждым тактом clk_sys вместо тика 1 мкс. После сброса SOURCE = 0 — счёт тиков из блока TICKS.

Источники

  1. Raspberry Pi. RP2350 Datasheet (release 8, build 80d627281ed5) — раздел 12.8.5: список регистров, назначение полей, тип доступа и значения после сброса
  2. Raspberry Pi. pico-sdk 2.1.1: заголовки src/rp2350/hardware_regs/include/hardware/regs/*.h (коммит bddd20f) — смещения, биты, тип доступа и значение после сброса каждого поля, базовые адреса из addressmap.h; лицензия BSD-3-Clause

Нашли ошибку в регистрах?

Другие регистры RP2350

Статьи и термины