mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 06:31:52 +00:00
staging: pi433: New driver
Added a driver for the pi433 radio module (see https://www.pi433.de/en.html for details). Signed-off-by: Marcus Wolf <linux@Wolf-Entwicklungen.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
07119e2573
commit
874bcba65f
@ -110,4 +110,6 @@ source "drivers/staging/ccree/Kconfig"
|
||||
|
||||
source "drivers/staging/typec/Kconfig"
|
||||
|
||||
source "drivers/staging/pi433/Kconfig"
|
||||
|
||||
endif # STAGING
|
||||
|
@ -44,3 +44,4 @@ obj-$(CONFIG_KS7010) += ks7010/
|
||||
obj-$(CONFIG_GREYBUS) += greybus/
|
||||
obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/
|
||||
obj-$(CONFIG_CRYPTO_DEV_CCREE) += ccree/
|
||||
obj-$(CONFIG_PI433) += pi433/
|
||||
|
@ -0,0 +1,53 @@
|
||||
// Definitions for Pi433
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
/ {
|
||||
compatible = "bcm,bcm2835", "bcm,bcm2708", "bcm,bcm2709";
|
||||
|
||||
fragment@0 {
|
||||
target = <&spi0>;
|
||||
__overlay__ {
|
||||
status = "okay";
|
||||
|
||||
spidev@0{
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spidev@1{
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
fragment@1 {
|
||||
target = <&gpio>;
|
||||
__overlay__ {
|
||||
pi433_pins: pi433_pins {
|
||||
brcm,pins = <7 25 24>;
|
||||
brcm,function = <0 0 0>; // in in in
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
fragment@2 {
|
||||
target = <&spi0>;
|
||||
__overlay__ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "okay";
|
||||
|
||||
pi433: pi433@0 {
|
||||
compatible = "Smarthome-Wolf,pi433";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <10000000>;
|
||||
status = "okay";
|
||||
|
||||
pinctrl-0 = <&pi433_pins>;
|
||||
DIO0-gpio = <&gpio 24 0>;
|
||||
DIO1-gpio = <&gpio 25 0>;
|
||||
DIO2-gpio = <&gpio 7 0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
62
drivers/staging/pi433/Documentation/devicetree/pi433.txt
Normal file
62
drivers/staging/pi433/Documentation/devicetree/pi433.txt
Normal file
@ -0,0 +1,62 @@
|
||||
* Smarthome-Wolf Pi433 - a 433MHz radio module/shield for Raspberry Pi (see www.pi433.de)
|
||||
|
||||
Required properties:
|
||||
- compatible: must be "Smarthome-Wolf,pi433"
|
||||
- reg: chip select of SPI Interface
|
||||
- DIOx-gpio must be dedicated to the GPIO, connected with DIOx of the RFM69 module
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
With the following lines in gpio-section, the gpio pins, connected with pi433 are
|
||||
reserved/declared.
|
||||
|
||||
&gpio{
|
||||
[...]
|
||||
|
||||
pi433_pins: pi433_pins {
|
||||
brcm,pins = <7 25 24>;
|
||||
brcm,function = <0 0 0>; // in in in
|
||||
};
|
||||
|
||||
[...]
|
||||
}
|
||||
|
||||
With the following lines in spi section, the device pi433 is declared.
|
||||
It consists of the three gpio pins and an spi interface (here chip select 0)
|
||||
|
||||
&spi0{
|
||||
[...]
|
||||
|
||||
pi433: pi433@0 {
|
||||
compatible = "Smarthome-Wolf,pi433";
|
||||
reg = <0>; /* CE 0 */
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
spi-max-frequency = <10000000>;
|
||||
|
||||
pinctrl-0 = <&pi433_pins>;
|
||||
DIO0-gpio = <&gpio 24 0>;
|
||||
DIO1-gpio = <&gpio 25 0>;
|
||||
DIO2-gpio = <&gpio 7 0>;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
For Raspbian users only
|
||||
=======================
|
||||
Since Raspbian supports device tree overlays, you may use and overlay, instead
|
||||
of editing your boards device tree.
|
||||
For using the overlay, you need to compile the file pi433-overlay.dts you can
|
||||
find aside to this documentation.
|
||||
The file needs to be compiled - either manually or by integration in your kernel
|
||||
source tree. For a manual compile, you may use a command line like the following:
|
||||
'linux/scripts/dtc/dtc -@ -I dts -O dtb -o pi433.dtbo pi433-overlay.dts'
|
||||
|
||||
For compiling inside of the kernel tree, you need to copy pi433-overlay.dts to
|
||||
arch/arm/boot/dts/overlays and you need to add the file to the list of files
|
||||
in the Makefile over there. Execute 'make dtbs' in kernel tree root to make the
|
||||
kernel make files compile the device tree overlay for you.
|
||||
|
||||
|
274
drivers/staging/pi433/Documentation/pi433.txt
Normal file
274
drivers/staging/pi433/Documentation/pi433.txt
Normal file
@ -0,0 +1,274 @@
|
||||
=====
|
||||
Pi433
|
||||
=====
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
This driver is for controlling pi433, a radio module for the Raspberry Pi
|
||||
(www.pi433.de). It supports transmission and reception. It can be opened
|
||||
by multiple applications for transmission and reception. While transmit
|
||||
jobs were queued and process automatically in the background, the first
|
||||
application asking for reception will block out all other applications
|
||||
until something gets received terminates the read request.
|
||||
The driver supports on the fly reloading of the hardware fifo of the rf
|
||||
chip, thus enabling for much longer telegrams then hardware fifo size.
|
||||
|
||||
Discription of driver operation
|
||||
===============================
|
||||
|
||||
a) transmission
|
||||
|
||||
Each transmission can take place with a different configuration of the rf
|
||||
module. Therfore each application can set its own set of parameters. The driver
|
||||
takes care, that each transmission takes place with the parameterset of the
|
||||
application, that requests the transmission. To allow the transmission to take
|
||||
place in the background, a tx thread is introduced.
|
||||
The transfer of data from the main thread to the tx thread is realised by a
|
||||
kfifo. With each write request of an application, the passed in data and the
|
||||
corresponding parameter set gets written to the kfifo.
|
||||
On the other "side" of the kfifo, the tx thread continuously checks, whether the
|
||||
kfifo is empty. If not, it gets one set of config and data from the kfifo. If
|
||||
there is no receive request or the receiver is still waiting for something in
|
||||
the air, the rf module is set to standby, the parameters for transmission gets
|
||||
set, the hardware fifo of the rf chip gets preloaded and the transmission gets
|
||||
started. Upon hardware fifo threshold interrupt it gets reloaded, thus enabling
|
||||
much longer telegrams then hardware fifo size. If the telegram is send and there
|
||||
is more data available in the kfifo, the procedure is repeated. If not the
|
||||
transmission cycle ends.
|
||||
|
||||
b) reception
|
||||
|
||||
Since there is only one application allowed to receive data at a time, for
|
||||
reception there is only one configuration set.
|
||||
As soon as an application sets an request for receiving a telegram, the reception
|
||||
configuration set is written to the rf module and it gets set into receiving mode.
|
||||
Now the driver is waiting, that a predefined RSSI level (signal strength at the
|
||||
receiver) is reached. Until this hasn't happened, the reception can be
|
||||
interrupted by the transmission thread at any time to insert a transmission cycle.
|
||||
As soon as the predefined RSSI level is meat, a receiving cycle starts. Similar
|
||||
as described for the transmission cycle the read out of the hardware fifo is done
|
||||
dynamically. Upon each hardware fifo threshold interrupt, a portion of data gets
|
||||
read. So also for reception it is possible to receive more data then the hardware
|
||||
fifo can hold.
|
||||
|
||||
|
||||
Driver API
|
||||
==========
|
||||
|
||||
The driver is currently implemented as a character device. Therefore it supports
|
||||
the calls open, ioctl, read, write and close.
|
||||
|
||||
|
||||
params for ioctl
|
||||
----------------
|
||||
|
||||
There are four options:
|
||||
PI433_IOC_RD_TX_CFG - get the transmission parameters from the driver
|
||||
PI433_IOC_WR_TX_CFG - set the transmission parameters
|
||||
PI433_IOC_RD_RX_CFG - get the receiving parameters from the driver
|
||||
PI433_IOC_WR_RX_CFG - set the receiving parameters
|
||||
|
||||
The tx configuration is transfered via struct pi433_tx_cfg, the parameterset for transmission.
|
||||
It is devided into two sections: rf parameters and packet format.
|
||||
|
||||
rf params:
|
||||
frequency
|
||||
frequency used for transmission.
|
||||
Allowed values: 433050000...434790000
|
||||
bit_rate
|
||||
bit rate used for transmission.
|
||||
Allowed values: #####
|
||||
dev_frequency
|
||||
frequency deviation in case of FSK.
|
||||
Allowed values: 600...500000
|
||||
modulation
|
||||
FSK - frequency shift key
|
||||
OOK - On-Off-key
|
||||
modShaping
|
||||
shapingOff - no shaping
|
||||
shaping1_0 - gauss filter with BT 1 (FSK only)
|
||||
shaping0_5 - gauss filter with BT 0.5 (FSK only)
|
||||
shaping0_3 - gauss filter with BT 0.3 (FSK only)
|
||||
shapingBR - filter cut off at BR (OOK only)
|
||||
shaping2BR - filter cut off at 2*BR (OOK only)
|
||||
paRamp (FSK only)
|
||||
ramp3400 - amp ramps up in 3.4ms
|
||||
ramp2000 - amp ramps up in 2.0ms
|
||||
ramp1000 - amp ramps up in 1ms
|
||||
ramp500 - amp ramps up in 500us
|
||||
ramp250 - amp ramps up in 250us
|
||||
ramp125 - amp ramps up in 125us
|
||||
ramp100 - amp ramps up in 100us
|
||||
ramp62 - amp ramps up in 62us
|
||||
ramp50 - amp ramps up in 50us
|
||||
ramp40 - amp ramps up in 40us
|
||||
ramp31 - amp ramps up in 31us
|
||||
ramp25 - amp ramps up in 25us
|
||||
ramp20 - amp ramps up in 20us
|
||||
ramp15 - amp ramps up in 15us
|
||||
ramp12 - amp ramps up in 12us
|
||||
ramp10 - amp ramps up in 10us
|
||||
tx_start_condition
|
||||
fifoLevel - transmission starts, if fifo is filled to
|
||||
threshold level
|
||||
fifoNotEmpty - transmission starts, as soon as there is one
|
||||
byte in internal fifo
|
||||
repetitions
|
||||
This gives the option, to send a telegram multiple times. Default: 1
|
||||
|
||||
packet format:
|
||||
enable_preamble
|
||||
optionOn - a preamble will be automatically generated
|
||||
optionOff - no preamble will be generated
|
||||
enable_sync
|
||||
optionOn - a sync word will be automatically added to
|
||||
the telegram after preamble
|
||||
optionOff - no sync word will be added
|
||||
Attention: While possible to generate sync without preamble, the
|
||||
receiver won't be able to detect the sync without preamble.
|
||||
enable_length_byte
|
||||
optionOn - the length of the telegram will be automatically
|
||||
added to the telegram. It's part of the payload
|
||||
optionOff - no length information will be automatically added
|
||||
to the telegram.
|
||||
Attention: For telegram length over 255 bytes, this option can't be used
|
||||
Attention: should be used in combination with sync, only
|
||||
enable_address_byte
|
||||
optionOn - the address byte will be automatically added to the
|
||||
telgram. It's part of the payload
|
||||
optionOff - the address byte will not be added to the telegram.
|
||||
The address byte can be used for address filtering, so the receiver
|
||||
will only receive telegrams with a given address byte.
|
||||
Attention: should be used in combination with sync, only
|
||||
enable_crc
|
||||
optionOn - an crc will be automatically calculated over the
|
||||
payload of the telegram and added to the telegram
|
||||
after payload.
|
||||
optionOff - no crc will be calculated
|
||||
preamble_length
|
||||
length of the preamble. Allowed values: 0...65536
|
||||
sync_length
|
||||
length of the sync word. Allowed values: 0...8
|
||||
fixed_message_length
|
||||
length of the payload of the telegram. Will override the length
|
||||
given by the buffer, passed in with the write command. Will be
|
||||
ignored if set to zero.
|
||||
sync_pattern[8]
|
||||
contains up to eight values, that are used as the sync pattern
|
||||
on sync option
|
||||
address_byte
|
||||
one byte, used as address byte on address byte option.
|
||||
|
||||
|
||||
The rx configuration is transfered via struct pi433_rx_cfg, the parameterset for receiving. It is devided into two sections: rf parameters and packet format.
|
||||
|
||||
rf params:
|
||||
frequency
|
||||
frequency used for transmission.
|
||||
Allowed values: 433050000...434790000
|
||||
bit_rate
|
||||
bit rate used for transmission.
|
||||
Allowed values: #####
|
||||
dev_frequency
|
||||
frequency deviation in case of FSK.
|
||||
Allowed values: 600...500000
|
||||
modulation
|
||||
FSK - frequency shift key
|
||||
OOK - on off key
|
||||
rssi_threshold
|
||||
threshold value for the signal strength on the receiver input.
|
||||
If this value is exeeded, a reception cycle starts
|
||||
Allowed values: 0...255
|
||||
thresholdDecrement
|
||||
in order to adapt to different levels of singnal strength, over
|
||||
time the receiver gets more and more sensitive. This value
|
||||
determs, how fast the sensitivity increases.
|
||||
step_0_5db - increase in 0,5dB steps
|
||||
step_1_0db - increase in 1 db steps
|
||||
step_1_5db - increase in 1,5dB steps
|
||||
step_2_0db - increase in 2 db steps
|
||||
step_3_0db - increase in 3 db steps
|
||||
step_4_0db - increase in 4 db steps
|
||||
step_5_0db - increase in 5 db steps
|
||||
step_6_0db - increase in 6 db steps
|
||||
antennaImpedance
|
||||
sets the electrical adoption of the antenna
|
||||
fiftyOhm - for antennas with an impedance of 50Ohm
|
||||
twohundretOhm - for antennas with an impedance of 200Ohm
|
||||
lnaGain
|
||||
sets the gain of the low noise amp
|
||||
automatic - lna gain is determed by an agc
|
||||
max - lna gain is set to maximum
|
||||
maxMinus6 - lna gain is set to 6db below max
|
||||
maxMinus12 - lna gain is set to 12db below max
|
||||
maxMinus24 - lna gain is set to 24db below max
|
||||
maxMinus36 - lna gain is set to 36db below max
|
||||
maxMinus48 - lna gain is set to 48db below max
|
||||
bw_mantisse
|
||||
sets the bandwidth of the channel filter - part one: mantisse.
|
||||
mantisse16 - mantisse is set to 16
|
||||
mantisse20 - mantisse is set to 20
|
||||
mantisse24 - mantisse is set to 24
|
||||
bw_exponent
|
||||
sets the bandwidth of the channel filter - part two: exponent.
|
||||
Allowd values: 0...7
|
||||
dagc;
|
||||
operation mode of the digital automatic gain control
|
||||
normalMode
|
||||
improve
|
||||
improve4LowModulationIndex
|
||||
|
||||
packet format:
|
||||
enable_sync
|
||||
optionOn - sync detection is enabled. If configured sync pattern
|
||||
isn't found, telegram will be internally discarded
|
||||
optionOff - sync detection is disabled.
|
||||
enable_length_byte
|
||||
optionOn - First byte of payload will be used as length byte,
|
||||
regardless of the amount of bytes that were requested
|
||||
by the read request.
|
||||
optionOff - Number of bytes to be read will be set according to
|
||||
amount of bytes that were requested by the read request.
|
||||
Attention: should be used in combination with sync, only
|
||||
enable_address_filtering;
|
||||
filteringOff - no adress filtering will take place
|
||||
nodeAddress - all telegrams, not matching the node
|
||||
address will be internally discarded
|
||||
nodeOrBroadcastAddress - all telegrams, neither matching the
|
||||
node, nor the broadcast address will
|
||||
be internally discarded
|
||||
Attention: Sync option must be enabled in order to use this feature
|
||||
enable_crc
|
||||
optionOn - a crc will be calculated over the payload of
|
||||
the telegram, that was received. If the
|
||||
calculated crc doesn't match to two bytes,
|
||||
that follow the payload, the telegram will be
|
||||
internally discarded.
|
||||
Attention: This option is only operational, if sync on and fixed length
|
||||
or length byte is used
|
||||
sync_length
|
||||
Gives the length of the payload.
|
||||
Attention: This setting must meet the setting of the transmitter,
|
||||
if sync option is used.
|
||||
fixed_message_length
|
||||
Overrides the telegram length either given by the first byte of
|
||||
payload or by the read request.
|
||||
bytes_to_drop
|
||||
gives the number of bytes, that will be dropped before transfering
|
||||
data to the read buffer
|
||||
This option is only usefull, if all packet helper are switched
|
||||
off and the rf chip is used in raw receiving mode. This may be
|
||||
needed, if a telegram of a third party device should be received,
|
||||
using a protocol not compatible with the packet engine of the rf69 chip.
|
||||
sync_pattern[8]
|
||||
contains up to eight values, that are used as the sync pattern
|
||||
on sync option.
|
||||
This setting must meet the configuration of the transmitting device,
|
||||
if sync option is enabled.
|
||||
node_address
|
||||
one byte, used as node address byte on address byte option.
|
||||
broadcast_address
|
||||
one byte, used as broadcast address byte on address byte option.
|
||||
|
||||
|
16
drivers/staging/pi433/Kconfig
Normal file
16
drivers/staging/pi433/Kconfig
Normal file
@ -0,0 +1,16 @@
|
||||
config PI433
|
||||
tristate "Pi433 - a 433MHz radio module for Raspberry Pi"
|
||||
default n
|
||||
---help---
|
||||
This option allows you to enable support for the radio module Pi433.
|
||||
|
||||
Pi433 is a shield that fits onto the GPIO header of a Raspberry Pi
|
||||
or compatible. It extends the Raspberry Pi with the option, to
|
||||
send and receive data in the 433MHz ISM band - for example to
|
||||
communicate between two systems without using ethernet or bluetooth
|
||||
or for control or read sockets, actors, sensors, widely available
|
||||
for low price.
|
||||
|
||||
For details or the option to buy, please visit https://pi433.de/en.html
|
||||
|
||||
If in doubt, say N here, but saying yes most probably won't hurt
|
3
drivers/staging/pi433/Makefile
Normal file
3
drivers/staging/pi433/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
obj-$(CONFIG_PI433) += pi433.o
|
||||
|
||||
pi433-objs := pi433_if.o rf69.o
|
5
drivers/staging/pi433/TODO
Normal file
5
drivers/staging/pi433/TODO
Normal file
@ -0,0 +1,5 @@
|
||||
* coding style does not fully comply with the kernel style guide.
|
||||
* still TODOs, annotated in the code
|
||||
* currently the code introduces new IOCTLs. I'm afraid this is a bad idea.
|
||||
-> Replace this with another interface, hints are welcome!
|
||||
* Some missing data (marked with ###) needs to be added in the documentation
|
1314
drivers/staging/pi433/pi433_if.c
Normal file
1314
drivers/staging/pi433/pi433_if.c
Normal file
File diff suppressed because it is too large
Load Diff
152
drivers/staging/pi433/pi433_if.h
Normal file
152
drivers/staging/pi433/pi433_if.h
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* include/linux/TODO
|
||||
*
|
||||
* userspace interface for pi433 radio module
|
||||
*
|
||||
* Pi433 is a 433MHz radio module for the Raspberry Pi.
|
||||
* It is based on the HopeRf Module RFM69CW. Therefore inside of this
|
||||
* driver, you'll find an abstraction of the rf69 chip.
|
||||
*
|
||||
* If needed, this driver could be extended, to also support other
|
||||
* devices, basing on HopeRfs rf69.
|
||||
*
|
||||
* The driver can also be extended, to support other modules of
|
||||
* HopeRf with a similar interace - e. g. RFM69HCW, RFM12, RFM95, ...
|
||||
* Copyright (C) 2016 Wolf-Entwicklungen
|
||||
* Marcus Wolf <linux@wolf-entwicklungen.de>
|
||||
*
|
||||
* 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 2 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.
|
||||
*/
|
||||
|
||||
#ifndef PI433_H
|
||||
#define PI433_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include "rf69_enum.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/* IOCTL structs and commands */
|
||||
|
||||
/**
|
||||
* struct pi433_tx_config - describes the configuration of the radio module for sending
|
||||
* @frequency:
|
||||
* @bit_rate:
|
||||
* @modulation:
|
||||
* @data_mode:
|
||||
* @preamble_length:
|
||||
* @sync_pattern:
|
||||
* @tx_start_condition:
|
||||
* @payload_length:
|
||||
* @repetitions:
|
||||
*
|
||||
* ATTENTION:
|
||||
* If the contents of 'pi433_tx_config' ever change
|
||||
* incompatibly, then the ioctl number (see define below) must change.
|
||||
*
|
||||
* NOTE: struct layout is the same in 64bit and 32bit userspace.
|
||||
*/
|
||||
#define PI433_TX_CFG_IOCTL_NR 0
|
||||
struct pi433_tx_cfg
|
||||
{
|
||||
__u32 frequency;
|
||||
__u16 bit_rate;
|
||||
__u32 dev_frequency;
|
||||
enum modulation modulation;
|
||||
enum modShaping modShaping;
|
||||
|
||||
enum paRamp pa_ramp;
|
||||
|
||||
enum txStartCondition tx_start_condition;
|
||||
|
||||
__u16 repetitions;
|
||||
|
||||
|
||||
/* packet format */
|
||||
enum optionOnOff enable_preamble;
|
||||
enum optionOnOff enable_sync;
|
||||
enum optionOnOff enable_length_byte;
|
||||
enum optionOnOff enable_address_byte;
|
||||
enum optionOnOff enable_crc;
|
||||
|
||||
__u16 preamble_length;
|
||||
__u8 sync_length;
|
||||
__u8 fixed_message_length;
|
||||
|
||||
__u8 sync_pattern[8];
|
||||
__u8 address_byte;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct pi433_rx_config - describes the configuration of the radio module for sending
|
||||
* @frequency:
|
||||
* @bit_rate:
|
||||
* @modulation:
|
||||
* @data_mode:
|
||||
* @preamble_length:
|
||||
* @sync_pattern:
|
||||
* @tx_start_condition:
|
||||
* @payload_length:
|
||||
* @repetitions:
|
||||
*
|
||||
* ATTENTION:
|
||||
* If the contents of 'pi433_rx_config' ever change
|
||||
* incompatibly, then the ioctl number (see define below) must change
|
||||
*
|
||||
* NOTE: struct layout is the same in 64bit and 32bit userspace.
|
||||
*/
|
||||
#define PI433_RX_CFG_IOCTL_NR 1
|
||||
struct pi433_rx_cfg {
|
||||
__u32 frequency;
|
||||
__u16 bit_rate;
|
||||
__u32 dev_frequency;
|
||||
|
||||
enum modulation modulation;
|
||||
|
||||
__u8 rssi_threshold;
|
||||
enum thresholdDecrement thresholdDecrement;
|
||||
enum antennaImpedance antenna_impedance;
|
||||
enum lnaGain lna_gain;
|
||||
enum mantisse bw_mantisse; /* normal: 0x50 */
|
||||
__u8 bw_exponent; /* during AFC: 0x8b */
|
||||
enum dagc dagc;
|
||||
|
||||
|
||||
|
||||
/* packet format */
|
||||
enum optionOnOff enable_sync;
|
||||
enum optionOnOff enable_length_byte; /* should be used in combination with sync, only */
|
||||
enum addressFiltering enable_address_filtering; /* operational with sync, only */
|
||||
enum optionOnOff enable_crc; /* only operational, if sync on and fixed length or length byte is used */
|
||||
|
||||
__u8 sync_length;
|
||||
__u8 fixed_message_length;
|
||||
__u32 bytes_to_drop;
|
||||
|
||||
__u8 sync_pattern[8];
|
||||
__u8 node_address;
|
||||
__u8 broadcast_address;
|
||||
};
|
||||
|
||||
|
||||
#define PI433_IOC_MAGIC 'r'
|
||||
|
||||
#define PI433_IOC_RD_TX_CFG _IOR(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)])
|
||||
#define PI433_IOC_WR_TX_CFG _IOW(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)])
|
||||
|
||||
#define PI433_IOC_RD_RX_CFG _IOR(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)])
|
||||
#define PI433_IOC_WR_RX_CFG _IOW(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)])
|
||||
|
||||
#endif /* PI433_H */
|
982
drivers/staging/pi433/rf69.c
Normal file
982
drivers/staging/pi433/rf69.c
Normal file
@ -0,0 +1,982 @@
|
||||
/*
|
||||
* abstraction of the spi interface of HopeRf rf69 radio module
|
||||
*
|
||||
* Copyright (C) 2016 Wolf-Entwicklungen
|
||||
* Marcus Wolf <linux@wolf-entwicklungen.de>
|
||||
*
|
||||
* 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 2 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.
|
||||
*/
|
||||
|
||||
/* enable prosa debug info */
|
||||
#undef DEBUG
|
||||
/* enable print of values on reg access */
|
||||
#undef DEBUG_VALUES
|
||||
/* enable print of values on fifo access */
|
||||
#undef DEBUG_FIFO_ACCESS
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include "rf69.h"
|
||||
#include "rf69_registers.h"
|
||||
|
||||
#define F_OSC 32000000 /* in Hz */
|
||||
#define FIFO_SIZE 66 /* in byte */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#define READ_REG(x) rf69_read_reg (spi, x)
|
||||
#define WRITE_REG(x,y) rf69_write_reg(spi, x, y)
|
||||
#define INVALID_PARAM \
|
||||
{ \
|
||||
dev_dbg(&spi->dev, "set: illegal input param"); \
|
||||
return -EINVAL; \
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int rf69_set_mode(struct spi_device *spi, enum mode mode)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: mode");
|
||||
#endif
|
||||
|
||||
switch (mode){
|
||||
case transmit: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_TRANSMIT);
|
||||
case receive: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_RECEIVE);
|
||||
case synthesizer: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_SYNTHESIZER);
|
||||
case standby: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_STANDBY);
|
||||
case mode_sleep: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_SLEEP);
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
|
||||
// we are using packet mode, so this check is not really needed
|
||||
// but waiting for mode ready is necessary when going from sleep because the FIFO may not be immediately available from previous mode
|
||||
//while (_mode == RF69_MODE_SLEEP && (READ_REG(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); // Wait for ModeReady
|
||||
|
||||
}
|
||||
|
||||
int rf69_set_data_mode(struct spi_device *spi, enum dataMode dataMode)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: data mode");
|
||||
#endif
|
||||
|
||||
switch (dataMode) {
|
||||
case packet: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_PACKET);
|
||||
case continuous: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_CONTINUOUS);
|
||||
case continuousNoSync: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_CONTINUOUS_NOSYNC);
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_modulation(struct spi_device *spi, enum modulation modulation)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: modulation");
|
||||
#endif
|
||||
|
||||
switch (modulation) {
|
||||
case OOK: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_TYPE) | DATAMODUL_MODULATION_TYPE_OOK);
|
||||
case FSK: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_TYPE) | DATAMODUL_MODULATION_TYPE_FSK);
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
enum modulation rf69_get_modulation(struct spi_device *spi)
|
||||
{
|
||||
u8 currentValue;
|
||||
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "get: mode");
|
||||
#endif
|
||||
|
||||
currentValue = READ_REG(REG_DATAMODUL);
|
||||
|
||||
switch (currentValue & MASK_DATAMODUL_MODULATION_TYPE >> 3) // TODO improvement: change 3 to define
|
||||
{
|
||||
case DATAMODUL_MODULATION_TYPE_OOK: return OOK;
|
||||
case DATAMODUL_MODULATION_TYPE_FSK: return FSK;
|
||||
default: return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_modulation_shaping(struct spi_device *spi, enum modShaping modShaping)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: mod shaping");
|
||||
#endif
|
||||
|
||||
if (rf69_get_modulation(spi) == FSK)
|
||||
{
|
||||
switch (modShaping) {
|
||||
case shapingOff: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_NONE);
|
||||
case shaping1_0: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_1_0);
|
||||
case shaping0_5: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_0_3);
|
||||
case shaping0_3: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_0_5);
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (modShaping) {
|
||||
case shapingOff: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_NONE);
|
||||
case shapingBR: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_BR);
|
||||
case shaping2BR: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_2BR);
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_bit_rate(struct spi_device *spi, u16 bitRate)
|
||||
{
|
||||
int retval;
|
||||
u32 bitRate_min;
|
||||
u32 bitRate_reg;
|
||||
u8 msb;
|
||||
u8 lsb;
|
||||
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: bit rate");
|
||||
#endif
|
||||
|
||||
// check input value
|
||||
bitRate_min = F_OSC / 8388608; // 8388608 = 2^23;
|
||||
if (bitRate < bitRate_min)
|
||||
{
|
||||
dev_dbg(&spi->dev, "setBitRate: illegal input param");
|
||||
INVALID_PARAM;
|
||||
}
|
||||
|
||||
// calculate reg settings
|
||||
bitRate_reg = (F_OSC / bitRate);
|
||||
|
||||
msb = (bitRate_reg&0xff00) >> 8;
|
||||
lsb = (bitRate_reg&0xff);
|
||||
|
||||
// transmit to RF 69
|
||||
retval = WRITE_REG(REG_BITRATE_MSB, msb);
|
||||
if (retval) return retval;
|
||||
retval = WRITE_REG(REG_BITRATE_LSB, lsb);
|
||||
if (retval) return retval;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rf69_set_deviation(struct spi_device *spi, u32 deviation)
|
||||
{
|
||||
int retval;
|
||||
// u32 f_max; TODO: Abhängigkeit von Bitrate beachten!!
|
||||
u64 f_reg;
|
||||
u64 f_step;
|
||||
u8 msb;
|
||||
u8 lsb;
|
||||
u64 factor = 1000000; // to improve precision of calculation
|
||||
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: deviation");
|
||||
#endif
|
||||
|
||||
if (deviation < 600 || deviation > 500000) //TODO: Abhängigkeit von Bitrate beachten!!
|
||||
{
|
||||
dev_dbg(&spi->dev, "set_deviation: illegal input param");
|
||||
INVALID_PARAM;
|
||||
}
|
||||
|
||||
// calculat f step
|
||||
f_step = F_OSC * factor;
|
||||
do_div(f_step, 524288); // 524288 = 2^19
|
||||
|
||||
// calculate register settings
|
||||
f_reg = deviation * factor;
|
||||
do_div(f_reg , f_step);
|
||||
|
||||
msb = (f_reg&0xff00) >> 8;
|
||||
lsb = (f_reg&0xff);
|
||||
|
||||
// check msb
|
||||
if (msb & !FDEVMASB_MASK)
|
||||
{
|
||||
dev_dbg(&spi->dev, "set_deviation: err in calc of msb");
|
||||
INVALID_PARAM;
|
||||
}
|
||||
|
||||
// write to chip
|
||||
retval = WRITE_REG(REG_FDEV_MSB, msb);
|
||||
if (retval) return retval;
|
||||
retval = WRITE_REG(REG_FDEV_LSB, lsb);
|
||||
if (retval) return retval;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rf69_set_frequency(struct spi_device *spi, u32 frequency)
|
||||
{
|
||||
int retval;
|
||||
u32 f_max;
|
||||
u64 f_reg;
|
||||
u64 f_step;
|
||||
u8 msb;
|
||||
u8 mid;
|
||||
u8 lsb;
|
||||
u64 factor = 1000000; // to improve precision of calculation
|
||||
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: frequency");
|
||||
#endif
|
||||
|
||||
// calculat f step
|
||||
f_step = F_OSC * factor;
|
||||
do_div(f_step, 524288); // 524288 = 2^19
|
||||
|
||||
// check input value
|
||||
f_max = f_step * 8388608 / factor;
|
||||
if (frequency > f_max)
|
||||
{
|
||||
dev_dbg(&spi->dev, "setFrequency: illegal input param");
|
||||
INVALID_PARAM;
|
||||
}
|
||||
|
||||
// calculate reg settings
|
||||
f_reg = frequency * factor;
|
||||
do_div(f_reg , f_step);
|
||||
|
||||
msb = (f_reg&0xff0000) >> 16;
|
||||
mid = (f_reg&0xff00) >> 8;
|
||||
lsb = (f_reg&0xff);
|
||||
|
||||
// write to chip
|
||||
retval = WRITE_REG(REG_FRF_MSB, msb);
|
||||
if (retval) return retval;
|
||||
retval = WRITE_REG(REG_FRF_MID, mid);
|
||||
if (retval) return retval;
|
||||
retval = WRITE_REG(REG_FRF_LSB, lsb);
|
||||
if (retval) return retval;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rf69_set_amplifier_0(struct spi_device *spi, enum optionOnOff optionOnOff)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: amp #0");
|
||||
#endif
|
||||
|
||||
switch(optionOnOff) {
|
||||
case optionOn: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) | MASK_PALEVEL_PA0) );
|
||||
case optionOff: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_PA0) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_amplifier_1(struct spi_device *spi, enum optionOnOff optionOnOff)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: amp #1");
|
||||
#endif
|
||||
|
||||
switch(optionOnOff) {
|
||||
case optionOn: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) | MASK_PALEVEL_PA1) );
|
||||
case optionOff: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_PA1) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_amplifier_2(struct spi_device *spi, enum optionOnOff optionOnOff)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: amp #2");
|
||||
#endif
|
||||
|
||||
switch(optionOnOff) {
|
||||
case optionOn: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) | MASK_PALEVEL_PA2) );
|
||||
case optionOff: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_PA2) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_output_power_level(struct spi_device *spi, u8 powerLevel)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: power level");
|
||||
#endif
|
||||
|
||||
powerLevel +=18; // TODO Abhängigkeit von PA0,1,2 setting
|
||||
|
||||
// check input value
|
||||
if (powerLevel > 0x1f)
|
||||
INVALID_PARAM;
|
||||
|
||||
// write value
|
||||
return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_OUTPUT_POWER) | powerLevel);
|
||||
}
|
||||
|
||||
int rf69_set_pa_ramp(struct spi_device *spi, enum paRamp paRamp)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: pa ramp");
|
||||
#endif
|
||||
|
||||
switch(paRamp) {
|
||||
case ramp3400: return WRITE_REG(REG_PARAMP, PARAMP_3400);
|
||||
case ramp2000: return WRITE_REG(REG_PARAMP, PARAMP_2000);
|
||||
case ramp1000: return WRITE_REG(REG_PARAMP, PARAMP_1000);
|
||||
case ramp500: return WRITE_REG(REG_PARAMP, PARAMP_500);
|
||||
case ramp250: return WRITE_REG(REG_PARAMP, PARAMP_250);
|
||||
case ramp125: return WRITE_REG(REG_PARAMP, PARAMP_125);
|
||||
case ramp100: return WRITE_REG(REG_PARAMP, PARAMP_100);
|
||||
case ramp62: return WRITE_REG(REG_PARAMP, PARAMP_62);
|
||||
case ramp50: return WRITE_REG(REG_PARAMP, PARAMP_50);
|
||||
case ramp40: return WRITE_REG(REG_PARAMP, PARAMP_40);
|
||||
case ramp31: return WRITE_REG(REG_PARAMP, PARAMP_31);
|
||||
case ramp25: return WRITE_REG(REG_PARAMP, PARAMP_25);
|
||||
case ramp20: return WRITE_REG(REG_PARAMP, PARAMP_20);
|
||||
case ramp15: return WRITE_REG(REG_PARAMP, PARAMP_15);
|
||||
case ramp12: return WRITE_REG(REG_PARAMP, PARAMP_12);
|
||||
case ramp10: return WRITE_REG(REG_PARAMP, PARAMP_10);
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_antenna_impedance(struct spi_device *spi, enum antennaImpedance antennaImpedance)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: antenna impedance");
|
||||
#endif
|
||||
|
||||
switch(antennaImpedance) {
|
||||
case fiftyOhm: return WRITE_REG(REG_LNA, (READ_REG(REG_LNA) & ~MASK_LNA_ZIN) );
|
||||
case twohundretOhm: return WRITE_REG(REG_LNA, (READ_REG(REG_LNA) | MASK_LNA_ZIN) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_lna_gain(struct spi_device *spi, enum lnaGain lnaGain)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: lna gain");
|
||||
#endif
|
||||
|
||||
switch(lnaGain) {
|
||||
case automatic: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_AUTO) );
|
||||
case max: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX) );
|
||||
case maxMinus6: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_6) );
|
||||
case maxMinus12: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_12) );
|
||||
case maxMinus24: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_24) );
|
||||
case maxMinus36: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_36) );
|
||||
case maxMinus48: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_48) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
enum lnaGain rf69_get_lna_gain(struct spi_device *spi)
|
||||
{
|
||||
u8 currentValue;
|
||||
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "get: lna gain");
|
||||
#endif
|
||||
|
||||
currentValue = READ_REG(REG_LNA);
|
||||
|
||||
switch (currentValue & MASK_LNA_CURRENT_GAIN >> 3) // improvement: change 3 to define
|
||||
{
|
||||
case LNA_GAIN_AUTO: return automatic;
|
||||
case LNA_GAIN_MAX: return max;
|
||||
case LNA_GAIN_MAX_MINUS_6: return maxMinus6;
|
||||
case LNA_GAIN_MAX_MINUS_12: return maxMinus12;
|
||||
case LNA_GAIN_MAX_MINUS_24: return maxMinus24;
|
||||
case LNA_GAIN_MAX_MINUS_36: return maxMinus36;
|
||||
case LNA_GAIN_MAX_MINUS_48: return maxMinus48;
|
||||
default: return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_dc_cut_off_frequency_intern(struct spi_device *spi ,u8 reg, enum dccPercent dccPercent)
|
||||
{
|
||||
switch (dccPercent) {
|
||||
case dcc16Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_16_PERCENT) );
|
||||
case dcc8Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_8_PERCENT) );
|
||||
case dcc4Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_4_PERCENT) );
|
||||
case dcc2Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_2_PERCENT) );
|
||||
case dcc1Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_1_PERCENT) );
|
||||
case dcc0_5Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_0_5_PERCENT) );
|
||||
case dcc0_25Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_0_25_PERCENT) );
|
||||
case dcc0_125Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_0_125_PERCENT) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_dc_cut_off_frequency(struct spi_device *spi, enum dccPercent dccPercent)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: cut off freq");
|
||||
#endif
|
||||
|
||||
return rf69_set_dc_cut_off_frequency_intern(spi, REG_RXBW, dccPercent);
|
||||
}
|
||||
|
||||
int rf69_set_dc_cut_off_frequency_during_afc(struct spi_device *spi, enum dccPercent dccPercent)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: cut off freq during afc");
|
||||
#endif
|
||||
|
||||
return rf69_set_dc_cut_off_frequency_intern(spi, REG_AFCBW, dccPercent);
|
||||
}
|
||||
|
||||
int rf69_set_bandwidth_intern(struct spi_device *spi, u8 reg, enum mantisse mantisse, u8 exponent)
|
||||
{
|
||||
u8 newValue;
|
||||
|
||||
// check value for mantisse and exponent
|
||||
if (exponent > 7) INVALID_PARAM;
|
||||
if ( (mantisse!=mantisse16) &&
|
||||
(mantisse!=mantisse20) &&
|
||||
(mantisse!=mantisse24) ) INVALID_PARAM;
|
||||
|
||||
// read old value
|
||||
newValue = READ_REG(reg);
|
||||
|
||||
// "delete" mantisse and exponent = just keep the DCC setting
|
||||
newValue = newValue & MASK_BW_DCC_FREQ;
|
||||
|
||||
// add new mantisse
|
||||
switch(mantisse) {
|
||||
case mantisse16: newValue = newValue | BW_MANT_16; break;
|
||||
case mantisse20: newValue = newValue | BW_MANT_20; break;
|
||||
case mantisse24: newValue = newValue | BW_MANT_24; break;
|
||||
}
|
||||
|
||||
// add new exponent
|
||||
newValue = newValue | exponent;
|
||||
|
||||
// write back
|
||||
return WRITE_REG(reg, newValue);
|
||||
}
|
||||
|
||||
int rf69_set_bandwidth(struct spi_device *spi, enum mantisse mantisse, u8 exponent)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: band width");
|
||||
#endif
|
||||
|
||||
return rf69_set_bandwidth_intern(spi, REG_RXBW, mantisse, exponent);
|
||||
}
|
||||
|
||||
int rf69_set_bandwidth_during_afc(struct spi_device *spi, enum mantisse mantisse, u8 exponent)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: band width during afc");
|
||||
#endif
|
||||
|
||||
return rf69_set_bandwidth_intern(spi, REG_AFCBW, mantisse, exponent);
|
||||
}
|
||||
|
||||
int rf69_set_ook_threshold_type(struct spi_device *spi, enum thresholdType thresholdType)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: threshold type");
|
||||
#endif
|
||||
|
||||
switch (thresholdType)
|
||||
{
|
||||
case fixed: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESTYPE) | OOKPEAK_THRESHTYPE_FIXED) );
|
||||
case peak: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESTYPE) | OOKPEAK_THRESHTYPE_PEAK) );
|
||||
case average: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESTYPE) | OOKPEAK_THRESHTYPE_AVERAGE) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_ook_threshold_step(struct spi_device *spi, enum thresholdStep thresholdStep)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: threshold step");
|
||||
#endif
|
||||
|
||||
switch (thresholdStep) {
|
||||
case step_0_5db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_0_5_DB) );
|
||||
case step_1_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_1_0_DB) );
|
||||
case step_1_5db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_1_5_DB) );
|
||||
case step_2_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_2_0_DB) );
|
||||
case step_3_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_3_0_DB) );
|
||||
case step_4_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_4_0_DB) );
|
||||
case step_5_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_5_0_DB) );
|
||||
case step_6_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_6_0_DB) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_ook_threshold_dec(struct spi_device *spi, enum thresholdDecrement thresholdDecrement)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: threshold decrement");
|
||||
#endif
|
||||
|
||||
switch (thresholdDecrement) {
|
||||
case dec_every8th: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_EVERY_8TH) );
|
||||
case dec_every4th: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_EVERY_4TH) );
|
||||
case dec_every2nd: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_EVERY_2ND) );
|
||||
case dec_once: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_ONCE) );
|
||||
case dec_twice: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_TWICE) );
|
||||
case dec_4times: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_4_TIMES) );
|
||||
case dec_8times: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_8_TIMES) );
|
||||
case dec_16times: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_16_TIMES) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_dio_mapping(struct spi_device *spi, u8 DIONumber, u8 value)
|
||||
{
|
||||
u8 mask;
|
||||
u8 shift;
|
||||
u8 regaddr;
|
||||
u8 regValue;
|
||||
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: DIO mapping");
|
||||
#endif
|
||||
|
||||
// check DIO number
|
||||
if (DIONumber > 5) INVALID_PARAM;
|
||||
|
||||
switch (DIONumber) {
|
||||
case 0: mask=MASK_DIO0; shift=SHIFT_DIO0; regaddr=REG_DIOMAPPING1; break;
|
||||
case 1: mask=MASK_DIO1; shift=SHIFT_DIO1; regaddr=REG_DIOMAPPING1; break;
|
||||
case 2: mask=MASK_DIO2; shift=SHIFT_DIO2; regaddr=REG_DIOMAPPING1; break;
|
||||
case 3: mask=MASK_DIO3; shift=SHIFT_DIO3; regaddr=REG_DIOMAPPING1; break;
|
||||
case 4: mask=MASK_DIO4; shift=SHIFT_DIO4; regaddr=REG_DIOMAPPING2; break;
|
||||
case 5: mask=MASK_DIO5; shift=SHIFT_DIO5; regaddr=REG_DIOMAPPING2; break;
|
||||
}
|
||||
|
||||
// read reg
|
||||
regValue=READ_REG(regaddr);
|
||||
// delete old value
|
||||
regValue = regValue & ~mask;
|
||||
// add new value
|
||||
regValue = regValue | value << shift;
|
||||
// write back
|
||||
return WRITE_REG(regaddr,regValue);
|
||||
}
|
||||
|
||||
bool rf69_get_flag(struct spi_device *spi, enum flag flag)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "get: flag");
|
||||
#endif
|
||||
|
||||
switch(flag) {
|
||||
case modeSwitchCompleted: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_MODE_READY);
|
||||
case readyToReceive: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_RX_READY);
|
||||
case readyToSend: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_TX_READY);
|
||||
case pllLocked: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_PLL_LOCK);
|
||||
case rssiExceededThreshold: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_RSSI);
|
||||
case timeout: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_TIMEOUT);
|
||||
case automode: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_AUTOMODE);
|
||||
case syncAddressMatch: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_SYNC_ADDRESS_MATCH);
|
||||
case fifoFull: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_FULL);
|
||||
/* case fifoNotEmpty: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_NOT_EMPTY); */
|
||||
case fifoEmpty: return !(READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_NOT_EMPTY);
|
||||
case fifoLevelBelowThreshold: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_LEVEL);
|
||||
case fifoOverrun: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_OVERRUN);
|
||||
case packetSent: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_PACKET_SENT);
|
||||
case payloadReady: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_PAYLOAD_READY);
|
||||
case crcOk: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_CRC_OK);
|
||||
case batteryLow: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_LOW_BAT);
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_reset_flag(struct spi_device *spi, enum flag flag)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "reset: flag");
|
||||
#endif
|
||||
|
||||
switch(flag) {
|
||||
case rssiExceededThreshold: return WRITE_REG(REG_IRQFLAGS1, MASK_IRQFLAGS1_RSSI);
|
||||
case syncAddressMatch: return WRITE_REG(REG_IRQFLAGS1, MASK_IRQFLAGS1_SYNC_ADDRESS_MATCH);
|
||||
case fifoOverrun: return WRITE_REG(REG_IRQFLAGS2, MASK_IRQFLAGS2_FIFO_OVERRUN);
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_rssi_threshold(struct spi_device *spi, u8 threshold)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: rssi threshold");
|
||||
#endif
|
||||
|
||||
/* no value check needed - u8 exactly matches register size */
|
||||
|
||||
return WRITE_REG(REG_RSSITHRESH, threshold);
|
||||
}
|
||||
|
||||
int rf69_set_rx_start_timeout(struct spi_device *spi, u8 timeout)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: start timeout");
|
||||
#endif
|
||||
|
||||
/* no value check needed - u8 exactly matches register size */
|
||||
|
||||
return WRITE_REG(REG_RXTIMEOUT1, timeout);
|
||||
}
|
||||
|
||||
int rf69_set_rssi_timeout(struct spi_device *spi, u8 timeout)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: rssi timeout");
|
||||
#endif
|
||||
|
||||
/* no value check needed - u8 exactly matches register size */
|
||||
|
||||
return WRITE_REG(REG_RXTIMEOUT2, timeout);
|
||||
}
|
||||
|
||||
int rf69_set_preamble_length(struct spi_device *spi, u16 preambleLength)
|
||||
{
|
||||
int retval;
|
||||
u8 msb, lsb;
|
||||
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: preample length");
|
||||
#endif
|
||||
|
||||
/* no value check needed - u16 exactly matches register size */
|
||||
|
||||
/* calculate reg settings */
|
||||
msb = (preambleLength&0xff00) >> 8;
|
||||
lsb = (preambleLength&0xff);
|
||||
|
||||
/* transmit to chip */
|
||||
retval = WRITE_REG(REG_PREAMBLE_MSB, msb);
|
||||
if (retval) return retval;
|
||||
retval = WRITE_REG(REG_PREAMBLE_LSB, lsb);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int rf69_set_sync_enable(struct spi_device *spi, enum optionOnOff optionOnOff)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: sync enable");
|
||||
#endif
|
||||
|
||||
switch(optionOnOff) {
|
||||
case optionOn: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) | MASK_SYNC_CONFIG_SYNC_ON) );
|
||||
case optionOff: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_SYNC_ON) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_fifo_fill_condition(struct spi_device *spi, enum fifoFillCondition fifoFillCondition)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: fifo fill condition");
|
||||
#endif
|
||||
|
||||
switch(fifoFillCondition) {
|
||||
case always: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) | MASK_SYNC_CONFIG_FIFO_FILL_CONDITION) );
|
||||
case afterSyncInterrupt: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_FIFO_FILL_CONDITION) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_sync_size(struct spi_device *spi, u8 syncSize)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: sync size");
|
||||
#endif
|
||||
|
||||
// check input value
|
||||
if (syncSize > 0x07)
|
||||
INVALID_PARAM;
|
||||
|
||||
// write value
|
||||
return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_SYNC_SIZE) | (syncSize << 3) );
|
||||
}
|
||||
|
||||
int rf69_set_sync_tolerance(struct spi_device *spi, u8 syncTolerance)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: sync tolerance");
|
||||
#endif
|
||||
|
||||
// check input value
|
||||
if (syncTolerance > 0x07)
|
||||
INVALID_PARAM;
|
||||
|
||||
// write value
|
||||
return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_SYNC_SIZE) | syncTolerance);
|
||||
}
|
||||
|
||||
int rf69_set_sync_values(struct spi_device *spi, u8 syncValues[8])
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: sync values");
|
||||
#endif
|
||||
|
||||
retval += WRITE_REG(REG_SYNCVALUE1, syncValues[0]);
|
||||
retval += WRITE_REG(REG_SYNCVALUE2, syncValues[1]);
|
||||
retval += WRITE_REG(REG_SYNCVALUE3, syncValues[2]);
|
||||
retval += WRITE_REG(REG_SYNCVALUE4, syncValues[3]);
|
||||
retval += WRITE_REG(REG_SYNCVALUE5, syncValues[4]);
|
||||
retval += WRITE_REG(REG_SYNCVALUE6, syncValues[5]);
|
||||
retval += WRITE_REG(REG_SYNCVALUE7, syncValues[6]);
|
||||
retval += WRITE_REG(REG_SYNCVALUE8, syncValues[7]);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int rf69_set_packet_format(struct spi_device * spi, enum packetFormat packetFormat)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: packet format");
|
||||
#endif
|
||||
|
||||
switch(packetFormat) {
|
||||
case packetLengthVar: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) | MASK_PACKETCONFIG1_PAKET_FORMAT_VARIABLE) );
|
||||
case packetLengthFix: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_PAKET_FORMAT_VARIABLE) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_crc_enable(struct spi_device *spi, enum optionOnOff optionOnOff)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: crc enable");
|
||||
#endif
|
||||
|
||||
switch(optionOnOff) {
|
||||
case optionOn: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) | MASK_PACKETCONFIG1_CRC_ON) );
|
||||
case optionOff: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_CRC_ON) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_adressFiltering(struct spi_device *spi, enum addressFiltering addressFiltering)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: address filtering");
|
||||
#endif
|
||||
|
||||
switch (addressFiltering) {
|
||||
case filteringOff: return WRITE_REG(REG_PACKETCONFIG1, ( (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_ADDRESSFILTERING) | PACKETCONFIG1_ADDRESSFILTERING_OFF) );
|
||||
case nodeAddress: return WRITE_REG(REG_PACKETCONFIG1, ( (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_ADDRESSFILTERING) | PACKETCONFIG1_ADDRESSFILTERING_NODE) );
|
||||
case nodeOrBroadcastAddress: return WRITE_REG(REG_PACKETCONFIG1, ( (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_ADDRESSFILTERING) | PACKETCONFIG1_ADDRESSFILTERING_NODEBROADCAST) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_payload_length(struct spi_device *spi, u8 payloadLength)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: payload length");
|
||||
#endif
|
||||
|
||||
return WRITE_REG(REG_PAYLOAD_LENGTH, payloadLength);
|
||||
}
|
||||
|
||||
u8 rf69_get_payload_length(struct spi_device *spi)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "get: payload length");
|
||||
#endif
|
||||
|
||||
return (u8) READ_REG(REG_PAYLOAD_LENGTH);
|
||||
}
|
||||
|
||||
int rf69_set_node_address(struct spi_device *spi, u8 nodeAddress)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: node address");
|
||||
#endif
|
||||
|
||||
return WRITE_REG(REG_NODEADRS, nodeAddress);
|
||||
}
|
||||
|
||||
int rf69_set_broadcast_address(struct spi_device *spi, u8 broadcastAddress)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: broadcast address");
|
||||
#endif
|
||||
|
||||
return WRITE_REG(REG_BROADCASTADRS, broadcastAddress);
|
||||
}
|
||||
|
||||
int rf69_set_tx_start_condition(struct spi_device *spi, enum txStartCondition txStartCondition)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: start condition");
|
||||
#endif
|
||||
|
||||
switch(txStartCondition) {
|
||||
case fifoLevel: return WRITE_REG(REG_FIFO_THRESH, (READ_REG(REG_FIFO_THRESH) & ~MASK_FIFO_THRESH_TXSTART) );
|
||||
case fifoNotEmpty: return WRITE_REG(REG_FIFO_THRESH, (READ_REG(REG_FIFO_THRESH) | MASK_FIFO_THRESH_TXSTART) );
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
int rf69_set_fifo_threshold(struct spi_device *spi, u8 threshold)
|
||||
{
|
||||
int retval;
|
||||
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: fifo threshold");
|
||||
#endif
|
||||
|
||||
// check input value
|
||||
if (threshold & 0x80)
|
||||
INVALID_PARAM;
|
||||
|
||||
// write value
|
||||
retval = WRITE_REG(REG_FIFO_THRESH, (READ_REG(REG_FIFO_THRESH) & ~MASK_FIFO_THRESH_VALUE) | threshold);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
// access the fifo to activate new threshold
|
||||
return rf69_read_fifo (spi, (u8*) &retval, 1); // retval used as buffer
|
||||
}
|
||||
|
||||
int rf69_set_dagc(struct spi_device *spi, enum dagc dagc)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "set: dagc");
|
||||
#endif
|
||||
|
||||
switch(dagc) {
|
||||
case normalMode: return WRITE_REG(REG_TESTDAGC, DAGC_NORMAL);
|
||||
case improve: return WRITE_REG(REG_TESTDAGC, DAGC_IMPROVED_LOWBETA0);
|
||||
case improve4LowModulationIndex: return WRITE_REG(REG_TESTDAGC, DAGC_IMPROVED_LOWBETA1);
|
||||
default: INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int rf69_read_fifo (struct spi_device *spi, u8 *buffer, unsigned int size)
|
||||
{
|
||||
#ifdef DEBUG_FIFO_ACCESS
|
||||
int i;
|
||||
#endif
|
||||
struct spi_transfer transfer;
|
||||
u8 local_buffer[FIFO_SIZE + 1];
|
||||
int retval;
|
||||
|
||||
if (size > FIFO_SIZE)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "read fifo: passed in buffer bigger then internal buffer \n");
|
||||
#endif
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
/* prepare a bidirectional transfer */
|
||||
local_buffer[0] = REG_FIFO;
|
||||
memset(&transfer, 0, sizeof(transfer));
|
||||
transfer.tx_buf = local_buffer;
|
||||
transfer.rx_buf = local_buffer;
|
||||
transfer.len = size+1;
|
||||
|
||||
retval = spi_sync_transfer(spi, &transfer, 1);
|
||||
|
||||
#ifdef DEBUG_FIFO_ACCESS
|
||||
for (i=0; i<size; i++)
|
||||
dev_dbg(&spi->dev, "%d - 0x%x\n", i, local_buffer[i+1]);
|
||||
#endif
|
||||
|
||||
memcpy(buffer, &local_buffer[1], size); // TODO: ohne memcopy wäre schöner
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size)
|
||||
{
|
||||
#ifdef DEBUG_FIFO_ACCESS
|
||||
int i;
|
||||
#endif
|
||||
char spi_address = REG_FIFO | WRITE_BIT;
|
||||
u8 local_buffer[FIFO_SIZE + 1];
|
||||
|
||||
if (size > FIFO_SIZE)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dev_dbg(&spi->dev, "read fifo: passed in buffer bigger then internal buffer \n");
|
||||
#endif
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
local_buffer[0] = spi_address;
|
||||
memcpy(&local_buffer[1], buffer, size); // TODO: ohne memcopy wäre schöner
|
||||
|
||||
#ifdef DEBUG_FIFO_ACCESS
|
||||
for (i=0; i<size; i++)
|
||||
dev_dbg(&spi->dev, "0x%x\n",buffer[i]);
|
||||
#endif
|
||||
|
||||
return spi_write (spi, local_buffer, size + 1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
u8 rf69_read_reg(struct spi_device *spi, u8 addr)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = spi_w8r8(spi, addr);
|
||||
|
||||
#ifdef DEBUG_VALUES
|
||||
if (retval < 0)
|
||||
/* should never happen, since we already checked,
|
||||
that module is connected. Therefore no error
|
||||
handling, just an optional error message... */
|
||||
dev_dbg(&spi->dev, "read 0x%x FAILED\n",
|
||||
addr);
|
||||
else
|
||||
dev_dbg(&spi->dev, "read 0x%x from reg 0x%x\n",
|
||||
retval,
|
||||
addr);
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int rf69_write_reg(struct spi_device *spi, u8 addr, u8 value)
|
||||
{
|
||||
int retval;
|
||||
char buffer[2];
|
||||
|
||||
buffer[0] = addr | WRITE_BIT;
|
||||
buffer[1] = value;
|
||||
|
||||
retval = spi_write(spi, &buffer, 2);
|
||||
|
||||
#ifdef DEBUG_VALUES
|
||||
if (retval < 0)
|
||||
/* should never happen, since we already checked,
|
||||
that module is connected. Therefore no error
|
||||
handling, just an optional error message... */
|
||||
dev_dbg(&spi->dev, "write 0x%x to 0x%x FAILED\n",
|
||||
value,
|
||||
addr);
|
||||
else
|
||||
dev_dbg(&spi->dev, "wrote 0x%x to reg 0x%x\n",
|
||||
value,
|
||||
addr);
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
82
drivers/staging/pi433/rf69.h
Normal file
82
drivers/staging/pi433/rf69.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* hardware abstraction/register access for HopeRf rf69 radio module
|
||||
*
|
||||
* Copyright (C) 2016 Wolf-Entwicklungen
|
||||
* Marcus Wolf <linux@wolf-entwicklungen.de>
|
||||
*
|
||||
* 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 2 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.
|
||||
*/
|
||||
#ifndef RF69_H
|
||||
#define RF69_H
|
||||
|
||||
#include "rf69_enum.h"
|
||||
#include "rf69_registers.h"
|
||||
|
||||
#define F_OSC 32000000 /* in Hz */
|
||||
#define FREQUENCY 433920000 /* in Hz, modifying this value impacts CE certification */
|
||||
#define FIFO_SIZE 66 /* in byte */
|
||||
#define FIFO_THRESHOLD 15 /* in byte */
|
||||
|
||||
int rf69_set_mode(struct spi_device *spi, enum mode mode);
|
||||
int rf69_set_data_mode(struct spi_device *spi, enum dataMode dataMode);
|
||||
int rf69_set_modulation(struct spi_device *spi, enum modulation modulation);
|
||||
enum modulation rf69_get_modulation(struct spi_device *spi);
|
||||
int rf69_set_modulation_shaping(struct spi_device *spi, enum modShaping modShaping);
|
||||
int rf69_set_bit_rate(struct spi_device *spi, u16 bitRate);
|
||||
int rf69_set_deviation(struct spi_device *spi, u32 deviation);
|
||||
int rf69_set_frequency(struct spi_device *spi, u32 frequency);
|
||||
int rf69_set_amplifier_0(struct spi_device *spi, enum optionOnOff optionOnOff);
|
||||
int rf69_set_amplifier_1(struct spi_device *spi, enum optionOnOff optionOnOff);
|
||||
int rf69_set_amplifier_2(struct spi_device *spi, enum optionOnOff optionOnOff);
|
||||
int rf69_set_output_power_level(struct spi_device *spi, u8 powerLevel);
|
||||
int rf69_set_pa_ramp(struct spi_device *spi, enum paRamp paRamp);
|
||||
int rf69_set_antenna_impedance(struct spi_device *spi, enum antennaImpedance antennaImpedance);
|
||||
int rf69_set_lna_gain(struct spi_device *spi, enum lnaGain lnaGain);
|
||||
enum lnaGain rf69_get_lna_gain(struct spi_device *spi);
|
||||
int rf69_set_dc_cut_off_frequency_intern(struct spi_device *spi, u8 reg, enum dccPercent dccPercent);
|
||||
int rf69_set_dc_cut_off_frequency(struct spi_device *spi, enum dccPercent dccPercent);
|
||||
int rf69_set_dc_cut_off_frequency_during_afc(struct spi_device *spi, enum dccPercent dccPercent);
|
||||
int rf69_set_bandwidth(struct spi_device *spi, enum mantisse mantisse, u8 exponent);
|
||||
int rf69_set_bandwidth_during_afc(struct spi_device *spi, enum mantisse mantisse, u8 exponent);
|
||||
int rf69_set_ook_threshold_type(struct spi_device *spi, enum thresholdType thresholdType);
|
||||
int rf69_set_ook_threshold_step(struct spi_device *spi, enum thresholdStep thresholdStep);
|
||||
int rf69_set_ook_threshold_dec(struct spi_device *spi, enum thresholdDecrement thresholdDecrement);
|
||||
int rf69_set_dio_mapping(struct spi_device *spi, u8 DIONumber, u8 value);
|
||||
bool rf69_get_flag(struct spi_device *spi, enum flag flag);
|
||||
int rf69_reset_flag(struct spi_device *spi, enum flag flag);
|
||||
int rf69_set_rssi_threshold(struct spi_device *spi, u8 threshold);
|
||||
int rf69_set_rx_start_timeout(struct spi_device *spi, u8 timeout);
|
||||
int rf69_set_rssi_timeout(struct spi_device *spi, u8 timeout);
|
||||
int rf69_set_preamble_length(struct spi_device *spi, u16 preambleLength);
|
||||
int rf69_set_sync_enable(struct spi_device *spi, enum optionOnOff optionOnOff);
|
||||
int rf69_set_fifo_fill_condition(struct spi_device *spi, enum fifoFillCondition fifoFillCondition);
|
||||
int rf69_set_sync_size(struct spi_device *spi, u8 sync_size);
|
||||
int rf69_set_sync_tolerance(struct spi_device *spi, u8 syncTolerance);
|
||||
int rf69_set_sync_values(struct spi_device *spi, u8 syncValues[8]);
|
||||
int rf69_set_packet_format(struct spi_device * spi, enum packetFormat packetFormat);
|
||||
int rf69_set_crc_enable(struct spi_device *spi, enum optionOnOff optionOnOff);
|
||||
int rf69_set_adressFiltering(struct spi_device *spi, enum addressFiltering addressFiltering);
|
||||
int rf69_set_payload_length(struct spi_device *spi, u8 payloadLength);
|
||||
u8 rf69_get_payload_length(struct spi_device *spi);
|
||||
int rf69_set_node_address(struct spi_device *spi, u8 nodeAddress);
|
||||
int rf69_set_broadcast_address(struct spi_device *spi, u8 broadcastAddress);
|
||||
int rf69_set_tx_start_condition(struct spi_device *spi, enum txStartCondition txStartCondition);
|
||||
int rf69_set_fifo_threshold(struct spi_device *spi, u8 threshold);
|
||||
int rf69_set_dagc(struct spi_device *spi, enum dagc dagc);
|
||||
|
||||
int rf69_read_fifo (struct spi_device *spi, u8 *buffer, unsigned int size);
|
||||
int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size);
|
||||
|
||||
u8 rf69_read_reg (struct spi_device *spi, u8 addr);
|
||||
int rf69_write_reg(struct spi_device *spi, u8 addr, u8 value);
|
||||
|
||||
|
||||
#endif
|
201
drivers/staging/pi433/rf69_enum.h
Normal file
201
drivers/staging/pi433/rf69_enum.h
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* enumerations for HopeRf rf69 radio module
|
||||
*
|
||||
* Copyright (C) 2016 Wolf-Entwicklungen
|
||||
* Marcus Wolf <linux@wolf-entwicklungen.de>
|
||||
*
|
||||
* 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 2 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.
|
||||
*/
|
||||
|
||||
#ifndef RF69_ENUM_H
|
||||
#define RF69_ENUM_H
|
||||
|
||||
enum optionOnOff
|
||||
{
|
||||
optionOff,
|
||||
optionOn
|
||||
};
|
||||
|
||||
enum mode
|
||||
{
|
||||
mode_sleep,
|
||||
standby,
|
||||
synthesizer,
|
||||
transmit,
|
||||
receive
|
||||
};
|
||||
|
||||
enum dataMode
|
||||
{
|
||||
packet,
|
||||
continuous,
|
||||
continuousNoSync
|
||||
};
|
||||
|
||||
enum modulation
|
||||
{
|
||||
OOK,
|
||||
FSK
|
||||
};
|
||||
|
||||
enum modShaping
|
||||
{
|
||||
shapingOff,
|
||||
shaping1_0,
|
||||
shaping0_5,
|
||||
shaping0_3,
|
||||
shapingBR,
|
||||
shaping2BR
|
||||
};
|
||||
|
||||
enum paRamp
|
||||
{
|
||||
ramp3400,
|
||||
ramp2000,
|
||||
ramp1000,
|
||||
ramp500,
|
||||
ramp250,
|
||||
ramp125,
|
||||
ramp100,
|
||||
ramp62,
|
||||
ramp50,
|
||||
ramp40,
|
||||
ramp31,
|
||||
ramp25,
|
||||
ramp20,
|
||||
ramp15,
|
||||
ramp12,
|
||||
ramp10
|
||||
};
|
||||
|
||||
enum antennaImpedance
|
||||
{
|
||||
fiftyOhm,
|
||||
twohundretOhm
|
||||
};
|
||||
|
||||
enum lnaGain
|
||||
{
|
||||
automatic,
|
||||
max,
|
||||
maxMinus6,
|
||||
maxMinus12,
|
||||
maxMinus24,
|
||||
maxMinus36,
|
||||
maxMinus48,
|
||||
undefined
|
||||
};
|
||||
|
||||
enum dccPercent
|
||||
{
|
||||
dcc16Percent,
|
||||
dcc8Percent,
|
||||
dcc4Percent,
|
||||
dcc2Percent,
|
||||
dcc1Percent,
|
||||
dcc0_5Percent,
|
||||
dcc0_25Percent,
|
||||
dcc0_125Percent
|
||||
};
|
||||
|
||||
enum mantisse
|
||||
{
|
||||
mantisse16,
|
||||
mantisse20,
|
||||
mantisse24
|
||||
};
|
||||
|
||||
enum thresholdType
|
||||
{
|
||||
fixed,
|
||||
peak,
|
||||
average
|
||||
};
|
||||
|
||||
enum thresholdStep
|
||||
{
|
||||
step_0_5db,
|
||||
step_1_0db,
|
||||
step_1_5db,
|
||||
step_2_0db,
|
||||
step_3_0db,
|
||||
step_4_0db,
|
||||
step_5_0db,
|
||||
step_6_0db
|
||||
};
|
||||
|
||||
enum thresholdDecrement
|
||||
{
|
||||
dec_every8th,
|
||||
dec_every4th,
|
||||
dec_every2nd,
|
||||
dec_once,
|
||||
dec_twice,
|
||||
dec_4times,
|
||||
dec_8times,
|
||||
dec_16times
|
||||
};
|
||||
|
||||
enum flag
|
||||
{
|
||||
modeSwitchCompleted,
|
||||
readyToReceive,
|
||||
readyToSend,
|
||||
pllLocked,
|
||||
rssiExceededThreshold,
|
||||
timeout,
|
||||
automode,
|
||||
syncAddressMatch,
|
||||
fifoFull,
|
||||
// fifoNotEmpty, collision with next enum; replaced by following enum...
|
||||
fifoEmpty,
|
||||
fifoLevelBelowThreshold,
|
||||
fifoOverrun,
|
||||
packetSent,
|
||||
payloadReady,
|
||||
crcOk,
|
||||
batteryLow
|
||||
};
|
||||
|
||||
enum fifoFillCondition
|
||||
{
|
||||
afterSyncInterrupt,
|
||||
always
|
||||
};
|
||||
|
||||
enum packetFormat
|
||||
{
|
||||
packetLengthFix,
|
||||
packetLengthVar
|
||||
};
|
||||
|
||||
enum txStartCondition
|
||||
{
|
||||
fifoLevel,
|
||||
fifoNotEmpty
|
||||
};
|
||||
|
||||
enum addressFiltering
|
||||
{
|
||||
filteringOff,
|
||||
nodeAddress,
|
||||
nodeOrBroadcastAddress
|
||||
};
|
||||
|
||||
enum dagc
|
||||
{
|
||||
normalMode,
|
||||
improve,
|
||||
improve4LowModulationIndex
|
||||
};
|
||||
|
||||
|
||||
#endif
|
489
drivers/staging/pi433/rf69_registers.h
Normal file
489
drivers/staging/pi433/rf69_registers.h
Normal file
@ -0,0 +1,489 @@
|
||||
/*
|
||||
* register description for HopeRf rf69 radio module
|
||||
*
|
||||
* Copyright (C) 2016 Wolf-Entwicklungen
|
||||
* Marcus Wolf <linux@wolf-entwicklungen.de>
|
||||
*
|
||||
* 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 2 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.
|
||||
*/
|
||||
|
||||
/*******************************************/
|
||||
/* RF69 register addresses */
|
||||
/*******************************************/
|
||||
#define REG_FIFO 0x00
|
||||
#define REG_OPMODE 0x01
|
||||
#define REG_DATAMODUL 0x02
|
||||
#define REG_BITRATE_MSB 0x03
|
||||
#define REG_BITRATE_LSB 0x04
|
||||
#define REG_FDEV_MSB 0x05
|
||||
#define REG_FDEV_LSB 0x06
|
||||
#define REG_FRF_MSB 0x07
|
||||
#define REG_FRF_MID 0x08
|
||||
#define REG_FRF_LSB 0x09
|
||||
#define REG_OSC1 0x0A
|
||||
#define REG_AFCCTRL 0x0B
|
||||
#define REG_LOWBAT 0x0C
|
||||
#define REG_LISTEN1 0x0D
|
||||
#define REG_LISTEN2 0x0E
|
||||
#define REG_LISTEN3 0x0F
|
||||
#define REG_VERSION 0x10
|
||||
#define REG_PALEVEL 0x11
|
||||
#define REG_PARAMP 0x12
|
||||
#define REG_OCP 0x13
|
||||
#define REG_AGCREF 0x14 /* not available on RF69 */
|
||||
#define REG_AGCTHRESH1 0x15 /* not available on RF69 */
|
||||
#define REG_AGCTHRESH2 0x16 /* not available on RF69 */
|
||||
#define REG_AGCTHRESH3 0x17 /* not available on RF69 */
|
||||
#define REG_LNA 0x18
|
||||
#define REG_RXBW 0x19
|
||||
#define REG_AFCBW 0x1A
|
||||
#define REG_OOKPEAK 0x1B
|
||||
#define REG_OOKAVG 0x1C
|
||||
#define REG_OOKFIX 0x1D
|
||||
#define REG_AFCFEI 0x1E
|
||||
#define REG_AFCMSB 0x1F
|
||||
#define REG_AFCLSB 0x20
|
||||
#define REG_FEIMSB 0x21
|
||||
#define REG_FEILSB 0x22
|
||||
#define REG_RSSICONFIG 0x23
|
||||
#define REG_RSSIVALUE 0x24
|
||||
#define REG_DIOMAPPING1 0x25
|
||||
#define REG_DIOMAPPING2 0x26
|
||||
#define REG_IRQFLAGS1 0x27
|
||||
#define REG_IRQFLAGS2 0x28
|
||||
#define REG_RSSITHRESH 0x29
|
||||
#define REG_RXTIMEOUT1 0x2A
|
||||
#define REG_RXTIMEOUT2 0x2B
|
||||
#define REG_PREAMBLE_MSB 0x2C
|
||||
#define REG_PREAMBLE_LSB 0x2D
|
||||
#define REG_SYNC_CONFIG 0x2E
|
||||
#define REG_SYNCVALUE1 0x2F
|
||||
#define REG_SYNCVALUE2 0x30
|
||||
#define REG_SYNCVALUE3 0x31
|
||||
#define REG_SYNCVALUE4 0x32
|
||||
#define REG_SYNCVALUE5 0x33
|
||||
#define REG_SYNCVALUE6 0x34
|
||||
#define REG_SYNCVALUE7 0x35
|
||||
#define REG_SYNCVALUE8 0x36
|
||||
#define REG_PACKETCONFIG1 0x37
|
||||
#define REG_PAYLOAD_LENGTH 0x38
|
||||
#define REG_NODEADRS 0x39
|
||||
#define REG_BROADCASTADRS 0x3A
|
||||
#define REG_AUTOMODES 0x3B
|
||||
#define REG_FIFO_THRESH 0x3C
|
||||
#define REG_PACKETCONFIG2 0x3D
|
||||
#define REG_AESKEY1 0x3E
|
||||
#define REG_AESKEY2 0x3F
|
||||
#define REG_AESKEY3 0x40
|
||||
#define REG_AESKEY4 0x41
|
||||
#define REG_AESKEY5 0x42
|
||||
#define REG_AESKEY6 0x43
|
||||
#define REG_AESKEY7 0x44
|
||||
#define REG_AESKEY8 0x45
|
||||
#define REG_AESKEY9 0x46
|
||||
#define REG_AESKEY10 0x47
|
||||
#define REG_AESKEY11 0x48
|
||||
#define REG_AESKEY12 0x49
|
||||
#define REG_AESKEY13 0x4A
|
||||
#define REG_AESKEY14 0x4B
|
||||
#define REG_AESKEY15 0x4C
|
||||
#define REG_AESKEY16 0x4D
|
||||
#define REG_TEMP1 0x4E
|
||||
#define REG_TEMP2 0x4F
|
||||
#define REG_TESTPA1 0x5A /* only present on RFM69HW */
|
||||
#define REG_TESTPA2 0x5C /* only present on RFM69HW */
|
||||
#define REG_TESTDAGC 0x6F
|
||||
|
||||
/******************************************************/
|
||||
/* RF69/SX1231 bit definition */
|
||||
/******************************************************/
|
||||
/* write bit */
|
||||
#define WRITE_BIT 0x80
|
||||
|
||||
/* RegOpMode */
|
||||
#define MASK_OPMODE_SEQUENCER_OFF 0x80
|
||||
#define MASK_OPMODE_LISTEN_ON 0x40
|
||||
#define MASK_OPMODE_LISTEN_ABORT 0x20
|
||||
#define MASK_OPMODE_MODE 0x1C
|
||||
|
||||
#define OPMODE_MODE_SLEEP 0x00
|
||||
#define OPMODE_MODE_STANDBY 0x04 /* default */
|
||||
#define OPMODE_MODE_SYNTHESIZER 0x08
|
||||
#define OPMODE_MODE_TRANSMIT 0x0C
|
||||
#define OPMODE_MODE_RECEIVE 0x10
|
||||
|
||||
/* RegDataModul */
|
||||
#define MASK_DATAMODUL_MODE 0x06
|
||||
#define MASK_DATAMODUL_MODULATION_TYPE 0x18
|
||||
#define MASK_DATAMODUL_MODULATION_SHAPE 0x03
|
||||
|
||||
#define DATAMODUL_MODE_PACKET 0x00 /* default */
|
||||
#define DATAMODUL_MODE_CONTINUOUS 0x40
|
||||
#define DATAMODUL_MODE_CONTINUOUS_NOSYNC 0x60
|
||||
|
||||
#define DATAMODUL_MODULATION_TYPE_FSK 0x00 /* default */
|
||||
#define DATAMODUL_MODULATION_TYPE_OOK 0x08
|
||||
|
||||
#define DATAMODUL_MODULATION_SHAPE_NONE 0x00 /* default */
|
||||
#define DATAMODUL_MODULATION_SHAPE_1_0 0x01
|
||||
#define DATAMODUL_MODULATION_SHAPE_0_5 0x02
|
||||
#define DATAMODUL_MODULATION_SHAPE_0_3 0x03
|
||||
#define DATAMODUL_MODULATION_SHAPE_BR 0x01
|
||||
#define DATAMODUL_MODULATION_SHAPE_2BR 0x02
|
||||
|
||||
/* RegFDevMsb (0x05)*/
|
||||
#define FDEVMASB_MASK 0x3f
|
||||
|
||||
/*
|
||||
// RegOsc1
|
||||
#define OSC1_RCCAL_START 0x80
|
||||
#define OSC1_RCCAL_DONE 0x40
|
||||
|
||||
// RegLowBat
|
||||
#define LOWBAT_MONITOR 0x10
|
||||
#define LOWBAT_ON 0x08
|
||||
#define LOWBAT_OFF 0x00 // Default
|
||||
|
||||
#define LOWBAT_TRIM_1695 0x00
|
||||
#define LOWBAT_TRIM_1764 0x01
|
||||
#define LOWBAT_TRIM_1835 0x02 // Default
|
||||
#define LOWBAT_TRIM_1905 0x03
|
||||
#define LOWBAT_TRIM_1976 0x04
|
||||
#define LOWBAT_TRIM_2045 0x05
|
||||
#define LOWBAT_TRIM_2116 0x06
|
||||
#define LOWBAT_TRIM_2185 0x07
|
||||
|
||||
|
||||
// RegListen1
|
||||
#define LISTEN1_RESOL_64 0x50
|
||||
#define LISTEN1_RESOL_4100 0xA0 // Default
|
||||
#define LISTEN1_RESOL_262000 0xF0
|
||||
|
||||
#define LISTEN1_CRITERIA_RSSI 0x00 // Default
|
||||
#define LISTEN1_CRITERIA_RSSIANDSYNC 0x08
|
||||
|
||||
#define LISTEN1_END_00 0x00
|
||||
#define LISTEN1_END_01 0x02 // Default
|
||||
#define LISTEN1_END_10 0x04
|
||||
|
||||
|
||||
// RegListen2
|
||||
#define LISTEN2_COEFIDLE_VALUE 0xF5 // Default
|
||||
|
||||
// RegListen3
|
||||
#define LISTEN3_COEFRX_VALUE 0x20 // Default
|
||||
*/
|
||||
|
||||
// RegPaLevel
|
||||
#define MASK_PALEVEL_PA0 0x80
|
||||
#define MASK_PALEVEL_PA1 0x40
|
||||
#define MASK_PALEVEL_PA2 0x20
|
||||
#define MASK_PALEVEL_OUTPUT_POWER 0x1F
|
||||
|
||||
|
||||
|
||||
// RegPaRamp
|
||||
#define PARAMP_3400 0x00
|
||||
#define PARAMP_2000 0x01
|
||||
#define PARAMP_1000 0x02
|
||||
#define PARAMP_500 0x03
|
||||
#define PARAMP_250 0x04
|
||||
#define PARAMP_125 0x05
|
||||
#define PARAMP_100 0x06
|
||||
#define PARAMP_62 0x07
|
||||
#define PARAMP_50 0x08
|
||||
#define PARAMP_40 0x09 /* default */
|
||||
#define PARAMP_31 0x0A
|
||||
#define PARAMP_25 0x0B
|
||||
#define PARAMP_20 0x0C
|
||||
#define PARAMP_15 0x0D
|
||||
#define PARAMP_12 0x0E
|
||||
#define PARAMP_10 0x0F
|
||||
|
||||
#define MASK_PARAMP 0x0F
|
||||
|
||||
/*
|
||||
// RegOcp
|
||||
#define OCP_OFF 0x0F
|
||||
#define OCP_ON 0x1A // Default
|
||||
|
||||
#define OCP_TRIM_45 0x00
|
||||
#define OCP_TRIM_50 0x01
|
||||
#define OCP_TRIM_55 0x02
|
||||
#define OCP_TRIM_60 0x03
|
||||
#define OCP_TRIM_65 0x04
|
||||
#define OCP_TRIM_70 0x05
|
||||
#define OCP_TRIM_75 0x06
|
||||
#define OCP_TRIM_80 0x07
|
||||
#define OCP_TRIM_85 0x08
|
||||
#define OCP_TRIM_90 0x09
|
||||
#define OCP_TRIM_95 0x0A
|
||||
#define OCP_TRIM_100 0x0B // Default
|
||||
#define OCP_TRIM_105 0x0C
|
||||
#define OCP_TRIM_110 0x0D
|
||||
#define OCP_TRIM_115 0x0E
|
||||
#define OCP_TRIM_120 0x0F
|
||||
*/
|
||||
|
||||
/* RegLna (0x18) */
|
||||
#define MASK_LNA_ZIN 0x80
|
||||
#define MASK_LNA_CURRENT_GAIN 0x38
|
||||
#define MASK_LNA_GAIN 0x07
|
||||
|
||||
#define LNA_GAIN_AUTO 0x00 /* default */
|
||||
#define LNA_GAIN_MAX 0x01
|
||||
#define LNA_GAIN_MAX_MINUS_6 0x02
|
||||
#define LNA_GAIN_MAX_MINUS_12 0x03
|
||||
#define LNA_GAIN_MAX_MINUS_24 0x04
|
||||
#define LNA_GAIN_MAX_MINUS_36 0x05
|
||||
#define LNA_GAIN_MAX_MINUS_48 0x06
|
||||
|
||||
|
||||
/* RegRxBw (0x19) and RegAfcBw (0x1A) */
|
||||
#define MASK_BW_DCC_FREQ 0xE0
|
||||
#define MASK_BW_MANTISSE 0x18
|
||||
#define MASK_BW_EXPONENT 0x07
|
||||
|
||||
#define BW_DCC_16_PERCENT 0x00
|
||||
#define BW_DCC_8_PERCENT 0x20
|
||||
#define BW_DCC_4_PERCENT 0x40 /* default */
|
||||
#define BW_DCC_2_PERCENT 0x60
|
||||
#define BW_DCC_1_PERCENT 0x80
|
||||
#define BW_DCC_0_5_PERCENT 0xA0
|
||||
#define BW_DCC_0_25_PERCENT 0xC0
|
||||
#define BW_DCC_0_125_PERCENT 0xE0
|
||||
|
||||
#define BW_MANT_16 0x00
|
||||
#define BW_MANT_20 0x08
|
||||
#define BW_MANT_24 0x10 /* default */
|
||||
|
||||
|
||||
/* RegOokPeak (0x1B) */
|
||||
#define MASK_OOKPEAK_THRESTYPE 0xc0
|
||||
#define MASK_OOKPEAK_THRESSTEP 0x38
|
||||
#define MASK_OOKPEAK_THRESDEC 0x07
|
||||
|
||||
#define OOKPEAK_THRESHTYPE_FIXED 0x00
|
||||
#define OOKPEAK_THRESHTYPE_PEAK 0x40 /* default */
|
||||
#define OOKPEAK_THRESHTYPE_AVERAGE 0x80
|
||||
|
||||
#define OOKPEAK_THRESHSTEP_0_5_DB 0x00 /* default */
|
||||
#define OOKPEAK_THRESHSTEP_1_0_DB 0x08
|
||||
#define OOKPEAK_THRESHSTEP_1_5_DB 0x10
|
||||
#define OOKPEAK_THRESHSTEP_2_0_DB 0x18
|
||||
#define OOKPEAK_THRESHSTEP_3_0_DB 0x20
|
||||
#define OOKPEAK_THRESHSTEP_4_0_DB 0x28
|
||||
#define OOKPEAK_THRESHSTEP_5_0_DB 0x30
|
||||
#define OOKPEAK_THRESHSTEP_6_0_DB 0x38
|
||||
|
||||
#define OOKPEAK_THRESHDEC_ONCE 0x00 /* default */
|
||||
#define OOKPEAK_THRESHDEC_EVERY_2ND 0x01
|
||||
#define OOKPEAK_THRESHDEC_EVERY_4TH 0x02
|
||||
#define OOKPEAK_THRESHDEC_EVERY_8TH 0x03
|
||||
#define OOKPEAK_THRESHDEC_TWICE 0x04
|
||||
#define OOKPEAK_THRESHDEC_4_TIMES 0x05
|
||||
#define OOKPEAK_THRESHDEC_8_TIMES 0x06
|
||||
#define OOKPEAK_THRESHDEC_16_TIMES 0x07
|
||||
|
||||
/*
|
||||
// RegOokAvg
|
||||
#define OOKAVG_AVERAGETHRESHFILT_00 0x00
|
||||
#define OOKAVG_AVERAGETHRESHFILT_01 0x40
|
||||
#define OOKAVG_AVERAGETHRESHFILT_10 0x80 // Default
|
||||
#define OOKAVG_AVERAGETHRESHFILT_11 0xC0
|
||||
|
||||
|
||||
// RegAfcFei
|
||||
#define AFCFEI_FEI_DONE 0x40
|
||||
#define AFCFEI_FEI_START 0x20
|
||||
#define AFCFEI_AFC_DONE 0x10
|
||||
#define AFCFEI_AFCAUTOCLEAR_ON 0x08
|
||||
#define AFCFEI_AFCAUTOCLEAR_OFF 0x00 // Default
|
||||
|
||||
#define AFCFEI_AFCAUTO_ON 0x04
|
||||
#define AFCFEI_AFCAUTO_OFF 0x00 // Default
|
||||
|
||||
#define AFCFEI_AFC_CLEAR 0x02
|
||||
#define AFCFEI_AFC_START 0x01
|
||||
|
||||
// RegRssiConfig
|
||||
#define RSSI_FASTRX_ON 0x08
|
||||
#define RSSI_FASTRX_OFF 0x00 // Default
|
||||
#define RSSI_DONE 0x02
|
||||
#define RSSI_START 0x01
|
||||
*/
|
||||
|
||||
/* RegDioMapping1 */
|
||||
#define MASK_DIO0 0xC0
|
||||
#define MASK_DIO1 0x30
|
||||
#define MASK_DIO2 0x0C
|
||||
#define MASK_DIO3 0x03
|
||||
#define SHIFT_DIO0 6
|
||||
#define SHIFT_DIO1 4
|
||||
#define SHIFT_DIO2 2
|
||||
#define SHIFT_DIO3 0
|
||||
|
||||
/* RegDioMapping2 */
|
||||
#define MASK_DIO4 0xC0
|
||||
#define MASK_DIO5 0x30
|
||||
#define SHIFT_DIO4 6
|
||||
#define SHIFT_DIO5 4
|
||||
|
||||
/* DIO numbers */
|
||||
#define DIO0 0
|
||||
#define DIO1 1
|
||||
#define DIO2 2
|
||||
#define DIO3 3
|
||||
#define DIO4 4
|
||||
#define DIO5 5
|
||||
|
||||
/* DIO Mapping values (packet mode) */
|
||||
#define DIO_ModeReady_DIO4 0x00
|
||||
#define DIO_ModeReady_DIO5 0x03
|
||||
#define DIO_ClkOut 0x00
|
||||
#define DIO_Data 0x01
|
||||
#define DIO_TimeOut_DIO1 0x03
|
||||
#define DIO_TimeOut_DIO4 0x00
|
||||
#define DIO_Rssi_DIO0 0x03
|
||||
#define DIO_Rssi_DIO3_4 0x01
|
||||
#define DIO_RxReady 0x02
|
||||
#define DIO_PLLLock 0x03
|
||||
#define DIO_TxReady 0x01
|
||||
#define DIO_FifoFull_DIO1 0x01
|
||||
#define DIO_FifoFull_DIO3 0x00
|
||||
#define DIO_SyncAddress 0x02
|
||||
#define DIO_FifoNotEmpty_DIO1 0x02
|
||||
#define DIO_FifoNotEmpty_FIO2 0x00
|
||||
#define DIO_Automode 0x04
|
||||
#define DIO_FifoLevel 0x00
|
||||
#define DIO_CrcOk 0x00
|
||||
#define DIO_PayloadReady 0x01
|
||||
#define DIO_PacketSent 0x00
|
||||
#define DIO_Dclk 0x00
|
||||
|
||||
/* RegDioMapping2 CLK_OUT part */
|
||||
#define MASK_DIOMAPPING2_CLK_OUT 0x07
|
||||
|
||||
#define DIOMAPPING2_CLK_OUT_NO_DIV 0x00
|
||||
#define DIOMAPPING2_CLK_OUT_DIV_2 0x01
|
||||
#define DIOMAPPING2_CLK_OUT_DIV_4 0x02
|
||||
#define DIOMAPPING2_CLK_OUT_DIV_8 0x03
|
||||
#define DIOMAPPING2_CLK_OUT_DIV_16 0x04
|
||||
#define DIOMAPPING2_CLK_OUT_DIV_32 0x05
|
||||
#define DIOMAPPING2_CLK_OUT_RC 0x06
|
||||
#define DIOMAPPING2_CLK_OUT_OFF 0x07 /* default */
|
||||
|
||||
/* RegIrqFlags1 */
|
||||
#define MASK_IRQFLAGS1_MODE_READY 0x80
|
||||
#define MASK_IRQFLAGS1_RX_READY 0x40
|
||||
#define MASK_IRQFLAGS1_TX_READY 0x20
|
||||
#define MASK_IRQFLAGS1_PLL_LOCK 0x10
|
||||
#define MASK_IRQFLAGS1_RSSI 0x08
|
||||
#define MASK_IRQFLAGS1_TIMEOUT 0x04
|
||||
#define MASK_IRQFLAGS1_AUTOMODE 0x02
|
||||
#define MASK_IRQFLAGS1_SYNC_ADDRESS_MATCH 0x01
|
||||
|
||||
/* RegIrqFlags2 */
|
||||
#define MASK_IRQFLAGS2_FIFO_FULL 0x80
|
||||
#define MASK_IRQFLAGS2_FIFO_NOT_EMPTY 0x40
|
||||
#define MASK_IRQFLAGS2_FIFO_LEVEL 0x20
|
||||
#define MASK_IRQFLAGS2_FIFO_OVERRUN 0x10
|
||||
#define MASK_IRQFLAGS2_PACKET_SENT 0x08
|
||||
#define MASK_IRQFLAGS2_PAYLOAD_READY 0x04
|
||||
#define MASK_IRQFLAGS2_CRC_OK 0x02
|
||||
#define MASK_IRQFLAGS2_LOW_BAT 0x01
|
||||
|
||||
/* RegSyncConfig */
|
||||
#define MASK_SYNC_CONFIG_SYNC_ON 0x80 /* default */
|
||||
#define MASK_SYNC_CONFIG_FIFO_FILL_CONDITION 0x40
|
||||
#define MASK_SYNC_CONFIG_SYNC_SIZE 0x38
|
||||
#define MASK_SYNC_CONFIG_SYNC_TOLERANCE 0x07
|
||||
|
||||
/* RegPacketConfig1 */
|
||||
#define MASK_PACKETCONFIG1_PAKET_FORMAT_VARIABLE 0x80
|
||||
#define MASK_PACKETCONFIG1_DCFREE 0x60
|
||||
#define MASK_PACKETCONFIG1_CRC_ON 0x10 /* default */
|
||||
#define MASK_PACKETCONFIG1_CRCAUTOCLEAR_OFF 0x08
|
||||
#define MASK_PACKETCONFIG1_ADDRESSFILTERING 0x06
|
||||
|
||||
#define PACKETCONFIG1_DCFREE_OFF 0x00 /* default */
|
||||
#define PACKETCONFIG1_DCFREE_MANCHESTER 0x20
|
||||
#define PACKETCONFIG1_DCFREE_WHITENING 0x40
|
||||
#define PACKETCONFIG1_ADDRESSFILTERING_OFF 0x00 /* default */
|
||||
#define PACKETCONFIG1_ADDRESSFILTERING_NODE 0x02
|
||||
#define PACKETCONFIG1_ADDRESSFILTERING_NODEBROADCAST 0x04
|
||||
|
||||
/*
|
||||
// RegAutoModes
|
||||
#define AUTOMODES_ENTER_OFF 0x00 // Default
|
||||
#define AUTOMODES_ENTER_FIFONOTEMPTY 0x20
|
||||
#define AUTOMODES_ENTER_FIFOLEVEL 0x40
|
||||
#define AUTOMODES_ENTER_CRCOK 0x60
|
||||
#define AUTOMODES_ENTER_PAYLOADREADY 0x80
|
||||
#define AUTOMODES_ENTER_SYNCADRSMATCH 0xA0
|
||||
#define AUTOMODES_ENTER_PACKETSENT 0xC0
|
||||
#define AUTOMODES_ENTER_FIFOEMPTY 0xE0
|
||||
|
||||
#define AUTOMODES_EXIT_OFF 0x00 // Default
|
||||
#define AUTOMODES_EXIT_FIFOEMPTY 0x04
|
||||
#define AUTOMODES_EXIT_FIFOLEVEL 0x08
|
||||
#define AUTOMODES_EXIT_CRCOK 0x0C
|
||||
#define AUTOMODES_EXIT_PAYLOADREADY 0x10
|
||||
#define AUTOMODES_EXIT_SYNCADRSMATCH 0x14
|
||||
#define AUTOMODES_EXIT_PACKETSENT 0x18
|
||||
#define AUTOMODES_EXIT_RXTIMEOUT 0x1C
|
||||
|
||||
#define AUTOMODES_INTERMEDIATE_SLEEP 0x00 // Default
|
||||
#define AUTOMODES_INTERMEDIATE_STANDBY 0x01
|
||||
#define AUTOMODES_INTERMEDIATE_RECEIVER 0x02
|
||||
#define AUTOMODES_INTERMEDIATE_TRANSMITTER 0x03
|
||||
|
||||
*/
|
||||
/* RegFifoThresh (0x3c) */
|
||||
#define MASK_FIFO_THRESH_TXSTART 0x80
|
||||
#define MASK_FIFO_THRESH_VALUE 0x7F
|
||||
|
||||
/*
|
||||
|
||||
// RegPacketConfig2
|
||||
#define PACKET2_RXRESTARTDELAY_1BIT 0x00 // Default
|
||||
#define PACKET2_RXRESTARTDELAY_2BITS 0x10
|
||||
#define PACKET2_RXRESTARTDELAY_4BITS 0x20
|
||||
#define PACKET2_RXRESTARTDELAY_8BITS 0x30
|
||||
#define PACKET2_RXRESTARTDELAY_16BITS 0x40
|
||||
#define PACKET2_RXRESTARTDELAY_32BITS 0x50
|
||||
#define PACKET2_RXRESTARTDELAY_64BITS 0x60
|
||||
#define PACKET2_RXRESTARTDELAY_128BITS 0x70
|
||||
#define PACKET2_RXRESTARTDELAY_256BITS 0x80
|
||||
#define PACKET2_RXRESTARTDELAY_512BITS 0x90
|
||||
#define PACKET2_RXRESTARTDELAY_1024BITS 0xA0
|
||||
#define PACKET2_RXRESTARTDELAY_2048BITS 0xB0
|
||||
#define PACKET2_RXRESTARTDELAY_NONE 0xC0
|
||||
#define PACKET2_RXRESTART 0x04
|
||||
|
||||
#define PACKET2_AUTORXRESTART_ON 0x02 // Default
|
||||
#define PACKET2_AUTORXRESTART_OFF 0x00
|
||||
|
||||
#define PACKET2_AES_ON 0x01
|
||||
#define PACKET2_AES_OFF 0x00 // Default
|
||||
|
||||
|
||||
// RegTemp1
|
||||
#define TEMP1_MEAS_START 0x08
|
||||
#define TEMP1_MEAS_RUNNING 0x04
|
||||
#define TEMP1_ADCLOWPOWER_ON 0x01 // Default
|
||||
#define TEMP1_ADCLOWPOWER_OFF 0x00
|
||||
*/
|
||||
|
||||
// RegTestDagc (0x6F)
|
||||
#define DAGC_NORMAL 0x00 /* Reset value */
|
||||
#define DAGC_IMPROVED_LOWBETA1 0x20
|
||||
#define DAGC_IMPROVED_LOWBETA0 0x30 /* Recommended val */
|
Loading…
Reference in New Issue
Block a user