Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: СС1101
Форум разработчиков электроники ELECTRONIX.ru > Аналоговая и цифровая техника, прикладная электроника > Rf & Microwave Design
ivainc1789
Разработал и изготовил 4 устройства на сс1101: устройства A1,A2,A3 посылают на устройство B пакеты, а устройство B квитирует их (передает своему Ax короткий пакет подтверждения). Все работает до тех пор, пока не наступит момент, когда два устрйства Ax пытаются передать свои пакеты одновременно (ну или почти одновременно, тактирование от внутреннего RC STM32F051). В этом случае устройство B "зависает", т. е. его сс1101 не может принять пакет от любого Ax. Помогает только сброс/переинициализация устройства В.
Сейчас усложнять протокол тайм-слотами нет времени, хотелось бы разобраться как можно выявить эту ситуацию коллизии в устройстве В с помощью регистров сс1101 и просто по этому событию перегрузить трансивер. Если такая возможность есть, подскажите в какую сторону смотреть?
Pasha_a13
В настройках СС1101 есть флажок, который позволяет очищать входной буфер в случае принятия битого пакета(несовпадения контрольно суммы). Но для этого пакеты должны быть фиксированной длины и включена проверка контрольной суммы. Посмотрите в этом направлении.

Какой у Вас формат пакетов? Фиксированная длина пакета? Один пакет помещается в приемный буфер?
ivainc1789
Цитата(Pasha_a13 @ Feb 1 2014, 21:02) *
Какой у Вас формат пакетов? Фиксированная длина пакета? Один пакет помещается в приемный буфер?

Все верно, софт сделал для пакетов от 4 до 64 байт. Устройство В проверяет адрес входящего пакета автоматически (регист ADDR в сс1101). Кроме того проверяется CRC входящего. Если эти две проверки ОК и пакет не более 64 байт, на GDO0 у меня встает 1 и контроллер считывает пакет.
Так вот, если например два Ax устройства одновременно передают пакеты, в RXFIFO скорее всего не пройдет проверка адреса и/или CRC. Но у меня установлены настройки автоочистки RXFIFO при битых пакетах и тогда прием пакетов восстановился бы, просто были бы пропущены несколько битых. А по факту прием в устройстве В встает навсегда! Что-то упускаю...

P.S. Причину нашел, но объяснить пока не могу: при одновременном/последовательном приеме нескольких пакетов устройство В вываливается в IDLE режим. Хотя после приема последнего пакета запрограммирован переход в RX режим.
Salamander
Цитата
при одновременном/последовательном приеме нескольких пакетов устройство В вываливается в IDLE режим.


Так это причина известная. И она не связана с одновременной работой с несколькими модулями.

Борюсь следующим образом - в один из моментов, когда трансивер точно должен быть в приеме вызываю следующую функцию
Код
        
void CCxx00_monitoring()
{
       MARCSTATE=TI_CC_SPIReadStatus(TI_CCxxx0_MARCSTATE);
        if (MARCSTATE !=0x0D)
    {
    TI_CC_SPIStrobe(TI_CCxxx0_SIDLE);     
     TI_CC_SPIStrobe(TI_CCxxx0_SFRX);
                 TI_CC_SPIStrobe(TI_CCxxx0_SRX);
     errors++;
    }    
    }


За сутки набегает до 10 ошибок, к зависанию не приводит.
Mihey_K
Код бы приемника B показали. Как вариант борьбы с коллизиями добавить задержку статичную перед каждой отправкой по номеру устройства, например 1* 10мс., 2* 10 мс. и т.д. В каждом передатчике включите прерывание прослушивания несущей, как толька среда освободиться, выставится флаг, там и включайте передачу.
ivainc1789
Цитата(Salamander @ Feb 2 2014, 12:16) *
Так это причина известная. И она не связана с одновременной работой с несколькими модулями.
За сутки набегает до 10 ошибок, к зависанию не приводит.


Я тоже об этом подумал - отслеживать состояние по регистру MARCSTATE. Единственное, не нравится постоянный поллинг к кристаллу - время реакции на другие события в программе критично. Кроме того в руководстве написано, что поллинг в режиме RX нежелателен, т. к. чувствительность приемника деградирует...
Хорошая мысль: устройства Ax должны использовать CCA перед началом "общения", если канал занят, это "общение" откладывается.

В приемнике B режим RX включен все время (главный цикл) и отслеживается состояние GDO0, по 1 на этом пине в RXFIFO имеем пакет с верным адресом и верным CRC. По уровню GDO0=1 трансивер автоматом переходит в IDLE. Далее пакет обрабатывается, переходим в режим TX, отправляем квитанцию для конкретного Ax и опять автоматом переходим в IDLE. Наконец, переходим в RX. Выходим в главный цикл программы с ожиданием нового состояния GDO0=1.
Mihey_K
Посмотрите эррату, для 64 байт может быть похожий косяк с зависанием.
ivainc1789
Написал функцию восстановления RX режима (все же решил использовать статус байт стробом SNOP) - теперь все работает прекрасно.
Цитата
Так это причина известная. И она не связана с одновременной работой с несколькими модулями.

Просто раздирает любопытство, почему не связано с одновременной работой модулей? ИМХО, приемник может находится в режиме RX сколь угодно долго, если RX timeout не запрограммирован. У меня он вылетает в IDLE исключительно при коллизиях...
Теперь занялся реализацией CCA на устройствах Ax. Сейчас они просто начинают передачу по стробу STX и CCA отключен. Если его включить, то как я понимаю, нужно при желании начать передачу пакета сначала перейти в режим RX чтобы прослушать канал ("получить данные" CCA) и только потом начать передачу пакета. Вопрос: каково должно быть минимальное время нахождения в RX чтобы данные по CCA были валидны?
Salamander
Код
Просто раздирает любопытство, почему не связано с одновременной работой модулей?

Элементарно, Ватсон, у меня работает один модуль и проблема имеет место быть.
Mihey_K
Цитата
Так это причина известная.
Нигде о подобном не слышал, самому дико любопытно, хотя с зависаниями сталкивался, но так и не выяснил их природу.
Да, надо включать RX, у меня был включен переход автоматом на RX. Слушает среду недолго, если там тихо, а так почти всегда, только если в упор никто не вещает без умолку, сразу в передачу. У меня полное время передачи занимало 10-20 мс., т.е. с прослушиванием, подготовкой в TX и передачей в эфир 20 байт на 10к. Несколько мс. должно быть достаточно.
ivainc1789
Цитата
Элементарно, Ватсон, у меня работает один модуль и проблема имеет место быть.
Сидел час отладчиком на приемнике B - не обнаружил ни единого вылета в IDLE при единственном передающем Ax. Как только передают несколько Ax сразу хорошо видно как передаваемые пакеты все ближе и ближе во времени становятся друг к другу и, в определенный момент ловлю вылет в IDLE на устройстве B. Очень интересная ситуация, выяснить бы, откуда ноги растут...
Цитата(Mihey_K @ Feb 2 2014, 19:30) *
Да, надо включать RX, у меня был включен переход автоматом на RX. Слушает среду недолго...
Дело в том, что мои устройства Ax - приборы с батарейным питанием, которые раз в минуту передают данные устройству B. Ясно, что для экономии батарейки время передачи и вообще активности нужно стремить к нулю. Даже протокол я построил вокруг этого требования. Поэтому, из режима сна нужно было бы сразу начинать передачу. Но после подключения CCA ясно, что сначала нужно прослушать канал. Все же сколько времени слушать??? Думаю миллисекунды - это много, предположительно - не более 1ms... Запрограммировал GDO1=0x09 на индикацию CCA но это ничего не решает - при переходе SLEEP->IDLE->RX неясно, когда данные на ноге GDO1 будут валидны...

P.S. Вот, надумал: время нахождения в RX должно быть примерно: T = T1 + T2, где T1 - время перехода SLEEP->IDLE->RX, T2 - время приема примерно ДВУХ байт на текущей скорости. У мну скорость 1200 бод/сек., т. е. время T = 1ms вроде должно быть оптимально минимальным )))
Mihey_K
1 мс. хватит. Можно проверить имперически: выставить порт в 1 на входе IDLE->RX и сбросить уже в прерывании CCA. Глянуть осциллом. Боитесь, что будет долго слушать эфир и жрать батарею? Заведите таймер на требуемое максимальное время прослушивания эфира, при входе в IDLE->RX запускайте его, в прерывании CCA останавливайте. Если CCA висит долго, то оказываемся в прерывании таймера, где выключаем таймер и переводим радио в IDLE и вообще усыпляем систему на таймаут...и так далее.
Похоже, что у Вас сбор с датчиков, тогда вообще нет смысла собирать данные примерно в одно время, разграничьте время пробуждения Ax случайными задержками.

Цитата
Элементарно, Ватсон, у меня работает один модуль и проблема имеет место быть.

В том-то и дело, что это элементарно, когда работает 1 модуль. Видать что-то неправильно настроено.
ivainc1789
Цитата
Похоже, что у Вас сбор с датчиков, тогда вообще нет смысла...

Именно так! Сбор с датчиков. Причем если приемник B не примет очередной пакет - ничего страшного по ТЗ не произойдет.
Тогда встает вопрос, что меньше сожрет батарею при пробуждении датчика с необходимостью передать данные:
1. Слушаем канал, режим RX, 1ms. Если занят - не передаем пакет, иначе - передаем.
2. Да нафик этот CCA, просто сразу передаем - и все. Нужно все же делать тайм-слоты...
Сдается мне, что вариант 2 здесь более бережет батарейку...
Mihey_K
Пробуждение по часовому таймеру? И каким образом разные датчики будут передавать одновременно, если их не синхронизировать? Т. е. если их не синхронизировать и использовать корявый источник тактирования часов, то вероятность одновременной передачи невелика. А если и будет коллизия, то и черт с ней, передадут через минуту.
ivainc1789
Цитата(Mihey_K @ Feb 2 2014, 21:10) *
И каким образом разные датчики будут передавать одновременно, если их не синхронизировать?

Пользователь может вводить датчик в эксплуатацию (вставлять батарейку) в произвольный момент времени. Но в целом вы правы, по ТЗ возможно иногда терять пакеты, т. к. регистрируемые процессы вялотекущие. Так что редкие коллизии не страшны...
Mihey_K
Тогда не заморачивайтесь, разве что добавить повторную отправку sm.gif Ошибки в работе таймеров всегда будут набегать, так что коллизии маловероятны. А почему не зигби?
ivainc1789
Цитата(Mihey_K @ Feb 3 2014, 03:43) *
А почему не зигби?

Тогда нужно в сторону STM32Wxxx смотреть - у меня очень хорошо бы легло по ТЗ. Но я не уверен, что смогу обеспечить в этом диапазоне необходимую дальность. Такого опыта в Инете не удалось найти...
Mihey_K
Какая дальность требуется? В помещении?
ivainc1789
Цитата(Mihey_K @ Feb 3 2014, 11:59) *
Какая дальность требуется? В помещении?

Соседние помещения, стены железобетон, 50-80метров.
ivainc1789
Кстати, я вроде понял, почему трансивер вываливается в IDLE при обсуждаемых выше условиях!
Ответ дан на стр. 40 даташита сс1101 (ревизия I) в разделе CRC filtering.
Дело в том, что если принят битый пакет (одновременно или почти одновременно прилетели валидные пакеты), то CRC failed, RXFIFO autoflushed, и состояние трансивера определяется в MCSM1.RXOFF_MODE. А он у меня предполагает IDLE.
Но все равно, это не избавляет от функции контроля нахождения в режиме RX, приведенной выше...
rx3apf
Почему не избавляет ? Если используется непрерывный прием, то трансивер так и останется в режиме приема, и проверять тут нечего.
ivainc1789
Цитата(rx3apf @ Feb 3 2014, 14:06) *
Почему не избавляет ? Если используется непрерывный прием, то трансивер так и останется в режиме приема, и проверять тут нечего.

1. Мой самопальный протокол предполагает IDLE после приема пакета. Изменять конфигурацию на лету не хотелось бы.
2. Длительное нахождение в RX не рекомендуется.

Если кому не трудно, подскажите еще по режиму WOR в CC1101: при скорости 1.2 кБод как правильно выбрать период пробуждений трансивера, если передача пакета начинается с преамбулы 30 бит и затем sync word 32 бита? Я изучил вроде соот разделы в даташите, но до конца не разобрался сколько времени должен находится сс1101 в режиме приема внутри WOR режима? Вроде он должен определить наличие N sync bits в эфире и выставить уровень на GDOx? Чему равно N? 32 бита sync word будут приниматься из эфира ~27ms при скорости 1200бод и период должен быть меньше? И возможно ли как-то использовать обработку преамбулы с целью увеличения периода пробуждений?
rx3apf
Зависит от наличия или отсутствия FEC, и я использовал внешнее, принудительное, задание времени приема, не пользуясь внутренними средствами. Можно и "живьем" измерить это время, и ориентироваться (с запасом) на полученные результаты. У меня скорость на два порядка выше, поэтому времянки совсем иные, на малых скоростях не рискну что-то советовать (но напомню, кстати, о высоких требованиях к точности установки частоты на низких скоростях при малой полосе). Использование высокой скорости существенно сокращает потребление при опросе эфира.

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

Переходить или не переходить в idle - вопрос удобства. Я, например, в разных частях протокола поступаю по-разному, и переконфигурирование "на лету" происходит постоянно.
ivainc1789
И все же. Передатчик передает 4 байта преамбулы и 4 байта синхрослова на скорости 1200 бод/сек. Сколько бит преамбулы и/или синхрослова требуется приемнику сс1101, чтобы определить это как начало пакета??? Это требуется для режима WOR (расчета периода пробуждений).
Я думаю, требуется 8 бит синхрослова минимум...
Mihey_K
В регистре MCSM2 же задается таймаут поиска преамбулы для выхода из sleep.
ivainc1789
Цитата(Mihey_K @ Feb 3 2014, 18:05) *
В регистре MCSM2 же задается таймаут поиска преамбулы для выхода из sleep.

Ну и как будете задавать?
Mihey_K
Цитата
Ну и как будете задавать?
Даташит, стр. 80, там есть пример, где сказано, что приемник слушает эфир 1.96 мс. с заполнением для пробуждения в 0.195%. Это же поясняется на рис. 28.
ivainc1789
Цитата(Mihey_K @ Feb 3 2014, 19:00) *
Даташит, стр. 80, там есть пример, где сказано, что приемник слушает эфир 1.96 мс. с заполнением для пробуждения в 0.195%. Это же поясняется на рис. 28.


Я ведь даже ситуацию обрисовал:
Цитата
И все же. Передатчик передает 4 байта преамбулы и 4 байта синхрослова на скорости 1200 бод/сек. Сколько бит преамбулы и/или синхрослова требуется приемнику сс1101, чтобы определить это как начало пакета??? Это требуется для режима WOR (расчета периода пробуждений).

Вопросы, если нужно максимально поберечь батарейку для вышеприведенных условий:
1. Чему будет равен максимальный период пробуждений (EVENT0)?
2. Из каких соображений определите содержимое С(RX_TIME,WOR_RES) (стр. 80 даташита)?

При этом учтем, что на скорости 1200 бод/сек время трансляции бита в эфире примерно ~0.8ms !!!

Выше имеется ввиду, что пакет передается в эфире лишь однажды и именно с этой позиции рассматриваются вопросы настроек WOR принимающей стороны...
Pasha_a13
Если я правильно понял, то устройство B у Вас со стационарным питанием. Зачем в таком случае использовать WOR.
А от коллизии действительно удобно использовать псевдослучайную задержку перед передачей (прослушивание канала не дает особых преимуществ, если только два передающих устройства не находятся близко друг к другу...если же они находятся на разные стороны от приемника, то они могут друг друга и не услышать), время которой находиться в пределах, например, 0..0,5*(длительность пакета).
Плюс, в случае если устройство А не приняло пакета подтверждения, то через какой-то промежуток времени оно делает еще одну попытку передать пакет, затем его отбрасывает(количество переповторов подбирается исходя из важности информации).
ivainc1789
Цитата(Pasha_a13 @ Feb 9 2014, 15:40) *
Если я правильно понял, то устройство B у Вас со стационарным питанием. Зачем в таком случае использовать WOR.

Да, со стац питанием. С WOR я ранее не работал, думал это поможет в моей задаче. Казалось бы, мастером должно быть устройство B, но это больно бьет по энергопотреблению устройств А (датчиков) - они должны отправлять свой пакет 1 раз в минуту - я так и не придумал, как это обыграть, если мастер - устройство В. Получается, датчики должны входить в прием на довольно длительный период + еще потребуется синхронизация... Поэтому мастером (а точнее Инициатором) выступают датчики. Но все не просто. Устройство В тоже должно передавать на датчики их конфигурацию и др данные (изредка). Итак, сделал следующее: датчик инициирует обмен и передает свои данные. База (устройство В) квитирует этот пакет, передавая помимо квитанции специальный служебный байт (команда датчику о его дальнейшем поведении). Если в этом байте передается 0, значит дальнейшие действия датчика - standby mode. Т. е. получается, что большую часть времени датчик передает один лишь пакет своих данных (макс сохр потребления). В итоге имеем "мультимастерную" систему, где база - слэйв, но логически все же база - мастер ибо она руководит обменом по факту... Придумать что-то лучшее пока не смог, может подскажете что-то. Мне не очень нравится "мультимастерность", вот в чем беда. Я думал, что WOR как то поможет эту проблему разрешить...

Цитата
Плюс, в случае если устройство А не приняло пакета подтверждения, то через какой-то промежуток времени оно делает еще одну попытку передать пакет, затем его отбрасывает(количество переповторов подбирается исходя из важности информации).
Датчики и так должны передавать инфу раз в минуту, по условиям ТЗ допускается один пропуск данных, но не реже...
Mihey_K
Да как в ZigBee похоже. Там проснулся датчик, сообщил арбитру, что он проснулся, и уже сам передает данные, или получает их с арбитра. А арбитр пакеты для энд-девайсов буферизирует, пока те не проснутся. Энд-девайсы там просыпаются каждую секунду, если ничего не надо делать - дальше спать.
Pasha_a13
В Вашем случае для устройства В WOR не нужен, он больше нужен в случае если устройство ограничено в ресурсах по питанию.
Устроство В пусть постоянно висит в приеме и слушает эфир. Он отвечает за то чтобы в любой произвольный момент времени принять пакет от датчика, обработать его и ответить датчику. Если смотреть в сторону ZigBee и городить чето подобное это только головную боль себе нажить. Определенные вещи можно взять оттуда, но отнють не все.
Не советую делать В мастером и чтобы датчики просыпались и принимали от него запросы, получите головную боль с синронизацией. Проще привязываться к моментам приема последнего пакета от каждого конкретного датчика и уже от них, в случае необходимости, отсчитывать момент когда датчик следующий раз ответит(развивая это направление можно отслеживать пропадание датчиков проверяя периодически промежутки времени с момента последнего выхода датчика на связь).
По поводу посылки параметров датчику - я тоже делал подобным образом...в памяти центрального устройства В хранились очереди команд для каждого датчика и когда датчик присылает пакет я смотрю нет ли для данного датчика управляющих команд и в ответном пакете подтверждения делаю пометку что для него есть управлющие данные и передаю их. Я просто изначально размер пакета сделал с запасом, потому мне не надо было передавать ему дополнительные пакеты.
Сколько служебных(командных) байт Вы планируете ему передавать и какая у Вас длина пакета подтверждения?
ivainc1789
Цитата(Pasha_a13 @ Feb 10 2014, 22:05) *
Сколько служебных(командных) байт Вы планируете ему передавать и какая у Вас длина пакета подтверждения?
Ну пока у меня 4 команды. Одним байтом CmdID обхожусь: как тока датчик проснулся, отправил свои основные даныые и принял в ответ пакет подтверждения (4 байта+CmdID), он выполняет ряд действий исходя из содержимого CmdID, в том числе может продолжить RF общение. Пока все хорошо работает и следуя рекомендациям в этой теме - я повысил скорость передачи с 1.2 кБод до 38.4 кБод. Это существенно улучшило энергопотребление.
FPGAz
Цитата(Salamander @ Feb 2 2014, 18:24) *
Элементарно, Ватсон, у меня работает один модуль и проблема имеет место быть.

Если принимающую сторону быстро закидывать пакетами, то она склеивает ласты даже при одном посылающем эти пакеты модуле. biggrin.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.