2019-08-31 18:47:09 +02:00
/*
This project is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Multiprotocol is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Multiprotocol . If not , see < http : //www.gnu.org/licenses/>.
*/
# if defined(SCANNER_CYRF6936_INO)
// Ported from DeviationTX frequency scanner
# include "iface_cyrf6936.h"
struct Scanner {
uint8_t rssi [ 255 ] ;
uint8_t chan_min ;
uint8_t chan_max ;
uint8_t attenuator ;
uint16_t averaging ;
} Scanner ;
# define MIN_RADIOCHANNEL 0x00
# define MAX_RADIOCHANNEL 0x62
# define CHANNEL_LOCK_TIME 300 // slow channel requires 270 usec for synthesizer to settle
# define AVERAGE_INTVL 30
static int scan_averages , scan_channel , scan_state ;
enum ScanStates {
SCAN_CHANNEL_CHANGE = 0 ,
SCAN_GET_RSSI = 1 ,
} ;
static void __attribute__ ( ( unused ) ) Scanner_cyrf_init ( )
{
/* Initialize CYRF chip */
CYRF_WriteRegister ( CYRF_1D_MODE_OVERRIDE , 0x38 ) ; // FRC SEN (forces the synthesizer to start) + FRC AWAKE (force the oscillator to keep running at all times)
CYRF_WriteRegister ( CYRF_03_TX_CFG , 0x08 | 7 ) ; // Data Code Length = 32 chip codes + Data Mode = 8DR Mode + max-power(+4 dBm)
CYRF_WriteRegister ( CYRF_06_RX_CFG , 0x4A ) ; // LNA + FAST TURN EN + RXOW EN, enable low noise amplifier, fast turning, overwrite enable
CYRF_WriteRegister ( CYRF_0B_PWR_CTRL , 0x00 ) ; // Reset power control
CYRF_WriteRegister ( CYRF_10_FRAMING_CFG , 0xA4 ) ; // SOP EN + SOP LEN = 32 chips + LEN EN + SOP TH = 04h
CYRF_WriteRegister ( CYRF_11_DATA32_THOLD , 0x05 ) ; // TH32 = 0x05
CYRF_WriteRegister ( CYRF_12_DATA64_THOLD , 0x0E ) ; // TH64 = 0Eh, set pn correlation threshold
CYRF_WriteRegister ( CYRF_1B_TX_OFFSET_LSB , 0x55 ) ; // STRIM LSB = 0x55, typical configuration
CYRF_WriteRegister ( CYRF_1C_TX_OFFSET_MSB , 0x05 ) ; // STRIM MSB = 0x05, typical configuration
CYRF_WriteRegister ( CYRF_32_AUTO_CAL_TIME , 0x3C ) ; // AUTO_CAL_TIME = 3Ch, typical configuration
CYRF_WriteRegister ( CYRF_35_AUTOCAL_OFFSET , 0x14 ) ; // AUTO_CAL_OFFSET = 14h, typical configuration
CYRF_WriteRegister ( CYRF_39_ANALOG_CTRL , 0x01 ) ; // ALL SLOW
CYRF_WriteRegister ( CYRF_1E_RX_OVERRIDE , 0x10 ) ; // FRC RXDR (Force Receive Data Rate)
CYRF_WriteRegister ( CYRF_1F_TX_OVERRIDE , 0x00 ) ; // Reset TX overrides
CYRF_WriteRegister ( CYRF_01_TX_LENGTH , 0x10 ) ; // TX Length = 16 byte packet
CYRF_WriteRegister ( CYRF_27_CLK_OVERRIDE , 0x02 ) ; // RXF, force receive clock
CYRF_WriteRegister ( CYRF_28_CLK_EN , 0x02 ) ; // RXF, force receive clock enable
}
static void __attribute__ ( ( unused ) ) _scan_next ( )
{
CYRF_ConfigRFChannel ( scan_channel + Scanner . chan_min ) ;
switch ( Scanner . attenuator ) {
case 0 : CYRF_WriteRegister ( CYRF_06_RX_CFG , 0x4A ) ; break ; // LNA on, ATT off
case 1 : CYRF_WriteRegister ( CYRF_06_RX_CFG , 0x0A ) ; break ; // LNA off, ATT off
default : CYRF_WriteRegister ( CYRF_06_RX_CFG , 0x2A ) ; break ; // LNA off, no ATT on
}
}
static int __attribute__ ( ( unused ) ) _scan_rssi ( )
{
if ( ! ( CYRF_ReadRegister ( CYRF_05_RX_CTRL ) & 0x80 ) ) {
CYRF_WriteRegister ( CYRF_05_RX_CTRL , 0x80 ) ; // Prepare to receive
delayMicroseconds ( 1 ) ;
CYRF_ReadRegister ( CYRF_13_RSSI ) ; // dummy read
delayMicroseconds ( 1 ) ;
}
return CYRF_ReadRegister ( CYRF_13_RSSI ) & 0x1F ;
}
uint16 Scanner_callback ( )
{
int rssi_value ;
switch ( scan_state ) {
case SCAN_CHANNEL_CHANGE :
scan_averages = 0 ;
scan_channel + + ;
if ( scan_channel = = ( Scanner . chan_max - Scanner . chan_min + 1 ) )
scan_channel = 0 ;
_scan_next ( ) ;
scan_state = SCAN_GET_RSSI ;
return CHANNEL_LOCK_TIME ;
case SCAN_GET_RSSI :
rssi_value = _scan_rssi ( ) ;
Scanner . rssi [ scan_channel ] = ( rssi_value + 9 * Scanner . rssi [ scan_channel ] ) / 10 ; // fast exponential smoothing with alpha 0.1
scan_averages + + ;
if ( scan_averages < Scanner . averaging )
return AVERAGE_INTVL + random ( 0xfefefefe ) % 10 ; // make measurements slightly random in time
scan_state = SCAN_CHANNEL_CHANGE ;
// send data to TX
pkt [ 0 ] = scan_channel ; // channel
pkt [ 1 ] = Scanner . rssi [ scan_channel ] ; // power
telemetry_link = 1 ;
return AVERAGE_INTVL ;
}
}
uint16_t initScanner ( void )
{
Scanner . chan_min = MIN_RADIOCHANNEL ;
Scanner . chan_max = MAX_RADIOCHANNEL ;
// todo: find optimal values or use user options
Scanner . averaging = 2 ;
2019-09-01 14:27:47 +02:00
Scanner . attenuator = 0 ;
2019-08-31 18:47:09 +02:00
scan_averages = 0 ;
scan_channel = 0 ;
scan_state = SCAN_CHANNEL_CHANGE ;
memset ( Scanner . rssi , 0 , sizeof ( Scanner . rssi ) ) ; // clear old rssi values
CYRF_Reset ( ) ;
Scanner_cyrf_init ( ) ;
CYRF_SetTxRxMode ( RX_EN ) ; // Receive mode
BIND_DONE ;
return 1250 ;
}
# endif