2011-01-13 09:45:18 +01:00
/**
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* @ file rfm22b . c
* @ author The OpenPilot Team , http : //www.openpilot.org Copyright (C) 2010.
* @ brief RF Module hardware layer
* @ see The GNU Public License ( GPL ) Version 3
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* This program 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 .
*
* This program 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 this program ; if not , write to the Free Software Foundation , Inc . ,
* 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
// *****************************************************************
// RFM22B hardware layer
//
// This module uses the RFM22B's internal packet handling hardware to encapsulate our own packet data.
//
// The RFM22B internal hardware packet handler configuration is as follows ..
//
// 4-byte (32-bit) preamble .. alternating 0's & 1's
// 4-byte (32-bit) sync
// 1-byte packet length (number of data bytes to follow)
// 0 to 255 user data bytes
//
// Our own packet data will also contain it's own header and 32-bit CRC as a single 16-bit CRC is not sufficient for wireless comms.
//
// *****************************************************************
# include <string.h> // memmove
# include "stm32f10x.h"
# include "main.h"
# include "stopwatch.h"
# include "gpio_in.h"
# include "rfm22b.h"
# if defined(PIOS_COM_DEBUG)
2011-02-06 22:21:50 +01:00
# define RFM22_DEBUG
2011-01-13 09:45:18 +01:00
// #define RFM22_INT_TIMEOUT_DEBUG
# endif
// *****************************************************************
// forward delarations
# if defined(RFM22_EXT_INT_USE)
void rfm22_processInt ( void ) ;
# endif
// ************************************
// this is too adjust the RF module so that it is on frequency
# define OSC_LOAD_CAP 0x7F // cap = 12.5pf .. default
# define OSC_LOAD_CAP_1 0x7D // board 1
# define OSC_LOAD_CAP_2 0x7B // board 2
# define OSC_LOAD_CAP_3 0x7E // board 3
# define OSC_LOAD_CAP_4 0x7F // board 4
// ************************************
# define TX_TEST_MODE_TIMELIMIT_MS 30000 // TX test modes time limit (in ms)
2011-02-25 12:28:39 +01:00
//#define TX_PREAMBLE_NIBBLES 8 // 7 to 511 (number of nibbles)
//#define RX_PREAMBLE_NIBBLES 5 // 5 to 31 (number of nibbles)
# define TX_PREAMBLE_NIBBLES 12 // 7 to 511 (number of nibbles)
# define RX_PREAMBLE_NIBBLES 6 // 5 to 31 (number of nibbles)
2011-01-13 09:45:18 +01:00
# define FIFO_SIZE 64 // the size of the rf modules internal FIFO buffers
# define TX_FIFO_HI_WATERMARK 62 // 0-63
# define TX_FIFO_LO_WATERMARK 32 // 0-63
# define RX_FIFO_HI_WATERMARK 32 // 0-63
2011-03-03 17:32:43 +01:00
# define PREAMBLE_BYTE 0x55 // preamble byte (preceeds SYNC_BYTE's)
2011-01-13 09:45:18 +01:00
# define SYNC_BYTE_1 0x2D // RF sync bytes (32-bit in all)
# define SYNC_BYTE_2 0xD4 //
# define SYNC_BYTE_3 0x4B //
# define SYNC_BYTE_4 0x59 //
// ************************************
// the default TX power level
2011-02-06 11:55:08 +01:00
# define RFM22_DEFAULT_RF_POWER RFM22_tx_pwr_txpow_0 // +1dBm ... 1.25mW
//#define RFM22_DEFAULT_RF_POWER RFM22_tx_pwr_txpow_1 // +2dBm ... 1.6mW
//#define RFM22_DEFAULT_RF_POWER RFM22_tx_pwr_txpow_2 // +5dBm ... 3.16mW
//#define RFM22_DEFAULT_RF_POWER RFM22_tx_pwr_txpow_3 // +8dBm ... 6.3mW
//#define RFM22_DEFAULT_RF_POWER RFM22_tx_pwr_txpow_4 // +11dBm .. 12.6mW
//#define RFM22_DEFAULT_RF_POWER RFM22_tx_pwr_txpow_5 // +14dBm .. 25mW
//#define RFM22_DEFAULT_RF_POWER RFM22_tx_pwr_txpow_6 // +17dBm .. 50mW
//#define RFM22_DEFAULT_RF_POWER RFM22_tx_pwr_txpow_7 // +20dBm .. 100mW
2011-01-13 09:45:18 +01:00
// ************************************
// the default RF datarate
//#define RFM22_DEFAULT_RF_DATARATE 500 // 500 bits per sec
//#define RFM22_DEFAULT_RF_DATARATE 1000 // 1k bits per sec
//#define RFM22_DEFAULT_RF_DATARATE 2000 // 2k bits per sec
//#define RFM22_DEFAULT_RF_DATARATE 4000 // 4k bits per sec
//#define RFM22_DEFAULT_RF_DATARATE 8000 // 8k bits per sec
//#define RFM22_DEFAULT_RF_DATARATE 9600 // 9.6k bits per sec
//#define RFM22_DEFAULT_RF_DATARATE 16000 // 16k bits per sec
//#define RFM22_DEFAULT_RF_DATARATE 19200 // 19k2 bits per sec
//#define RFM22_DEFAULT_RF_DATARATE 24000 // 24k bits per sec
//#define RFM22_DEFAULT_RF_DATARATE 32000 // 32k bits per sec
//#define RFM22_DEFAULT_RF_DATARATE 64000 // 64k bits per sec
# define RFM22_DEFAULT_RF_DATARATE 128000 // 128k bits per sec
//#define RFM22_DEFAULT_RF_DATARATE 192000 // 192k bits per sec
//#define RFM22_DEFAULT_RF_DATARATE 256000 // 256k bits per sec .. NOT YET WORKING
// ************************************
2011-02-23 10:30:06 +01:00
# define RFM22_DEFAULT_SS_RF_DATARATE 125 // 128bps
// ************************************
// Normal data streaming
2011-01-13 09:45:18 +01:00
// GFSK modulation
// no manchester encoding
// data whitening
// FIFO mode
// 5-nibble rx preamble length detection
// 10-nibble tx preamble length
2011-02-23 10:30:06 +01:00
// AFC enabled
2011-01-13 09:45:18 +01:00
# define LOOKUP_SIZE 14
// xtal 10 ppm, 434MHz
2011-02-23 10:30:06 +01:00
const uint32_t data_rate [ LOOKUP_SIZE ] = { 500 , 1000 , 2000 , 4000 , 8000 , 9600 , 16000 , 19200 , 24000 , 32000 , 64000 , 128000 , 192000 , 256000 } ;
const uint8_t modulation_index [ LOOKUP_SIZE ] = { 16 , 8 , 4 , 2 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 } ;
const uint32_t freq_deviation [ LOOKUP_SIZE ] = { 4000 , 4000 , 4000 , 4000 , 4000 , 4800 , 8000 , 9600 , 12000 , 16000 , 32000 , 64000 , 96000 , 128000 } ;
const uint32_t rx_bandwidth [ LOOKUP_SIZE ] = { 17500 , 17500 , 17500 , 17500 , 17500 , 19400 , 32200 , 38600 , 51200 , 64100 , 137900 , 269300 , 420200 , 518800 } ;
const int8_t est_rx_sens_dBm [ LOOKUP_SIZE ] = { - 118 , - 118 , - 117 , - 116 , - 115 , - 115 , - 112 , - 112 , - 110 , - 109 , - 106 , - 103 , - 101 , - 100 } ; // estimated receiver sensitivity for BER = 1E-3
2011-02-25 12:28:39 +01:00
const uint8_t reg_1C [ LOOKUP_SIZE ] = { 0x37 , 0x37 , 0x37 , 0x37 , 0x3A , 0x3B , 0x26 , 0x28 , 0x2E , 0x16 , 0x07 , 0x83 , 0x8A , 0x8C } ; // rfm22_if_filter_bandwidth
2011-02-23 10:30:06 +01:00
2011-02-25 12:28:39 +01:00
const uint8_t reg_1D [ LOOKUP_SIZE ] = { 0x44 , 0x44 , 0x44 , 0x44 , 0x44 , 0x44 , 0x44 , 0x44 , 0x44 , 0x44 , 0x44 , 0x44 , 0x44 , 0x44 } ; // rfm22_afc_loop_gearshift_override
const uint8_t reg_1E [ LOOKUP_SIZE ] = { 0x0A , 0x0A , 0x0A , 0x0A , 0x0A , 0x0A , 0x0A , 0x0A , 0x0A , 0x0A , 0x0A , 0x0A , 0x0A , 0x02 } ; // rfm22_afc_timing_control
const uint8_t reg_1F [ LOOKUP_SIZE ] = { 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 } ; // rfm22_clk_recovery_gearshift_override
const uint8_t reg_20 [ LOOKUP_SIZE ] = { 0xE8 , 0xF4 , 0xFA , 0x70 , 0x3F , 0x34 , 0x3F , 0x34 , 0x2A , 0x3F , 0x3F , 0x5E , 0x3F , 0x2F } ; // rfm22_clk_recovery_oversampling_ratio
2011-02-23 10:30:06 +01:00
const uint8_t reg_21 [ LOOKUP_SIZE ] = { 0x60 , 0x20 , 0x00 , 0x01 , 0x02 , 0x02 , 0x02 , 0x02 , 0x03 , 0x02 , 0x02 , 0x01 , 0x02 , 0x02 } ; // rfm22_clk_recovery_offset2
const uint8_t reg_22 [ LOOKUP_SIZE ] = { 0x20 , 0x41 , 0x83 , 0x06 , 0x0C , 0x75 , 0x0C , 0x75 , 0x12 , 0x0C , 0x0C , 0x5D , 0x0C , 0xBB } ; // rfm22_clk_recovery_offset1
const uint8_t reg_23 [ LOOKUP_SIZE ] = { 0xC5 , 0x89 , 0x12 , 0x25 , 0x4A , 0x25 , 0x4A , 0x25 , 0x6F , 0x4A , 0x4A , 0x86 , 0x4A , 0x0D } ; // rfm22_clk_recovery_offset0
2011-02-25 12:28:39 +01:00
const uint8_t reg_24 [ LOOKUP_SIZE ] = { 0x00 , 0x00 , 0x00 , 0x02 , 0x07 , 0x07 , 0x07 , 0x07 , 0x07 , 0x07 , 0x07 , 0x05 , 0x07 , 0x07 } ; // rfm22_clk_recovery_timing_loop_gain1
const uint8_t reg_25 [ LOOKUP_SIZE ] = { 0x0A , 0x23 , 0x85 , 0x0E , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0x74 , 0xFF , 0xFF } ; // rfm22_clk_recovery_timing_loop_gain0
2011-02-23 10:30:06 +01:00
const uint8_t reg_2A [ LOOKUP_SIZE ] = { 0x0E , 0x0E , 0x0E , 0x0E , 0x0E , 0x0D , 0x0D , 0x0E , 0x12 , 0x17 , 0x31 , 0x50 , 0x50 , 0x50 } ; // rfm22_afc_limiter .. AFC_pull_in_range = <20> AFCLimiter[7:0] x (hbsel+1) x 625 Hz
const uint8_t reg_6E [ LOOKUP_SIZE ] = { 0x04 , 0x08 , 0x10 , 0x20 , 0x41 , 0x4E , 0x83 , 0x9D , 0xC4 , 0x08 , 0x10 , 0x20 , 0x31 , 0x41 } ; // rfm22_tx_data_rate1
const uint8_t reg_6F [ LOOKUP_SIZE ] = { 0x19 , 0x31 , 0x62 , 0xC5 , 0x89 , 0xA5 , 0x12 , 0x49 , 0x9C , 0x31 , 0x62 , 0xC5 , 0x27 , 0x89 } ; // rfm22_tx_data_rate0
const uint8_t reg_70 [ LOOKUP_SIZE ] = { 0x2D , 0x2D , 0x2D , 0x2D , 0x2D , 0x2D , 0x2D , 0x2D , 0x2D , 0x0D , 0x0D , 0x0D , 0x0D , 0x0D } ; // rfm22_modulation_mode_control1
const uint8_t reg_71 [ LOOKUP_SIZE ] = { 0x23 , 0x23 , 0x23 , 0x23 , 0x23 , 0x23 , 0x23 , 0x23 , 0x23 , 0x23 , 0x23 , 0x23 , 0x23 , 0x23 } ; // rfm22_modulation_mode_control2
const uint8_t reg_72 [ LOOKUP_SIZE ] = { 0x06 , 0x06 , 0x06 , 0x06 , 0x06 , 0x08 , 0x0D , 0x0F , 0x13 , 0x1A , 0x33 , 0x66 , 0x9A , 0xCD } ; // rfm22_frequency_deviation
// ************************************
// Scan Spectrum settings
// GFSK modulation
// no manchester encoding
// data whitening
// FIFO mode
// 5-nibble rx preamble length detection
// 10-nibble tx preamble length
// AFC disabled
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
# define SS_LOOKUP_SIZE 2
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
// xtal 1 ppm, 434MHz
const uint32_t ss_rx_bandwidth [ SS_LOOKUP_SIZE ] = { 2600 , 10600 } ;
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
const uint8_t ss_reg_1C [ SS_LOOKUP_SIZE ] = { 0x51 , 0x32 } ; // rfm22_if_filter_bandwidth
const uint8_t ss_reg_1D [ SS_LOOKUP_SIZE ] = { 0x00 , 0x00 } ; // rfm22_afc_loop_gearshift_override
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
const uint8_t ss_reg_20 [ SS_LOOKUP_SIZE ] = { 0xE8 , 0x38 } ; // rfm22_clk_recovery_oversampling_ratio
const uint8_t ss_reg_21 [ SS_LOOKUP_SIZE ] = { 0x60 , 0x02 } ; // rfm22_clk_recovery_offset2
const uint8_t ss_reg_22 [ SS_LOOKUP_SIZE ] = { 0x20 , 0x4D } ; // rfm22_clk_recovery_offset1
const uint8_t ss_reg_23 [ SS_LOOKUP_SIZE ] = { 0xC5 , 0xD3 } ; // rfm22_clk_recovery_offset0
const uint8_t ss_reg_24 [ SS_LOOKUP_SIZE ] = { 0x00 , 0x07 } ; // rfm22_clk_recovery_timing_loop_gain1
const uint8_t ss_reg_25 [ SS_LOOKUP_SIZE ] = { 0x0F , 0xFF } ; // rfm22_clk_recovery_timing_loop_gain0
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
const uint8_t ss_reg_2A [ SS_LOOKUP_SIZE ] = { 0xFF , 0xFF } ; // rfm22_afc_limiter .. AFC_pull_in_range = <20> AFCLimiter[7:0] x (hbsel+1) x 625 Hz
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
const uint8_t ss_reg_70 [ SS_LOOKUP_SIZE ] = { 0x24 , 0x2D } ; // rfm22_modulation_mode_control1
const uint8_t ss_reg_71 [ SS_LOOKUP_SIZE ] = { 0x2B , 0x23 } ; // rfm22_modulation_mode_control2
2011-01-13 09:45:18 +01:00
// ************************************
volatile bool initialized = false ;
# if defined(RFM22_EXT_INT_USE)
volatile bool exec_using_spi ; // set this if you want to access the SPI bus outside of the interrupt
volatile bool inside_ext_int ; // this is set whenever we are inside the interrupt
# endif
uint8_t device_type ; // the RF chips device ID number
uint8_t device_version ; // the RF chips revision number
volatile uint8_t rf_mode ; // holds our current RF mode
uint32_t lower_carrier_frequency_limit_Hz ; // the minimum RF frequency we can use
uint32_t upper_carrier_frequency_limit_Hz ; // the maximum RF frequency we can use
2011-02-02 18:53:46 +01:00
uint32_t carrier_frequency_hz ; // the current RF frequency we are on
2011-01-13 09:45:18 +01:00
uint32_t carrier_datarate_bps ; // the RF data rate we are using
2011-02-05 00:00:48 +01:00
uint32_t rf_bandwidth_used ; // the RF bandwidth currently used
2011-02-23 10:30:06 +01:00
uint32_t ss_rf_bandwidth_used ; // the RF bandwidth currently used
2011-02-05 00:00:48 +01:00
2011-01-13 09:45:18 +01:00
uint8_t hbsel ; // holds the hbsel (1 or 2)
2011-02-05 14:45:16 +01:00
float frequency_step_size ; // holds the minimum frequency step size
2011-01-13 09:45:18 +01:00
uint8_t frequency_hop_channel ; // current frequency hop channel
uint8_t frequency_hop_step_size_reg ; //
uint8_t adc_config ; // holds the adc config reg value
volatile uint8_t device_status ; // device status register
volatile uint8_t int_status1 ; // interrupt status register 1
volatile uint8_t int_status2 ; // interrupt status register 2
volatile uint8_t ezmac_status ; // ezmac status register
volatile int16_t afc_correction ; // afc correction reading
volatile int32_t afc_correction_Hz ; // afc correction reading (in Hz)
volatile int16_t temperature_reg ; // the temperature sensor reading
# if defined(RFM22_DEBUG)
volatile uint8_t prev_device_status ; // just for debugging
volatile uint8_t prev_int_status1 ; // " "
volatile uint8_t prev_int_status2 ; // " "
volatile uint8_t prev_ezmac_status ; // " "
bool debug_outputted ;
# endif
2011-02-02 12:44:23 +01:00
volatile uint8_t osc_load_cap ; // xtal frequency calibration value
2011-01-13 09:45:18 +01:00
volatile uint8_t rssi ; // the current RSSI (register value)
volatile int16_t rssi_dBm ; // dBm value
2011-02-06 22:21:50 +01:00
uint8_t tx_power ; // the transmit power to use for data transmissions
2011-01-13 09:45:18 +01:00
volatile uint8_t tx_pwr ; // the tx power register read back
volatile uint8_t rx_buffer_current ; // the current receive buffer in use (double buffer)
volatile uint8_t rx_buffer [ 256 ] __attribute__ ( ( aligned ( 4 ) ) ) ; // the receive buffer .. received packet data is saved here
volatile uint16_t rx_buffer_wr ; // the receive buffer write index
volatile uint8_t rx_packet_buf [ 256 ] __attribute__ ( ( aligned ( 4 ) ) ) ; // the received packet
volatile uint16_t rx_packet_wr ; // the receive packet write index
2011-02-03 08:05:32 +01:00
volatile int16_t rx_packet_start_rssi_dBm ; //
2011-02-04 11:03:47 +01:00
volatile int32_t rx_packet_start_afc_Hz ; //
2011-02-03 08:05:32 +01:00
volatile int16_t rx_packet_rssi_dBm ; // the received packet signal strength
2011-01-13 09:45:18 +01:00
volatile int32_t rx_packet_afc_Hz ; // the receive packet frequency offset
volatile uint8_t * tx_data_addr ; // the address of the data we send in the transmitted packets
volatile uint16_t tx_data_rd ; // the tx data read index
volatile uint16_t tx_data_wr ; // the tx data write index
int lookup_index ;
2011-02-23 10:30:06 +01:00
int ss_lookup_index ;
2011-01-13 09:45:18 +01:00
volatile bool power_on_reset ; // set if the RF module has reset itself
volatile uint16_t rfm22_int_timer ; // used to detect if the RF module stops responding. thus act accordingly if it does stop responding.
volatile uint16_t rfm22_int_time_outs ; // counter
volatile uint16_t prev_rfm22_int_time_outs ; //
uint32_t clear_channel_count = ( TX_PREAMBLE_NIBBLES + 4 ) * 2 ; // minimum clear channel time before allowing transmit
uint16_t timeout_ms = 20000 ; //
uint16_t timeout_sync_ms = 3 ; //
uint16_t timeout_data_ms = 20 ; //
2011-03-03 17:32:43 +01:00
t_rfm22_TxDataCallback tx_data_callback_function ;
2011-01-13 09:45:18 +01:00
// ************************************
// SPI read/write
void rfm22_startBurstWrite ( uint8_t addr )
{
// wait 1us .. so we don't toggle the CS line to quickly
PIOS_DELAY_WaituS ( 1 ) ;
// chip select line LOW
PIOS_SPI_RC_PinSet ( RFM22_PIOS_SPI , 0 ) ;
PIOS_SPI_TransferByte ( RFM22_PIOS_SPI , 0x80 | addr ) ;
}
inline void rfm22_burstWrite ( uint8_t data )
{
PIOS_SPI_TransferByte ( RFM22_PIOS_SPI , data ) ;
}
void rfm22_endBurstWrite ( void )
{
// chip select line HIGH
PIOS_SPI_RC_PinSet ( RFM22_PIOS_SPI , 1 ) ;
}
void rfm22_write ( uint8_t addr , uint8_t data )
{
// wait 1us .. so we don't toggle the CS line to quickly
PIOS_DELAY_WaituS ( 1 ) ;
// chip select line LOW
PIOS_SPI_RC_PinSet ( RFM22_PIOS_SPI , 0 ) ;
PIOS_SPI_TransferByte ( RFM22_PIOS_SPI , 0x80 | addr ) ;
PIOS_SPI_TransferByte ( RFM22_PIOS_SPI , data ) ;
// chip select line HIGH
PIOS_SPI_RC_PinSet ( RFM22_PIOS_SPI , 1 ) ;
}
void rfm22_startBurstRead ( uint8_t addr )
{
// wait 1us .. so we don't toggle the CS line to quickly
PIOS_DELAY_WaituS ( 1 ) ;
// chip select line LOW
PIOS_SPI_RC_PinSet ( RFM22_PIOS_SPI , 0 ) ;
PIOS_SPI_TransferByte ( RFM22_PIOS_SPI , addr & 0x7f ) ;
}
inline uint8_t rfm22_burstRead ( void )
{
return PIOS_SPI_TransferByte ( RFM22_PIOS_SPI , 0xff ) ;
}
void rfm22_endBurstRead ( void )
{
// chip select line HIGH
PIOS_SPI_RC_PinSet ( RFM22_PIOS_SPI , 1 ) ;
}
uint8_t rfm22_read ( uint8_t addr )
{
uint8_t rdata ;
// wait 1us .. so we don't toggle the CS line to quickly
PIOS_DELAY_WaituS ( 1 ) ;
// chip select line LOW
PIOS_SPI_RC_PinSet ( RFM22_PIOS_SPI , 0 ) ;
PIOS_SPI_TransferByte ( RFM22_PIOS_SPI , addr & 0x7f ) ;
rdata = PIOS_SPI_TransferByte ( RFM22_PIOS_SPI , 0xff ) ;
// chip select line HIGH
PIOS_SPI_RC_PinSet ( RFM22_PIOS_SPI , 1 ) ;
return rdata ;
}
// ************************************
// external interrupt
# if defined(RFM22_EXT_INT_USE)
void RFM22_EXT_INT_FUNC ( void )
{
inside_ext_int = TRUE ;
if ( EXTI_GetITStatus ( RFM22_EXT_INT_LINE ) ! = RESET )
{
// Clear the EXTI line pending bit
EXTI_ClearITPendingBit ( RFM22_EXT_INT_LINE ) ;
// USB_LED_TOGGLE; // TEST ONLY
if ( ! booting & & ! exec_using_spi )
{
// while (!GPIO_IN(RF_INT_PIN) && !exec_using_spi)
{ // stay here until the interrupt line returns HIGH
rfm22_processInt ( ) ;
}
}
}
inside_ext_int = FALSE ;
}
void rfm22_disableExtInt ( void )
{
// Configure the external interrupt
GPIO_EXTILineConfig ( RFM22_EXT_INT_PORT_SOURCE , RFM22_EXT_INT_PIN_SOURCE ) ;
EXTI_InitTypeDef EXTI_InitStructure ;
EXTI_InitStructure . EXTI_Line = RFM22_EXT_INT_LINE ;
EXTI_InitStructure . EXTI_Mode = EXTI_Mode_Interrupt ;
EXTI_InitStructure . EXTI_Trigger = EXTI_Trigger_Falling ;
EXTI_InitStructure . EXTI_LineCmd = DISABLE ;
EXTI_Init ( & EXTI_InitStructure ) ;
EXTI_ClearFlag ( RFM22_EXT_INT_LINE ) ;
}
void rfm22_enableExtInt ( void )
{
// Configure the external interrupt
GPIO_EXTILineConfig ( RFM22_EXT_INT_PORT_SOURCE , RFM22_EXT_INT_PIN_SOURCE ) ;
EXTI_InitTypeDef EXTI_InitStructure ;
EXTI_InitStructure . EXTI_Line = RFM22_EXT_INT_LINE ;
EXTI_InitStructure . EXTI_Mode = EXTI_Mode_Interrupt ;
EXTI_InitStructure . EXTI_Trigger = EXTI_Trigger_Falling ;
EXTI_InitStructure . EXTI_LineCmd = ENABLE ;
EXTI_Init ( & EXTI_InitStructure ) ;
EXTI_ClearFlag ( RFM22_EXT_INT_LINE ) ;
// Enable and set the external interrupt
NVIC_InitTypeDef NVIC_InitStructure ;
NVIC_InitStructure . NVIC_IRQChannel = RFM22_EXT_INT_IRQn ;
NVIC_InitStructure . NVIC_IRQChannelPreemptionPriority = RFM22_EXT_INT_PRIORITY ;
NVIC_InitStructure . NVIC_IRQChannelSubPriority = 0 ;
NVIC_InitStructure . NVIC_IRQChannelCmd = ENABLE ;
NVIC_Init ( & NVIC_InitStructure ) ;
}
# endif
2011-02-05 14:45:16 +01:00
// ************************************
// set/get the current tx power setting
void rfm22_setTxPower ( uint8_t tx_pwr )
{
switch ( tx_pwr )
{
2011-02-06 11:55:08 +01:00
case 0 : tx_power = RFM22_tx_pwr_txpow_0 ; break ; // +1dBm ... 1.25mW
case 1 : tx_power = RFM22_tx_pwr_txpow_1 ; break ; // +2dBm ... 1.6mW
case 2 : tx_power = RFM22_tx_pwr_txpow_2 ; break ; // +5dBm ... 3.16mW
case 3 : tx_power = RFM22_tx_pwr_txpow_3 ; break ; // +8dBm ... 6.3mW
case 4 : tx_power = RFM22_tx_pwr_txpow_4 ; break ; // +11dBm .. 12.6mW
case 5 : tx_power = RFM22_tx_pwr_txpow_5 ; break ; // +14dBm .. 25mW
case 6 : tx_power = RFM22_tx_pwr_txpow_6 ; break ; // +17dBm .. 50mW
case 7 : tx_power = RFM22_tx_pwr_txpow_7 ; break ; // +20dBm .. 100mW
2011-02-05 14:45:16 +01:00
default : break ;
}
}
uint8_t rfm22_getTxPower ( void )
{
return tx_power ;
}
// ************************************
2011-02-16 13:32:44 +01:00
uint32_t rfm22_minFrequency ( void )
{
return lower_carrier_frequency_limit_Hz ;
}
uint32_t rfm22_maxFrequency ( void )
{
return upper_carrier_frequency_limit_Hz ;
}
2011-02-05 14:45:16 +01:00
void rfm22_setNominalCarrierFrequency ( uint32_t frequency_hz )
{
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = TRUE ;
# endif
// *******
if ( frequency_hz < lower_carrier_frequency_limit_Hz ) frequency_hz = lower_carrier_frequency_limit_Hz ;
else
if ( frequency_hz > upper_carrier_frequency_limit_Hz ) frequency_hz = upper_carrier_frequency_limit_Hz ;
if ( frequency_hz < 480000000 )
hbsel = 1 ;
else
hbsel = 2 ;
uint8_t fb = ( uint8_t ) ( frequency_hz / ( 10000000 * hbsel ) ) ;
uint32_t fc = ( uint32_t ) ( frequency_hz - ( 10000000 * hbsel * fb ) ) ;
fc = ( fc * 64u ) / ( 10000ul * hbsel ) ;
fb - = 24 ;
2011-02-06 22:21:50 +01:00
// carrier_frequency_hz = frequency_hz;
carrier_frequency_hz = ( ( uint32_t ) fb + 24 + ( ( float ) fc / 64000 ) ) * 10000000 * hbsel ;
2011-02-05 14:45:16 +01:00
if ( hbsel > 1 )
2011-02-06 11:55:08 +01:00
fb | = RFM22_fbs_hbsel ;
2011-02-05 14:45:16 +01:00
2011-02-06 11:55:08 +01:00
fb | = RFM22_fbs_sbse ; // is this the RX LO polarity?
2011-02-05 14:45:16 +01:00
frequency_step_size = 156.25f * hbsel ;
2011-02-23 10:30:06 +01:00
rfm22_write ( RFM22_frequency_hopping_channel_select , frequency_hop_channel ) ; // frequency hopping channel (0-255)
2011-02-05 14:45:16 +01:00
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_frequency_offset1 , 0 ) ; // no frequency offset
rfm22_write ( RFM22_frequency_offset2 , 0 ) ; // no frequency offset
2011-02-05 14:45:16 +01:00
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_frequency_band_select , fb ) ; // set the carrier frequency
rfm22_write ( RFM22_nominal_carrier_frequency1 , fc > > 8 ) ; // " "
rfm22_write ( RFM22_nominal_carrier_frequency0 , fc & 0xff ) ; // " "
2011-02-05 14:45:16 +01:00
// *******
# if defined(RFM22_DEBUG)
2011-02-06 22:21:50 +01:00
DEBUG_PRINTF ( " rf setFreq: %u \r \n " , carrier_frequency_hz ) ;
// DEBUG_PRINTF("rf setFreq frequency_step_size: %0.2f\r\n", frequency_step_size);
2011-02-05 14:45:16 +01:00
# endif
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = FALSE ;
# endif
}
uint32_t rfm22_getNominalCarrierFrequency ( void )
{
return carrier_frequency_hz ;
}
float rfm22_getFrequencyStepSize ( void )
{
return frequency_step_size ;
}
void rfm22_setFreqHopChannel ( uint8_t channel )
{ // set the frequency hopping channel
frequency_hop_channel = channel ;
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_frequency_hopping_channel_select , frequency_hop_channel ) ;
2011-02-05 14:45:16 +01:00
}
uint8_t rfm22_freqHopChannel ( void )
{ // return the current frequency hopping channel
return frequency_hop_channel ;
}
2011-02-16 13:32:44 +01:00
uint32_t rfm22_freqHopSize ( void )
{ // return the frequency hopping step size
return ( ( uint32_t ) frequency_hop_step_size_reg * 10000 ) ;
}
2011-01-13 09:45:18 +01:00
// ************************************
// radio datarate about 19200 Baud
// radio frequency deviation 45kHz
// radio receiver bandwidth 67kHz.
//
// Carson's rule:
// The signal bandwidth is about 2(Delta-f + fm) ..
//
// Delta-f = frequency deviation
// fm = maximum frequency of the signal
//
// This gives 2(45 + 9.6) = 109.2kHz.
2011-03-03 17:32:43 +01:00
void rfm22_setDatarate ( uint32_t datarate_bps , bool data_whitening )
2011-01-13 09:45:18 +01:00
{
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = TRUE ;
# endif
// *******
lookup_index = 0 ;
while ( lookup_index < ( LOOKUP_SIZE - 1 ) & & data_rate [ lookup_index ] < datarate_bps )
lookup_index + + ;
carrier_datarate_bps = datarate_bps = data_rate [ lookup_index ] ;
2011-02-05 00:00:48 +01:00
rf_bandwidth_used = rx_bandwidth [ lookup_index ] ;
2011-01-13 09:45:18 +01:00
// ********************************
# if defined(RFM22_DEBUG)
uint32_t frequency_deviation = freq_deviation [ lookup_index ] ; // Hz
uint32_t modulation_bandwidth = datarate_bps + ( 2 * frequency_deviation ) ;
# endif
rfm22_write ( 0x1C , reg_1C [ lookup_index ] ) ; // rfm22_if_filter_bandwidth
2011-02-25 12:28:39 +01:00
2011-01-13 09:45:18 +01:00
rfm22_write ( 0x1D , reg_1D [ lookup_index ] ) ; // rfm22_afc_loop_gearshift_override
2011-02-25 12:28:39 +01:00
rfm22_write ( 0x1E , reg_1E [ lookup_index ] ) ; // RFM22_afc_timing_control
2011-01-13 09:45:18 +01:00
2011-02-25 12:28:39 +01:00
rfm22_write ( 0x1F , reg_1F [ lookup_index ] ) ; // RFM22_clk_recovery_gearshift_override
2011-01-13 09:45:18 +01:00
rfm22_write ( 0x20 , reg_20 [ lookup_index ] ) ; // rfm22_clk_recovery_oversampling_ratio
rfm22_write ( 0x21 , reg_21 [ lookup_index ] ) ; // rfm22_clk_recovery_offset2
rfm22_write ( 0x22 , reg_22 [ lookup_index ] ) ; // rfm22_clk_recovery_offset1
rfm22_write ( 0x23 , reg_23 [ lookup_index ] ) ; // rfm22_clk_recovery_offset0
rfm22_write ( 0x24 , reg_24 [ lookup_index ] ) ; // rfm22_clk_recovery_timing_loop_gain1
rfm22_write ( 0x25 , reg_25 [ lookup_index ] ) ; // rfm22_clk_recovery_timing_loop_gain0
rfm22_write ( 0x2A , reg_2A [ lookup_index ] ) ; // rfm22_afc_limiter
if ( carrier_datarate_bps < 100000 )
rfm22_write ( 0x58 , 0x80 ) ; // rfm22_chargepump_current_trimming_override
else
rfm22_write ( 0x58 , 0xC0 ) ; // rfm22_chargepump_current_trimming_override
rfm22_write ( 0x6E , reg_6E [ lookup_index ] ) ; // rfm22_tx_data_rate1
rfm22_write ( 0x6F , reg_6F [ lookup_index ] ) ; // rfm22_tx_data_rate0
2011-03-03 17:32:43 +01:00
// Enable data whitening
// uint8_t txdtrtscale_bit = rfm22_read(RFM22_modulation_mode_control1) & RFM22_mmc1_txdtrtscale;
// rfm22_write(RFM22_modulation_mode_control1, txdtrtscale_bit | RFM22_mmc1_enwhite);
if ( ! data_whitening )
rfm22_write ( 0x70 , reg_70 [ lookup_index ] & ~ RFM22_mmc1_enwhite ) ; // rfm22_modulation_mode_control1
else
rfm22_write ( 0x70 , reg_70 [ lookup_index ] | RFM22_mmc1_enwhite ) ; // rfm22_modulation_mode_control1
2011-01-13 09:45:18 +01:00
rfm22_write ( 0x71 , reg_71 [ lookup_index ] ) ; // rfm22_modulation_mode_control2
rfm22_write ( 0x72 , reg_72 [ lookup_index ] ) ; // rfm22_frequency_deviation
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_ook_counter_value1 , 0x00 ) ;
rfm22_write ( RFM22_ook_counter_value2 , 0x00 ) ;
2011-01-13 09:45:18 +01:00
// ********************************
// calculate the TX register values
/*
uint16_t fd = frequency_deviation / 625 ;
2011-02-06 11:55:08 +01:00
uint8_t mmc1 = RFM22_mmc1_enphpwdn | RFM22_mmc1_manppol ;
2011-01-13 09:45:18 +01:00
uint16_t txdr ;
if ( datarate_bps < 30000 )
{
txdr = ( datarate_bps * 20972 ) / 10000 ;
2011-02-06 11:55:08 +01:00
mmc1 | = RFM22_mmc1_txdtrtscale ;
2011-01-13 09:45:18 +01:00
}
else
txdr = ( datarate_bps * 6553 ) / 100000 ;
2011-02-06 11:55:08 +01:00
uint8_t mmc2 = RFM22_mmc2_dtmod_fifo | RFM22_mmc2_modtyp_gfsk ; // FIFO mode, GFSK
// uint8_t mmc2 = RFM22_mmc2_dtmod_pn9 | RFM22_mmc2_modtyp_gfsk; // PN9 mode, GFSK .. TX TEST MODE
if ( fd & 0x100 ) mmc2 | = RFM22_mmc2_fd ;
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_frequency_deviation , fd ) ; // set the TX peak frequency deviation
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_modulation_mode_control1 , mmc1 ) ;
rfm22_write ( RFM22_modulation_mode_control2 , mmc2 ) ;
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_tx_data_rate1 , txdr > > 8 ) ; // set the TX data rate
rfm22_write ( RFM22_tx_data_rate0 , txdr ) ; // " "
2011-01-13 09:45:18 +01:00
*/
// ********************************
// determine a clear channel time
// initialise the stopwatch with a suitable resolution for the datarate
STOPWATCH_init ( 4000000ul / carrier_datarate_bps ) ; // set resolution to the time for 1 nibble (4-bits) at rf datarate
// ********************************
// determine suitable time-out periods
timeout_sync_ms = ( 8000ul * 16 ) / carrier_datarate_bps ; // milliseconds
if ( timeout_sync_ms < 3 )
timeout_sync_ms = 3 ; // because out timer resolution is only 1ms
timeout_data_ms = ( 8000ul * 100 ) / carrier_datarate_bps ; // milliseconds
if ( timeout_data_ms < 3 )
timeout_data_ms = 3 ; // because out timer resolution is only 1ms
// ********************************
# if defined(RFM22_DEBUG)
DEBUG_PRINTF ( " rf datarate_bps: %d \r \n " , datarate_bps ) ;
DEBUG_PRINTF ( " rf frequency_deviation: %d \r \n " , frequency_deviation ) ;
DEBUG_PRINTF ( " rf modulation_bandwidth: %u \r \n " , modulation_bandwidth ) ;
DEBUG_PRINTF ( " rf_rx_bandwidth[%u]: %u \r \n " , lookup_index , rx_bandwidth [ lookup_index ] ) ;
DEBUG_PRINTF ( " rf est rx sensitivity[%u]: %ddBm \r \n " , lookup_index , est_rx_sens_dBm [ lookup_index ] ) ;
# endif
// *******
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = FALSE ;
# endif
}
uint32_t rfm22_getDatarate ( void )
{
return carrier_datarate_bps ;
}
// ************************************
2011-02-23 10:30:06 +01:00
void rfm22_setSSBandwidth ( uint32_t bandwidth_index )
2011-01-13 09:45:18 +01:00
{
2011-02-23 10:30:06 +01:00
2011-01-13 09:45:18 +01:00
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = TRUE ;
# endif
2011-02-23 10:30:06 +01:00
// *******
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
ss_lookup_index = bandwidth_index ;
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
ss_rf_bandwidth_used = ss_rx_bandwidth [ lookup_index ] ;
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
// ********************************
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
rfm22_write ( 0x1C , ss_reg_1C [ ss_lookup_index ] ) ; // rfm22_if_filter_bandwidth
rfm22_write ( 0x1D , ss_reg_1D [ ss_lookup_index ] ) ; // rfm22_afc_loop_gearshift_override
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
rfm22_write ( 0x20 , ss_reg_20 [ ss_lookup_index ] ) ; // rfm22_clk_recovery_oversampling_ratio
rfm22_write ( 0x21 , ss_reg_21 [ ss_lookup_index ] ) ; // rfm22_clk_recovery_offset2
rfm22_write ( 0x22 , ss_reg_22 [ ss_lookup_index ] ) ; // rfm22_clk_recovery_offset1
rfm22_write ( 0x23 , ss_reg_23 [ ss_lookup_index ] ) ; // rfm22_clk_recovery_offset0
rfm22_write ( 0x24 , ss_reg_24 [ ss_lookup_index ] ) ; // rfm22_clk_recovery_timing_loop_gain1
rfm22_write ( 0x25 , ss_reg_25 [ ss_lookup_index ] ) ; // rfm22_clk_recovery_timing_loop_gain0
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
rfm22_write ( 0x2A , ss_reg_2A [ ss_lookup_index ] ) ; // rfm22_afc_limiter
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
rfm22_write ( 0x58 , 0x80 ) ; // rfm22_chargepump_current_trimming_override
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
rfm22_write ( 0x70 , ss_reg_70 [ ss_lookup_index ] ) ; // rfm22_modulation_mode_control1
rfm22_write ( 0x71 , ss_reg_71 [ ss_lookup_index ] ) ; // rfm22_modulation_mode_control2
rfm22_write ( RFM22_ook_counter_value1 , 0x00 ) ;
rfm22_write ( RFM22_ook_counter_value2 , 0x00 ) ;
// ********************************
# if defined(RFM22_DEBUG)
DEBUG_PRINTF ( " ss_rf_rx_bandwidth[%u]: %u \r \n " , ss_lookup_index , ss_rx_bandwidth [ ss_lookup_index ] ) ;
# endif
// *******
2011-01-13 09:45:18 +01:00
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = FALSE ;
# endif
}
2011-02-23 10:30:06 +01:00
// ************************************
void rfm22_setRxMode ( uint8_t mode , bool multi_packet_mode )
2011-01-13 09:45:18 +01:00
{
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = TRUE ;
# endif
// disable interrupts
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_interrupt_enable1 , 0x00 ) ;
rfm22_write ( RFM22_interrupt_enable2 , 0x00 ) ;
2011-01-13 09:45:18 +01:00
// disable the receiver and transmitter
2011-02-06 11:55:08 +01:00
// rfm22_write(RFM22_op_and_func_ctrl1, RFM22_opfc1_xton); // READY mode
rfm22_write ( RFM22_op_and_func_ctrl1 , RFM22_opfc1_pllon ) ; // TUNE mode
2011-01-13 09:45:18 +01:00
RX_LED_OFF ;
TX_LED_OFF ;
2011-02-06 11:55:08 +01:00
// rfm22_write(RFM22_rx_fifo_control, RX_FIFO_HI_WATERMARK); // RX FIFO Almost Full Threshold (0 - 63)
2011-01-13 09:45:18 +01:00
if ( rf_mode = = TX_CARRIER_MODE | | rf_mode = = TX_PN_MODE )
{ // FIFO mode, GFSK modulation
2011-02-06 11:55:08 +01:00
uint8_t fd_bit = rfm22_read ( RFM22_modulation_mode_control2 ) & RFM22_mmc2_fd ;
rfm22_write ( RFM22_modulation_mode_control2 , fd_bit | RFM22_mmc2_dtmod_fifo | RFM22_mmc2_modtyp_gfsk ) ;
2011-01-13 09:45:18 +01:00
}
rx_buffer_wr = 0 ; // empty the rx buffer
rfm22_int_timer = 0 ; // reset the timer
2011-02-23 10:30:06 +01:00
rf_mode = mode ;
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
if ( mode ! = RX_SCAN_SPECTRUM )
{
STOPWATCH_reset ( ) ; // reset clear channel detect timer
2011-01-13 09:45:18 +01:00
2011-02-23 10:30:06 +01:00
// enable RX interrupts
rfm22_write ( RFM22_interrupt_enable1 , RFM22_ie1_encrcerror | RFM22_ie1_enpkvalid | RFM22_ie1_enrxffafull | RFM22_ie1_enfferr ) ;
rfm22_write ( RFM22_interrupt_enable2 , RFM22_ie2_enpreainval | RFM22_ie2_enpreaval | RFM22_ie2_enswdet ) ;
}
2011-01-13 09:45:18 +01:00
// read interrupt status - clear interrupts
2011-02-06 11:55:08 +01:00
rfm22_read ( RFM22_interrupt_status1 ) ;
rfm22_read ( RFM22_interrupt_status2 ) ;
2011-01-13 09:45:18 +01:00
// clear FIFOs
2011-02-23 10:30:06 +01:00
if ( ! multi_packet_mode )
{
rfm22_write ( RFM22_op_and_func_ctrl2 , RFM22_opfc2_ffclrrx | RFM22_opfc2_ffclrtx ) ;
rfm22_write ( RFM22_op_and_func_ctrl2 , 0x00 ) ;
}
else
{
rfm22_write ( RFM22_op_and_func_ctrl2 , RFM22_opfc2_rxmpk | RFM22_opfc2_ffclrrx | RFM22_opfc2_ffclrtx ) ;
rfm22_write ( RFM22_op_and_func_ctrl2 , RFM22_opfc2_rxmpk ) ;
}
2011-01-13 09:45:18 +01:00
// enable the receiver
2011-02-06 11:55:08 +01:00
// rfm22_write(RFM22_op_and_func_ctrl1, RFM22_opfc1_xton | RFM22_opfc1_rxon);
rfm22_write ( RFM22_op_and_func_ctrl1 , RFM22_opfc1_pllon | RFM22_opfc1_rxon ) ;
2011-01-13 09:45:18 +01:00
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = FALSE ;
# endif
# if defined(RFM22_DEBUG)
DEBUG_PRINTF ( " RX Mode \r \n " ) ;
# endif
}
// ************************************
2011-03-03 17:32:43 +01:00
uint16_t rfm22_addHeader ( uint8_t mode )
{
uint16_t i = 0 ;
if ( mode = = TX_STREAM_MODE )
{ // add header
for ( uint16_t j = ( TX_PREAMBLE_NIBBLES + 1 ) / 2 ; j > 0 ; j - - )
{
rfm22_burstWrite ( PREAMBLE_BYTE ) ;
i + + ;
}
rfm22_burstWrite ( SYNC_BYTE_1 ) ; i + + ;
rfm22_burstWrite ( SYNC_BYTE_2 ) ; i + + ;
}
return i ;
}
// ************************************
2011-01-13 09:45:18 +01:00
void rfm22_setTxMode ( uint8_t mode )
{
2011-03-03 17:32:43 +01:00
if ( mode ! = TX_DATA_MODE & & mode ! = TX_STREAM_MODE & & mode ! = TX_CARRIER_MODE & & mode ! = TX_PN_MODE )
2011-01-13 09:45:18 +01:00
return ; // invalid mode
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = TRUE ;
# endif
// *******************
// disable interrupts
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_interrupt_enable1 , 0x00 ) ;
rfm22_write ( RFM22_interrupt_enable2 , 0x00 ) ;
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
// rfm22_write(RFM22_op_and_func_ctrl1, RFM22_opfc1_xton); // READY mode
rfm22_write ( RFM22_op_and_func_ctrl1 , RFM22_opfc1_pllon ) ; // TUNE mode
2011-01-13 09:45:18 +01:00
RX_LED_OFF ;
2011-02-06 22:21:50 +01:00
// set the tx power
// rfm22_write(RFM22_tx_power, RFM22_tx_pwr_lna_sw | tx_power);
// rfm22_write(RFM22_tx_power, RFM22_tx_pwr_papeaken | RFM22_tx_pwr_papeaklvl_0 | RFM22_tx_pwr_lna_sw | tx_power);
rfm22_write ( RFM22_tx_power , RFM22_tx_pwr_papeaken | RFM22_tx_pwr_papeaklvl_1 | RFM22_tx_pwr_papeaklvl_0 | RFM22_tx_pwr_lna_sw | tx_power ) ;
2011-02-06 11:55:08 +01:00
uint8_t fd_bit = rfm22_read ( RFM22_modulation_mode_control2 ) & RFM22_mmc2_fd ;
2011-01-13 09:45:18 +01:00
if ( mode = = TX_CARRIER_MODE )
{ // blank carrier mode - for testing
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_modulation_mode_control2 , fd_bit | RFM22_mmc2_dtmod_pn9 | RFM22_mmc2_modtyp_none ) ; // FIFO mode, Blank carrier
2011-01-13 09:45:18 +01:00
}
else
if ( mode = = TX_PN_MODE )
{ // psuedo random data carrier mode - for testing
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_modulation_mode_control2 , fd_bit | RFM22_mmc2_dtmod_pn9 | RFM22_mmc2_modtyp_gfsk ) ; // FIFO mode, PN9 carrier
2011-01-13 09:45:18 +01:00
}
else
{ // data transmission
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_modulation_mode_control2 , fd_bit | RFM22_mmc2_dtmod_fifo | RFM22_mmc2_modtyp_gfsk ) ; // FIFO mode, GFSK modulation
2011-01-13 09:45:18 +01:00
}
// rfm22_write(0x72, reg_72[lookup_index]); // rfm22_frequency_deviation
// clear FIFOs
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_op_and_func_ctrl2 , RFM22_opfc2_ffclrrx | RFM22_opfc2_ffclrtx ) ;
rfm22_write ( RFM22_op_and_func_ctrl2 , 0x00 ) ;
2011-01-13 09:45:18 +01:00
// *******************
// add some data to the chips TX FIFO before enabling the transmitter
{
2011-03-03 17:32:43 +01:00
uint16_t rd = 0 ;
uint16_t wr = tx_data_wr ;
if ( ! tx_data_addr ) wr = 0 ;
2011-01-13 09:45:18 +01:00
2011-03-03 17:32:43 +01:00
if ( mode = = TX_DATA_MODE )
rfm22_write ( RFM22_transmit_packet_length , wr ) ; // set the total number of data bytes we are going to transmit
2011-01-13 09:45:18 +01:00
2011-03-03 17:32:43 +01:00
uint16_t max_bytes = FIFO_SIZE - 1 ;
2011-01-13 09:45:18 +01:00
2011-03-03 17:32:43 +01:00
uint16_t i = 0 ;
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
rfm22_startBurstWrite ( RFM22_fifo_access ) ;
2011-01-13 09:45:18 +01:00
2011-03-03 17:32:43 +01:00
if ( mode = = TX_STREAM_MODE )
{
if ( rd > = wr )
{ // no data to send - yet .. just send preamble pattern
while ( true )
{
rfm22_burstWrite ( PREAMBLE_BYTE ) ;
if ( + + i > = max_bytes ) break ;
}
}
else
{ // add the RF heaader
i + = rfm22_addHeader ( mode ) ;
}
}
2011-01-13 09:45:18 +01:00
2011-03-03 17:32:43 +01:00
// add some data
for ( uint16_t j = wr - rd ; j > 0 ; j - - )
{
rfm22_burstWrite ( tx_data_addr [ rd + + ] ) ;
if ( + + i > = max_bytes ) break ;
}
rfm22_endBurstWrite ( ) ;
tx_data_rd = rd ;
2011-01-13 09:45:18 +01:00
}
// *******************
rfm22_int_timer = 0 ; // reset the timer
rf_mode = mode ;
// enable TX interrupts
2011-02-06 11:55:08 +01:00
// rfm22_write(RFM22_interrupt_enable1, RFM22_ie1_enpksent | RFM22_ie1_entxffaem | RFM22_ie1_enfferr);
rfm22_write ( RFM22_interrupt_enable1 , RFM22_ie1_enpksent | RFM22_ie1_entxffaem ) ;
2011-01-13 09:45:18 +01:00
// read interrupt status - clear interrupts
2011-02-06 11:55:08 +01:00
rfm22_read ( RFM22_interrupt_status1 ) ;
rfm22_read ( RFM22_interrupt_status2 ) ;
2011-01-13 09:45:18 +01:00
// enable the transmitter
2011-02-06 11:55:08 +01:00
// rfm22_write(RFM22_op_and_func_ctrl1, RFM22_opfc1_xton | RFM22_opfc1_txon);
rfm22_write ( RFM22_op_and_func_ctrl1 , RFM22_opfc1_pllon | RFM22_opfc1_txon ) ;
2011-01-13 09:45:18 +01:00
TX_LED_ON ;
// *******************
// create new slightly random clear channel detector count value
uint32_t ccc = ( TX_PREAMBLE_NIBBLES + 8 ) + 4 ; // minimum clear channel time before allowing transmit
clear_channel_count = ccc + ( random32 % ( ccc * 2 ) ) ; // plus a some randomness
// *******************
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = FALSE ;
# endif
# if defined(RFM22_DEBUG)
if ( rf_mode = = TX_DATA_MODE ) DEBUG_PRINTF ( " TX_Data_Mode \r \n " ) ;
else
2011-03-03 17:32:43 +01:00
if ( rf_mode = = TX_STREAM_MODE ) DEBUG_PRINTF ( " TX_Stream_Mode \r \n " ) ;
else
2011-01-13 09:45:18 +01:00
if ( rf_mode = = TX_CARRIER_MODE ) DEBUG_PRINTF ( " TX_Carrier_Mode \r \n " ) ;
else
if ( rf_mode = = TX_PN_MODE ) DEBUG_PRINTF ( " TX_PN_Mode \r \n " ) ;
# endif
}
// ************************************
// external interrupt line triggered (or polled) from the rf chip
void rfm22_processRxInt ( void )
{
register uint8_t int_stat1 = int_status1 ;
register uint8_t int_stat2 = int_status2 ;
2011-02-06 11:55:08 +01:00
if ( int_stat2 & RFM22_is2_ipreaval )
2011-01-13 09:45:18 +01:00
{ // Valid preamble detected
if ( rf_mode = = RX_WAIT_PREAMBLE_MODE )
{
rfm22_int_timer = 0 ; // reset the timer
rf_mode = RX_WAIT_SYNC_MODE ;
RX_LED_ON ;
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " pream_det " ) ;
debug_outputted = true ;
# endif
}
}
/* else
2011-02-06 11:55:08 +01:00
if ( int_stat2 & RFM22_is2_ipreainval )
2011-01-13 09:45:18 +01:00
{ // Invalid preamble detected
if ( rf_mode = = RX_WAIT_SYNC_MODE )
{
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " invalid_preamble " ) ;
debug_outputted = true ;
# endif
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ;
2011-01-13 09:45:18 +01:00
return ;
}
else
{
}
}
*/
2011-02-06 11:55:08 +01:00
if ( int_stat2 & RFM22_is2_iswdet )
2011-01-13 09:45:18 +01:00
{ // Sync word detected
STOPWATCH_reset ( ) ; // reset timer
if ( rf_mode = = RX_WAIT_PREAMBLE_MODE | | rf_mode = = RX_WAIT_SYNC_MODE )
{
rfm22_int_timer = 0 ; // reset the timer
rf_mode = RX_DATA_MODE ;
RX_LED_ON ;
// read the 10-bit signed afc correction value
2011-02-06 11:55:08 +01:00
afc_correction = ( uint16_t ) rfm22_read ( RFM22_afc_correction_read ) < < 8 ; // bits 9 to 2
afc_correction | = ( uint16_t ) rfm22_read ( RFM22_ook_counter_value1 ) & 0x00c0 ; // bits 1 & 0
2011-01-13 09:45:18 +01:00
afc_correction > > = 6 ;
2011-02-04 11:03:47 +01:00
afc_correction_Hz = ( int32_t ) ( frequency_step_size * afc_correction + 0.5f ) ; // convert the afc value to Hz
2011-01-13 09:45:18 +01:00
2011-02-04 11:03:47 +01:00
rx_packet_start_rssi_dBm = rssi_dBm ; // remember the rssi for this packet
rx_packet_start_afc_Hz = afc_correction_Hz ; // remember the afc value for this packet
2011-01-13 09:45:18 +01:00
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " sync_det " ) ;
DEBUG_PRINTF ( " AFC_%d_%dHz " , afc_correction , afc_correction_Hz ) ;
debug_outputted = true ;
# endif
}
}
2011-02-06 11:55:08 +01:00
if ( int_stat1 & RFM22_is1_irxffafull )
2011-01-13 09:45:18 +01:00
{ // RX FIFO almost full, it needs emptying
if ( rf_mode = = RX_DATA_MODE )
{ // read data from the rf chips FIFO buffer
rfm22_int_timer = 0 ; // reset the timer
2011-02-06 11:55:08 +01:00
register uint16_t len = rfm22_read ( RFM22_received_packet_length ) ; // read the total length of the packet data
2011-01-13 09:45:18 +01:00
register uint16_t wr = rx_buffer_wr ;
if ( ( wr + RX_FIFO_HI_WATERMARK ) > len )
{ // some kind of error in the RF module
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " r_size_error1 " ) ;
debug_outputted = true ;
# endif
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ;
2011-01-13 09:45:18 +01:00
return ;
}
2011-02-06 11:55:08 +01:00
if ( ( ( wr + RX_FIFO_HI_WATERMARK ) > = len ) & & ! ( int_stat1 & RFM22_is1_ipkvalid ) )
2011-01-13 09:45:18 +01:00
{ // some kind of error in the RF module
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " r_size_error2 " ) ;
debug_outputted = true ;
# endif
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ;
2011-01-13 09:45:18 +01:00
return ;
}
// fetch the rx'ed data from the rf chips RX FIFO
2011-02-06 11:55:08 +01:00
rfm22_startBurstRead ( RFM22_fifo_access ) ;
2011-01-13 09:45:18 +01:00
for ( register uint16_t i = RX_FIFO_HI_WATERMARK ; i > 0 ; i - - )
{
register uint8_t b = rfm22_burstRead ( ) ; // read a byte from the rf modules RX FIFO buffer
if ( wr < sizeof ( rx_buffer ) )
rx_buffer [ wr + + ] = b ; // save the byte into our rx buffer
}
rfm22_endBurstRead ( ) ;
rx_buffer_wr = wr ;
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
// DEBUG_PRINTF(" r_data_%u/%u", rx_buffer_wr, len);
// debug_outputted = true;
# endif
}
else
{ // just clear the RX FIFO
2011-02-06 11:55:08 +01:00
rfm22_startBurstRead ( RFM22_fifo_access ) ;
2011-01-13 09:45:18 +01:00
for ( register uint16_t i = RX_FIFO_HI_WATERMARK ; i > 0 ; i - - )
rfm22_burstRead ( ) ; // read a byte from the rf modules RX FIFO buffer
rfm22_endBurstRead ( ) ;
}
}
2011-02-06 11:55:08 +01:00
if ( int_stat1 & RFM22_is1_icrerror )
2011-01-13 09:45:18 +01:00
{ // CRC error .. discard the received data
if ( rf_mode = = RX_DATA_MODE )
{
rfm22_int_timer = 0 ; // reset the timer
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " CRC_ERR " ) ;
debug_outputted = true ;
# endif
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // reset the receiver
2011-01-13 09:45:18 +01:00
return ;
}
}
2011-02-06 11:55:08 +01:00
// if (int_stat2 & RFM22_is2_irssi)
2011-01-13 09:45:18 +01:00
// { // RSSI level is >= the set threshold
// }
2011-02-06 11:55:08 +01:00
// if (device_status & RFM22_ds_rxffem)
2011-01-13 09:45:18 +01:00
// { // RX FIFO empty
// }
2011-02-06 11:55:08 +01:00
// if (device_status & RFM22_ds_headerr)
2011-01-13 09:45:18 +01:00
// { // Header check error
// }
2011-02-06 11:55:08 +01:00
if ( int_stat1 & RFM22_is1_ipkvalid )
2011-01-13 09:45:18 +01:00
{ // Valid packet received
if ( rf_mode = = RX_DATA_MODE )
{
rfm22_int_timer = 0 ; // reset the timer
// disable the receiver
2011-02-06 11:55:08 +01:00
// rfm22_write(RFM22_op_and_func_ctrl1, RFM22_opfc1_xton); // READY mode
rfm22_write ( RFM22_op_and_func_ctrl1 , RFM22_opfc1_pllon ) ; // TUNE mode
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
register uint16_t len = rfm22_read ( RFM22_received_packet_length ) ; // read the total length of the packet data
2011-01-13 09:45:18 +01:00
register uint16_t wr = rx_buffer_wr ;
if ( wr < len )
{ // their must still be data in the RX FIFO we need to get
2011-02-06 11:55:08 +01:00
rfm22_startBurstRead ( RFM22_fifo_access ) ;
2011-01-13 09:45:18 +01:00
while ( wr < len )
{
if ( wr > = sizeof ( rx_buffer ) ) break ;
rx_buffer [ wr + + ] = rfm22_burstRead ( ) ;
}
rfm22_endBurstRead ( ) ;
rx_buffer_wr = wr ;
}
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // reset the receiver
2011-01-13 09:45:18 +01:00
if ( wr ! = len )
{ // we have a packet length error .. discard the packet
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " r_pack_len_error_%u_%u " , len , wr ) ;
debug_outputted = true ;
# endif
return ;
}
// we have a valid received packet
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " VALID_R_PACKET_%u " , wr ) ;
debug_outputted = true ;
# endif
if ( rx_packet_wr = = 0 )
{ // save the received packet for further processing
2011-02-03 08:05:32 +01:00
rx_packet_rssi_dBm = rx_packet_start_rssi_dBm ; // remember the rssi for this packet
2011-02-04 11:03:47 +01:00
rx_packet_afc_Hz = rx_packet_start_afc_Hz ; // remember the afc offset for this packet
2011-01-13 09:45:18 +01:00
memmove ( ( void * ) rx_packet_buf , ( void * ) rx_buffer , wr ) ; // copy the packet data
rx_packet_wr = wr ; // save the length of the data
}
else
{ // the save buffer is still in use .. nothing we can do but to drop the packet
}
// return;
}
else
{
2011-02-23 10:30:06 +01:00
// rfm22_setRxMode(RX_WAIT_PREAMBLE_MODE, false); // reset the receiver
2011-01-13 09:45:18 +01:00
// return;
}
}
}
2011-03-03 17:32:43 +01:00
uint8_t rfm22_topUpRFTxFIFO ( void )
{
rfm22_int_timer = 0 ; // reset the timer
uint16_t rd = tx_data_rd ;
uint16_t wr = tx_data_wr ;
if ( rf_mode = = TX_DATA_MODE & & ( ! tx_data_addr | | rd > = wr ) )
return 0 ; // no more data to send
uint16_t max_bytes = FIFO_SIZE - TX_FIFO_LO_WATERMARK - 1 ;
uint16_t i = 0 ;
// top-up the rf chips TX FIFO buffer
rfm22_startBurstWrite ( RFM22_fifo_access ) ;
// add some data
for ( uint16_t j = wr - rd ; j > 0 ; j - - )
{
rfm22_burstWrite ( tx_data_addr [ rd + + ] ) ;
if ( + + i > = max_bytes ) break ;
}
tx_data_rd = rd ;
if ( rf_mode = = TX_STREAM_MODE & & rd > = wr )
{ // all data sent .. need to start sending RF header again
tx_data_addr = NULL ;
tx_data_rd = tx_data_wr = 0 ;
while ( i < max_bytes )
{
rfm22_burstWrite ( PREAMBLE_BYTE ) ; // preamble byte
i + + ;
}
// todo:
// add the RF heaader
// i += rfm22_addHeader(rf_mode);
}
rfm22_endBurstWrite ( ) ;
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
// DEBUG_PRINTF(" added_%d_bytes", i);
// debug_outputted = true;
# endif
return i ;
}
2011-01-13 09:45:18 +01:00
void rfm22_processTxInt ( void )
{
register uint8_t int_stat1 = int_status1 ;
// register uint8_t int_stat2 = int_status2;
/*
2011-02-06 11:55:08 +01:00
if ( int_stat1 & RFM22_is1_ifferr )
2011-01-13 09:45:18 +01:00
{ // FIFO underflow/overflow error
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ;
2011-01-13 09:45:18 +01:00
tx_data_addr = NULL ;
tx_data_rd = tx_data_wr = 0 ;
return ;
}
*/
2011-02-06 11:55:08 +01:00
if ( int_stat1 & RFM22_is1_ixtffaem )
2011-01-13 09:45:18 +01:00
{ // TX FIFO almost empty, it needs filling up
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
// DEBUG_PRINTF(" T_FIFO_AE");
// debug_outputted = true;
# endif
2011-03-03 17:32:43 +01:00
// uint8_t bytes_added = rfm22_topUpRFTxFIFO();
rfm22_topUpRFTxFIFO ( ) ;
2011-01-13 09:45:18 +01:00
}
2011-02-06 11:55:08 +01:00
if ( int_stat1 & RFM22_is1_ipksent )
2011-01-13 09:45:18 +01:00
{ // Packet has been sent
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " T_Sent " ) ;
debug_outputted = true ;
# endif
if ( rf_mode = = TX_DATA_MODE )
{
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // back to receive mode
2011-01-13 09:45:18 +01:00
tx_data_addr = NULL ;
tx_data_rd = tx_data_wr = 0 ;
return ;
}
2011-03-03 17:32:43 +01:00
else
if ( rf_mode = = TX_STREAM_MODE )
{
tx_data_addr = NULL ;
tx_data_rd = tx_data_wr = 0 ;
rfm22_setTxMode ( TX_STREAM_MODE ) ;
return ;
}
2011-01-13 09:45:18 +01:00
}
2011-02-06 11:55:08 +01:00
// if (int_stat1 & RFM22_is1_itxffafull)
2011-01-13 09:45:18 +01:00
// { // TX FIFO almost full, it needs to be transmitted
// }
}
void rfm22_processInt ( void )
{ // this is called from the external interrupt handler
# if !defined(RFM22_EXT_INT_USE)
if ( GPIO_IN ( RF_INT_PIN ) )
return ; // the external int line is high (no signalled interrupt)
# endif
if ( ! initialized | | power_on_reset )
return ; // we haven't yet been initialized
# if defined(RFM22_DEBUG)
debug_outputted = false ;
# endif
// ********************************
// read the RF modules current status registers
// read device status register
2011-02-06 11:55:08 +01:00
device_status = rfm22_read ( RFM22_device_status ) ;
2011-01-13 09:45:18 +01:00
// read ezmac status register
2011-02-06 11:55:08 +01:00
ezmac_status = rfm22_read ( RFM22_ezmac_status ) ;
2011-01-13 09:45:18 +01:00
// read interrupt status registers - clears the interrupt line
2011-02-06 11:55:08 +01:00
int_status1 = rfm22_read ( RFM22_interrupt_status1 ) ;
int_status2 = rfm22_read ( RFM22_interrupt_status2 ) ;
2011-01-13 09:45:18 +01:00
2011-03-03 17:32:43 +01:00
if ( rf_mode ! = TX_DATA_MODE & & rf_mode ! = TX_STREAM_MODE & & rf_mode ! = TX_CARRIER_MODE & & rf_mode ! = TX_PN_MODE )
2011-01-13 09:45:18 +01:00
{
2011-02-06 11:55:08 +01:00
rssi = rfm22_read ( RFM22_rssi ) ; // read rx signal strength .. 45 = -100dBm, 205 = -20dBm
2011-01-13 09:45:18 +01:00
rssi_dBm = ( ( int16_t ) rssi / 2 ) - 122 ; // convert to dBm
2011-02-05 00:00:48 +01:00
// calibrate the RSSI value (rf bandwidth appears to affect it)
// if (rf_bandwidth_used > 0)
// rssi_dBm -= 10000 / rf_bandwidth_used;
2011-01-13 09:45:18 +01:00
}
else
{
2011-02-06 11:55:08 +01:00
tx_pwr = rfm22_read ( RFM22_tx_power ) ; // read the tx power register
2011-01-13 09:45:18 +01:00
}
2011-02-06 11:55:08 +01:00
if ( int_status2 & RFM22_is2_ipor )
2011-01-13 09:45:18 +01:00
{ // the RF module has gone and done a reset - we need to re-initialize the rf module
initialized = FALSE ;
power_on_reset = TRUE ;
return ;
}
// ********************************
// debug stuff
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
if ( prev_device_status ! = device_status | | prev_int_status1 ! = int_status1 | | prev_int_status2 ! = int_status2 | | prev_ezmac_status ! = ezmac_status )
{
DEBUG_PRINTF ( " %02x %02x %02x %02x %dC " , device_status , int_status1 , int_status2 , ezmac_status , temperature_reg ) ;
2011-02-06 11:55:08 +01:00
if ( ( device_status & RFM22_ds_cps_mask ) = = RFM22_ds_cps_rx )
2011-01-13 09:45:18 +01:00
DEBUG_PRINTF ( " %ddBm " , rssi_dBm ) ; // rx mode
else
2011-02-06 11:55:08 +01:00
if ( ( device_status & RFM22_ds_cps_mask ) = = RFM22_ds_cps_tx )
DEBUG_PRINTF ( " %s " , ( tx_pwr & RFM22_tx_pwr_papeakval ) ? " ANT_MISMATCH " : " ant_ok " ) ; // tx mode
2011-01-13 09:45:18 +01:00
debug_outputted = true ;
prev_device_status = device_status ;
prev_int_status1 = int_status1 ;
prev_int_status2 = int_status2 ;
prev_ezmac_status = ezmac_status ;
}
# endif
// ********************************
// read the ADC - temperature sensor .. this can only be used in IDLE mode
/*
2011-02-06 11:55:08 +01:00
if ( ! ( rfm22_read ( RFM22_adc_config ) & RFM22_ac_adcstartbusy ) )
2011-01-13 09:45:18 +01:00
{ // the ADC has completed it's conversion
// read the ADC sample
2011-02-06 11:55:08 +01:00
temperature_reg = ( int16_t ) rfm22_read ( RFM22_adc_value ) * 0.5f - 64 ;
2011-01-13 09:45:18 +01:00
// start a new ADC conversion
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_adc_config , adc_config | RFM22_ac_adcstartbusy ) ;
2011-01-13 09:45:18 +01:00
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " , %dC " , temperature_reg ) ;
debug_outputted = true ;
# endif
}
*/
// ********************************
register uint16_t timer_ms = rfm22_int_timer ;
switch ( rf_mode )
{
2011-02-23 10:30:06 +01:00
case RX_SCAN_SPECTRUM :
break ;
2011-01-13 09:45:18 +01:00
case RX_WAIT_PREAMBLE_MODE :
case RX_WAIT_SYNC_MODE :
case RX_DATA_MODE :
2011-02-06 11:55:08 +01:00
if ( device_status & ( RFM22_ds_ffunfl | RFM22_ds_ffovfl ) )
2011-01-13 09:45:18 +01:00
{ // FIFO under/over flow error
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " R_UNDER/OVERRUN " ) ;
debug_outputted = true ;
# endif
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // reset the receiver
2011-01-13 09:45:18 +01:00
tx_data_rd = tx_data_wr = 0 ; // wipe TX buffer
break ;
}
if ( rf_mode = = RX_WAIT_SYNC_MODE & & timer_ms > = timeout_sync_ms )
{
rfm22_int_time_outs + + ;
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " R_SYNC_TIMEOUT " ) ;
debug_outputted = true ;
# endif
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // reset the receiver
2011-01-13 09:45:18 +01:00
tx_data_rd = tx_data_wr = 0 ; // wipe TX buffer
break ;
}
if ( rf_mode = = RX_DATA_MODE & & timer_ms > = timeout_data_ms )
{ // missing interrupts
rfm22_int_time_outs + + ;
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // reset the receiver
2011-01-13 09:45:18 +01:00
tx_data_rd = tx_data_wr = 0 ; // wipe TX buffer
break ;
}
2011-02-06 11:55:08 +01:00
if ( ( device_status & RFM22_ds_cps_mask ) ! = RFM22_ds_cps_rx )
2011-01-13 09:45:18 +01:00
{ // the rf module is not in rx mode
if ( timer_ms > = 100 )
{
rfm22_int_time_outs + + ;
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " R_TIMEOUT " ) ;
debug_outputted = true ;
# endif
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // reset the receiver
2011-01-13 09:45:18 +01:00
tx_data_rd = tx_data_wr = 0 ; // wipe TX buffer
break ;
}
}
rfm22_processRxInt ( ) ; // process the interrupt
break ;
case TX_DATA_MODE :
2011-02-06 11:55:08 +01:00
if ( device_status & ( RFM22_ds_ffunfl | RFM22_ds_ffovfl ) )
2011-01-13 09:45:18 +01:00
{ // FIFO under/over flow error
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " T_UNDER/OVERRUN " ) ;
debug_outputted = true ;
# endif
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // back to rx mode
2011-01-13 09:45:18 +01:00
tx_data_rd = tx_data_wr = 0 ; // wipe TX buffer
break ;
}
if ( timer_ms > = timeout_data_ms )
{
rfm22_int_time_outs + + ;
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // back to rx mode
2011-01-13 09:45:18 +01:00
tx_data_rd = tx_data_wr = 0 ; // wipe TX buffer
break ;
}
2011-02-06 11:55:08 +01:00
if ( ( device_status & RFM22_ds_cps_mask ) ! = RFM22_ds_cps_tx )
2011-01-13 09:45:18 +01:00
{ // the rf module is not in tx mode
if ( timer_ms > = 100 )
{
rfm22_int_time_outs + + ;
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
DEBUG_PRINTF ( " T_TIMEOUT " ) ;
debug_outputted = true ;
# endif
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // back to rx mode
2011-01-13 09:45:18 +01:00
tx_data_rd = tx_data_wr = 0 ; // wipe TX buffer
break ;
}
}
rfm22_processTxInt ( ) ; // process the interrupt
break ;
2011-03-03 17:32:43 +01:00
case TX_STREAM_MODE :
// todo:
rfm22_processTxInt ( ) ; // process the interrupt
break ;
2011-01-13 09:45:18 +01:00
case TX_CARRIER_MODE :
case TX_PN_MODE :
2011-02-06 22:21:50 +01:00
// if (timer_ms >= TX_TEST_MODE_TIMELIMIT_MS) // 'nn'ms limit
// {
2011-02-23 10:30:06 +01:00
// rfm22_setRxMode(RX_WAIT_PREAMBLE_MODE, false); // back to rx mode
2011-02-06 22:21:50 +01:00
// tx_data_rd = tx_data_wr = 0; // wipe TX buffer
// break;
// }
2011-01-13 09:45:18 +01:00
break ;
default : // unknown mode - this should NEVER happen, maybe we should do a complete CPU reset here
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // to rx mode
2011-01-13 09:45:18 +01:00
tx_data_rd = tx_data_wr = 0 ; // wipe TX buffer
break ;
}
// ********************************
# if defined(RFM22_DEBUG) && !defined(RFM22_EXT_INT_USE)
if ( debug_outputted )
{
switch ( rf_mode )
{
2011-02-23 10:30:06 +01:00
case RX_SCAN_SPECTRUM :
DEBUG_PRINTF ( " R_SCAN_SPECTRUM \r \n " ) ;
break ;
2011-01-13 09:45:18 +01:00
case RX_WAIT_PREAMBLE_MODE :
DEBUG_PRINTF ( " R_WAIT_PREAMBLE \r \n " ) ;
break ;
case RX_WAIT_SYNC_MODE :
DEBUG_PRINTF ( " R_WAIT_SYNC \r \n " ) ;
break ;
case RX_DATA_MODE :
DEBUG_PRINTF ( " R_DATA \r \n " ) ;
break ;
case TX_DATA_MODE :
DEBUG_PRINTF ( " T_DATA \r \n " ) ;
break ;
2011-03-03 17:32:43 +01:00
case TX_STREAM_MODE :
DEBUG_PRINTF ( " T_STREAM \r \n " ) ;
break ;
2011-01-13 09:45:18 +01:00
case TX_CARRIER_MODE :
DEBUG_PRINTF ( " T_CARRIER \r \n " ) ;
break ;
case TX_PN_MODE :
DEBUG_PRINTF ( " T_PN \r \n " ) ;
break ;
default :
DEBUG_PRINTF ( " UNKNOWN_MODE \r \n " ) ;
break ;
}
}
# endif
// ********************************
}
// ************************************
2011-02-23 10:30:06 +01:00
int16_t rfm22_getRSSI ( void )
{
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = TRUE ;
# endif
rssi = rfm22_read ( RFM22_rssi ) ; // read rx signal strength .. 45 = -100dBm, 205 = -20dBm
rssi_dBm = ( ( int16_t ) rssi / 2 ) - 122 ; // convert to dBm
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = FALSE ;
# endif
return rssi_dBm ;
}
2011-01-13 09:45:18 +01:00
int16_t rfm22_receivedRSSI ( void )
{ // return the packets signal strength
if ( ! initialized )
return - 200 ;
else
return rx_packet_rssi_dBm ;
}
int32_t rfm22_receivedAFCHz ( void )
{ // return the packets offset frequency
if ( ! initialized )
return 0 ;
else
return rx_packet_afc_Hz ;
}
uint16_t rfm22_receivedLength ( void )
{ // return the size of the data received
if ( ! initialized )
return 0 ;
else
return rx_packet_wr ;
}
uint8_t * rfm22_receivedPointer ( void )
{ // return the address of the data
return ( uint8_t * ) & rx_packet_buf ;
}
void rfm22_receivedDone ( void )
{ // empty the rx packet buffer
rx_packet_wr = 0 ;
}
// ************************************
int32_t rfm22_sendData ( void * data , uint16_t length , bool send_immediately )
{
if ( ! initialized )
return - 1 ; // we are not yet initialized
if ( length = = 0 )
return - 2 ; // no data to send
2011-03-03 17:32:43 +01:00
if ( ! data | | length > 255 )
return - 3 ; // no data or too much data to send
2011-01-13 09:45:18 +01:00
if ( tx_data_wr > 0 )
return - 4 ; // already have data to be sent
2011-03-03 17:32:43 +01:00
if ( rf_mode = = TX_DATA_MODE | | rf_mode = = TX_STREAM_MODE | | rf_mode = = TX_CARRIER_MODE | | rf_mode = = TX_PN_MODE | | rf_mode = = RX_SCAN_SPECTRUM )
return - 5 ; // we are currently transmitting or scanning the spectrum
2011-01-13 09:45:18 +01:00
tx_data_addr = data ;
tx_data_rd = 0 ;
tx_data_wr = length ;
# if defined(RFM22_DEBUG)
DEBUG_PRINTF ( " rf sendData(0x%08x %u) \r \n " , ( uint32_t ) tx_data_addr , tx_data_wr ) ;
# endif
if ( send_immediately | | rfm22_channelIsClear ( ) ) // is the channel clear to transmit on?
rfm22_setTxMode ( TX_DATA_MODE ) ; // transmit NOW
return tx_data_wr ;
}
// ************************************
2011-03-03 17:32:43 +01:00
void rfm22_setTxStream ( void ) // TEST ONLY
{
if ( ! initialized )
return ;
tx_data_rd = tx_data_wr = 0 ;
rfm22_setTxMode ( TX_STREAM_MODE ) ;
}
// ************************************
2011-02-06 22:21:50 +01:00
void rfm22_setTxNormal ( void )
{
if ( ! initialized )
return ;
// if (rf_mode == TX_CARRIER_MODE || rf_mode == TX_PN_MODE)
2011-02-23 10:30:06 +01:00
if ( rf_mode ! = RX_SCAN_SPECTRUM )
2011-02-06 22:21:50 +01:00
{
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ;
2011-02-06 22:21:50 +01:00
tx_data_rd = tx_data_wr = 0 ;
rx_packet_wr = 0 ;
rx_packet_start_rssi_dBm = 0 ;
rx_packet_start_afc_Hz = 0 ;
rx_packet_rssi_dBm = 0 ;
rx_packet_afc_Hz = 0 ;
}
}
2011-01-13 09:45:18 +01:00
// enable a blank tx carrier (for frequency alignment)
void rfm22_setTxCarrierMode ( void )
{
if ( ! initialized )
return ;
2011-02-23 10:30:06 +01:00
if ( rf_mode ! = TX_CARRIER_MODE & & rf_mode ! = RX_SCAN_SPECTRUM )
2011-01-13 09:45:18 +01:00
rfm22_setTxMode ( TX_CARRIER_MODE ) ;
}
// enable a psuedo random data tx carrier (for spectrum inspection)
void rfm22_setTxPNMode ( void )
{
if ( ! initialized )
return ;
2011-02-23 10:30:06 +01:00
if ( rf_mode ! = TX_PN_MODE & & rf_mode ! = RX_SCAN_SPECTRUM )
2011-01-13 09:45:18 +01:00
rfm22_setTxMode ( TX_PN_MODE ) ;
}
// ************************************
// return the current mode
int8_t rfm22_currentMode ( void )
{
return rf_mode ;
}
// return TRUE if we are transmitting
bool rfm22_transmitting ( void )
{
2011-03-03 17:32:43 +01:00
return ( rf_mode = = TX_DATA_MODE | | rf_mode = = TX_STREAM_MODE | | rf_mode = = TX_CARRIER_MODE | | rf_mode = = TX_PN_MODE ) ;
2011-01-13 09:45:18 +01:00
}
// return TRUE if the channel is clear to transmit on
bool rfm22_channelIsClear ( void )
{
if ( ! initialized )
return FALSE ; // we haven't yet been initialized
if ( rf_mode ! = RX_WAIT_PREAMBLE_MODE & & rf_mode ! = RX_WAIT_SYNC_MODE )
2011-02-23 10:30:06 +01:00
return FALSE ; // we are receiving something or we are transmitting or we are scanning the spectrum
2011-01-13 09:45:18 +01:00
return TRUE ;
// return (STOPWATCH_get_count() > clear_channel_count);
}
// return TRUE if the transmiter is ready for use
bool rfm22_txReady ( void )
{
if ( ! initialized )
return FALSE ; // we haven't yet been initialized
2011-03-03 17:32:43 +01:00
return ( tx_data_rd = = 0 & & tx_data_wr = = 0 & & rf_mode ! = TX_DATA_MODE & & rf_mode ! = TX_STREAM_MODE & & rf_mode ! = TX_CARRIER_MODE & & rf_mode ! = TX_PN_MODE & & rf_mode ! = RX_SCAN_SPECTRUM ) ;
2011-01-13 09:45:18 +01:00
}
2011-02-06 22:21:50 +01:00
// ************************************
// set/get the frequency calibration value
void rfm22_setFreqCalibration ( uint8_t value )
{
osc_load_cap = value ;
if ( ! initialized | | power_on_reset )
return ; // we haven't yet been initialized
uint8_t prev_rf_mode = rf_mode ;
if ( rf_mode = = TX_CARRIER_MODE | | rf_mode = = TX_PN_MODE )
{
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ;
2011-02-06 22:21:50 +01:00
tx_data_rd = tx_data_wr = 0 ;
}
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = TRUE ;
# endif
rfm22_write ( RFM22_xtal_osc_load_cap , osc_load_cap ) ;
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = FALSE ;
# endif
if ( prev_rf_mode = = TX_CARRIER_MODE | | prev_rf_mode = = TX_PN_MODE )
rfm22_setTxMode ( prev_rf_mode ) ;
}
uint8_t rfm22_getFreqCalibration ( void )
{
return osc_load_cap ;
}
2011-01-13 09:45:18 +01:00
// ************************************
// can be called from an interrupt if you wish
void rfm22_1ms_tick ( void )
{ // call this once every ms
if ( ! initialized )
return ; // we haven't yet been initialized
2011-02-23 10:30:06 +01:00
if ( rf_mode ! = RX_SCAN_SPECTRUM )
{
if ( rfm22_int_timer < 0xffff ) rfm22_int_timer + + ;
}
2011-01-13 09:45:18 +01:00
}
// *****************************************************************************
// call this as often as possible - not from an interrupt
void rfm22_process ( void )
{
if ( ! initialized )
return ; // we haven't yet been initialized
# if !defined(RFM22_EXT_INT_USE)
2011-02-23 10:30:06 +01:00
if ( rf_mode ! = RX_SCAN_SPECTRUM )
rfm22_processInt ( ) ; // manually poll the interrupt line routine
2011-01-13 09:45:18 +01:00
# endif
if ( power_on_reset )
{ // we need to re-initialize the RF module - it told us it's reset itself
2011-02-23 10:30:06 +01:00
if ( rf_mode ! = RX_SCAN_SPECTRUM )
{ // normal data mode
uint32_t current_freq = carrier_frequency_hz ; // fetch current rf nominal frequency
rfm22_init_normal ( lower_carrier_frequency_limit_Hz , upper_carrier_frequency_limit_Hz , rfm22_freqHopSize ( ) ) ;
rfm22_setNominalCarrierFrequency ( current_freq ) ; // restore the nominal carrier frequency
}
else
{ // we are scanning the spectrum
rfm22_init_scan_spectrum ( lower_carrier_frequency_limit_Hz , upper_carrier_frequency_limit_Hz ) ;
}
2011-01-13 09:45:18 +01:00
return ;
}
switch ( rf_mode )
{
2011-02-23 10:30:06 +01:00
case RX_SCAN_SPECTRUM : // we are scanning the spectrum
// read device status register
device_status = rfm22_read ( RFM22_device_status ) ;
// read ezmac status register
ezmac_status = rfm22_read ( RFM22_ezmac_status ) ;
// read interrupt status registers - clears the interrupt line
int_status1 = rfm22_read ( RFM22_interrupt_status1 ) ;
int_status2 = rfm22_read ( RFM22_interrupt_status2 ) ;
if ( int_status2 & RFM22_is2_ipor )
{ // the RF module has gone and done a reset - we need to re-initialize the rf module
initialized = FALSE ;
power_on_reset = TRUE ;
return ;
}
break ;
2011-01-13 09:45:18 +01:00
case RX_WAIT_PREAMBLE_MODE :
if ( rfm22_int_timer > = timeout_ms )
{ // assume somethings locked up
rfm22_int_time_outs + + ;
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // reset the RF module to rx mode
2011-01-13 09:45:18 +01:00
tx_data_rd = tx_data_wr = 0 ; // wipe TX buffer
break ;
}
// go to transmit mode if we have data to send and the channel is clear to transmit on
if ( tx_data_rd = = 0 & & tx_data_wr > 0 & & rfm22_channelIsClear ( ) )
{
rfm22_setTxMode ( TX_DATA_MODE ) ; // transmit packet NOW
break ;
}
break ;
case RX_WAIT_SYNC_MODE :
if ( rfm22_int_timer > = timeout_sync_ms )
{ // assume somethings locked up
rfm22_int_time_outs + + ;
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // reset the RF module to rx mode
2011-01-13 09:45:18 +01:00
tx_data_rd = tx_data_wr = 0 ; // wipe TX buffer
break ;
}
// go to transmit mode if we have data to send and the channel is clear to transmit on
if ( tx_data_rd = = 0 & & tx_data_wr > 0 & & rfm22_channelIsClear ( ) )
{
rfm22_setTxMode ( TX_DATA_MODE ) ; // transmit packet NOW
break ;
}
break ;
case RX_DATA_MODE :
case TX_DATA_MODE :
if ( rfm22_int_timer > = timeout_data_ms )
{ // assume somethings locked up
rfm22_int_time_outs + + ;
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // reset the RF module to rx mode
2011-01-13 09:45:18 +01:00
tx_data_rd = tx_data_wr = 0 ; // wipe TX buffer
break ;
}
break ;
2011-03-03 17:32:43 +01:00
case TX_STREAM_MODE :
// todo:
break ;
2011-01-13 09:45:18 +01:00
case TX_CARRIER_MODE :
case TX_PN_MODE :
2011-02-06 22:21:50 +01:00
// if (rfm22_int_timer >= TX_TEST_MODE_TIMELIMIT_MS)
// {
2011-02-23 10:30:06 +01:00
// rfm22_setRxMode(RX_WAIT_PREAMBLE_MODE, false); // back to rx mode
2011-02-06 22:21:50 +01:00
// tx_data_rd = tx_data_wr = 0; // wipe TX buffer
// break;
// }
2011-01-13 09:45:18 +01:00
break ;
default :
// unknown mode - this should never happen, maybe we should do a complete CPU reset here?
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ; // to rx mode
2011-01-13 09:45:18 +01:00
tx_data_rd = tx_data_wr = 0 ; // wipe TX buffer
break ;
}
# if defined(RFM22_INT_TIMEOUT_DEBUG)
if ( prev_rfm22_int_time_outs ! = rfm22_int_time_outs )
{
prev_rfm22_int_time_outs = rfm22_int_time_outs ;
DEBUG_PRINTF ( " rf int timeouts %d \r \n " , rfm22_int_time_outs ) ;
}
# endif
}
2011-03-03 17:32:43 +01:00
// ************************************
void rfm22_TxData_SetCallback ( t_rfm22_TxDataCallback new_function )
{
tx_data_callback_function = new_function ;
}
2011-01-13 09:45:18 +01:00
// ************************************
2011-02-16 13:32:44 +01:00
// reset the RF module
2011-01-13 09:45:18 +01:00
2011-03-03 17:32:43 +01:00
int rfm22_resetModule ( uint8_t mode , uint32_t min_frequency_hz , uint32_t max_frequency_hz )
2011-01-13 09:45:18 +01:00
{
initialized = false ;
# if defined(RFM22_EXT_INT_USE)
rfm22_disableExtInt ( ) ;
# endif
power_on_reset = false ;
// ****************
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = TRUE ;
# endif
// ****************
// setup the SPI port
// chip select line HIGH
PIOS_SPI_RC_PinSet ( RFM22_PIOS_SPI , 1 ) ;
// set SPI port SCLK frequency .. 4.5MHz
PIOS_SPI_SetClockSpeed ( RFM22_PIOS_SPI , PIOS_SPI_PRESCALER_16 ) ;
2011-02-27 14:13:10 +01:00
// set SPI port SCLK frequency .. 2.25MHz
// PIOS_SPI_SetClockSpeed(RFM22_PIOS_SPI, PIOS_SPI_PRESCALER_32);
// set SPI port SCLK frequency .. 285kHz .. purely for hardware fault finding
// PIOS_SPI_SetClockSpeed(RFM22_PIOS_SPI, PIOS_SPI_PRESCALER_256);
2011-01-13 09:45:18 +01:00
// ****************
// software reset the RF chip .. following procedure according to Si4x3x Errata (rev. B)
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_op_and_func_ctrl1 , RFM22_opfc1_swres ) ; // software reset the radio
2011-01-13 09:45:18 +01:00
PIOS_DELAY_WaitmS ( 26 ) ; // wait 26ms
for ( int i = 50 ; i > 0 ; i - - )
{
PIOS_DELAY_WaitmS ( 1 ) ; // wait 1ms
// read the status registers
2011-02-06 11:55:08 +01:00
int_status1 = rfm22_read ( RFM22_interrupt_status1 ) ;
int_status2 = rfm22_read ( RFM22_interrupt_status2 ) ;
if ( int_status2 & RFM22_is2_ichiprdy ) break ;
2011-01-13 09:45:18 +01:00
}
// ****************
// read status - clears interrupt
2011-02-06 11:55:08 +01:00
device_status = rfm22_read ( RFM22_device_status ) ;
int_status1 = rfm22_read ( RFM22_interrupt_status1 ) ;
int_status2 = rfm22_read ( RFM22_interrupt_status2 ) ;
ezmac_status = rfm22_read ( RFM22_ezmac_status ) ;
2011-01-13 09:45:18 +01:00
// disable all interrupts
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_interrupt_enable1 , 0x00 ) ;
rfm22_write ( RFM22_interrupt_enable2 , 0x00 ) ;
2011-01-13 09:45:18 +01:00
// ****************
# if defined(RFM22_EXT_INT_USE)
exec_using_spi = FALSE ;
# endif
// ****************
# if defined(RFM22_EXT_INT_USE)
inside_ext_int = FALSE ;
# endif
2011-02-23 10:30:06 +01:00
rf_mode = mode ;
2011-01-13 09:45:18 +01:00
device_status = int_status1 = int_status2 = ezmac_status = 0 ;
rssi = 0 ;
rssi_dBm = - 200 ;
2011-03-03 17:32:43 +01:00
tx_data_callback_function = NULL ;
2011-01-13 09:45:18 +01:00
rx_buffer_current = 0 ;
rx_buffer_wr = 0 ;
rx_packet_wr = 0 ;
2011-02-04 11:03:47 +01:00
rx_packet_rssi_dBm = - 200 ;
rx_packet_afc_Hz = 0 ;
2011-01-13 09:45:18 +01:00
tx_data_addr = NULL ;
tx_data_rd = tx_data_wr = 0 ;
lookup_index = 0 ;
2011-02-23 10:30:06 +01:00
ss_lookup_index = 0 ;
2011-01-13 09:45:18 +01:00
2011-02-05 00:00:48 +01:00
rf_bandwidth_used = 0 ;
2011-02-23 10:30:06 +01:00
ss_rf_bandwidth_used = 0 ;
2011-02-05 00:00:48 +01:00
2011-01-13 09:45:18 +01:00
rfm22_int_timer = 0 ;
rfm22_int_time_outs = 0 ;
prev_rfm22_int_time_outs = 0 ;
hbsel = 0 ;
frequency_step_size = 0.0f ;
frequency_hop_channel = 0 ;
afc_correction = 0 ;
2011-02-04 11:03:47 +01:00
afc_correction_Hz = 0 ;
2011-01-13 09:45:18 +01:00
temperature_reg = 0 ;
// set the TX power
tx_power = RFM22_DEFAULT_RF_POWER ;
tx_pwr = 0 ;
2011-02-16 13:32:44 +01:00
// ****************
// read the RF chip ID bytes
device_type = rfm22_read ( RFM22_DEVICE_TYPE ) & RFM22_DT_MASK ; // read the device type
2011-02-27 14:13:10 +01:00
device_version = rfm22_read ( RFM22_DEVICE_VERSION ) & RFM22_DV_MASK ; // read the device version
2011-02-16 13:32:44 +01:00
# if defined(RFM22_DEBUG)
DEBUG_PRINTF ( " rf device type: %d \r \n " , device_type ) ;
2011-02-27 14:13:10 +01:00
DEBUG_PRINTF ( " rf device version: %d \r \n " , device_version ) ;
2011-02-16 13:32:44 +01:00
# endif
2011-02-27 14:13:10 +01:00
2011-02-16 13:32:44 +01:00
if ( device_type ! = 0x08 )
2011-02-27 14:13:10 +01:00
{
# if defined(RFM22_DEBUG)
DEBUG_PRINTF ( " rf device type: INCORRECT - should be 0x08 \r \n " ) ;
# endif
2011-02-16 13:32:44 +01:00
return - 1 ; // incorrect RF module type
2011-02-27 14:13:10 +01:00
}
2011-02-16 13:32:44 +01:00
// if (device_version != RFM22_DEVICE_VERSION_V2) // V2
// return -2; // incorrect RF module version
// if (device_version != RFM22_DEVICE_VERSION_A0) // A0
// return -2; // incorrect RF module version
if ( device_version ! = RFM22_DEVICE_VERSION_B1 ) // B1
2011-02-27 14:13:10 +01:00
{
# if defined(RFM22_DEBUG)
DEBUG_PRINTF ( " rf device version: INCORRECT \r \n " ) ;
# endif
2011-02-16 13:32:44 +01:00
return - 2 ; // incorrect RF module version
2011-02-27 14:13:10 +01:00
}
2011-02-16 13:32:44 +01:00
2011-03-03 17:32:43 +01:00
// ****************
// set the minimum and maximum carrier frequency allowed
if ( min_frequency_hz < RFM22_MIN_CARRIER_FREQUENCY_HZ ) min_frequency_hz = RFM22_MIN_CARRIER_FREQUENCY_HZ ;
else
if ( min_frequency_hz > RFM22_MAX_CARRIER_FREQUENCY_HZ ) min_frequency_hz = RFM22_MAX_CARRIER_FREQUENCY_HZ ;
if ( max_frequency_hz < RFM22_MIN_CARRIER_FREQUENCY_HZ ) max_frequency_hz = RFM22_MIN_CARRIER_FREQUENCY_HZ ;
else
if ( max_frequency_hz > RFM22_MAX_CARRIER_FREQUENCY_HZ ) max_frequency_hz = RFM22_MAX_CARRIER_FREQUENCY_HZ ;
if ( min_frequency_hz > max_frequency_hz )
{ // swap them over
uint32_t tmp = min_frequency_hz ;
min_frequency_hz = max_frequency_hz ;
max_frequency_hz = tmp ;
}
lower_carrier_frequency_limit_Hz = min_frequency_hz ;
upper_carrier_frequency_limit_Hz = max_frequency_hz ;
// ****************
// calibrate our RF module to be exactly on frequency .. different for every module
osc_load_cap = OSC_LOAD_CAP ; // default
rfm22_write ( RFM22_xtal_osc_load_cap , osc_load_cap ) ;
2011-02-16 13:32:44 +01:00
// ****************
// disable Low Duty Cycle Mode
rfm22_write ( RFM22_op_and_func_ctrl2 , 0x00 ) ;
2011-03-03 17:32:43 +01:00
rfm22_write ( RFM22_cpu_output_clk , RFM22_coc_1MHz ) ; // 1MHz clock output
2011-02-16 13:32:44 +01:00
rfm22_write ( RFM22_op_and_func_ctrl1 , RFM22_opfc1_xton ) ; // READY mode
// rfm22_write(RFM22_op_and_func_ctrl1, RFM22_opfc1_pllon); // TUNE mode
// choose the 3 GPIO pin functions
rfm22_write ( RFM22_io_port_config , RFM22_io_port_default ) ; // GPIO port use default value
rfm22_write ( RFM22_gpio0_config , RFM22_gpio0_config_drv3 | RFM22_gpio0_config_txstate ) ; // GPIO0 = TX State (to control RF Switch)
rfm22_write ( RFM22_gpio1_config , RFM22_gpio1_config_drv3 | RFM22_gpio1_config_rxstate ) ; // GPIO1 = RX State (to control RF Switch)
rfm22_write ( RFM22_gpio2_config , RFM22_gpio2_config_drv3 | RFM22_gpio2_config_cca ) ; // GPIO2 = Clear Channel Assessment
// ****************
return 0 ; // OK
}
2011-02-23 10:30:06 +01:00
// ************************************
int rfm22_init_scan_spectrum ( uint32_t min_frequency_hz , uint32_t max_frequency_hz )
{
# if defined(RFM22_DEBUG)
DEBUG_PRINTF ( " \r \n RF init scan spectrum \r \n " ) ;
# endif
2011-03-03 17:32:43 +01:00
int res = rfm22_resetModule ( RX_SCAN_SPECTRUM , min_frequency_hz , max_frequency_hz ) ;
2011-02-23 10:30:06 +01:00
if ( res < 0 )
return res ;
// rfm22_setSSBandwidth(0);
rfm22_setSSBandwidth ( 1 ) ;
// FIFO mode, GFSK modulation
uint8_t fd_bit = rfm22_read ( RFM22_modulation_mode_control2 ) & RFM22_mmc2_fd ;
rfm22_write ( RFM22_modulation_mode_control2 , RFM22_mmc2_trclk_clk_none | RFM22_mmc2_dtmod_fifo | fd_bit | RFM22_mmc2_modtyp_gfsk ) ;
rfm22_write ( RFM22_cpu_output_clk , RFM22_coc_1MHz ) ; // 1MHz clock output
rfm22_write ( RFM22_rssi_threshold_clear_chan_indicator , 0 ) ;
rfm22_write ( RFM22_preamble_detection_ctrl1 , 31 < < 3 ) ; // 31-nibbles rx preamble detection
// avoid packet detection
rfm22_write ( RFM22_data_access_control , RFM22_dac_enpacrx | RFM22_dac_encrc ) ;
rfm22_write ( RFM22_header_control1 , 0x0f ) ;
rfm22_write ( RFM22_header_control2 , 0x77 ) ;
rfm22_write ( RFM22_sync_word3 , SYNC_BYTE_1 ) ;
rfm22_write ( RFM22_sync_word2 , SYNC_BYTE_2 ) ;
rfm22_write ( RFM22_sync_word1 , SYNC_BYTE_3 ^ 0xff ) ;
rfm22_write ( RFM22_sync_word0 , SYNC_BYTE_4 ^ 0xff ) ;
// all the bits to be checked
rfm22_write ( RFM22_header_enable3 , 0xff ) ;
rfm22_write ( RFM22_header_enable2 , 0xff ) ;
rfm22_write ( RFM22_header_enable1 , 0xff ) ;
rfm22_write ( RFM22_header_enable0 , 0xff ) ;
// rfm22_write(RFM22_frequency_hopping_step_size, 0); // set frequency hopping channel step size (multiples of 10kHz)
rfm22_setNominalCarrierFrequency ( min_frequency_hz ) ; // set our nominal carrier frequency
rfm22_write ( RFM22_tx_power , RFM22_tx_pwr_lna_sw | 0 ) ; // set minimum tx power
rfm22_write ( RFM22_agc_override1 , RFM22_agc_ovr1_sgi | RFM22_agc_ovr1_agcen ) ;
// rfm22_write(RFM22_vco_current_trimming, 0x7f);
// rfm22_write(RFM22_vco_calibration_override, 0x40);
// rfm22_write(RFM22_chargepump_current_trimming_override, 0x80);
# if defined(RFM22_EXT_INT_USE)
// Enable RF module external interrupt
rfm22_enableExtInt ( ) ;
# endif
rfm22_setRxMode ( RX_SCAN_SPECTRUM , true ) ;
initialized = true ;
return 0 ; // OK
}
2011-02-16 13:32:44 +01:00
// ************************************
2011-03-03 17:32:43 +01:00
int rfm22_init_tx_stream ( uint32_t min_frequency_hz , uint32_t max_frequency_hz )
2011-02-16 13:32:44 +01:00
{
# if defined(RFM22_DEBUG)
2011-03-03 17:32:43 +01:00
DEBUG_PRINTF ( " \r \n RF init TX stream \r \n " ) ;
2011-02-16 13:32:44 +01:00
# endif
2011-03-03 17:32:43 +01:00
int res = rfm22_resetModule ( TX_STREAM_MODE , min_frequency_hz , max_frequency_hz ) ;
2011-02-16 13:32:44 +01:00
if ( res < 0 )
return res ;
2011-03-03 17:32:43 +01:00
frequency_hop_step_size_reg = 0 ;
2011-01-13 09:45:18 +01:00
2011-03-03 17:32:43 +01:00
// set the RF datarate
rfm22_setDatarate ( RFM22_DEFAULT_RF_DATARATE , FALSE ) ;
2011-01-13 09:45:18 +01:00
2011-03-03 17:32:43 +01:00
// FIFO mode, GFSK modulation
uint8_t fd_bit = rfm22_read ( RFM22_modulation_mode_control2 ) & RFM22_mmc2_fd ;
rfm22_write ( RFM22_modulation_mode_control2 , RFM22_mmc2_trclk_clk_none | RFM22_mmc2_dtmod_fifo | fd_bit | RFM22_mmc2_modtyp_gfsk ) ;
2011-01-13 09:45:18 +01:00
2011-03-03 17:32:43 +01:00
// disable the internal Tx & Rx packet handlers (without CRC)
rfm22_write ( RFM22_data_access_control , 0 ) ;
2011-01-13 09:45:18 +01:00
2011-03-03 17:32:43 +01:00
rfm22_write ( RFM22_preamble_length , TX_PREAMBLE_NIBBLES ) ; // x-nibbles tx preamble
rfm22_write ( RFM22_preamble_detection_ctrl1 , RX_PREAMBLE_NIBBLES < < 3 ) ; // x-nibbles rx preamble detection
rfm22_write ( RFM22_header_control1 , RFM22_header_cntl1_bcen_none | RFM22_header_cntl1_hdch_none ) ; // header control - we are not using the header
rfm22_write ( RFM22_header_control2 , RFM22_header_cntl2_fixpklen | RFM22_header_cntl2_hdlen_none | RFM22_header_cntl2_synclen_32 | ( ( TX_PREAMBLE_NIBBLES > > 8 ) & 0x01 ) ) ; // no header bytes, synchronization word length 3, 2 used, packet length not included in header (fixed packet length).
rfm22_write ( RFM22_sync_word3 , SYNC_BYTE_1 ) ; // sync word
rfm22_write ( RFM22_sync_word2 , SYNC_BYTE_2 ) ; //
// rfm22_write(RFM22_modem_test, 0x01);
rfm22_write ( RFM22_agc_override1 , RFM22_agc_ovr1_agcen ) ;
// rfm22_write(RFM22_agc_override1, RFM22_agc_ovr1_sgi | RFM22_agc_ovr1_agcen);
rfm22_write ( RFM22_frequency_hopping_step_size , frequency_hop_step_size_reg ) ; // set frequency hopping channel step size (multiples of 10kHz)
rfm22_setNominalCarrierFrequency ( ( min_frequency_hz + max_frequency_hz ) / 2 ) ; // set our nominal carrier frequency
rfm22_write ( RFM22_tx_power , RFM22_tx_pwr_papeaken | RFM22_tx_pwr_papeaklvl_0 | RFM22_tx_pwr_lna_sw | tx_power ) ; // set the tx power
// rfm22_write(RFM22_tx_power, RFM22_tx_pwr_lna_sw | tx_power); // set the tx power
// rfm22_write(RFM22_vco_current_trimming, 0x7f);
// rfm22_write(RFM22_vco_calibration_override, 0x40);
// rfm22_write(RFM22_chargepump_current_trimming_override, 0x80);
rfm22_write ( RFM22_tx_fifo_control1 , TX_FIFO_HI_WATERMARK ) ; // TX FIFO Almost Full Threshold (0 - 63)
rfm22_write ( RFM22_tx_fifo_control2 , TX_FIFO_LO_WATERMARK ) ; // TX FIFO Almost Empty Threshold (0 - 63)
# if defined(RFM22_EXT_INT_USE)
// Enable RF module external interrupt
rfm22_enableExtInt ( ) ;
# endif
initialized = true ;
return 0 ; // OK
}
// ************************************
int rfm22_init_rx_stream ( uint32_t min_frequency_hz , uint32_t max_frequency_hz )
{
# if defined(RFM22_DEBUG)
DEBUG_PRINTF ( " \r \n RF init RX stream \r \n " ) ;
# endif
int res = rfm22_resetModule ( RX_WAIT_PREAMBLE_MODE , min_frequency_hz , max_frequency_hz ) ;
if ( res < 0 )
return res ;
frequency_hop_step_size_reg = 0 ;
// set the RF datarate
rfm22_setDatarate ( RFM22_DEFAULT_RF_DATARATE , FALSE ) ;
// FIFO mode, GFSK modulation
uint8_t fd_bit = rfm22_read ( RFM22_modulation_mode_control2 ) & RFM22_mmc2_fd ;
rfm22_write ( RFM22_modulation_mode_control2 , RFM22_mmc2_trclk_clk_none | RFM22_mmc2_dtmod_fifo | fd_bit | RFM22_mmc2_modtyp_gfsk ) ;
// disable the internal Tx & Rx packet handlers (without CRC)
rfm22_write ( RFM22_data_access_control , 0 ) ;
rfm22_write ( RFM22_preamble_length , TX_PREAMBLE_NIBBLES ) ; // x-nibbles tx preamble
rfm22_write ( RFM22_preamble_detection_ctrl1 , RX_PREAMBLE_NIBBLES < < 3 ) ; // x-nibbles rx preamble detection
rfm22_write ( RFM22_header_control1 , RFM22_header_cntl1_bcen_none | RFM22_header_cntl1_hdch_none ) ; // header control - we are not using the header
rfm22_write ( RFM22_header_control2 , RFM22_header_cntl2_fixpklen | RFM22_header_cntl2_hdlen_none | RFM22_header_cntl2_synclen_32 | ( ( TX_PREAMBLE_NIBBLES > > 8 ) & 0x01 ) ) ; // no header bytes, synchronization word length 3, 2 used, packet length not included in header (fixed packet length).
rfm22_write ( RFM22_sync_word3 , SYNC_BYTE_1 ) ; // sync word
rfm22_write ( RFM22_sync_word2 , SYNC_BYTE_2 ) ; //
// no header bits to be checked
rfm22_write ( RFM22_header_enable3 , 0x00 ) ;
rfm22_write ( RFM22_header_enable2 , 0x00 ) ;
rfm22_write ( RFM22_header_enable1 , 0x00 ) ;
rfm22_write ( RFM22_header_enable0 , 0x00 ) ;
// rfm22_write(RFM22_modem_test, 0x01);
rfm22_write ( RFM22_agc_override1 , RFM22_agc_ovr1_agcen ) ;
// rfm22_write(RFM22_agc_override1, RFM22_agc_ovr1_sgi | RFM22_agc_ovr1_agcen);
rfm22_write ( RFM22_frequency_hopping_step_size , frequency_hop_step_size_reg ) ; // set frequency hopping channel step size (multiples of 10kHz)
rfm22_setNominalCarrierFrequency ( ( min_frequency_hz + max_frequency_hz ) / 2 ) ; // set our nominal carrier frequency
// rfm22_write(RFM22_vco_current_trimming, 0x7f);
// rfm22_write(RFM22_vco_calibration_override, 0x40);
// rfm22_write(RFM22_chargepump_current_trimming_override, 0x80);
rfm22_write ( RFM22_rx_fifo_control , RX_FIFO_HI_WATERMARK ) ; // RX FIFO Almost Full Threshold (0 - 63)
# if defined(RFM22_EXT_INT_USE)
// Enable RF module external interrupt
rfm22_enableExtInt ( ) ;
# endif
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ;
initialized = true ;
return 0 ; // OK
}
// ************************************
// Initialise this hardware layer module and the rf module
int rfm22_init_normal ( uint32_t min_frequency_hz , uint32_t max_frequency_hz , uint32_t freq_hop_step_size )
{
# if defined(RFM22_DEBUG)
DEBUG_PRINTF ( " \r \n RF init normal \r \n " ) ;
# endif
int res = rfm22_resetModule ( RX_WAIT_PREAMBLE_MODE , min_frequency_hz , max_frequency_hz ) ;
if ( res < 0 )
return res ;
2011-01-13 09:45:18 +01:00
// ****************
freq_hop_step_size / = 10000 ; // in 10kHz increments
if ( freq_hop_step_size > 255 ) freq_hop_step_size = 255 ;
frequency_hop_step_size_reg = freq_hop_step_size ;
2011-02-16 13:32:44 +01:00
// ****************
2011-02-23 10:30:06 +01:00
2011-02-16 13:32:44 +01:00
// set the RF datarate
2011-03-03 17:32:43 +01:00
rfm22_setDatarate ( RFM22_DEFAULT_RF_DATARATE , TRUE ) ;
2011-01-13 09:45:18 +01:00
// FIFO mode, GFSK modulation
2011-02-06 11:55:08 +01:00
uint8_t fd_bit = rfm22_read ( RFM22_modulation_mode_control2 ) & RFM22_mmc2_fd ;
rfm22_write ( RFM22_modulation_mode_control2 , RFM22_mmc2_trclk_clk_none | RFM22_mmc2_dtmod_fifo | fd_bit | RFM22_mmc2_modtyp_gfsk ) ;
2011-01-13 09:45:18 +01:00
// setup to read the internal temperature sensor
2011-02-06 11:55:08 +01:00
adc_config = RFM22_ac_adcsel_temp_sensor | RFM22_ac_adcref_bg ; // ADC used to sample the temperature sensor
rfm22_write ( RFM22_adc_config , adc_config ) ; //
rfm22_write ( RFM22_adc_sensor_amp_offset , 0 ) ; // adc offset
rfm22_write ( RFM22_temp_sensor_calib , RFM22_tsc_tsrange0 | RFM22_tsc_entsoffs ) ; // temp sensor calibration .. <20> 40C to +64C 0.5C resolution
rfm22_write ( RFM22_temp_value_offset , 0 ) ; // temp sensor offset
rfm22_write ( RFM22_adc_config , adc_config | RFM22_ac_adcstartbusy ) ; // start an ADC conversion
2011-01-13 09:45:18 +01:00
2011-03-03 17:32:43 +01:00
rfm22_write ( RFM22_rssi_threshold_clear_chan_indicator , ( - 90 + 122 ) * 2 ) ; // set the RSSI threshold interrupt to about -90dBm
2011-01-13 09:45:18 +01:00
// enable the internal Tx & Rx packet handlers (with CRC)
2011-02-06 11:55:08 +01:00
// rfm22_write(RFM22_data_access_control, RFM22_dac_enpacrx | RFM22_dac_enpactx | RFM22_dac_encrc | RFM22_dac_crc_crc16);
2011-01-13 09:45:18 +01:00
// enable the internal Tx & Rx packet handlers (without CRC)
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_data_access_control , RFM22_dac_enpacrx | RFM22_dac_enpactx ) ;
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_preamble_length , TX_PREAMBLE_NIBBLES ) ; // x-nibbles tx preamble
rfm22_write ( RFM22_preamble_detection_ctrl1 , RX_PREAMBLE_NIBBLES < < 3 ) ; // x-nibbles rx preamble detection
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_header_control1 , RFM22_header_cntl1_bcen_none | RFM22_header_cntl1_hdch_none ) ; // header control - we are not using the header
rfm22_write ( RFM22_header_control2 , RFM22_header_cntl2_hdlen_none | RFM22_header_cntl2_synclen_3210 | ( ( TX_PREAMBLE_NIBBLES > > 8 ) & 0x01 ) ) ; // no header bytes, synchronization word length 3, 2, 1 & 0 used, packet length included in header.
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_sync_word3 , SYNC_BYTE_1 ) ; // sync word
rfm22_write ( RFM22_sync_word2 , SYNC_BYTE_2 ) ; //
rfm22_write ( RFM22_sync_word1 , SYNC_BYTE_3 ) ; //
rfm22_write ( RFM22_sync_word0 , SYNC_BYTE_4 ) ; //
2011-01-13 09:45:18 +01:00
/*
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_transmit_header3 , ' p ' ) ; // set tx header
rfm22_write ( RFM22_transmit_header2 , ' i ' ) ; //
rfm22_write ( RFM22_transmit_header1 , ' p ' ) ; //
rfm22_write ( RFM22_transmit_header0 , ' ' ) ; //
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_check_header3 , ' p ' ) ; // set expected rx header
rfm22_write ( RFM22_check_header2 , ' i ' ) ; //
rfm22_write ( RFM22_check_header1 , ' p ' ) ; //
rfm22_write ( RFM22_check_header0 , ' ' ) ; //
2011-01-13 09:45:18 +01:00
// all the bits to be checked
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_header_enable3 , 0xff ) ;
rfm22_write ( RFM22_header_enable2 , 0xff ) ;
rfm22_write ( RFM22_header_enable1 , 0xff ) ;
rfm22_write ( RFM22_header_enable0 , 0xff ) ;
2011-01-13 09:45:18 +01:00
*/ // no bits to be checked
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_header_enable3 , 0x00 ) ;
rfm22_write ( RFM22_header_enable2 , 0x00 ) ;
rfm22_write ( RFM22_header_enable1 , 0x00 ) ;
rfm22_write ( RFM22_header_enable0 , 0x00 ) ;
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
// rfm22_write(RFM22_modem_test, 0x01);
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_agc_override1 , RFM22_agc_ovr1_agcen ) ;
// rfm22_write(RFM22_agc_override1, RFM22_agc_ovr1_sgi | RFM22_agc_ovr1_agcen);
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_frequency_hopping_step_size , frequency_hop_step_size_reg ) ; // set frequency hopping channel step size (multiples of 10kHz)
2011-01-13 09:45:18 +01:00
rfm22_setNominalCarrierFrequency ( ( min_frequency_hz + max_frequency_hz ) / 2 ) ; // set our nominal carrier frequency
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_tx_power , RFM22_tx_pwr_papeaken | RFM22_tx_pwr_papeaklvl_0 | RFM22_tx_pwr_lna_sw | tx_power ) ; // set the tx power
2011-02-06 22:21:50 +01:00
// rfm22_write(RFM22_tx_power, RFM22_tx_pwr_lna_sw | tx_power); // set the tx power
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
// rfm22_write(RFM22_vco_current_trimming, 0x7f);
// rfm22_write(RFM22_vco_calibration_override, 0x40);
// rfm22_write(RFM22_chargepump_current_trimming_override, 0x80);
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_tx_fifo_control1 , TX_FIFO_HI_WATERMARK ) ; // TX FIFO Almost Full Threshold (0 - 63)
rfm22_write ( RFM22_tx_fifo_control2 , TX_FIFO_LO_WATERMARK ) ; // TX FIFO Almost Empty Threshold (0 - 63)
2011-01-13 09:45:18 +01:00
2011-02-06 11:55:08 +01:00
rfm22_write ( RFM22_rx_fifo_control , RX_FIFO_HI_WATERMARK ) ; // RX FIFO Almost Full Threshold (0 - 63)
2011-01-13 09:45:18 +01:00
# if defined(RFM22_EXT_INT_USE)
// Enable RF module external interrupt
rfm22_enableExtInt ( ) ;
# endif
2011-02-23 10:30:06 +01:00
rfm22_setRxMode ( RX_WAIT_PREAMBLE_MODE , false ) ;
2011-01-13 09:45:18 +01:00
initialized = true ;
return 0 ; // ok
}
// ************************************