repstosw 18 30 января, 2023 Опубликовано 30 января, 2023 · Жалоба Дано: приёмо-передатчик. Приёмник с выходом демодулятора в двоичном виде - последовательность нулей и единиц: 0010001011100000011111111... И тактовая синхронизация. Вопрос: как в мешанине нулей и единиц искать синхро-слово? Авто-корреляция, да. А как это практически - для дискретных отсчётов? Циклом сдвигать битовый поток с образцом с поиском по максимальному совпадению? В качестве синхро-слова - брать код Баркера или длинную М-последовательность? Есть ли смысл делать синхрослово очень большим? Например 63 бита, чтобы АКФ была максимальна. Есть литература, которая рассказывает как на практике делать поиск пакета в сырых данных? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 26 30 января, 2023 Опубликовано 30 января, 2023 · Жалоба 1 hour ago, repstosw said: Дано: приёмо-передатчик. Приёмник с выходом демодулятора в двоичном виде - последовательность нулей и единиц: 0010001011100000011111111... И тактовая синхронизация. Как обрабатываем: ПЛИС на верилоге побитно или ЦСП на СИ блоками? Иногда с приёмника ещё уровень сигнала заводят для определения начала пакета. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
V_G 11 30 января, 2023 Опубликовано 30 января, 2023 · Жалоба 3 часа назад, repstosw сказал: Дано: приёмо-передатчик Приемопередатчик какой? Если эфирный, то перед синхрословом принято передавать (передатчиком) и искать (приемником) преамбулу: чаще всего это последовательность 010101... А потом уже синхрослово. ПЛИС тут особенно не нужна, достаточно сдвигового регистра и схемы сравнения. Изредка допускают потерю 1-2 бит в синхрослове, тогда схема сравнения должна считать число совпадений синхрослова и содержимого сдвигового регистра. Чаще всего после обнаружения преамбулы заданной длины ищут синхрослово в течение заданного числа тактовых интервалов, схема дополняется счетчиком и сбросом в исходное состояние поиска преамбулы при переполнении счетчика. Реализация всего этого может быть как программная, так и аппаратная. P.S. Контроля несущей я не делаю, он ограничивает чувствительность системы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 31 января, 2023 Опубликовано 31 января, 2023 · Жалоба 11 hours ago, _4afc_ said: Как обрабатываем: ПЛИС на верилоге побитно или ЦСП на СИ блоками? На CPU Си-кодом. 10 hours ago, V_G said: Приемопередатчик какой? Если эфирный, то перед синхрословом принято передавать (передатчиком) и искать (приемником) преамбулу: чаще всего это последовательность 010101... А потом уже синхрослово. ПЛИС тут особенно не нужна, достаточно сдвигового регистра и схемы сравнения. CMT2300A, SI4463, и им подобные. Преамбула перед синхрословом есть - 8 байт 0xAA Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 26 31 января, 2023 Опубликовано 31 января, 2023 · Жалоба 8 hours ago, repstosw said: На CPU Си-кодом. Преамбула перед синхрословом есть - 8 байт 0xAA Когда у меня был приём на Си последовательности бит для хороших каналов я делал следующее: На передатчике передавал 6 байт синхры, скремблированные данные и 2 байта RS. Блочная синхронизация была: 0xAA, 0xAA, 0xF9, 0xA8, 0xAA, 0xAA. Ловилась она так: Spoiler u08 CheckSync(u08 *p) { u32 D=0; D=p[0]<<24; D|=p[1]<<16; D|=p[2]<<8; D|=p[3]; switch(D) { case 0xAAAAF9A8: return 0x00; case 0x5555f351: return 0x01; case 0xAAABE6A2: return 0x02; case 0x5557CD45: return 0x03; case 0xAAAF9A8A: return 0x04; case 0x555f3515: return 0x05; case 0xAABE6A2A: return 0x06; case 0x557CD455: return 0x07; case 0x55550657: return 0x80; case 0xAAAA0CAE: return 0x81; case 0x5554195D: return 0x82; case 0xAAA832BA: return 0x83; case 0x55506575: return 0x84; case 0xAAA0CAEA: return 0x85; case 0x554195D5: return 0x86; case 0XAA832BAA: return 0x87; } return 0xff; } Пачка блоков находилась так: Spoiler void FillTempBuf(u08 *pOut,u08 *pIn,u08 R) { int i; u16 D; D=pIn[0]; D=D>>(R&7); if ((R>>7)>0) D=D^0xff; pOut[0]=D&0xff; for (i=0;i<BLOCKSIZE;i++) { D=pIn[i]<<8; D|=pIn[i+1]; D=D>>(R&7); if ((R>>7)>0) D=D^0xff; pOut[i+1]=D&0xff; } } for (i=0;i<(Flen-5-BLOCKSIZE*BLOKS*2);i++) { u08 R=0xff; if ((Bin[i]==0xAA)&&(Bin[i+4]==0xAA)) R=CheckSync(&Bin[i]); if ((Bin[i]==0x55)&&(Bin[i+4]==0x55)) R=CheckSync(&Bin[i]); if (R!=0xff) { FillTempBuf(&TempBuf[0],&Bin[i],R); Descrambler8(&TempBuf[6],BLOCKSIZE-6); if ((TempBuf[6]|TempBuf[7]|TempBuf[8]|TempBuf[9])==0) { } BloksOUT(); } } } Это не нужно повторять - это как пример. Т.к. в том изделии нужно было собрать именно пачку блоков в несколько килобайт. Особенность в том, что F9A8 - это 15бит код Баркера и теоретически для плохого канала можно впоследствии улучшить блочную синхронизацию. Также поток можно инвертировать в канале, т.е. не следить сколько раз он проинвертировался на платах. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
V_G 11 31 января, 2023 Опубликовано 31 января, 2023 · Жалоба 10 часов назад, repstosw сказал: CMT2300A, SI4463, и им подобные. Преамбула перед синхрословом есть - 8 байт 0xAA Тогда исходный вопрос странен в принципе. Поиском синхрослова и обработкой пакета занимаются указанные ИС, вам-то зачем это делать вручную? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 31 января, 2023 Опубликовано 31 января, 2023 (изменено) · Жалоба 2 hours ago, _4afc_ said: Особенность в том, что F9A8 - это 15бит код Баркера и теоретически для плохого канала можно впоследствии улучшить блочную синхронизацию. Также поток можно инвертировать в канале, т.е. не следить сколько раз он проинвертировался на платах. Спасибо за образцы, попробую осмыслить. В CMT2300A для синхрослова использовал 63-битную последовательность (не помню как называется) + ноль в качестве младшего бита в конце: 0x8629E8E4B766AFC0 34 minutes ago, V_G said: Тогда исходный вопрос странен в принципе. Поиском синхрослова и обработкой пакета занимаются указанные ИС, вам-то зачем это делать вручную? Тут кто-то ранее на форуме писал (ник не помню), что более помехоустойчивого приёма можно достичь, отказавшись от пакетного автомата и сделав кореляционный приём с помощью ПСП или кодов Баркера. Что ещё и повысит чувствительность. Вот интересно стало, насколько эффективно и трудозатаратно будет кодировать и декодировать сырой поток. Так как преамбула и синхрослово никак не защищаются, только на payload накладывается свёрточный кодер или манчестер. P.S. Offtopic. Недавно обнаружил трансивер с аппаратным Ридом-Соломоном : Zarlink(Microsemi) ZL70101 Для медицинского оборудования. Но модулей на них не нашёл на алиэкспрессе. Изменено 31 января, 2023 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 26 31 января, 2023 Опубликовано 31 января, 2023 · Жалоба 3 minutes ago, repstosw said: В CMT2300A для синхрослова использовал 63-битную последовательность (не помню как называется) + ноль в качестве 64-го бита: 0x8629E8E4B766AFC0 Ну если CPU доступны 64битные переменные - можете её тоже через 8 case отловить целиком. 3 minutes ago, repstosw said: Тут кто-то ранее на форуме писал (ник не помню), что более помехоустойчивого приёма можно достичь, отказавшись от пакетного автомата и сделав кореляционный приём с помощью ПСП или кодов Баркера. Что ещё и повысит чувствительность. Раз AFE чужой - я бы для начала сделал записи потока - что происходит с битовой синхронизацией и ошибками в данных, в том числе синхро-слове, в новом режиме SNR. А уж потом думал можно ли эти данные вообще восстановить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
V_G 11 31 января, 2023 Опубликовано 31 января, 2023 · Жалоба 8 часов назад, _4afc_ сказал: Раз AFE чужой - я бы для начала сделал записи потока - что происходит с битовой синхронизацией и ошибками в данных, в том числе синхро-слове, в новом режиме SNR. Если уж о front-end, то подкину еще более разрушительную идею - брать сигнал не с обработчика пакетов (плохой) и не с компаратора, а уж напрямую с частотного детектора. Та же SiLabs передала производство цифровых приемников с аналоговым выходом в SkyWorks. У последних есть ИС Si4704 по 5 копеек - радиовещательные ЧМ приемники с цифровым (I2S) и аналоговым (с ЦАП) выходами. Внутри та же цифровая обработка, что и в Si4362, но остановленная чуть раньше - на частотном детектировании. Сносим свой приемный диапазон в FM (64...108 МГц) и наслаждаемся аналоговыми Raw Data. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 1 февраля, 2023 Опубликовано 1 февраля, 2023 · Жалоба 20 часов назад, _4afc_ сказал: Ловилась она так: Показать контент u08 CheckSync(u08 *p) { u32 D=0; D=p[0]<<24; D|=p[1]<<16; D|=p[2]<<8; D|=p[3]; switch(D) { case 0xAAAAF9A8: return 0x00; case 0x5555f351: return 0x01; case 0xAAABE6A2: return 0x02; case 0x5557CD45: return 0x03; case 0xAAAF9A8A: return 0x04; case 0x555f3515: return 0x05; case 0xAABE6A2A: return 0x06; case 0x557CD455: return 0x07; case 0x55550657: return 0x80; case 0xAAAA0CAE: return 0x81; case 0x5554195D: return 0x82; case 0xAAA832BA: return 0x83; case 0x55506575: return 0x84; case 0xAAA0CAEA: return 0x85; case 0x554195D5: return 0x86; case 0XAA832BAA: return 0x87; } return 0xff; } 20 часов назад, _4afc_ сказал: if ((Bin[i]==0xAA)&&(Bin[i+4]==0xAA)) R=CheckSync(&Bin[i]); if ((Bin[i]==0x55)&&(Bin[i+4]==0x55)) R=CheckSync(&Bin[i]); У Вас половина кода CheckSync() в обоих её вызовах не используется. Зачем так? Просто сделать 2 функции - для прямого и инверсного. И такие вещи лучше реализовывать на ассемблере. Например - для Cortex-M портянку switch() из CheckSync() си-компилятор скорее всего скомпилит в крайне неэффективную последовательность из множества: LDR.N Ry, ... CMP Rx,Ry BEQ.N label_... Даже на высоких уровнях оптимизации. В то время как на асме можно написать: SECTION .text:CODE:NOROOT(2) PUBLIC CheckSync_a ;extern "C" int CheckSync_a(u32); THUMB CheckSync_a: LDR R1, =0AAAAF9A8h CMP R0, R1 BEQ CheckSync_a00 CMP R0, R1, ROR #32 - 1 BEQ CheckSync_a01 CMP R0, R1, ROR #32 - 2 BEQ CheckSync_a02 CMP R0, R1, ROR #32 - 3 BEQ CheckSync_a03 CMP R0, R1, ROR #32 - 4 BEQ CheckSync_a04 CMP R0, R1, ROR #32 - 5 BEQ CheckSync_a05 CMP R0, R1, ROR #32 - 6 BEQ CheckSync_a06 CMP R0, R1, ROR #32 - 7 BEQ CheckSync_a07 MOVS R0, #255 BX LR CheckSync_a00: MOVS R0, #0 BX LR CheckSync_a01: MOVS R0, #1 BX LR CheckSync_a02: MOVS R0, #2 BX LR CheckSync_a03: MOVS R0, #3 BX LR CheckSync_a04: MOVS R0, #4 BX LR CheckSync_a05: MOVS R0, #5 BX LR CheckSync_a06: MOVS R0, #6 BX LR CheckSync_a07: MOVS R0, #7 BX LR LTORG и получить на каждом шаге сравнения = ~2-кратное ускорение (2 такта вместо 4-х). Сомневаюсь, что какой-то си-компилятор догадается так сделать..... А если: переписать весь цикл поиска шаблона в блоке на ассемблере; убрать лишние половину сравнений; использовать невыровненное чтение (на ядрах, поддерживающих его) вместо побайтного с конкатенацией и т.п., то (имхо) - ускорение будет более чем 4-кратное. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 26 1 февраля, 2023 Опубликовано 1 февраля, 2023 · Жалоба 3 hours ago, jcxz said: У Вас половина кода CheckSync() в обоих её вызовах не используется. Зачем так? Просто сделать 2 функции - для прямого и инверсного Вы абсолютно правы. Это не зачем, а почему - это исторически сложилось за три шага: 1. CheckSync() вызывался всегда и в нём проверялось равенство =[i+4] 2. Для уменьшения вызовов CheckSync() добавился if (AA) 3. В железе в очередной раз добавили транзистор и пришлось добавить if (55) 3 hours ago, jcxz said: И такие вещи лучше реализовывать на ассемблере. Например - для Cortex-M портянку switch() из CheckSync() си-компилятор скорее всего скомпилит в крайне неэффективную последовательность... Даже на высоких уровнях оптимизации. А если: переписать весь цикл поиска шаблона в блоке на ассемблере; убрать лишние половину сравнений; использовать невыровненное чтение (на ядрах, поддерживающих его) вместо побайтного с конкатенацией и т.п., то (имхо) - ускорение будет более чем 4-кратное. Это классно для ARM/Cortex. Но у меня был BF561 🙂 И его асм я не знал. Тем более что первый этам - (поиск алгоритма на низких SNR) шёл на PC по записанным с эфира дампам. Т.е. код на PC и BF561@500МГц был одинаковый. А уже этап оптимизации алгоритма в BF561 шёл до тех пор пока модем не влез на 300МГц ядра - далее оптимизация уже не так эффективна. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 2 февраля, 2023 Опубликовано 2 февраля, 2023 · Жалоба On 2/1/2023 at 8:37 AM, V_G said: У последних есть ИС Si4704 по 5 копеек - радиовещательные ЧМ приемники с цифровым (I2S) и аналоговым (с ЦАП) выходами. Внутри та же цифровая обработка, что и в Si4362, но остановленная чуть раньше - на частотном детектировании. Сносим свой приемный диапазон в FM (64...108 МГц) и наслаждаемся аналоговыми Raw Data. И 1 мбит/c потянет? В крайнем случае - 250 кбит/c. 23 hours ago, jcxz said: И такие вещи лучше реализовывать на ассемблере. Например - для Cortex-M портянку switch() из CheckSync() си-компилятор скорее всего скомпилит в крайне неэффективную последовательность из множества: Длинный switch/case нормальные Си-компиляторы преобразуют в таблицу переходов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 2 февраля, 2023 Опубликовано 2 февраля, 2023 · Жалоба 45 минут назад, repstosw сказал: Длинный switch/case нормальные Си-компиляторы преобразуют в таблицу переходов. Такой - не преобразуют. Посмотрите внимательно на значения case и подумайте - почему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
V_G 11 2 февраля, 2023 Опубликовано 2 февраля, 2023 · Жалоба 6 часов назад, repstosw сказал: И 1 мбит/c потянет? В крайнем случае - 250 кбит/c. Ну, прежде вы своих скоростных потребностей не обозначали. Но делать аппаратуру связи (профессионально, не для себя одного) с частотной модуляцией в указанном частотном диапазоне и с данной скоростью я бы не стал. Есть более продвинутые способы модуляции, QAM какой-нибудь. И для этого можно подыскать компактный front-end (в цивилизованном мире, у нас не пойму как с доставаемостью...). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 3 февраля, 2023 Опубликовано 3 февраля, 2023 · Жалоба 15 hours ago, V_G said: Ну, прежде вы своих скоростных потребностей не обозначали. Но делать аппаратуру связи (профессионально, не для себя одного) с частотной модуляцией в указанном частотном диапазоне и с данной скоростью я бы не стал. Есть более продвинутые способы модуляции, QAM какой-нибудь. И для этого можно подыскать компактный front-end (в цивилизованном мире, у нас не пойму как с доставаемостью...). С чипами/модулями проблема. Знаю только AT86RF215 с OFDM. На али в виде чипов, модулей нет. Другие не знаю. В идеале - модули LoRa, но скорость маловата (до 62,5 кбит/c). А делать чирп-несущую на дискретке или приспособить микросхемы PLL или FSK-трансивера - не встречал информации. Вот и приходится довольствоваться тем, что есть: модули FSK-трансиверов. Сейчас опытный образец на CMT2300A, придёт Si4463 - проверю насколько он лучше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться