Page:
POCSAG
Clone
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
POCSAG декодер
Обзор
POCSAG (Post Office Code Standardization Advisory Group) — стандарт пейджинговой связи. Данный декодер реализует приём и декодирование POCSAG сигналов с частотами 512 и 1200 бод.
Протокол POCSAG
Структура передачи
┌─────────────────┬──────────────┬──────────────────────────┐
│ Преамбула │ Sync word │ Batch 1 (32 слова) │
│ 0xAAAAAAAB... │ 0x7CD21538 │ [Address/Data] × 32 │
│ (≥576 бит) │ │ │
└─────────────────┴──────────────┴──────────────────────────┘
│
┌────────────────────────────────────┘
▼
┌──────────────────────────┐
│ Batch 2 (32 слова) │
│ + sync word │
└──────────────────────────┘
Параметры
| Параметр | Значение |
|---|---|
| Скорость | 512 или 1200 бод |
| Модуляция | FSK (FM) |
| Кодирование | BCH(31,21) |
| Исправление ошибок | До 2 бит на слово |
| Длина слова | 32 бита (21 данные + 10 BCH + 1 чётность) |
| Преамбула | 0x55555555... ≥ 576 бит, заканчивается на 1 |
| Sync word | 0x7CD21538 |
| Idle word | 0x7A89C197 |
Типы сообщений
| Function bits | Тип | Описание |
|---|---|---|
00 |
Numeric | Числовой пейджер (BCD цифры) |
01 |
Reserved | Зарезервировано |
10 |
Alpha | Алфавитный пейджер (7-bit ASCII) |
11 |
Reserved | Зарезервировано |
Архитектура декодера
Файлы
| Файл | Описание |
|---|---|
app/pocsag/pocsag.c |
Основной декодер |
app/pocsag/pocsag.h |
Заголовочный файл, API |
app/pocsag/bch31.c |
BCH(31,21) коррекция ошибок |
app/pocsag/bch31.h |
Заголовочный файл BCH |
Цепочка обработки
┌──────────┐ ┌──────────────┐ ┌──────────────┐ ┌───────────────┐
│ BK4819 │───▶│ Zero-crossing│───▶│ Bit slicing │───▶│ POCSAG decode │
│ FM demod │ │ detection │ │ (averaging) │ │ (state machine)│
└──────────┘ └──────────────┘ └──────────────┘ └───────────────┘
│
┌─────────────────────────────────────────┘
▼
┌──────────────┐
│ BCH correct │
│ (up to 2 err)│
└──────────────┘
│
▼
┌──────────────┐
│ Ring buffer │
│ (8 messages) │
└──────────────┘
Машина состояний
┌─────────┐
│ IDLE │
└────┬────┘
│ 576 alternating bits
▼
┌──────────────┐
┌───────▶│ PREAMBLE │
│ └──────┬───────┘
timeout │ │ sync word found (0x7CD21538)
│ ▼
│ ┌──────────────┐
│ │ SYNC │
│ └──────┬───────┘
│ │ 32-bit word valid
│ ▼
│ ┌──────────────┐
└────────│ DATA │
sync lost └──────────────┘
Алгоритм BCH(31,21)
Параметры кода
| Параметр | Значение |
|---|---|
| Длина кода (n) | 31 бит |
| Информационные биты (k) | 21 бит |
| Проверочные биты | 10 бит |
| Мин. расстояние (d_min) | 5 |
| Исправление ошибок | До 2 бит |
Генераторный полином
g(x) = x^10 + x^9 + x^8 + x^6 + x^5 + x^3 + 1
= 0x72D (binary: 111 0010 1101)
Процесс коррекции
1. Проверка чётности (even parity)
└─ Если OK и синдром = 0 → нет ошибок
2. Вычисление синдрома S(x) = R(x) mod g(x)
└─ Если S(x) = 0 → нет ошибок
3. Поиск одиночной ошибки
└─ S(x) = x^i mod g(x) для позиции i
└─ Если найдено → исправить бит i
4. Поиск двойной ошибки (перебор пар)
└─ S(x) = x^i + x^j mod g(x) для пар (i, j)
└─ 465 комбинаций для 31 бита
└─ Если найдено → исправить биты i и j
5. Если не найдено → слово отбрасывается
Оптимизация для Cortex-M0
Cortex-M0 не имеет аппаратного деления. Все операции в GF(2) реализованы через сдвиги и XOR:
// Умножение на x в GF(2^10 / g(x))
test_syn <<= 1;
if (test_syn & 0x0400U) { // Если бит 10 установлен
test_syn ^= BCH31_GEN_POLY; // XOR с генератором
}
test_syn &= 0x03FFU; // Оставляем 10 бит
Конфигурация BK4819
Для приёма POCSAG радиочип настраивается следующим образом:
// Узкая полоса (POCSAG обычно narrow FM)
BK4819_SetFilterBandwidth(BK4819_FILTER_BW_NARROW, true);
// Отключение шумоподавления (непрерывный приём аудио)
BK4819_SetupSquelch(0, 0, 0, 0, 255, 0);
// Включение RX链路
BK4819_WriteRegister(BK4819_REG_30,
BK4819_REG_30_ENABLE_VCO_CALIB |
BK4819_REG_30_ENABLE_RX_LINK |
BK4819_REG_30_ENABLE_AF_DAC |
BK4819_REG_30_ENABLE_DISC_MODE |
BK4819_REG_30_ENABLE_PLL_VCO |
BK4819_REG_30_ENABLE_RX_DSP);
// AF output — демодулированный FM сигнал
BK4819_SetAF(BK4819_AF_FM);
Известные ограничения
Сэмплинг (критично)
Проблема: POCSAG_FeedSample() вызывается ~1 раз в 10 мс из timeslice. Для корректного декодирования POCSAG 1200 бод требуется ~1 раз в 125 мкс (8000 сэмплов/сек).
Текущее состояние: Преамбула НЕ будет обнаружена при текущей частоте сэмплирования. BCH коррекция работает правильно, но до неё дело не доходит.
Планируемое исправление:
// В MODE_TimeSlice10ms(), case MODE_POCSAG:
for (int i = 0; i < 80; i++) {
uint16_t audio = BK4819_GetVoiceAmplitudeOut();
POCSAG_FeedSample(audio);
SYSTEM_DelayUs(125); // 8 kHz sampling rate
}
Ограничения памяти
| Ресурс | Использование |
|---|---|
| Кольцевой буфер сообщений | 8 сообщений × ~80 байт = 640 байт |
| Статические буферы декодера | ~200 байт |
| BCH таблица синдромов | 0 байт (вычисляется на лету) |
API декодера
Инициализация
// Инициализация с baud rate 1200
POCSAG_Init(POCSAG_BAUD_1200);
// Настройка радиочасти на частоту 145.525 MHz
POCSAG_ConfigureRadio(145525000);
Переключение скорости
// Переключение 1200 -> 512 бод
POCSAG_SwitchBaud(POCSAG_BAUD_512);
// Текущая скорость
uint32_t baud = POCSAG_GetBaud();
Проверка сообщений
// Проверка наличия декодированных сообщений
if (POCSAG_MessageAvailable()) {
pocsag_msg_t msg;
if (POCSAG_GetMessage(&msg)) {
// msg.address — адрес (21 бит)
// msg.func — function code (2 бита)
// msg.text — текст сообщения
// msg.is_alpha — true = алфавитный, false = числовой
}
}
Состояние декодера
pocsag_state_t state = POCSAG_GetState();
// POCSAG_STATE_IDLE — ожидание
// POCSAG_STATE_PREAMBLE — обнаружение преамбулы
// POCSAG_STATE_SYNC — поиск sync слова
// POCSAG_STATE_DATA — приём данных
bool signal = POCSAG_SignalDetected(); // true если sync найден