Перейти к содержанию
    

RAW Data: выделение синхро-слова, пакета итп.

Дано: приёмо-передатчик.  Приёмник с выходом демодулятора  в двоичном виде - последовательность нулей и единиц: 0010001011100000011111111...  И тактовая синхронизация.

Вопрос:  как в мешанине нулей и единиц искать синхро-слово?  Авто-корреляция, да.  А как это практически - для дискретных отсчётов?  Циклом сдвигать битовый поток с образцом с поиском по максимальному совпадению?

В качестве синхро-слова - брать код Баркера или длинную М-последовательность?

Есть ли смысл делать синхрослово очень большим?  Например 63 бита,  чтобы АКФ была максимальна.

Есть литература, которая рассказывает как на практике делать поиск пакета в сырых данных?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, repstosw said:

Дано: приёмо-передатчик.  Приёмник с выходом демодулятора  в двоичном виде - последовательность нулей и единиц: 0010001011100000011111111...  И тактовая синхронизация.

Как обрабатываем:  ПЛИС на верилоге побитно или ЦСП на СИ блоками?

Иногда с приёмника ещё уровень сигнала заводят для определения начала пакета.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, repstosw сказал:

Дано: приёмо-передатчик

Приемопередатчик какой? Если эфирный, то перед синхрословом принято передавать (передатчиком) и искать (приемником) преамбулу: чаще всего это последовательность 010101... А потом уже синхрослово. ПЛИС тут особенно не нужна, достаточно сдвигового регистра и схемы сравнения. Изредка допускают потерю 1-2 бит в синхрослове, тогда схема сравнения должна считать число совпадений синхрослова и содержимого сдвигового регистра. Чаще всего после обнаружения преамбулы заданной длины ищут синхрослово в течение заданного числа тактовых интервалов, схема дополняется счетчиком и сбросом в исходное состояние поиска преамбулы при переполнении счетчика. Реализация всего этого может быть как программная, так и аппаратная.

P.S. Контроля несущей я не делаю, он ограничивает чувствительность системы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 hours ago, _4afc_ said:

Как обрабатываем:  ПЛИС на верилоге побитно или ЦСП на СИ блоками?

На CPU Си-кодом.

10 hours ago, V_G said:

Приемопередатчик какой? Если эфирный, то перед синхрословом принято передавать (передатчиком) и искать (приемником) преамбулу: чаще всего это последовательность 010101... А потом уже синхрослово. ПЛИС тут особенно не нужна, достаточно сдвигового регистра и схемы сравнения.

CMT2300A, SI4463, и им подобные.

Преамбула перед синхрословом есть - 8 байт 0xAA

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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бит код Баркера и теоретически для плохого канала можно впоследствии улучшить блочную синхронизацию.

Также поток можно инвертировать в канале, т.е. не следить сколько раз он проинвертировался на платах.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 часов назад, repstosw сказал:

CMT2300A, SI4463, и им подобные.

Преамбула перед синхрословом есть - 8 байт 0xAA

Тогда исходный вопрос странен в принципе. Поиском синхрослова и обработкой пакета занимаются указанные ИС, вам-то зачем это делать вручную?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, _4afc_ said:

Особенность в том, что F9A8 - это 15бит код Баркера и теоретически для плохого канала можно впоследствии улучшить блочную синхронизацию.

Также поток можно инвертировать в канале, т.е. не следить сколько раз он проинвертировался на платах.

Спасибо за образцы, попробую осмыслить.

В CMT2300A для синхрослова использовал 63-битную последовательность (не помню как называется) + ноль в качестве младшего бита в конце:

0x8629E8E4B766AFC0

 

34 minutes ago, V_G said:

Тогда исходный вопрос странен в принципе. Поиском синхрослова и обработкой пакета занимаются указанные ИС, вам-то зачем это делать вручную?

Тут кто-то ранее на форуме писал (ник не помню), что более помехоустойчивого приёма можно достичь, отказавшись от пакетного автомата и сделав кореляционный приём с помощью ПСП или кодов Баркера.  Что ещё и повысит чувствительность.  Вот интересно стало, насколько эффективно и трудозатаратно будет кодировать и декодировать сырой поток.

Так как преамбула и синхрослово никак не защищаются, только на payload накладывается свёрточный кодер или манчестер.

 

P.S. Offtopic.

Недавно обнаружил трансивер с аппаратным Ридом-Соломоном : Zarlink(Microsemi) ZL70101

Для  медицинского оборудования. Но модулей на них не нашёл на алиэкспрессе.

image.thumb.png.8b005e611ec6e194414a47dd700b1f16.png

 

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, repstosw said:

В CMT2300A для синхрослова использовал 63-битную последовательность (не помню как называется) + ноль в качестве 64-го бита:

0x8629E8E4B766AFC0

Ну если CPU доступны 64битные переменные - можете её тоже через 8 case отловить целиком.

 

3 minutes ago, repstosw said:

Тут кто-то ранее на форуме писал (ник не помню), что более помехоустойчивого приёма можно достичь, отказавшись от пакетного автомата и сделав кореляционный приём с помощью ПСП или кодов Баркера.  Что ещё и повысит чувствительность.

Раз AFE чужой - я бы для начала сделал записи потока - что происходит с битовой синхронизацией и ошибками в данных, в том числе синхро-слове, в новом режиме SNR.

А уж потом думал можно ли эти данные вообще восстановить. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 часов назад, _4afc_ сказал:

Раз AFE чужой - я бы для начала сделал записи потока - что происходит с битовой синхронизацией и ошибками в данных, в том числе синхро-слове, в новом режиме SNR.

Если уж о front-end, то подкину еще более разрушительную идею - брать сигнал не с обработчика пакетов (плохой) и не с компаратора, а уж напрямую с частотного детектора. Та же SiLabs передала производство цифровых приемников с аналоговым выходом в SkyWorks. У последних есть ИС Si4704 по 5 копеек - радиовещательные ЧМ приемники с цифровым (I2S) и аналоговым (с ЦАП) выходами. Внутри та же цифровая обработка, что и в Si4362, но остановленная чуть раньше - на частотном детектировании. Сносим свой приемный диапазон в FM (64...108 МГц) и наслаждаемся аналоговыми Raw Data.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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-х).  Сомневаюсь, что какой-то си-компилятор догадается так сделать..... :wink:

А если: переписать весь цикл поиска шаблона в блоке на ассемблере; убрать лишние половину сравнений; использовать невыровненное чтение (на ядрах, поддерживающих его) вместо побайтного с конкатенацией и т.п., то (имхо) - ускорение будет более чем 4-кратное.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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МГц ядра - далее оптимизация уже не так эффективна.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 нормальные Си-компиляторы преобразуют в таблицу переходов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

45 минут назад, repstosw сказал:

Длинный switch/case нормальные Си-компиляторы преобразуют в таблицу переходов.

Такой - не преобразуют. Посмотрите внимательно на значения case и подумайте - почему.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 часов назад, repstosw сказал:

И 1 мбит/c потянет? В крайнем случае - 250 кбит/c.

Ну, прежде вы своих скоростных потребностей не обозначали. Но делать аппаратуру связи (профессионально, не для себя одного) с частотной модуляцией в указанном частотном диапазоне и с данной  скоростью я бы не стал. Есть более продвинутые способы модуляции, QAM какой-нибудь. И для этого можно подыскать компактный front-end (в цивилизованном мире, у нас не пойму как с доставаемостью...).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 hours ago, V_G said:

Ну, прежде вы своих скоростных потребностей не обозначали. Но делать аппаратуру связи (профессионально, не для себя одного) с частотной модуляцией в указанном частотном диапазоне и с данной  скоростью я бы не стал. Есть более продвинутые способы модуляции, QAM какой-нибудь. И для этого можно подыскать компактный front-end (в цивилизованном мире, у нас не пойму как с доставаемостью...).

С чипами/модулями проблема.  Знаю только AT86RF215  с OFDM.  На али в виде чипов, модулей нет.

Другие не знаю.  В идеале - модули LoRa, но скорость маловата (до 62,5 кбит/c).   А делать чирп-несущую на дискретке или приспособить микросхемы PLL или FSK-трансивера - не встречал информации.

Вот и приходится довольствоваться тем, что есть:  модули FSK-трансиверов.

Сейчас опытный образец на CMT2300A, придёт Si4463 - проверю насколько он лучше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...