[Из песочницы] Работа с радиомодулями SI4432
Описание микросхемы SI4432
Чувствительность приёмника -121 dBm. Мощность передатчика до +20 dBm (возможна программная настройка с шагом 3 dBm). Имеется встроенная функция разнесённого приёма (Antenna Diversity). Микросхема способна работать на частотах от 240 до 960 МГц с шагом 156 (240–480 МГц) или 312 Гц (480–960 МГц). Также микросхема имеет такие особенности как: таймер автоматического пробуждения, детектор низкого заряда батареи, 64-х байтный буфер приема/передачи, автоматический обработчик пакетов, датчик температуры, 8-ми разрядный АЦП, источник опорного напряжения, три вывода GPIO, различные виды модуляции сигнала (OOK, FSK, GFSK) и др.
Микросхема работает от 1.8 до 3.6 В питающего напряжения.
Особенности радтомодуля
На модуле отсутствуют какие-либо стабилизаторы напряжения, таким образом нужно соответствующее обеспечение питания и соответствующий уровень на логических входах. На модуле видна еще одна мелкая шестивыводная микросхема с маркировкой G4C. Это микросхема uPG2179TB, которая выполняет функцию переключения антенны между выводами TX и RX, обеспечивая тем самым возможность работы модуля как в режиме приема, так и в режиме передачи. Управление микросхемой переключателя осуществляется самой SI4432 по портам GPIO0 и GPIO1, которые, при инициализации нужно соответственно запрограммировать, для смены/установки режима приема/передачи. При этом данная схемотехническая конфигурация не позволяет использовать функцию разнеженного приема, а функционирование выводов GPIO0 и GPIO1 должно быть отведено только на управление переключателем uPG2179TB.
Номиналы конденсаторов и индуктивностей установленных в обвязке антенных входов SI4432 должны выбираться исходя из рабочего частотного диапазона, характеристик антенны и диапазона питающих напряжений. Какие именно номиналы имеют указанные элементы неизвестно.
Схему модуля, именно того, который приведен на рисунке я не нашёл, но по информации из даташита можно установить распиновку модуля:
NSEL, SCLK, SDI, SDO — интерфейс SPI (работа с SI4432 сводится к записи и чтению регистров SI4432 по интерфейсу SPI);
NIRQ — вывод прерываний (если произошло событие прием/передача и пр., то уровень на этом выводе падает в 0, какие именно события будут приводить к прерываниям зависит от значения битов в соответствующих регистрах);
SDN — вывод управления режимом работы SI4432, если установить высокий уровень на SDN, то SI4432 переходит в режим Shutdown, в котором микросхема переходит режим энергосбережения с током потребления 15 нА, при этом всё содержимое регистров возвращается к исходному состоянию и невозможна передача данных по SPI;
VDD — питание модуля от 1.8 до 3.6 В;
GND — «земля»;
GPIO0, GPIO1, GPIO2 — программируемые порты ввода/вывода (если не перепаивать модуль, то под свои цели можно запрограммировать только GPIO2, так как GPIO0 GPIO1 уже заняты для переключения режима приема/передачи).
Настройка модуля
Все настройки регистров описанные ниже взяты из документа AN415 Programming guide. В данном файле освещены вопросы использования SI4432 в качестве передатчика, приёмника, приёмопередатчика, а также рассматривается вопрос передачи пакетов с длиной более 64 кбайт.
Микросхемы SI4432 бывают разных ревизий: A, V, B. Определяется первой буквой в шифре, в моём случае BPS10P, значит ревизия B. Для разных ревизий имеются некоторые особенности в инициализации.
Подключение к контроллеру
Подключение модуля производится в соответствии с распиновкой приведенной выше. Для простого приёма или передачи данных выводы GPIO можно не заводить на входы микроконтроллера и оставить их висящими в воздухе. Выводы SPI подключаются к соответствующим выводам микроконтроллера, NIRQ можно повесить на любой свободный вывод микроконтроллера (наверное лучше на такой вывод, где можно получить внешнее прерывание по фронту). SDN можно завести на «землю» или на вывод МК, но при этом не забыть установить его в 0.
Чтение и запись по SPI
Производитель SI4432 предлагает использовать следующие функции для чтения и записи регистров по SPI.
Запись:
void SpiWriteRegister (U8 reg, U8 value)
{
//Отправка данных с двойной буферизацией
//Выбор модуля путем установки NSEL в 0
NSS = 0;
//Запись адреса регистра в буфер SPI МК
//Установка старшего бита в адресе регистра необходима для проведения операции записи (всего 127 регистров)
SPI1DAT = (reg|0x80);
//Ожидание отправки байта
while( SPIF1 == 0);
SPIF1 = 0;
//Запись желаемого значения регистра SI4432 в буфер SPI МК
SPI1DAT = value;
//Ожидание отправки байта
while( SPIF1 == 0);
SPIF1 = 0;
//Отпуск модуля
NSS = 1;
}
Чтение:
U8 SpiReadRegister (U8 reg)
{
//Выбор модуля путем установки NSEL в 0
NSS = 0;
//Запись адреса регистра в буфер SPI МК (старший бит адреса - 0)
SPI1DAT = reg;
//Ожидание отправки байта
while( SPIF1 == 0);
SPIF1 = 0;
//Запись произвольных даных в буфер SPI МК
//Во время отправки этих данных МК прочтет значение регистра SI4432
SPI1DAT = 0xFF;
//Ожидание отправки байта
while( SPIF1 == 0);
SPIF1 = 0;
//Отпуск модуля
NSS = 1;
//Чтение и возврат функции прочтенных полученных донных из регистра SI4432
return SPI1DAT;
}
Инициализация. Начало работы
Рекомендуется произвести следующие манипуляции.
1) Установить вывод SDN в 0.
2) Подождать 15 мс, до отправки команд по SPI.
3) Прочитать статусы регистров прерываний.
4) Выполнить программный сброс.
SDN = 0; // SDN в 0
delay_ms(15);
//чтение статусов
ItStatus1 = SpiReadRegister(0x03);
ItStatus2 = SpiReadRegister(0x04);
//выполнение программного сброса
SpiWriteRegister(0x07, 0x80); //запись 0x80 в регистр Operating & Function Control1
//ожидание возникновения прерывания
while ( NIRQ == 1);
//чтение статусов
ItStatus1 = SpiReadRegister(0x03); //read the Interrupt Status1 register
ItStatus2 = SpiReadRegister(0x04); //read the Interrupt Status2 register
Чтение статусов очищает флаги прерываний и сбрасывает вывод NIRQ в 1 (когда происходит прерывание NIRQ сбрасывается в 0 и остается в этом состоянии до тех пор пака не будет прочтён соответствующий статусный регистр).
Установка частотных параметров
Так как микросхема поддерживает работу в довольно широком диапазоне частот, то конфигурирование регистров ответственных за частоту довольно сложно. Производитель предлагает использовать калькулятор (EZRadioPRO Register Calculator) для расчета значений частотных регистров. Калькулятор представляет собой файл Microsoft Excell:
В этом файле уже выставлены подходящие значения по умолчанию. Изменять значения можно только в серых ячейках. Целесообразно менять в этом файле значение ячеек ответственных за скорость передачи (J9) и несущую частоту (B17). Обычно, чем меньше скорость передачи тем меньше вероятность возникновения ошибки в процессе передачи данных. Можно выбрать тип модуляции сигнала: FSK, GFSK, OOK.
OOK модуляция кодирует данные включением или выключением усилителя сигнала. Когда нет данных для передачи усилитель отключен, при передаче логического 0 усилитель отключен на время длительности одного бита, при передаче логической 1 усилитель включен на время длительности одного бита.
FSK основана на изменении частоты сигнала для передачи цифровых данных. Для передачи логического 0 частота несущего сигнала уменьшается на величину частоты отклонения, а для логической 1 увеличивается. Отличие GFSK от FSK в том, что GFSK применяет фильтр Гаусса к битам данных.
Производитель рекомендует использовать тип GFSK, так как при этом типе обеспечивается наилучшая эффективность работы и более чистый спектр сигнала по сравнению с другими типами доступных модуляций, что видно из рисунка (сравнение FSK и GFSK):
Конфигурирование регистров ответственных за частоту:
//установка центральной частоты 915 МГц
SpiWriteRegister(0x75, 0x75);
SpiWriteRegister(0x76, 0xBB);
SpiWriteRegister(0x77, 0x80);
//установка скорости передачи (9.6kbps)
SpiWriteRegister(0x6E, 0x4E);
SpiWriteRegister(0x6F, 0xA5);
SpiWriteRegister(0x70, 0x2C);
//установка отклонения частоты (+-45 кГц) (необходимый параметр при GFSK модуляции)
SpiWriteRegister(0x72, 0x48);
Передача пакета данных с помощью обработчика пакетов
Обработчик пакетов используется в режиме приёма и в режиме передачи. Можно передавать данные и без обработчика пакетов, в этом случае нужно описывать структуру пакета в регистрах самостоятельно. Обычно структура пакета выглядит следующим образом:
Преамбула (Preamble) — последовательность 0101… используемая для синхронизации приемника и передатчика. SI4432 имеет встроенный детектор преамбулы. При настройке SI4432 в регистрах задается значение длины преамбулы и величины порога детектирования преамбулы. Если длина преамбулы или порог детектирования преамбулы будет меньше определенного значения, то возрастет вероятность потери пакетов данных. Детектор преамбулы ищет преамбулу в соответствии с порогом детектирования. Если найдена соответствующая преамбула, то запускается механизм определения слова синхронизации (Sync Word).
Передаваемый пакет всегда начинается с преамбулы (010101… битовый паттерн), которая позволяет приемнику приготовится для приема передаваемых данных. Дина преамбулы, как и порог, зависят от настроек радио: типа модуляции, автоматической частотной подстройки (AFC). В SI4432 есть встроенный детектор преамбулы, который автоматически сравнивает полученные из эфира биты с битовым паттерном преамбулы, если детектор преамбулы обнаруживает предопределенную длину последовательности битов преамбулы в принятом сигнале, то SI4432 сообщает о приеме валидной преамбулы в статусных регистре или по выводу GPIO, если произведена соответствующая настройка GPIO.
Порог детектирования преамбулы — программируемая величина. В зависимости от типа модуляции (FSK, GFSK, OOK), задействования автоматической частотной подстройки (AFC) и разнесенного приёма (antenna diversity) производитель рекомендует выбирать длину преамбулы и порог детектирования преамбулы в соответствии с таблицей:
После успешного детектирования преамбулы, радио ожидает слова синхронизации. По его приходу сравнивает полученные биты. После успешного сравнения SI4432 начинает заполнять FIFO передаваемыми данными. Слово синхронизации, известная для приемника и передатчика последовательности битов, позволяет идентифицировать передаваемые данные.
Если передаваемые данные имеют произвольную длину (можно сделать фиксированную), то в пакет добавляется байт с информацией о длине передаваемых данных.
Также в пакет добавляется контрольная сумма CRC.
Используя обработчик пакетов, микроконтроллер конфигурирует формат передаваемого пакета один раз при первичной настройке SI4432, затем, чтобы передать данные микроконтроллер должен просто записать их в соответствующий FIFO регистр SI4432.
Отключение заголовка, установка переменного количества байт передаваемых данных (количество переданных байт записывается автоматически в передаваемый пакет данных) и 2 байта для слова синхронизации:
SpiWriteRegister(0x33, 0x02);
Непосредственная установка слова синхронизации 0×2DD4:
SpiWriteRegister(0x36, 0x2D);
SpiWriteRegister(0x37, 0xD4);
Включение обработчика пакетов передатчика и CRC:
SpiWriteRegister(0x30, 0x0D);
Выбор источника модуляции FIFO и установка GFSK модуляции:
SpiWriteRegister(0x71, 0x63);
Источник модуляции — данные которые необходимо промодулировать, чтобы передать в эфир. В данном случае FIFO установлен источником. Но есть и прямой режим когда биты данных, с определенным таймингом, подаются на какой-либо вывод SI4432 (GPIOn, SDI, NIRQ).
Как было описано ранее, модуль имеет один вывод под антенну и переключатель режима прием передача на микросхеме uPG2179TB, выводы которой заведены на GPIO0 и GPIO1. Таким образом, можно запрограммировать GPIO на автоматическое переключение:
SpiWriteRegister(0x0B, 0x12);// настройка GPIO0 для включения режима передачи TX
SpiWriteRegister(0x0C, 0x15);//настройка GPIO1 для включения режима приема RX
Точность установки центральной частоты определяется точностью кварцевого резонатора, его нагрузочной емкостью, а также различными паразитными емкостями в цепи резонатора. Уменьшить влияние указанных факторов на точность установки центральной частоты можно следующими способами:
1) Использовать более высокое значение частоты отклонения для передатчика и более широкий диапазон для приемника.
2) Использовать AFC (Auto-frequency calibration), для этого необходимо увеличить длительность преамбулы.
3) Настроить регистр ответственный за нагрузочную емкость кварцевого резонатора:
SpiWriteRegister(0x09, 0xD7); //запись 0xD7 в регистр ответственный за нагрузочную емкость
Отправка пакета
Будем отправлять пакет раз в секунду.
//главный цикл
while(1)
{
delay_ms(1000);
/*Настройка содержания пакета*/
//установка длины передаваемых данных - 8 байт
SpiWriteRegister(0x3E, 8); //запись 8 в регистр длины передаваемых данных
//заполнение FIFO передаваемыми данными
SpiWriteRegister(0x7F, 0x42);
SpiWriteRegister(0x7F, 0x55);
SpiWriteRegister(0x7F, 0x54);
SpiWriteRegister(0x7F, 0x54);
SpiWriteRegister(0x7F, 0x4F);
SpiWriteRegister(0x7F, 0x4E);
SpiWriteRegister(0x7F, 0x31);
SpiWriteRegister(0x7F, 0x0D);
//Отключение всех прерываний кроме прерывания по отправке пакета
//Данное действие сделано для извещения МК о успешной отправке
SpiWriteRegister(0x05, 0x04);
SpiWriteRegister(0x06, 0x00);
//Чтение регистров статусов прерываний, для очистки текущих прерываний и сброса NIRQ в лог. 1
ItStatus1 = SpiReadRegister(0x03);
ItStatus2 = SpiReadRegister(0x04);
/*активация передатчика*/
//При этом радиомодуль формирует пакет и отправляет его автоматически
SpiWriteRegister(0x07, 0x09);
//Ожидание прерывания по отправке
while(NIRQ == 1);
//чтение статусных регистров для очистки флагов прерываний
ItStatus1 = SpiReadRegister(0x03);
ItStatus2 = SpiReadRegister(0x04);
}
Приём пакета данных с помощью обработчика пакетов
Инициализация радио
Инициализации приемника аналогична инициализации передатчика. Необходимо сделать сброс и прочитать регистры статуса.
Установка частоты
//установка центральной частоты 915 МГц
SpiWriteRegister(0x75, 0x75);
SpiWriteRegister(0x76, 0xBB);
SpiWriteRegister(0x77, 0x80);
Параметры радио: 9,6 kbps, модуляция GFSK, отклонение частоты 45 кГц, приемный диапазон 112,1 кГц. В соответствии с калькулятором частоты заполняются следующие регистры:
SpiWriteRegister(0x1C, 0x05); //запись 0x05 в IF Filter Bandwidth регистр
SpiWriteRegister(0x20, 0xA1); //запись 0xA1 в Clock Recovery Oversampling Ratio регистр
SpiWriteRegister(0x21, 0x20); //запись 0x20 в Clock Recovery Offset 2 регистр
SpiWriteRegister(0x22, 0x4E); //запись 0x4E в Clock Recovery Offset 1 регистр
SpiWriteRegister(0x23, 0xA5); //запись 0xA5 в Clock Recovery Offset 0 регистр
SpiWriteRegister(0x24, 0x00); //запись 0x00 в Clock Recovery Timing Loop Gain 1 регистр
SpiWriteRegister(0x25, 0x13);//запись 0x13 в Clock Recovery Timing Loop Gain 0 регистр
SpiWriteRegister(0x1D, 0x40); //запись 0x40 в AFC Loop Gearshift Override регистр
SpiWriteRegister(0x72, 0x1F); //запись 0x1F в Frequency Deviation регистр
SpiWriteRegister(0x2A, 0x20); //запись 0x20 в AFC Limiter регистр
Установка структуры пакета
Аналогично передатчику: отключение заголовка, установка переменного количества байт передаваемых данных (количество переданных байт записывается автоматически в передаваемый пакет данных) и 2 байта для слова синхронизации:
SpiWriteRegister(0x33, 0x02);
Отключение фильтрации заголовков:
SpiWriteRegister(0x32, 0x00 );
Непосредственная установка слова синхронизации 0×2DD4:
SpiWriteRegister(0x36, 0x2D);
SpiWriteRegister(0x37, 0xD4);
Включение обработчика пакетов приемника и CRC:
SpiWriteRegister(0x30, 0x85);
Включение режима FIFO и GFSK модуляции:
SpiWriteRegister(0x71, 0x63);
Установка порога детектирования преамбулы 20 бит:
SpiWriteRegister(0x35, 0x28);
Установка GPIO на автоматическое переключение антенны:
SpiWriteRegister(0x0B, 0x12);// настройка GPIO0 для включения режима передачи TX
SpiWriteRegister(0x0C, 0x15);//настройка GPIO1 для включения режима приема RX
Если не используется разнесенный прием, бит SGI в регистре AGC должен быть установлен для корректной работы контроля аналогового усиления:
SpiWriteRegister(0x69, 0x60);
Настроика регистра ответственного за нагрузочную емкость кварцевого резонатора:
SpiWriteRegister(0x09, 0xD7); //запись 0xD7 в регистр ответственный за нагрузочную емкость
Прием пакета
Активация приемника:
SpiWriteRegister(0x07, 0x05);//запись 0x05 в Operating Function Control 1 регистр
Включаем два прерывания:
1) прерывание по приему валидного пакета;
2) Прерывание по ошибке CRC.
SpiWriteRegister(0x05, 0x03); //запись 0x03 в Interrupt Enable 1 регистр
SpiWriteRegister(0x06, 0x00); //запись 0x00 в Interrupt Enable 2 регистр
Чтение статусных регистров для сброса прерываний:
ItStatus1 = SpiReadRegister(0x03);
ItStatus2 = SpiReadRegister(0x04);
Главный цикл:
while(1)
{
//ожидание прерывания
if(NIRQ == 0)
{
//Чтение статусных регистров
ItStatus1 = SpiReadRegister(0x03);
ItStatus2 = SpiReadRegister(0x04);
if( (ItStatus1 & 0x01) == 0x01 )//произошла ошибка CRC
{
//отключение передатчика
SpiWriteRegister(0x07, 0x01);//запись 0x01 в Operating Function Control 1 регистр
//сброс RX FIFO
SpiWriteRegister(0x08, 0x02);//запись 0x02 в Operating Function Control 2 регистр
SpiWriteRegister(0x08, 0x00);//запись 0x00 в Operating Function Control 2 регистр
//включение приемника
SpiWriteRegister(0x07, 0x05);
}
if( (ItStatus1 & 0x02) == 0x02 )//принят валидный пакет
{
//отключение передатчика
SpiWriteRegister(0x07, 0x01);//запись 0x01 в Operating Function Control 1 регистр
//Чтение длины принятых данных
length = SpiReadRegister(0x4B);//чтение регистра Received Packet Length
//Обработка принятых данных из RX FIFO
for(temp8=0;temp8 < length;temp8++)
{
payload[temp8] = SpiReadRegister(0x7F);//чтение FIFO Access регистра
}
//работа с массивом принятых данных
{
//...
}
//сброс RX FIFO
SpiWriteRegister(0x08, 0x02);//запись 0x02 в Operating Function Control 2 регистр
SpiWriteRegister(0x08, 0x00);//запись 0x00 в Operating Function Control 2 регистр
//включение приемника
SpiWriteRegister(0x07, 0x05);
}
}
}
Заключение
Вся информацияпо программированию модулей взята из Application Note 415 Programming guide.
В даташите на SI4432 есть список всех Application Note, представляющих собой что-то вроде миркоотчетов связанных с работой SI4432. Кроме даташита и указанного Programming guide, есть среди Application Note еще один полезный документ — карту регистров. В Programming guide также описана настройка трансмиттера для двусторонней связи. В карте регистров дано подробное описание всех регистров, режимов работы и настроек.