Изучение радио трансивера

Цель лабораторной работы:

Исследовать возможности и особенности применения радио трансивера микроконтроллера ATMEGA128RFA1 в базовом режиме.

Предварительная подготовка к работе

  1. Изучить принципиальную схему учебного стенда LESO6.
  2. Изучить способы создания в среде Eclipse проекта с готовым makefile.
  3. Изучить способы загрузки исполняемого кода в память программ учебного стенда LESO6.
  4. По документации изучить особенность трансивера ATMEGA128RFA1.

Краткие теоретические сведения о встроенном радио интерфейсе

Особый интерес в микроконтроллере ATMEGA128RFA1 представляет встроенный модуль маломощного радио интерфейса, работающий на частоте 2.4ГГц. Так как приемопередатчик (трансивер) в первую очередь предназначен для работы в индустриальных сетях таких как ZigBee, IEEE 802.15.4, 6LoWPAN, RF4CE, помимо собственно радиопередатчика и приемника физического уровня он содержит блоки пакетной обработки данных, так называемый MAC-уровень (согласно модели OSI – open systems interconnection basic reference model). Однако это не мешает использовать приемопередатчик в режиме простого обмена данными.

Управление трансивером осуществляется также, как и любым другим периферийным устройством микроконтроллера, через регистры специального назначения.

Передаваемые и принимаемые данные хранятся в специальной области памяти, называемой буфер. Физически буфер приемника и буфер передатчика разделены, однако программно они оба отображены в пространстве адресов процессора как единый массив – Frame Buffer (FB). Формально на русский язык этот термин можно перевести как "буфер кадра" или "кадровый буфер", в дальнейшем Frame Buffer будем для краткости называть просто "буфер". Доступ к этому буферу осуществляется через два адреса: TRXFBST – адрес первого байта, и TRXFBEND – адрес последнего байта. Для того, что бы получить доступ к произвольному байту, нужно добавить к начальному адресу буфера порядковый номер требуемого байта, или отнять от адреса конца буфера соответствующее значение.

Размер буфера выбран удобным для работы по стандарту IEEE 802.15.4 и равен 128 байт. Когда по радиоканалу будет принят новый пакет, данные окажутся в буфере, перезаписав предыдущее значение. Если же мы сами собираемся передавать, то мы должны программно записать передаваемый пакет в этот буфер и только после этого запустить передачу. Даже если мы в своей программе не используем функции MAC-уровня, нужно учесть, что значение первого байта в передаваемом пакете равно длине самого пакета, то есть, количеству байт данных для отправки. Но когда мы принимаем пакет, длина пакета не попадает в буфер, там только данные. Значение длины записывается в специальный регистр TST_RX_LENGTH. Потому при ретрансляции только что принятого пакета, придется модифицировать буфер: высчитывать пакет, добавлять байт с длиной, снова записывать в буфер. Что вполне закономерно, если вспомнить, что буфер на прием и передачу – это физически разные области памяти.

Приемопередатчик может работать в двух режимах. Базовом, когда доступны только основные функции, такие как прием и передача пакета, спящий режим и выход из него. В расширенном режиме доступны аппаратные средства поддержки MAC-уроня. В рамках данной статьи рассмотрим базовый режим.

Во время работы трансивер находится в определенных состояниях. В теории программирования совокупность состояний какой-либо системы и условия перехода из одного состояние в другое, называют конечным автоматом или машиной состояний. Для управления состояниями используются два регистра TRXPR и TRX_STATE. Регистр TRXPR содержит 2 значащих бита: SLPTR и TRXRST. Запись в эти биты логического нуля или единицы приводят к смене состояния. Младшие пять бит регистра TRX_STATE служат для записи команд перехода. Для того, что бы понять как работать с радио трансивером рассмотрим его состояния и условия перехода подробнее. Итак, в базовом режиме работы приемопередатчик может находиться в семи следующих состояниях:

1. SLEEP

Спящий режим. В этом состоянии приемопередатчик отключен и его потребление сводится к токам утечки. В это состояние приемопередатчик может перейти только из состояния TRX_OFF, для этого бит SLPTR должен быть установлен в единицу: SLPTR = 1.

Сбросив SLPTR в ноль (SLPTR = 0) система вернется в состояние TRX_OFF.

Установив в бит TRXRST единицу (TRXRST = 1) переводим систему в состояние TRX_OFF, но при этом все регистры будут сброшены в их первоначальное состояние.

2. TRX_OFF

Это состояние активируется сразу, когда микроконтроллер был включен или сброшен. В этом состоянии на трансивер подаются импульсы синхронизации, на все цифровые цепи подано питание, все регистры управления и буфер доступны. Но аналоговые цепи выключены.

3. PLL_ON

При переходе в состояние PLL_ON из состояния TRX_OFF подается питание на аналоговые цепи, включается высокочастотный генератор PLL (Phase Locked Loop – Фазовая Автоподстройка Частоты – ФАПЧ). Согласно выбранному каналу (биты CHANNEL, регистра PHY_CC_CCA) генератор настраивается на несущую частоту.

4. RX_ON

В этом состоянии аналоговый приемник и ФАПЧ активны. В этом состоянии прием "слушает" эфир, если детектирует начало пакета (перед непосредственно данными в пакете передается преамбула, так называемый Synchronization HeaderSHR – заголовок синхронизации, приемник срабатывает на SHR), то система автоматически переходит в состояние BUSY_RX, при этом генерируется прерывание TRX24_RX_START.

5. BUSY_RX

В этом состоянии принимаемые байты данных непрерывно записываются в буфер приемника. После того как последний байт будет принят, сгенерируется прерывание (TRX24_RX_END) и система вернется в состояние RX_ON. Во время приема автоматически происходит проверка контрольной суммы, результат проверки записывается в бит RX_CRC_VALID регистра PHY_RSSI ("1" – пакет пришел без ошибки, "0" – ошибка контрольной суммы). Длина принятого пакета будет записана в регистр TST_RX_LENGTH.

6. BUSY_TX

Состояние передачи данных в эфир. В это состояние система может перейти только из состояния PLL_ON. Есть два способа запустить передачу. Первый, это установить бит SLPTR регистра TRXPR в единицу (TRXPR = 1). Этот бит должен быть очищен до того, как пакет полностью будет отправлен. Но этот способ устарел, поэтому рекомендуется начинать передачу с помощью регистра TRX_STATE, записав в его TRX_CMD биты команду TX_START. После того как будет передан заголовок синхронизации SHR будут последовательно отправлены байты данных из буфера передатчика. Когда пакет будет полностью отправлен в эфир вызовется прерывание TRX24_TX_END и система перейдет в состояние PLL_ON.

7. RESET

Это состояние используется для сброса всех регистров приемопередатчика в исходное состояние. Из этого состояния система автоматически переходит в TRX_OFF.

Ниже на рисунке показана машина состояний приемопередатчика микроконтроллера ATMEGA128RFA1.

Basic Operating Mode State Diagram

Рисунок 1 – Машина состояний трансивера в базовом режиме работы

Проанализируем граф состояний и разберемся как нам с этим работать в своей программе. Первое что нужно понять – после включения микропроцессора или его сброса трансивер находится в состоянии TRX_OFF. Во все управляющие регистры записано значение по умолчанию. В этом состоянии система может прибывать сколь угодно долго, ни прием, ни передача не осуществляются.

Передача

Допустим мы хотим передать пакет в эфир. Передача пакета, это состояние BUSY_TX. Судя по графу попасть в это состояние мы можем через состояние PLL_ON. Для перехода нужно подать команду RX_ON (смотрим стрелочку перехода, условие над стрелочкой). Команда подается записью в регистр TRX_STATE определенного значения. Для того, что бы было удобно читать текст программы и граф, все значения команд заменены текстовым определением, в нашем примере RX_ON равно 0x06. Все эти определения есть в подключаемом заголовочном файле и их можно смело использовать в своей программе. Для того, чтобы из состояния PLL_ON перейти в состояние BUSY_TX, используем команду TX_START. Естественно, передаваемые данные должны быть заранее загружены в буфер передатчика. Когда передача будет завершена, система автоматически перейдет в состояние PLL_ON.

Прием

Допустим мы хотим включить приемник и ждать посылку. Для этого мы должны попасть в состояние RX_ON. Судя по графу мы можем это сделать из двух состояний TRX_OFF и PLL_ON. В обоих случаях используется команда RX_ON. Если пакет окажется в эфире, то система автоматически перейдет в состояние BUSY_RX (смотрим граф), как только пакет будет принят полностью, система вернется в состояние RX_ON.

Прежде чем пойти дальше следует разобрать один нюанс. Выше указывалось, что смена состояний трансивера осуществляется записью команды регистр TRX_STATE, однако мгновенно система сменить свое состояние не может. Для этого, чтобы быть уверенным, что мы перешли в нужное состояние нужно выждать определенное время, для всех переходов в документации на ATMEGA128RFA1 приведены соответствующие задержки. Можно поступить по другому: в трансивере предусмотрен специальный регистр TRX_STATUS, где в младших пяти битах находится актуальное текущее состояние системы; после команды на смену состояний нужно подождать до тех пор, пока в этом регистре не окажется требуемое нам состояние. Кроме того, с помощью этого регистра можно в любом месте программы узнать, чем занимается трансивер.

Прерывания

Как уже было ранее сказано, прерывание происходит, когда трансивер начинает прием пакета (TRX24_RX_START), когда пакет принят полностью (TRX24_RX_END), когда пакет отправлен полностью (TRX24_TX_END). На самом деле событий, вызывающих прерывания больше, но эти три наиболее удобны для использования.

Номер вектора

Имя Описание
Таблица 1 – Вектора прерывания радио приемопередатчика
64

TRX24_AWAKE

Вызывается, когда трансивер перешел в состояние TRX_OFF, RESET или SLEEP.

63

TRX24_TX_END

Вызывается, когда трансивер полностью передал пакет.

62

TRX24_XAH_AMI

Вызывается, когда адрес пакета совпал с адресом приемника.

61

TRX24_CCA_ED_DONE

Вызывается, когда завершается измерения уровня несущей в канале.

60

TRX24_RX_END

Вызывается, когда завершен приема пакета.

59

TRX24_RX_START

Вызывается, когда начался прием пакета.

58

TRX24_PLL_UNLOCK

Вызывается, когда ФАПЧ выключается.

57

TRX24_PLL_LOCK

Вызывается, когда генератор ФАПЧ вышел на заданную частоту.

По умолчанию, все прерывания отключены. Для того, что бы разрешить какое-либо прерывание, нужно в регистре IRQ_MASK установить соответствующий бит.

Для простейшей работы с трансивером нам понадобится две функции и обработчик прерывания. Пусть функция rf_init() включает и настраивает трансивер, функция rf_send() отправляет пакет в эфир, а обработчик прерывания ISR(TRX24_RX_END_vect) срабатывает, когда пакет будет принят. Положим, что после инициализации трансивер всегда готов к приему и находится в состоянии RF_ON. Тогда в функции отправки мы должны перевести трансивер в режим PLL_ON, загрузить данные в буфер, при этом первый байт буфера должен содержать длину пакета, и запустить передачу (перевести в состояние TX_BUSY). Ниже показан листинг функции отправки пакета.

void rf_send(const void *data, uint8_t len)
{    // Переводим приемопередатчик в режим передачи.
    TRX_STATE = CMD_PLL_ON;
    // Ждем, пока установится состояние.
    while (((TRX_STATUS)& 0x1F) != PLL_ON);
    // В первый байт записываем длину пакета.
    TRXFBST = len + 2;
    // Копируем пакет в буфер передатчика.
    memcpy((void *)(&TRXFBST+1), data, len);
    // Запускаем передачу.
    TRX_STATE = CMD_TX_START;
}

Входные параметры функции rf_send() – указатель на массив данных, и количество байт данных, предназначенных для отправки, другими словами – длина пакета.

Разберемся с инициализацией. Как уже сообщилось выше, результат работы этой функции будет приемопередатчик в режиме RX_ON с настроенными параметрами. А вот на параметрах стоит остановится подробнее. Несмотря на впечатляющие возможности, трансивер в микроконтроллера ATMEGA128RFA1 сделан так, что для минимального работоспособного состояния большинство настроек можно оставить по умолчанию. Однако некоторые вещи, все же нам обойти не удастся, например, мы должны разрешить прерывание.

void rf_init(void)
{    // Сбрасываем регистры трансивера и конечный автомат.
    TRXPR |= (1<<TRXRST);
 
    // Разрешаем прерывание после приема пакета.
    IRQ_MASK = (1<<RX_END_EN);
 
    // Переводим приемопередатчик в режим RX_ON.
    TRX_STATE = CMD_RX_ON;
    // Ждем, пока установится состояние.
    while (((TRX_STATUS)& 0x1F) != RX_ON);
}

Ниже приведен листинг простейшего обработчика прерывания:

ISR(TRX24_RX_END_vect)
{
    uint8_t length;
    length = TST_RX_LENGTH;
    // Копируем буфер приемника
    memcpy(rf_RX_buffer, (void*)&TRXFBST, length);
}

Массив rf_RX_buffer должен быть объявлен и инициализирован заранее. Теперь в функции main() достаточно выполнить инициализацию и приемопередатчик готов к работе.

Задание к работе в лаборатории

Так как исследуется процесс обмена данными между двумя устройствами по радиоинтерфейсу, то для выполнения работы на одну бригаду необходимо два стенда.

Скачать исходный проект.

Задания базовой сложности:

  1. В среде Eclipse импортируем проект leso6/app/radiochat. Рекомендуется скопировать проект в отдельную директорию для того, чтобы изменения не затронули исходные файлы. Компилируем проект, при необходимости обновляем индексацию.
  2. Проанализировать исходный код. Найти функции отправки пакета и инициализации трансивера. Найти обработчики прерываний, разобраться когда они вызываются и как инициализированы. Определить, что показывают светодиоды.
  3. Добавить в функцию инициализации выбор радио канала. Каждая бригада работает на своем канале согласно варианту.
  4. Загрузить в память обоих микроконтроллеров hex-файл. Используя терминал подключится к стенду. Для каждого стенда использовать отдельное окно терминала. Хорошим вариантом будет работа на двух отдельных компьютерах. Проверить работоспособность программы. Сообщение набирается с клавиатуры ПК, при нажатии клавиши "Enter" сообщение отправляется на другое устройство и выводится в его терминале.
  5. Модифицировать исходный код согласно варианту.
Таблица 2 – Варианты заданий

№ вар.

Радиоканал (МГц)

Особенность программы

0 2405

При приеме пакета выводить уровень RSSI (в дБм).

1 2415

При приеме  выводить уровень энергии сигнала (в дБм).

2 2425

Выводить количество приняты пакетов, и количество пакетов, принятых с ошибкой CRC.

3 2435

Реализовать отправку строки неограниченной длины.

4 2445

При приеме пакета выводить уровень RSSI (в дБм).

5 2455

При приеме выводить уровень энергии сигнала (в дБм).

6 2465

Выводить количество приняты пакетов, и количество пакетов, принятых с ошибкой CRC.

7 2475

Реализовать отправку строки неограниченной длины.

Дополнительные задания повышенной сложности:

  1. Сохраняя функционал программы, перенести код из прерывания в основной цикл функции main().
  2. Реализовать подтверждение успешной доставки пакета.

Указания к составлению отчета по лабораторной работе

Отчет должен содержать:

  1. Цель работы.
  2. Граф конечного автомата трансивера.
  3. Вариант задания полностью.
  4. Текст программы и вывод консоли компилятора.
  5. Выводы по выполненной лабораторной работе.

Приложение А.

Орфографическая ошибка в тексте:
Чтобы сообщить об ошибке автору, нажмите кнопку "Отправить сообщение об ошибке". Вы также можете отправить свой комментарий.