#include "pocsag_pager_app_i.h" #define TAG "POCSAGPager" #include void pcsg_preset_init( void* context, const char* preset_name, uint32_t frequency, uint8_t* preset_data, size_t preset_data_size) { furi_assert(context); POCSAGPagerApp* app = context; furi_string_set(app->txrx->preset->name, preset_name); app->txrx->preset->frequency = frequency; app->txrx->preset->data = preset_data; app->txrx->preset->data_size = preset_data_size; } void pcsg_get_frequency_modulation( POCSAGPagerApp* app, FuriString* frequency, FuriString* modulation) { furi_assert(app); if(frequency != NULL) { furi_string_printf( frequency, "%03ld.%02ld", app->txrx->preset->frequency / 1000000 % 1000, app->txrx->preset->frequency / 10000 % 100); } if(modulation != NULL) { furi_string_printf(modulation, "%.2s", furi_string_get_cstr(app->txrx->preset->name)); } } void pcsg_begin(POCSAGPagerApp* app, uint8_t* preset_data) { furi_assert(app); subghz_devices_reset(app->txrx->radio_device); subghz_devices_idle(app->txrx->radio_device); subghz_devices_load_preset(app->txrx->radio_device, FuriHalSubGhzPresetCustom, preset_data); // furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow); app->txrx->txrx_state = PCSGTxRxStateIDLE; } uint32_t pcsg_rx(POCSAGPagerApp* app, uint32_t frequency) { furi_assert(app); if(!subghz_devices_is_frequency_valid(app->txrx->radio_device, frequency)) { furi_crash("POCSAGPager: Incorrect RX frequency."); } furi_assert( app->txrx->txrx_state != PCSGTxRxStateRx && app->txrx->txrx_state != PCSGTxRxStateSleep); subghz_devices_idle(app->txrx->radio_device); uint32_t value = subghz_devices_set_frequency(app->txrx->radio_device, frequency); // Not need. init in subghz_devices_start_async_tx // furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow); subghz_devices_flush_rx(app->txrx->radio_device); subghz_devices_set_rx(app->txrx->radio_device); subghz_devices_start_async_rx( app->txrx->radio_device, subghz_worker_rx_callback, app->txrx->worker); subghz_worker_start(app->txrx->worker); app->txrx->txrx_state = PCSGTxRxStateRx; return value; } void pcsg_idle(POCSAGPagerApp* app) { furi_assert(app); furi_assert(app->txrx->txrx_state != PCSGTxRxStateSleep); subghz_devices_idle(app->txrx->radio_device); app->txrx->txrx_state = PCSGTxRxStateIDLE; } void pcsg_rx_end(POCSAGPagerApp* app) { furi_assert(app); furi_assert(app->txrx->txrx_state == PCSGTxRxStateRx); if(subghz_worker_is_running(app->txrx->worker)) { subghz_worker_stop(app->txrx->worker); subghz_devices_stop_async_rx(app->txrx->radio_device); } subghz_devices_idle(app->txrx->radio_device); app->txrx->txrx_state = PCSGTxRxStateIDLE; } void pcsg_sleep(POCSAGPagerApp* app) { furi_assert(app); subghz_devices_sleep(app->txrx->radio_device); app->txrx->txrx_state = PCSGTxRxStateSleep; } void pcsg_hopper_update(POCSAGPagerApp* app) { furi_assert(app); switch(app->txrx->hopper_state) { case PCSGHopperStateOFF: return; break; case PCSGHopperStatePause: return; break; case PCSGHopperStateRSSITimeOut: if(app->txrx->hopper_timeout != 0) { app->txrx->hopper_timeout--; return; } break; default: break; } float rssi = -127.0f; if(app->txrx->hopper_state != PCSGHopperStateRSSITimeOut) { // See RSSI Calculation timings in CC1101 17.3 RSSI rssi = subghz_devices_get_rssi(app->txrx->radio_device); // Stay if RSSI is high enough if(rssi > -90.0f) { app->txrx->hopper_timeout = 10; app->txrx->hopper_state = PCSGHopperStateRSSITimeOut; return; } } else { app->txrx->hopper_state = PCSGHopperStateRunnig; } // Select next frequency if(app->txrx->hopper_idx_frequency < subghz_setting_get_hopper_frequency_count(app->setting) - 1) { app->txrx->hopper_idx_frequency++; } else { app->txrx->hopper_idx_frequency = 0; } if(app->txrx->txrx_state == PCSGTxRxStateRx) { pcsg_rx_end(app); }; if(app->txrx->txrx_state == PCSGTxRxStateIDLE) { subghz_receiver_reset(app->txrx->receiver); app->txrx->preset->frequency = subghz_setting_get_hopper_frequency(app->setting, app->txrx->hopper_idx_frequency); pcsg_rx(app, app->txrx->preset->frequency); } }