СС1101 под управлением PIC-контроллера или построение одноранговой сети для радиоинженера

Предистория

Как-то некоторое время назад я участвовал в проектировании одной сети сбора данных. Сеть использовала диапазон 869 МГц и протокол SimpliciTI. По своей структуре сеть была по сути одноранговой с центральным узлом накопления данных. Однако в сети был предусмотрен и вариант ретрансляции данных, хотя он был, скорее, вспомогательным.

Дальше прототипов дело не пошло, хотя дело поставлено было очень серьёзно, вплоть до сертификации по ЭМС.
Одной из причин неудачи было то, что штатный программист не сумел полностью овладеть управлением CC1101.

Штука в том, что пакет SimpliciTI, взятый с сайта Texas Instruments, уже имеет какие-то настройки по-умолчанию. Эти настройки далеко не оптимальны для задачи редкого сбора данных (раз в месяц) в сети, которая располагается в доме с железобетонными стенами, да ещё испытывает воздействие помех различного происхождения.

С самого начала было понятно, что параметры должны быть, скажем, вот такими, а не такими. Для установки параметров в CC1101 имеется целый ряд регистров. Это всё описано, несколько путано, но, в конце концов, после некоторых усилий осваивается.

И вот берётся программа SmartRF Studio, устанавливаются в ней нужные параметры, проверяются. После успешной проверки нужно бы эти параметры перенести в реальную аппаратуру. Для этого в приложении, использующем SimpliciTI, делаются установки в начале программы.

Но не тут-то было! После успешного старта где-то на какой-то функции из пакета SimpliciTI происходит откат к параметрам, которые устанавливались разработчиками пакета. И программист так и не нашёл, где это происходит. В частности, ему так и не удалось запустить пакеты с фиксированной длиной и FEC. А без последнего работа системы в условиях замирания сигнала и помех практически невозможна.

«Голый» CC1101 совместно с PIC

CC1101 имеет встроенный контроллер, поэтому может управляться с помощью вполне внятной системы команд через интерфейс SPI.

Возникла идея, а что если воспользоваться возможностями самого CC1101 в чистом виде? Разумеется, речь не шла о создании чего-то типа One-Net, но о каком-то элементарном инструментарии для построения одноранговой сети с полным использованием возможностей чипа CC1101.

Поскольку стандартный радиоинженер по большей части далёк от программирования контроллеров, была выбрана платформа PIC, поскольку для этих контроллеров имеется такой язык как PICBASIC.

Не знаю, преподают ли сегодня C для радиоинженеров, но раньше точно BASIC преподавали, да и изучить его не вопрос. Конечно, TCP/IP на BASIC не напишешь, но простые действия типа передать что-то куда-то по адресу или принять что-либо, а тем более, чтение регистров через SPI этот язык прекрасно описывает. А весь диалог с CC1101 — это сплошной обмен по SPI с регистрами и ничего другого!

Практическая реализация

Была собрана вот такая плата на основе PIC18F2455.

image

Нужно сказать, что этот прототип был собран только для проверки качества связи при изменении параметров радиоканала, поэтому на нём нет никаких интерфейсных разъёмов для подключения каких-либо датчиков или других внешних устройств. Как видно на снимке, присутствуют:
— индикаторный светодиод (2-х цветный);
— звуковой излучатель;
— кварц на 32768 Гц для часов реального времени;
— USB-интерфейс;
— чип-антенна;
— аккумулятор, подзаряжаемый от USB.

Схема представлена здесь.

В схеме отсутствует выключатель питания, антенна показана условно.

В данном посте не приводится программа целиком, но она и не использовала абсолютно всех возможностей CC1101.

В частности, режим WOR не был задействован. Режим ожидания с проверкой наличия сигнала был осуществлён непосредственно с помощью PIC18F2455 и таймера реального времени.

Основным в программе является, конечно, обмен по SPI. С другой стороны, при приёме должно срабатывать прерывание на запуск обработки. Прерывание по наличию принятого пакета запускается по сигналу GDO0, соответствующим образом сконфигурированного. Чтобы не усложнять обработчик прерываний, обмен по SPI сделан в варианте polling на основе примера, изложенного здесь.

Основной блок подпрограмм для управления CC1101 через SPI выглядит так:

wt_rd_reg:
' Чтение/запись регистра
'
CS = %0
pauseus 300
SSPBUF = NOW
GoSub letclear ' wait for buffer to clear
a[0] = SSPBUF ' чтение первого байта
SSPBUF = DAT '
GoSub letclear ' wait for buffer to clear
a[1] = SSPBUF ' чтение второго байта
CS = %1
return

wt_rd_fifo:
' Чтение-запись FIFO
'
SSPBUF = DAT
GoSub letclear ' wait for buffer to clear
d[i] = SSPBUF ' чтение ответного байта
return

sndstrobe:
' Отправка строба управления на CC1101
'
CS = %0
pauseus 300
SSPBUF = NOW
GoSub letclear ' wait for buffer to clear
a[0] = SSPBUF ' чтение первого байта
pauseus 800
SSPBUF = SNOP ' empty
GoSub letclear ' wait for buffer to clear
a[1] = SSPBUF ' чтение второго байта
CS = %1
return


letclear:
IF SSPIF = 0 Then letclear ' wait for SPI interupt flag
PauseUs 25 ' 25uS fudge factor
SSPIF = 0 ' reset flag


Здесь:
NOW — текущая команда,
DAT — текущие данные,
d[i] — массив для хранения данных из FIFO, не может быть меньше длины FIFO,
CS — chip select.

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

По вопросам кодов команд нужно смотреть базовое описание.

Значения регистров записывались в EEPROM PIC18F2455, откуда по мере надобности считывались, причём адрес в EEPROM соответствует адресу регистра, что позволяет легко загружать нужные значения и всегда проверить настройки.

Практические результаты

После того, как программа была написана, то к великой радости оказалось, что ВСЕ функции удаётся запустить, включая hardware filtering, whitening, FEC и т.д. и т.п. Передача пакетов пошла с пол-пинка.

Главное, что чётко понятно, где какой параметр изменяется, и как это происходит, и что с этим делать, и как это применять. С использованием PICBASIC всё понятно радиоинженеру без знания языка C и особых навыков в написании встраиваемых приложений.

Здесь не было цели выкладывать программу(-ы) полностью. Если это будет интересно, то это может быть выложено, но не на этом сайте. Собственно, если это будет жгуче интересно, то можно даже организовать что-то типа библиотеки.

Использованные ссылки

1. СС1101, вся документация
2. SmartRF Studio
3. Microengineering Labs, сайт компании
4. CC1101_Tester, схема электрическая принципиальная
5. SPI, управление в PICBASIC
6. CC1101, datasheet
Поделиться публикацией

Комментарии 3

    0
    Конечно, TCP/IP на BASIC не напишешь
    — никто не хочет «Challenge Accepted»? :)
      0
      Прототип был собран только для проверки качества связи при изменении параметров радиоканала, поэтому на нём нет никаких интерфейсных разъёмов для подключения каких-либо датчиков или других внешних устройств.

      Очень жаль, что нет интерфейсов. Сейчас нужны девайсы, на базе которых можно организовать mesh-сеть: соединить соседей на лестничной площадке, или замутить локальную сеть в частных домах. Поверх такой сети смогла бы например работать моя Пандора.

      TCP не обязательно, хотя бы сделать примитивный API для отправки и приёма небольших пакетов (<10Kb). Идентификация узла пусть будет случайная, или жёстко прописана на железке (что-то типа MAC-адреса). Пакеты пусть расходятся мультикастом от одного всем его соседям, кто в зоне видимости (а они дальше передают).

      Чтоб пакеты по кругу не гоняли, запоминать маркер пакета (содержит ID отправителя, время создания и хэш пакета), хранить где-то в буфере список этих маркеров 1 минуту. Отбрасывать, если маркер пакета есть в буфере, или если пакет старше 1 минуты. Другой способ: прикреплять в конце пакета ID узла, так будет копиться список ID, чтобы этим узлам пакет снова не отправляли. При получении пакета первым делом заглядывать в этот список: если есть свой ID, то отбросить пакет, если ID соседа, то ему не отправлять. Но так пакеты могут сильно раздуваться. Чтобы пакеты не раздувались, хранить номер передачи, увеличивать его на +1 при каждой передаче. Если число передач больше 30, то отбрасывать пакет.

      Ну и понятно, пакеты брать с интерфейса и класть туда же.
        0
        Разумеется, интерфейсы в реальности нужны. Идея сделать полновесный модуль (-и) есть. Однако нужно бы и финансирование где-то найти. Уж больно дорогостоящие приборы нужны для отладки радиотракта. Уже проходил и знаю, что без приборов лучше не соваться.
        Одной из целей публикации было пощупать, а есть ли интерес.

        Соображения по маркировке очень интересны. Только как бы не заняться изобретением велосипеда в 100-й раз…

        В том неудачном проекте как раз элементы TCP хотели применить, т.е. в пакет включается байт счётчика. Если число узлов превышает заданное N, то пакет уничтожается. В этом случае не нужен никакой буфер, где хранится информация о переданных пакетах. Даже если пакет заблудился и гуляет по кругу, то также ничего страшного не произойдёт. А навешивать ID в конце пакета — это путь к пакету переменной длины. Тогда можно забыть о FEC.

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

      Самое читаемое