Как проверить код BCH (15,11,1) / контрольную сумму для спутниковой системы BDS / Beidou



В PDF http://www.beidou.gov.cn/attach/2012/12/27/201212273da29c5eb8274deb8cd2b178228ba2bd.pdf Глава 5 (стр. 9 и далее) ВСН(15,11,1) код для системы Beidou описано.



Я пытаюсь реализовать использование этого кода для проверки ошибок (т. е. я хочу только проверить информацию о четности - мне не нужна возможность исправления ошибок). В идеале я ищу процедуру, которая получает 15 битов и возвращает соответствующие 4 бита четности.



Я проверил следующий код, но не мог заставить его делать то, что я хочу. В лучшем случае это делает код BCH (15,11,3).



Http://www.eccpage.com/bch3.c



Два примера строк::
E240DCB12D8201A043FFA7277777BA7777777B777776A777803503C00133E000EEC6EEEEEE60
E2411C9D2D9DD17DDDDDDA9DDDE0D500F0026478001635555552D555554B5555552D555554B0



Обратите внимание, что первые 15 битов не являются BCH-кодированными, второй набор является, и начиная с 3-го набора две кодировки чередуются, как описано на стр. 14.



То есть первый BCH (15,11,1) набор должен быть 01101110010 1100, второй без чередования
0100101101100000100000 00011010 и расщепленный
01001011011 0001 и 00000100000 1010.



То, что я ищу, - это процедура, которая получает эти 11 + 4 бита и может проверить четность. Чередование манипуляций и все остальное, что я могу сделать сам. Как уже было сказано, исправление ошибок для меня не важно, мне нужно только Да/нет.



Ценится все, что может мне помочь.

651   2  

2 ответов:

Углубившись в тему, я нашел рабочее решение. Я приведу его здесь как справку для всех, у кого есть такая же проблема.

Примечание: GETBITS-это макрокоманда, которая извлекает заданное количество битов из переменной" data " и сохраняет их в предоставленном аргументе. Мне лень извлекать и сокращать соответствующий код, поэтому используйте свою собственную версию : -)
static int checkbds(int bits)
{
  static int const at[15] = {1, 2, 4, 8, 3, 6, 12, 11, 5, 10, 7, 14, 15, 13, 9};
  int s, i, j;

  for(i = 1; i <= 2; i++)
  {
    s = 0;
    for(j = 0; j < 15; j++)
    {
      if(bits & (1<<j))
      {
        s ^= at[(i * j) % 15];
      }
    }
    if(s != 0)
    {
      return 0;
    }
  }
  return 1;
}

int bdsbch(const unsigned char *data)
{
  int 38, i, b, b2, j;

  GETBITS(b, 15) /* drop first 15 bits */

  GETBITS(b, 15) /* get first bit set */
  if(!checkbds(b))
    return 0;
  for(i = 0; i < 9; ++i)
  {
    GETBITS(b, 11) /* get first bit set */
    GETBITS(b2, 11) /* get second bit set */
    GETBITS(j, 4)
    b = (b<<4)|j;
    GETBITS(j, 4)
    b2 = (b2<<4)|j;
    if(!checkbds(b) || !checkbds(b2))
      return 0;
  }
  return 1;
}

int main(void)
{
  printf("%d\n", bdsbch((const unsigned char*)"\xE2\x40\xDC\xB1\x2D\x82\x01\xA0\x43\xFF"
                  "\xA7\x27\x77\x77\xBA\x77\x77\x77\x7B\x77\x77\x76\xA7\x77\x80"
                  "\x35\x03\xC0\x01\x33\xE0\x00\xEE\xC6\xEE\xEE\xEE\x60"));
  printf("%d\n", bdsbch((const unsigned char*)"\xE2\x41\x1C\x9D\x2D\x9D\xD1\x7D\xDD\xDD"
                  "\xDA\x9D\xDD\xE0\xD5\x00\xF0\x02\x64\x78\x00\x16\x35\x55\x55"
                  "\x52\xD5\x55\x55\x4B\x55\x55\x55\x2D\x55\x55\x54\xB0"));
}

В коде не реализовано чередование. Но МКБ БЕЙДУ говорит, что есть. Ваш код правильно работает ?

Кстати, моя функция вычисления crc -

typedef union {
    uint8_t val;
    struct {
        uint8_t b0:1;
        uint8_t b1:1;
        uint8_t b2:1;
        uint8_t b3:1;
    } bits;
} bch_reg;

uint8_t crc_calc(uint16_t data)
{
    bch_reg reg;
    int8_t i;
    uint8_t gate1; // icd
    reg.val = 0;

    for (i = 10; i >= 0; i--) {
        gate1 = reg.bits.b3^(data >> i & 1);
        reg.bits.b3 = reg.bits.b2;
        reg.bits.b2 = reg.bits.b1;
        reg.bits.b1 = reg.bits.b0^gate1;
        reg.bits.b0 = gate1;
    }

    return reg.val;
}

О, и еще кое-что. Я пытался вычислить crc без декодирования, и это не работает. Так что вам нужно перемежать, чем декодировать, а затем вычислять и проверять crc

uint16_t decode_bch_bin(uint16_t enc)
{
    bch_reg reg;
    int8_t i;
    uint8_t bit;
    uint16_t const err[16] = {0, 1, 2, 16, 4, 256, 32, 1024, 8, 16384, 512, 128, 64, 
        8192, 2048, 4096}; 
    /* see Table 5.2 */
    reg.val = 0;
    /* BCH decoding (Fig 5-4) */
    for (i = 14; i >= 0; i--) {
        bit = reg.bits.b3;
        reg.bits.b3 = reg.bits.b2;
        reg.bits.b2 = reg.bits.b1;
        reg.bits.b1 = reg.bits.b0^bit;
        reg.bits.b0 = (enc >> i & 1)^bit;
    }

    /*error correction*/
    enc ^= err[reg.val];
    /*wipe off crc bits*/
    return enc;
}

P.S. Я предпочитаю uin16_t int, потому что в 1 кодовой последовательности есть 15 бит, но он будет работать и с int

Comments

    Ничего не найдено.