Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Marcus Wolf and committed by
Greg Kroah-Hartman
874bcba6 07119e25

+3636
+2
drivers/staging/Kconfig
··· 110 110 111 111 source "drivers/staging/typec/Kconfig" 112 112 113 + source "drivers/staging/pi433/Kconfig" 114 + 113 115 endif # STAGING
+1
drivers/staging/Makefile
··· 44 44 obj-$(CONFIG_GREYBUS) += greybus/ 45 45 obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ 46 46 obj-$(CONFIG_CRYPTO_DEV_CCREE) += ccree/ 47 + obj-$(CONFIG_PI433) += pi433/
+53
drivers/staging/pi433/Documentation/devicetree/pi433-overlay.dts
··· 1 + // Definitions for Pi433 2 + /dts-v1/; 3 + /plugin/; 4 + 5 + / { 6 + compatible = "bcm,bcm2835", "bcm,bcm2708", "bcm,bcm2709"; 7 + 8 + fragment@0 { 9 + target = <&spi0>; 10 + __overlay__ { 11 + status = "okay"; 12 + 13 + spidev@0{ 14 + status = "disabled"; 15 + }; 16 + 17 + spidev@1{ 18 + status = "disabled"; 19 + }; 20 + }; 21 + }; 22 + 23 + fragment@1 { 24 + target = <&gpio>; 25 + __overlay__ { 26 + pi433_pins: pi433_pins { 27 + brcm,pins = <7 25 24>; 28 + brcm,function = <0 0 0>; // in in in 29 + }; 30 + }; 31 + }; 32 + 33 + fragment@2 { 34 + target = <&spi0>; 35 + __overlay__ { 36 + #address-cells = <1>; 37 + #size-cells = <0>; 38 + status = "okay"; 39 + 40 + pi433: pi433@0 { 41 + compatible = "Smarthome-Wolf,pi433"; 42 + reg = <0>; 43 + spi-max-frequency = <10000000>; 44 + status = "okay"; 45 + 46 + pinctrl-0 = <&pi433_pins>; 47 + DIO0-gpio = <&gpio 24 0>; 48 + DIO1-gpio = <&gpio 25 0>; 49 + DIO2-gpio = <&gpio 7 0>; 50 + }; 51 + }; 52 + }; 53 + };
+62
drivers/staging/pi433/Documentation/devicetree/pi433.txt
··· 1 + * Smarthome-Wolf Pi433 - a 433MHz radio module/shield for Raspberry Pi (see www.pi433.de) 2 + 3 + Required properties: 4 + - compatible: must be "Smarthome-Wolf,pi433" 5 + - reg: chip select of SPI Interface 6 + - DIOx-gpio must be dedicated to the GPIO, connected with DIOx of the RFM69 module 7 + 8 + 9 + Example: 10 + 11 + With the following lines in gpio-section, the gpio pins, connected with pi433 are 12 + reserved/declared. 13 + 14 + &gpio{ 15 + [...] 16 + 17 + pi433_pins: pi433_pins { 18 + brcm,pins = <7 25 24>; 19 + brcm,function = <0 0 0>; // in in in 20 + }; 21 + 22 + [...] 23 + } 24 + 25 + With the following lines in spi section, the device pi433 is declared. 26 + It consists of the three gpio pins and an spi interface (here chip select 0) 27 + 28 + &spi0{ 29 + [...] 30 + 31 + pi433: pi433@0 { 32 + compatible = "Smarthome-Wolf,pi433"; 33 + reg = <0>; /* CE 0 */ 34 + #address-cells = <1>; 35 + #size-cells = <0>; 36 + spi-max-frequency = <10000000>; 37 + 38 + pinctrl-0 = <&pi433_pins>; 39 + DIO0-gpio = <&gpio 24 0>; 40 + DIO1-gpio = <&gpio 25 0>; 41 + DIO2-gpio = <&gpio 7 0>; 42 + }; 43 + } 44 + 45 + 46 + 47 + For Raspbian users only 48 + ======================= 49 + Since Raspbian supports device tree overlays, you may use and overlay, instead 50 + of editing your boards device tree. 51 + For using the overlay, you need to compile the file pi433-overlay.dts you can 52 + find aside to this documentation. 53 + The file needs to be compiled - either manually or by integration in your kernel 54 + source tree. For a manual compile, you may use a command line like the following: 55 + 'linux/scripts/dtc/dtc -@ -I dts -O dtb -o pi433.dtbo pi433-overlay.dts' 56 + 57 + For compiling inside of the kernel tree, you need to copy pi433-overlay.dts to 58 + arch/arm/boot/dts/overlays and you need to add the file to the list of files 59 + in the Makefile over there. Execute 'make dtbs' in kernel tree root to make the 60 + kernel make files compile the device tree overlay for you. 61 + 62 +
+274
drivers/staging/pi433/Documentation/pi433.txt
··· 1 + ===== 2 + Pi433 3 + ===== 4 + 5 + 6 + Introduction 7 + ============ 8 + This driver is for controlling pi433, a radio module for the Raspberry Pi 9 + (www.pi433.de). It supports transmission and reception. It can be opened 10 + by multiple applications for transmission and reception. While transmit 11 + jobs were queued and process automatically in the background, the first 12 + application asking for reception will block out all other applications 13 + until something gets received terminates the read request. 14 + The driver supports on the fly reloading of the hardware fifo of the rf 15 + chip, thus enabling for much longer telegrams then hardware fifo size. 16 + 17 + Discription of driver operation 18 + =============================== 19 + 20 + a) transmission 21 + 22 + Each transmission can take place with a different configuration of the rf 23 + module. Therfore each application can set its own set of parameters. The driver 24 + takes care, that each transmission takes place with the parameterset of the 25 + application, that requests the transmission. To allow the transmission to take 26 + place in the background, a tx thread is introduced. 27 + The transfer of data from the main thread to the tx thread is realised by a 28 + kfifo. With each write request of an application, the passed in data and the 29 + corresponding parameter set gets written to the kfifo. 30 + On the other "side" of the kfifo, the tx thread continuously checks, whether the 31 + kfifo is empty. If not, it gets one set of config and data from the kfifo. If 32 + there is no receive request or the receiver is still waiting for something in 33 + the air, the rf module is set to standby, the parameters for transmission gets 34 + set, the hardware fifo of the rf chip gets preloaded and the transmission gets 35 + started. Upon hardware fifo threshold interrupt it gets reloaded, thus enabling 36 + much longer telegrams then hardware fifo size. If the telegram is send and there 37 + is more data available in the kfifo, the procedure is repeated. If not the 38 + transmission cycle ends. 39 + 40 + b) reception 41 + 42 + Since there is only one application allowed to receive data at a time, for 43 + reception there is only one configuration set. 44 + As soon as an application sets an request for receiving a telegram, the reception 45 + configuration set is written to the rf module and it gets set into receiving mode. 46 + Now the driver is waiting, that a predefined RSSI level (signal strength at the 47 + receiver) is reached. Until this hasn't happened, the reception can be 48 + interrupted by the transmission thread at any time to insert a transmission cycle. 49 + As soon as the predefined RSSI level is meat, a receiving cycle starts. Similar 50 + as described for the transmission cycle the read out of the hardware fifo is done 51 + dynamically. Upon each hardware fifo threshold interrupt, a portion of data gets 52 + read. So also for reception it is possible to receive more data then the hardware 53 + fifo can hold. 54 + 55 + 56 + Driver API 57 + ========== 58 + 59 + The driver is currently implemented as a character device. Therefore it supports 60 + the calls open, ioctl, read, write and close. 61 + 62 + 63 + params for ioctl 64 + ---------------- 65 + 66 + There are four options: 67 + PI433_IOC_RD_TX_CFG - get the transmission parameters from the driver 68 + PI433_IOC_WR_TX_CFG - set the transmission parameters 69 + PI433_IOC_RD_RX_CFG - get the receiving parameters from the driver 70 + PI433_IOC_WR_RX_CFG - set the receiving parameters 71 + 72 + The tx configuration is transfered via struct pi433_tx_cfg, the parameterset for transmission. 73 + It is devided into two sections: rf parameters and packet format. 74 + 75 + rf params: 76 + frequency 77 + frequency used for transmission. 78 + Allowed values: 433050000...434790000 79 + bit_rate 80 + bit rate used for transmission. 81 + Allowed values: ##### 82 + dev_frequency 83 + frequency deviation in case of FSK. 84 + Allowed values: 600...500000 85 + modulation 86 + FSK - frequency shift key 87 + OOK - On-Off-key 88 + modShaping 89 + shapingOff - no shaping 90 + shaping1_0 - gauss filter with BT 1 (FSK only) 91 + shaping0_5 - gauss filter with BT 0.5 (FSK only) 92 + shaping0_3 - gauss filter with BT 0.3 (FSK only) 93 + shapingBR - filter cut off at BR (OOK only) 94 + shaping2BR - filter cut off at 2*BR (OOK only) 95 + paRamp (FSK only) 96 + ramp3400 - amp ramps up in 3.4ms 97 + ramp2000 - amp ramps up in 2.0ms 98 + ramp1000 - amp ramps up in 1ms 99 + ramp500 - amp ramps up in 500us 100 + ramp250 - amp ramps up in 250us 101 + ramp125 - amp ramps up in 125us 102 + ramp100 - amp ramps up in 100us 103 + ramp62 - amp ramps up in 62us 104 + ramp50 - amp ramps up in 50us 105 + ramp40 - amp ramps up in 40us 106 + ramp31 - amp ramps up in 31us 107 + ramp25 - amp ramps up in 25us 108 + ramp20 - amp ramps up in 20us 109 + ramp15 - amp ramps up in 15us 110 + ramp12 - amp ramps up in 12us 111 + ramp10 - amp ramps up in 10us 112 + tx_start_condition 113 + fifoLevel - transmission starts, if fifo is filled to 114 + threshold level 115 + fifoNotEmpty - transmission starts, as soon as there is one 116 + byte in internal fifo 117 + repetitions 118 + This gives the option, to send a telegram multiple times. Default: 1 119 + 120 + packet format: 121 + enable_preamble 122 + optionOn - a preamble will be automatically generated 123 + optionOff - no preamble will be generated 124 + enable_sync 125 + optionOn - a sync word will be automatically added to 126 + the telegram after preamble 127 + optionOff - no sync word will be added 128 + Attention: While possible to generate sync without preamble, the 129 + receiver won't be able to detect the sync without preamble. 130 + enable_length_byte 131 + optionOn - the length of the telegram will be automatically 132 + added to the telegram. It's part of the payload 133 + optionOff - no length information will be automatically added 134 + to the telegram. 135 + Attention: For telegram length over 255 bytes, this option can't be used 136 + Attention: should be used in combination with sync, only 137 + enable_address_byte 138 + optionOn - the address byte will be automatically added to the 139 + telgram. It's part of the payload 140 + optionOff - the address byte will not be added to the telegram. 141 + The address byte can be used for address filtering, so the receiver 142 + will only receive telegrams with a given address byte. 143 + Attention: should be used in combination with sync, only 144 + enable_crc 145 + optionOn - an crc will be automatically calculated over the 146 + payload of the telegram and added to the telegram 147 + after payload. 148 + optionOff - no crc will be calculated 149 + preamble_length 150 + length of the preamble. Allowed values: 0...65536 151 + sync_length 152 + length of the sync word. Allowed values: 0...8 153 + fixed_message_length 154 + length of the payload of the telegram. Will override the length 155 + given by the buffer, passed in with the write command. Will be 156 + ignored if set to zero. 157 + sync_pattern[8] 158 + contains up to eight values, that are used as the sync pattern 159 + on sync option 160 + address_byte 161 + one byte, used as address byte on address byte option. 162 + 163 + 164 + 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. 165 + 166 + rf params: 167 + frequency 168 + frequency used for transmission. 169 + Allowed values: 433050000...434790000 170 + bit_rate 171 + bit rate used for transmission. 172 + Allowed values: ##### 173 + dev_frequency 174 + frequency deviation in case of FSK. 175 + Allowed values: 600...500000 176 + modulation 177 + FSK - frequency shift key 178 + OOK - on off key 179 + rssi_threshold 180 + threshold value for the signal strength on the receiver input. 181 + If this value is exeeded, a reception cycle starts 182 + Allowed values: 0...255 183 + thresholdDecrement 184 + in order to adapt to different levels of singnal strength, over 185 + time the receiver gets more and more sensitive. This value 186 + determs, how fast the sensitivity increases. 187 + step_0_5db - increase in 0,5dB steps 188 + step_1_0db - increase in 1 db steps 189 + step_1_5db - increase in 1,5dB steps 190 + step_2_0db - increase in 2 db steps 191 + step_3_0db - increase in 3 db steps 192 + step_4_0db - increase in 4 db steps 193 + step_5_0db - increase in 5 db steps 194 + step_6_0db - increase in 6 db steps 195 + antennaImpedance 196 + sets the electrical adoption of the antenna 197 + fiftyOhm - for antennas with an impedance of 50Ohm 198 + twohundretOhm - for antennas with an impedance of 200Ohm 199 + lnaGain 200 + sets the gain of the low noise amp 201 + automatic - lna gain is determed by an agc 202 + max - lna gain is set to maximum 203 + maxMinus6 - lna gain is set to 6db below max 204 + maxMinus12 - lna gain is set to 12db below max 205 + maxMinus24 - lna gain is set to 24db below max 206 + maxMinus36 - lna gain is set to 36db below max 207 + maxMinus48 - lna gain is set to 48db below max 208 + bw_mantisse 209 + sets the bandwidth of the channel filter - part one: mantisse. 210 + mantisse16 - mantisse is set to 16 211 + mantisse20 - mantisse is set to 20 212 + mantisse24 - mantisse is set to 24 213 + bw_exponent 214 + sets the bandwidth of the channel filter - part two: exponent. 215 + Allowd values: 0...7 216 + dagc; 217 + operation mode of the digital automatic gain control 218 + normalMode 219 + improve 220 + improve4LowModulationIndex 221 + 222 + packet format: 223 + enable_sync 224 + optionOn - sync detection is enabled. If configured sync pattern 225 + isn't found, telegram will be internally discarded 226 + optionOff - sync detection is disabled. 227 + enable_length_byte 228 + optionOn - First byte of payload will be used as length byte, 229 + regardless of the amount of bytes that were requested 230 + by the read request. 231 + optionOff - Number of bytes to be read will be set according to 232 + amount of bytes that were requested by the read request. 233 + Attention: should be used in combination with sync, only 234 + enable_address_filtering; 235 + filteringOff - no adress filtering will take place 236 + nodeAddress - all telegrams, not matching the node 237 + address will be internally discarded 238 + nodeOrBroadcastAddress - all telegrams, neither matching the 239 + node, nor the broadcast address will 240 + be internally discarded 241 + Attention: Sync option must be enabled in order to use this feature 242 + enable_crc 243 + optionOn - a crc will be calculated over the payload of 244 + the telegram, that was received. If the 245 + calculated crc doesn't match to two bytes, 246 + that follow the payload, the telegram will be 247 + internally discarded. 248 + Attention: This option is only operational, if sync on and fixed length 249 + or length byte is used 250 + sync_length 251 + Gives the length of the payload. 252 + Attention: This setting must meet the setting of the transmitter, 253 + if sync option is used. 254 + fixed_message_length 255 + Overrides the telegram length either given by the first byte of 256 + payload or by the read request. 257 + bytes_to_drop 258 + gives the number of bytes, that will be dropped before transfering 259 + data to the read buffer 260 + This option is only usefull, if all packet helper are switched 261 + off and the rf chip is used in raw receiving mode. This may be 262 + needed, if a telegram of a third party device should be received, 263 + using a protocol not compatible with the packet engine of the rf69 chip. 264 + sync_pattern[8] 265 + contains up to eight values, that are used as the sync pattern 266 + on sync option. 267 + This setting must meet the configuration of the transmitting device, 268 + if sync option is enabled. 269 + node_address 270 + one byte, used as node address byte on address byte option. 271 + broadcast_address 272 + one byte, used as broadcast address byte on address byte option. 273 + 274 +
+16
drivers/staging/pi433/Kconfig
··· 1 + config PI433 2 + tristate "Pi433 - a 433MHz radio module for Raspberry Pi" 3 + default n 4 + ---help--- 5 + This option allows you to enable support for the radio module Pi433. 6 + 7 + Pi433 is a shield that fits onto the GPIO header of a Raspberry Pi 8 + or compatible. It extends the Raspberry Pi with the option, to 9 + send and receive data in the 433MHz ISM band - for example to 10 + communicate between two systems without using ethernet or bluetooth 11 + or for control or read sockets, actors, sensors, widely available 12 + for low price. 13 + 14 + For details or the option to buy, please visit https://pi433.de/en.html 15 + 16 + If in doubt, say N here, but saying yes most probably won't hurt
+3
drivers/staging/pi433/Makefile
··· 1 + obj-$(CONFIG_PI433) += pi433.o 2 + 3 + pi433-objs := pi433_if.o rf69.o
+5
drivers/staging/pi433/TODO
··· 1 + * coding style does not fully comply with the kernel style guide. 2 + * still TODOs, annotated in the code 3 + * currently the code introduces new IOCTLs. I'm afraid this is a bad idea. 4 + -> Replace this with another interface, hints are welcome! 5 + * Some missing data (marked with ###) needs to be added in the documentation
+1314
drivers/staging/pi433/pi433_if.c
··· 1 + /* 2 + * userspace interface for pi433 radio module 3 + * 4 + * Pi433 is a 433MHz radio module for the Raspberry Pi. 5 + * It is based on the HopeRf Module RFM69CW. Therefore inside of this 6 + * driver, you'll find an abstraction of the rf69 chip. 7 + * 8 + * If needed, this driver could be extended, to also support other 9 + * devices, basing on HopeRfs rf69. 10 + * 11 + * The driver can also be extended, to support other modules of 12 + * HopeRf with a similar interace - e. g. RFM69HCW, RFM12, RFM95, ... 13 + * 14 + * Copyright (C) 2016 Wolf-Entwicklungen 15 + * Marcus Wolf <linux@wolf-entwicklungen.de> 16 + * 17 + * This program is free software; you can redistribute it and/or modify 18 + * it under the terms of the GNU General Public License as published by 19 + * the Free Software Foundation; either version 2 of the License, or 20 + * (at your option) any later version. 21 + * 22 + * This program is distributed in the hope that it will be useful, 23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 + * GNU General Public License for more details. 26 + */ 27 + 28 + #undef DEBUG 29 + 30 + #include <linux/init.h> 31 + #include <linux/module.h> 32 + #include <linux/idr.h> 33 + #include <linux/ioctl.h> 34 + #include <linux/uaccess.h> 35 + #include <linux/fs.h> 36 + #include <linux/device.h> 37 + #include <linux/cdev.h> 38 + #include <linux/err.h> 39 + #include <linux/kfifo.h> 40 + #include <linux/errno.h> 41 + #include <linux/mutex.h> 42 + #include <linux/of.h> 43 + #include <linux/of_device.h> 44 + #include <linux/interrupt.h> 45 + #include <linux/irq.h> 46 + #include <linux/gpio/consumer.h> 47 + #include <linux/kthread.h> 48 + #include <linux/wait.h> 49 + #include <linux/spi/spi.h> 50 + #ifdef CONFIG_COMPAT 51 + #include <asm/compat.h> 52 + #endif 53 + 54 + #include "pi433_if.h" 55 + #include "rf69.h" 56 + 57 + 58 + #define N_PI433_MINORS (1U << MINORBITS) /*32*/ /* ... up to 256 */ 59 + #define MAX_MSG_SIZE 900 /* min: FIFO_SIZE! */ 60 + #define MSG_FIFO_SIZE 65536 /* 65536 = 2^16 */ 61 + #define NUM_DIO 2 62 + 63 + static dev_t pi433_dev; 64 + static DEFINE_IDR(pi433_idr); 65 + static DEFINE_MUTEX(minor_lock); /* Protect idr accesses */ 66 + 67 + static struct class *pi433_class; /* mainly for udev to create /dev/pi433 */ 68 + 69 + /* tx config is instance specific 70 + so with each open a new tx config struct is needed */ 71 + /* rx config is device specific 72 + so we have just one rx config, ebedded in device struct */ 73 + struct pi433_device { 74 + /* device handling related values */ 75 + dev_t devt; 76 + int minor; 77 + struct device *dev; 78 + struct cdev *cdev; 79 + struct spi_device *spi; 80 + unsigned users; 81 + 82 + /* irq related values */ 83 + struct gpio_desc *gpiod[NUM_DIO]; 84 + int irq_num[NUM_DIO]; 85 + u8 irq_state[NUM_DIO]; 86 + 87 + /* tx related values */ 88 + STRUCT_KFIFO_REC_1(MSG_FIFO_SIZE) tx_fifo; 89 + struct mutex tx_fifo_lock; // TODO: check, whether necessary or obsolete 90 + struct task_struct *tx_task_struct; 91 + wait_queue_head_t tx_wait_queue; 92 + u8 free_in_fifo; 93 + 94 + /* rx related values */ 95 + struct pi433_rx_cfg rx_cfg; 96 + u8 *rx_buffer; 97 + unsigned int rx_buffer_size; 98 + u32 rx_bytes_to_drop; 99 + u32 rx_bytes_dropped; 100 + unsigned int rx_position; 101 + struct mutex rx_lock; 102 + wait_queue_head_t rx_wait_queue; 103 + 104 + /* fifo wait queue */ 105 + struct task_struct *fifo_task_struct; 106 + wait_queue_head_t fifo_wait_queue; 107 + 108 + /* flags */ 109 + bool rx_active; 110 + bool tx_active; 111 + bool interrupt_rx_allowed; 112 + }; 113 + 114 + struct pi433_instance { 115 + struct pi433_device *device; 116 + struct pi433_tx_cfg tx_cfg; 117 + }; 118 + 119 + /*-------------------------------------------------------------------------*/ 120 + 121 + /* macro for checked access of registers of radio module */ 122 + #define SET_CHECKED(retval) \ 123 + if (retval < 0) \ 124 + return retval; 125 + 126 + /*-------------------------------------------------------------------------*/ 127 + 128 + /* GPIO interrupt handlers */ 129 + static irq_handler_t 130 + DIO0_irq_handler(unsigned int irq, void *dev_id, struct pt_regs *regs) 131 + { 132 + struct pi433_device *device = dev_id; 133 + 134 + if (device->irq_state[DIO0] == DIO_PacketSent) 135 + { 136 + device->free_in_fifo = FIFO_SIZE; 137 + printk("DIO0 irq: Packet sent\n"); // TODO: printk() should include KERN_ facility level 138 + wake_up_interruptible(&device->fifo_wait_queue); 139 + } 140 + else if (device->irq_state[DIO0] == DIO_Rssi_DIO0) 141 + { 142 + printk("DIO0 irq: RSSI level over threshold\n"); 143 + wake_up_interruptible(&device->rx_wait_queue); 144 + } 145 + else if (device->irq_state[DIO0] == DIO_PayloadReady) 146 + { 147 + printk("DIO0 irq: PayloadReady\n"); 148 + device->free_in_fifo = 0; 149 + wake_up_interruptible(&device->fifo_wait_queue); 150 + } 151 + 152 + return (irq_handler_t) IRQ_HANDLED; 153 + } 154 + 155 + static irq_handler_t 156 + DIO1_irq_handler(unsigned int irq, void *dev_id, struct pt_regs *regs) 157 + { 158 + struct pi433_device *device = dev_id; 159 + 160 + if (device->irq_state[DIO1] == DIO_FifoNotEmpty_DIO1) 161 + { 162 + device->free_in_fifo = FIFO_SIZE; 163 + } 164 + else if (device->irq_state[DIO1] == DIO_FifoLevel) 165 + { 166 + if (device->rx_active) device->free_in_fifo = FIFO_THRESHOLD - 1; 167 + else device->free_in_fifo = FIFO_SIZE - FIFO_THRESHOLD - 1; 168 + } 169 + printk("DIO1 irq: %d bytes free in fifo\n", device->free_in_fifo); // TODO: printk() should include KERN_ facility level 170 + wake_up_interruptible(&device->fifo_wait_queue); 171 + 172 + return (irq_handler_t) IRQ_HANDLED; 173 + } 174 + 175 + static void *DIO_irq_handler[NUM_DIO] = { 176 + DIO0_irq_handler, 177 + DIO1_irq_handler 178 + }; 179 + 180 + /*-------------------------------------------------------------------------*/ 181 + 182 + static int 183 + rf69_set_rx_cfg(struct pi433_device *dev, struct pi433_rx_cfg *rx_cfg) 184 + { 185 + int payload_length; 186 + 187 + /* receiver config */ 188 + SET_CHECKED(rf69_set_frequency (dev->spi, rx_cfg->frequency)); 189 + SET_CHECKED(rf69_set_bit_rate (dev->spi, rx_cfg->bit_rate)); 190 + SET_CHECKED(rf69_set_modulation (dev->spi, rx_cfg->modulation)); 191 + SET_CHECKED(rf69_set_antenna_impedance (dev->spi, rx_cfg->antenna_impedance)); 192 + SET_CHECKED(rf69_set_rssi_threshold (dev->spi, rx_cfg->rssi_threshold)); 193 + SET_CHECKED(rf69_set_ook_threshold_dec (dev->spi, rx_cfg->thresholdDecrement)); 194 + SET_CHECKED(rf69_set_bandwidth (dev->spi, rx_cfg->bw_mantisse, rx_cfg->bw_exponent)); 195 + SET_CHECKED(rf69_set_bandwidth_during_afc(dev->spi, rx_cfg->bw_mantisse, rx_cfg->bw_exponent)); 196 + SET_CHECKED(rf69_set_dagc (dev->spi, rx_cfg->dagc)); 197 + 198 + dev->rx_bytes_to_drop = rx_cfg->bytes_to_drop; 199 + 200 + /* packet config */ 201 + /* enable */ 202 + SET_CHECKED(rf69_set_sync_enable(dev->spi, rx_cfg->enable_sync)); 203 + if (rx_cfg->enable_sync == optionOn) 204 + { 205 + SET_CHECKED(rf69_set_fifo_fill_condition(dev->spi, afterSyncInterrupt)); 206 + } 207 + else 208 + { 209 + SET_CHECKED(rf69_set_fifo_fill_condition(dev->spi, always)); 210 + } 211 + SET_CHECKED(rf69_set_packet_format (dev->spi, rx_cfg->enable_length_byte)); 212 + SET_CHECKED(rf69_set_adressFiltering(dev->spi, rx_cfg->enable_address_filtering)); 213 + SET_CHECKED(rf69_set_crc_enable (dev->spi, rx_cfg->enable_crc)); 214 + 215 + /* lengths */ 216 + SET_CHECKED(rf69_set_sync_size(dev->spi, rx_cfg->sync_length)); 217 + if (rx_cfg->enable_length_byte == optionOn) 218 + { 219 + SET_CHECKED(rf69_set_payload_length(dev->spi, 0xff)); 220 + } 221 + else if (rx_cfg->fixed_message_length != 0) 222 + { 223 + payload_length = rx_cfg->fixed_message_length; 224 + if (rx_cfg->enable_length_byte == optionOn) payload_length++; 225 + if (rx_cfg->enable_address_filtering != filteringOff) payload_length++; 226 + SET_CHECKED(rf69_set_payload_length(dev->spi, payload_length)); 227 + } 228 + else 229 + { 230 + SET_CHECKED(rf69_set_payload_length(dev->spi, 0)); 231 + } 232 + 233 + /* values */ 234 + if (rx_cfg->enable_sync == optionOn) 235 + { 236 + SET_CHECKED(rf69_set_sync_values(dev->spi, rx_cfg->sync_pattern)); 237 + } 238 + if (rx_cfg->enable_address_filtering != filteringOff) 239 + { 240 + SET_CHECKED(rf69_set_node_address (dev->spi, rx_cfg->node_address)); 241 + SET_CHECKED(rf69_set_broadcast_address(dev->spi, rx_cfg->broadcast_address)); 242 + } 243 + 244 + return 0; 245 + } 246 + 247 + static int 248 + rf69_set_tx_cfg(struct pi433_device *dev, struct pi433_tx_cfg *tx_cfg) 249 + { 250 + SET_CHECKED(rf69_set_frequency (dev->spi, tx_cfg->frequency)); 251 + SET_CHECKED(rf69_set_bit_rate (dev->spi, tx_cfg->bit_rate)); 252 + SET_CHECKED(rf69_set_modulation (dev->spi, tx_cfg->modulation)); 253 + SET_CHECKED(rf69_set_deviation (dev->spi, tx_cfg->dev_frequency)); 254 + SET_CHECKED(rf69_set_pa_ramp (dev->spi, tx_cfg->pa_ramp)); 255 + SET_CHECKED(rf69_set_modulation_shaping(dev->spi, tx_cfg->modShaping)); 256 + SET_CHECKED(rf69_set_tx_start_condition(dev->spi, tx_cfg->tx_start_condition)); 257 + 258 + /* packet format enable */ 259 + if (tx_cfg->enable_preamble == optionOn) 260 + { 261 + SET_CHECKED(rf69_set_preamble_length(dev->spi, tx_cfg->preamble_length)); 262 + } 263 + else 264 + { 265 + SET_CHECKED(rf69_set_preamble_length(dev->spi, 0)); 266 + } 267 + SET_CHECKED(rf69_set_sync_enable (dev->spi, tx_cfg->enable_sync)); 268 + SET_CHECKED(rf69_set_packet_format(dev->spi, tx_cfg->enable_length_byte)); 269 + SET_CHECKED(rf69_set_crc_enable (dev->spi, tx_cfg->enable_crc)); 270 + 271 + /* configure sync, if enabled */ 272 + if (tx_cfg->enable_sync == optionOn) 273 + { 274 + SET_CHECKED(rf69_set_sync_size(dev->spi, tx_cfg->sync_length)); 275 + SET_CHECKED(rf69_set_sync_values(dev->spi, tx_cfg->sync_pattern)); 276 + } 277 + 278 + return 0; 279 + } 280 + 281 + /*-------------------------------------------------------------------------*/ 282 + 283 + static int 284 + pi433_start_rx(struct pi433_device *dev) 285 + { 286 + int retval; 287 + 288 + /* return without action, if no pending read request */ 289 + if (!dev->rx_active) 290 + return 0; 291 + 292 + /* setup for receiving */ 293 + retval = rf69_set_rx_cfg(dev, &dev->rx_cfg); 294 + if (retval) return retval; 295 + 296 + /* setup rssi irq */ 297 + SET_CHECKED(rf69_set_dio_mapping(dev->spi, DIO0, DIO_Rssi_DIO0)); 298 + dev->irq_state[DIO0] = DIO_Rssi_DIO0; 299 + irq_set_irq_type(dev->irq_num[DIO0], IRQ_TYPE_EDGE_RISING); 300 + 301 + /* setup fifo level interrupt */ 302 + SET_CHECKED(rf69_set_fifo_threshold(dev->spi, FIFO_SIZE - FIFO_THRESHOLD)); 303 + SET_CHECKED(rf69_set_dio_mapping(dev->spi, DIO1, DIO_FifoLevel)); 304 + dev->irq_state[DIO1] = DIO_FifoLevel; 305 + irq_set_irq_type(dev->irq_num[DIO1], IRQ_TYPE_EDGE_RISING); 306 + 307 + /* set module to receiving mode */ 308 + SET_CHECKED(rf69_set_mode(dev->spi, receive)); 309 + 310 + return 0; 311 + } 312 + 313 + 314 + /*-------------------------------------------------------------------------*/ 315 + 316 + int 317 + pi433_receive(void *data) 318 + { 319 + struct pi433_device *dev = data; 320 + struct spi_device *spi = dev->spi; /* needed for SET_CHECKED */ 321 + int bytes_to_read, bytes_total; 322 + int retval; 323 + 324 + dev->interrupt_rx_allowed = false; 325 + 326 + /* wait for any tx to finish */ 327 + dev_dbg(dev->dev,"rx: going to wait for any tx to finish"); 328 + retval = wait_event_interruptible(dev->rx_wait_queue, !dev->tx_active); 329 + if(retval) /* wait was interrupted */ 330 + { 331 + dev->interrupt_rx_allowed = true; 332 + wake_up_interruptible(&dev->tx_wait_queue); 333 + return retval; 334 + } 335 + 336 + /* prepare status vars */ 337 + dev->free_in_fifo = FIFO_SIZE; 338 + dev->rx_position = 0; 339 + dev->rx_bytes_dropped = 0; 340 + 341 + /* setup radio module to listen for something "in the air" */ 342 + retval = pi433_start_rx(dev); 343 + if (retval) 344 + return retval; 345 + 346 + /* now check RSSI, if low wait for getting high (RSSI interrupt) */ 347 + while ( !rf69_get_flag(dev->spi, rssiExceededThreshold) ) 348 + { 349 + /* allow tx to interrupt us while waiting for high RSSI */ 350 + dev->interrupt_rx_allowed = true; 351 + wake_up_interruptible(&dev->tx_wait_queue); 352 + 353 + /* wait for RSSI level to become high */ 354 + dev_dbg(dev->dev, "rx: going to wait for high RSSI level"); 355 + retval = wait_event_interruptible(dev->rx_wait_queue, 356 + rf69_get_flag(dev->spi, 357 + rssiExceededThreshold)); 358 + if (retval) goto abort; /* wait was interrupted */ 359 + dev->interrupt_rx_allowed = false; 360 + 361 + /* cross check for ongoing tx */ 362 + if (!dev->tx_active) break; 363 + } 364 + 365 + /* configure payload ready irq */ 366 + SET_CHECKED(rf69_set_dio_mapping(spi, DIO0, DIO_PayloadReady)); 367 + dev->irq_state[DIO0] = DIO_PayloadReady; 368 + irq_set_irq_type(dev->irq_num[DIO0], IRQ_TYPE_EDGE_RISING); 369 + 370 + /* fixed or unlimited length? */ 371 + if (dev->rx_cfg.fixed_message_length != 0) 372 + { 373 + if (dev->rx_cfg.fixed_message_length > dev->rx_buffer_size) 374 + { 375 + retval = -1; 376 + goto abort; 377 + } 378 + bytes_total = dev->rx_cfg.fixed_message_length; 379 + dev_dbg(dev->dev,"rx: msg len set to %d by fixed length", bytes_total); 380 + } 381 + else 382 + { 383 + bytes_total = dev->rx_buffer_size; 384 + dev_dbg(dev->dev, "rx: msg len set to %d as requested by read", bytes_total); 385 + } 386 + 387 + /* length byte enabled? */ 388 + if (dev->rx_cfg.enable_length_byte == optionOn) 389 + { 390 + retval = wait_event_interruptible(dev->fifo_wait_queue, 391 + dev->free_in_fifo < FIFO_SIZE); 392 + if (retval) goto abort; /* wait was interrupted */ 393 + 394 + rf69_read_fifo(spi, (u8 *)&bytes_total, 1); 395 + if (bytes_total > dev->rx_buffer_size) 396 + { 397 + retval = -1; 398 + goto abort; 399 + } 400 + dev->free_in_fifo++; 401 + dev_dbg(dev->dev, "rx: msg len reset to %d due to length byte", bytes_total); 402 + } 403 + 404 + /* address byte enabled? */ 405 + if (dev->rx_cfg.enable_address_filtering != filteringOff) 406 + { 407 + u8 dummy; 408 + 409 + bytes_total--; 410 + 411 + retval = wait_event_interruptible(dev->fifo_wait_queue, 412 + dev->free_in_fifo < FIFO_SIZE); 413 + if (retval) goto abort; /* wait was interrupted */ 414 + 415 + rf69_read_fifo(spi, &dummy, 1); 416 + dev->free_in_fifo++; 417 + dev_dbg(dev->dev, "rx: address byte stripped off"); 418 + } 419 + 420 + /* get payload */ 421 + while (dev->rx_position < bytes_total) 422 + { 423 + if ( !rf69_get_flag(dev->spi, payloadReady) ) 424 + { 425 + retval = wait_event_interruptible(dev->fifo_wait_queue, 426 + dev->free_in_fifo < FIFO_SIZE); 427 + if (retval) goto abort; /* wait was interrupted */ 428 + } 429 + 430 + /* need to drop bytes or acquire? */ 431 + if (dev->rx_bytes_to_drop > dev->rx_bytes_dropped) 432 + bytes_to_read = dev->rx_bytes_to_drop - dev->rx_bytes_dropped; 433 + else 434 + bytes_to_read = bytes_total - dev->rx_position; 435 + 436 + 437 + /* access the fifo */ 438 + if (bytes_to_read > FIFO_SIZE - dev->free_in_fifo) 439 + bytes_to_read = FIFO_SIZE - dev->free_in_fifo; 440 + retval = rf69_read_fifo(spi, 441 + &dev->rx_buffer[dev->rx_position], 442 + bytes_to_read); 443 + if (retval) goto abort; /* read failed */ 444 + dev->free_in_fifo += bytes_to_read; 445 + 446 + /* adjust status vars */ 447 + if (dev->rx_bytes_to_drop > dev->rx_bytes_dropped) 448 + dev->rx_bytes_dropped += bytes_to_read; 449 + else 450 + dev->rx_position += bytes_to_read; 451 + } 452 + 453 + 454 + /* rx done, wait was interrupted or error occured */ 455 + abort: 456 + dev->interrupt_rx_allowed = true; 457 + SET_CHECKED(rf69_set_mode(dev->spi, standby)); 458 + wake_up_interruptible(&dev->tx_wait_queue); 459 + 460 + if (retval) 461 + return retval; 462 + else 463 + return bytes_total; 464 + } 465 + 466 + int 467 + pi433_tx_thread(void *data) 468 + { 469 + struct pi433_device *device = data; 470 + struct spi_device *spi = device->spi; /* needed for SET_CHECKED */ 471 + struct pi433_tx_cfg tx_cfg; 472 + u8 buffer[MAX_MSG_SIZE]; 473 + size_t size; 474 + bool rx_interrupted = false; 475 + int position, repetitions; 476 + int retval; 477 + 478 + while (1) 479 + { 480 + /* wait for fifo to be populated or for request to terminate*/ 481 + dev_dbg(device->dev, "thread: going to wait for new messages"); 482 + wait_event_interruptible(device->tx_wait_queue, 483 + ( !kfifo_is_empty(&device->tx_fifo) || 484 + kthread_should_stop() )); 485 + if ( kthread_should_stop() ) 486 + return 0; 487 + 488 + /* get data from fifo in the following order: 489 + - tx_cfg 490 + - size of message 491 + - message */ 492 + mutex_lock(&device->tx_fifo_lock); 493 + 494 + retval = kfifo_out(&device->tx_fifo, &tx_cfg, sizeof(tx_cfg)); 495 + if (retval != sizeof(tx_cfg)) 496 + { 497 + dev_dbg(device->dev, "reading tx_cfg from fifo failed: got %d byte(s), expected %d", retval, (unsigned int)sizeof(tx_cfg) ); 498 + mutex_unlock(&device->tx_fifo_lock); 499 + continue; 500 + } 501 + 502 + retval = kfifo_out(&device->tx_fifo, &size, sizeof(size_t)); 503 + if (retval != sizeof(size_t)) 504 + { 505 + dev_dbg(device->dev, "reading msg size from fifo failed: got %d, expected %d", retval, (unsigned int)sizeof(size_t) ); 506 + mutex_unlock(&device->tx_fifo_lock); 507 + continue; 508 + } 509 + 510 + /* use fixed message length, if requested */ 511 + if (tx_cfg.fixed_message_length != 0) 512 + size = tx_cfg.fixed_message_length; 513 + 514 + /* increase size, if len byte is requested */ 515 + if (tx_cfg.enable_length_byte == optionOn) 516 + size++; 517 + 518 + /* increase size, if adr byte is requested */ 519 + if (tx_cfg.enable_address_byte == optionOn) 520 + size++; 521 + 522 + /* prime buffer */ 523 + memset(buffer, 0, size); 524 + position = 0; 525 + 526 + /* add length byte, if requested */ 527 + if (tx_cfg.enable_length_byte == optionOn) 528 + buffer[position++] = size-1; /* according to spec length byte itself must be excluded from the length calculation */ 529 + 530 + /* add adr byte, if requested */ 531 + if (tx_cfg.enable_address_byte == optionOn) 532 + buffer[position++] = tx_cfg.address_byte; 533 + 534 + /* finally get message data from fifo */ 535 + retval = kfifo_out(&device->tx_fifo, &buffer[position], sizeof(buffer)-position ); 536 + dev_dbg(device->dev, "read %d message byte(s) from fifo queue.", retval); 537 + mutex_unlock(&device->tx_fifo_lock); 538 + 539 + /* if rx is active, we need to interrupt the waiting for 540 + incoming telegrams, to be able to send something. 541 + We are only allowed, if currently no reception takes 542 + place otherwise we need to wait for the incoming telegram 543 + to finish */ 544 + wait_event_interruptible(device->tx_wait_queue, 545 + !device->rx_active || 546 + device->interrupt_rx_allowed == true); 547 + 548 + /* prevent race conditions 549 + irq will be reenabled after tx config is set */ 550 + disable_irq(device->irq_num[DIO0]); 551 + device->tx_active = true; 552 + 553 + if (device->rx_active && rx_interrupted == false) 554 + { 555 + /* rx is currently waiting for a telegram; 556 + we need to set the radio module to standby */ 557 + SET_CHECKED(rf69_set_mode(device->spi, standby)); 558 + rx_interrupted = true; 559 + } 560 + 561 + /* clear fifo, set fifo threshold, set payload length */ 562 + SET_CHECKED(rf69_set_mode(spi, standby)); /* this clears the fifo */ 563 + SET_CHECKED(rf69_set_fifo_threshold(spi, FIFO_THRESHOLD)); 564 + if (tx_cfg.enable_length_byte == optionOn) 565 + { 566 + SET_CHECKED(rf69_set_payload_length(spi, size * tx_cfg.repetitions)); 567 + } 568 + else 569 + { 570 + SET_CHECKED(rf69_set_payload_length(spi, 0)); 571 + } 572 + 573 + /* configure the rf chip */ 574 + rf69_set_tx_cfg(device, &tx_cfg); 575 + 576 + /* enable fifo level interrupt */ 577 + SET_CHECKED(rf69_set_dio_mapping(spi, DIO1, DIO_FifoLevel)); 578 + device->irq_state[DIO1] = DIO_FifoLevel; 579 + irq_set_irq_type(device->irq_num[DIO1], IRQ_TYPE_EDGE_FALLING); 580 + 581 + /* enable packet sent interrupt */ 582 + SET_CHECKED(rf69_set_dio_mapping(spi, DIO0, DIO_PacketSent)); 583 + device->irq_state[DIO0] = DIO_PacketSent; 584 + irq_set_irq_type(device->irq_num[DIO0], IRQ_TYPE_EDGE_RISING); 585 + enable_irq(device->irq_num[DIO0]); /* was disabled by rx active check */ 586 + 587 + /* enable transmission */ 588 + SET_CHECKED(rf69_set_mode(spi, transmit)); 589 + 590 + /* transfer this msg (and repetitions) to chip fifo */ 591 + device->free_in_fifo = FIFO_SIZE; 592 + position = 0; 593 + repetitions = tx_cfg.repetitions; 594 + while( (repetitions > 0) && (size > position) ) 595 + { 596 + if ( (size - position) > device->free_in_fifo) 597 + { /* msg to big for fifo - take a part */ 598 + int temp = device->free_in_fifo; 599 + device->free_in_fifo = 0; 600 + rf69_write_fifo(spi, 601 + &buffer[position], 602 + temp); 603 + position +=temp; 604 + } 605 + else 606 + { /* msg fits into fifo - take all */ 607 + device->free_in_fifo -= size; 608 + repetitions--; 609 + rf69_write_fifo(spi, 610 + &buffer[position], 611 + (size - position) ); 612 + position = 0; /* reset for next repetition */ 613 + } 614 + 615 + retval = wait_event_interruptible(device->fifo_wait_queue, 616 + device->free_in_fifo > 0); 617 + if (retval) { printk("ABORT\n"); goto abort; } 618 + } 619 + 620 + /* we are done. Wait for packet to get sent */ 621 + dev_dbg(device->dev, "thread: wiat for packet to get sent/fifo to be empty"); 622 + wait_event_interruptible(device->fifo_wait_queue, 623 + device->free_in_fifo == FIFO_SIZE || 624 + kthread_should_stop() ); 625 + if ( kthread_should_stop() ) printk("ABORT\n"); 626 + 627 + 628 + /* STOP_TRANSMISSION */ 629 + dev_dbg(device->dev, "thread: Packet sent. Set mode to stby."); 630 + SET_CHECKED(rf69_set_mode(spi, standby)); 631 + 632 + /* everything sent? */ 633 + if ( kfifo_is_empty(&device->tx_fifo) ) 634 + { 635 + abort: 636 + if (rx_interrupted) 637 + { 638 + rx_interrupted = false; 639 + pi433_start_rx(device); 640 + } 641 + device->tx_active = false; 642 + wake_up_interruptible(&device->rx_wait_queue); 643 + } 644 + } 645 + } 646 + 647 + /*-------------------------------------------------------------------------*/ 648 + 649 + static ssize_t 650 + pi433_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos) 651 + { 652 + struct pi433_instance *instance; 653 + struct pi433_device *device; 654 + int bytes_received; 655 + ssize_t retval; 656 + 657 + /* check, whether internal buffer is big enough for requested size */ 658 + if (size > MAX_MSG_SIZE) 659 + return -EMSGSIZE; 660 + 661 + instance = filp->private_data; 662 + device = instance->device; 663 + 664 + /* just one read request at a time */ 665 + mutex_lock(&device->rx_lock); 666 + if (device->rx_active) 667 + { 668 + mutex_unlock(&device->rx_lock); 669 + return -EAGAIN; 670 + } 671 + else 672 + { 673 + device->rx_active = true; 674 + mutex_unlock(&device->rx_lock); 675 + } 676 + 677 + /* start receiving */ 678 + /* will block until something was received*/ 679 + device->rx_buffer_size = size; 680 + bytes_received = pi433_receive(device); 681 + 682 + /* release rx */ 683 + mutex_lock(&device->rx_lock); 684 + device->rx_active = false; 685 + mutex_unlock(&device->rx_lock); 686 + 687 + /* if read was successful copy to user space*/ 688 + if (bytes_received > 0) 689 + { 690 + retval = copy_to_user(buf, device->rx_buffer, bytes_received); 691 + if (retval) 692 + return retval; 693 + } 694 + 695 + return bytes_received; 696 + } 697 + 698 + 699 + static ssize_t 700 + pi433_write(struct file *filp, const char __user *buf, 701 + size_t count, loff_t *f_pos) 702 + { 703 + struct pi433_instance *instance; 704 + struct pi433_device *device; 705 + int copied, retval; 706 + 707 + instance = filp->private_data; 708 + device = instance->device; 709 + 710 + /* check, whether internal buffer (tx thread) is big enough for requested size */ 711 + if (count > MAX_MSG_SIZE) 712 + return -EMSGSIZE; 713 + 714 + /* write the following sequence into fifo: 715 + - tx_cfg 716 + - size of message 717 + - message */ 718 + mutex_lock(&device->tx_fifo_lock); 719 + retval = kfifo_in(&device->tx_fifo, &instance->tx_cfg, sizeof(instance->tx_cfg)); 720 + if ( retval != sizeof(instance->tx_cfg) ) 721 + goto abort; 722 + 723 + retval = kfifo_in (&device->tx_fifo, &count, sizeof(size_t)); 724 + if ( retval != sizeof(size_t) ) 725 + goto abort; 726 + 727 + retval = kfifo_from_user(&device->tx_fifo, buf, count, &copied); 728 + if (retval || copied != count) 729 + goto abort; 730 + 731 + mutex_unlock(&device->tx_fifo_lock); 732 + 733 + /* start transfer */ 734 + wake_up_interruptible(&device->tx_wait_queue); 735 + dev_dbg(device->dev, "write: generated new msg with %d bytes.", copied); 736 + 737 + return 0; 738 + 739 + abort: 740 + dev_dbg(device->dev, "write to fifo failed: 0x%x", retval); 741 + kfifo_reset(&device->tx_fifo); // TODO: maybe find a solution, not to discard already stored, valid entries 742 + mutex_unlock(&device->tx_fifo_lock); 743 + return -EAGAIN; 744 + } 745 + 746 + 747 + static long 748 + pi433_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 749 + { 750 + int err = 0; 751 + int retval = 0; 752 + struct pi433_instance *instance; 753 + struct pi433_device *device; 754 + u32 tmp; 755 + 756 + /* Check type and command number */ 757 + if (_IOC_TYPE(cmd) != PI433_IOC_MAGIC) 758 + return -ENOTTY; 759 + 760 + /* Check access direction once here; don't repeat below. 761 + * IOC_DIR is from the user perspective, while access_ok is 762 + * from the kernel perspective; so they look reversed. 763 + */ 764 + if (_IOC_DIR(cmd) & _IOC_READ) 765 + err = !access_ok(VERIFY_WRITE, 766 + (void __user *)arg, 767 + _IOC_SIZE(cmd)); 768 + 769 + if (err == 0 && _IOC_DIR(cmd) & _IOC_WRITE) 770 + err = !access_ok(VERIFY_READ, 771 + (void __user *)arg, 772 + _IOC_SIZE(cmd)); 773 + if (err) 774 + return -EFAULT; 775 + 776 + /* TODO? guard against device removal before, or while, 777 + * we issue this ioctl. --> device_get() 778 + */ 779 + instance = filp->private_data; 780 + device = instance->device; 781 + 782 + if (device == NULL) 783 + return -ESHUTDOWN; 784 + 785 + switch (cmd) { 786 + case PI433_IOC_RD_TX_CFG: 787 + tmp = _IOC_SIZE(cmd); 788 + if ( (tmp == 0) || ((tmp % sizeof(struct pi433_tx_cfg)) != 0) ) 789 + { 790 + retval = -EINVAL; 791 + break; 792 + } 793 + 794 + if (__copy_to_user((void __user *)arg, 795 + &instance->tx_cfg, 796 + tmp)) 797 + { 798 + retval = -EFAULT; 799 + break; 800 + } 801 + 802 + break; 803 + case PI433_IOC_WR_TX_CFG: 804 + tmp = _IOC_SIZE(cmd); 805 + if ( (tmp == 0) || ((tmp % sizeof(struct pi433_tx_cfg)) != 0) ) 806 + { 807 + retval = -EINVAL; 808 + break; 809 + } 810 + 811 + if (__copy_from_user(&instance->tx_cfg, 812 + (void __user *)arg, 813 + tmp)) 814 + { 815 + retval = -EFAULT; 816 + break; 817 + } 818 + 819 + break; 820 + 821 + case PI433_IOC_RD_RX_CFG: 822 + tmp = _IOC_SIZE(cmd); 823 + if ( (tmp == 0) || ((tmp % sizeof(struct pi433_rx_cfg)) != 0) ) { 824 + retval = -EINVAL; 825 + break; 826 + } 827 + 828 + if (__copy_to_user((void __user *)arg, 829 + &device->rx_cfg, 830 + tmp)) 831 + { 832 + retval = -EFAULT; 833 + break; 834 + } 835 + 836 + break; 837 + case PI433_IOC_WR_RX_CFG: 838 + tmp = _IOC_SIZE(cmd); 839 + mutex_lock(&device->rx_lock); 840 + 841 + /* during pendig read request, change of config not allowed */ 842 + if (device->rx_active) { 843 + retval = -EAGAIN; 844 + mutex_unlock(&device->rx_lock); 845 + break; 846 + } 847 + 848 + if ( (tmp == 0) || ((tmp % sizeof(struct pi433_rx_cfg)) != 0) ) { 849 + retval = -EINVAL; 850 + mutex_unlock(&device->rx_lock); 851 + break; 852 + } 853 + 854 + if (__copy_from_user(&device->rx_cfg, 855 + (void __user *)arg, 856 + tmp)) 857 + { 858 + retval = -EFAULT; 859 + mutex_unlock(&device->rx_lock); 860 + break; 861 + } 862 + 863 + mutex_unlock(&device->rx_lock); 864 + break; 865 + default: 866 + retval = -EINVAL; 867 + } 868 + 869 + return retval; 870 + } 871 + 872 + #ifdef CONFIG_COMPAT 873 + static long 874 + pi433_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 875 + { 876 + return pi433_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); 877 + } 878 + #else 879 + #define pi433_compat_ioctl NULL 880 + #endif /* CONFIG_COMPAT */ 881 + 882 + /*-------------------------------------------------------------------------*/ 883 + 884 + static int pi433_open(struct inode *inode, struct file *filp) 885 + { 886 + struct pi433_device *device; 887 + struct pi433_instance *instance; 888 + 889 + mutex_lock(&minor_lock); 890 + device = idr_find(&pi433_idr, iminor(inode)); 891 + mutex_unlock(&minor_lock); 892 + if (!device) { 893 + pr_debug("device: minor %d unknown.\n", iminor(inode)); 894 + return -ENODEV; 895 + } 896 + 897 + if (!device->rx_buffer) { 898 + device->rx_buffer = kmalloc(MAX_MSG_SIZE, GFP_KERNEL); 899 + if (!device->rx_buffer) 900 + { 901 + dev_dbg(device->dev, "open/ENOMEM\n"); 902 + return -ENOMEM; 903 + } 904 + } 905 + 906 + device->users++; 907 + instance = kzalloc(sizeof(*instance), GFP_KERNEL); 908 + if (!instance) 909 + { 910 + kfree(device->rx_buffer); 911 + device->rx_buffer = NULL; 912 + return -ENOMEM; 913 + } 914 + 915 + /* setup instance data*/ 916 + instance->device = device; 917 + instance->tx_cfg.bit_rate = 4711; 918 + // TODO: fill instance->tx_cfg; 919 + 920 + /* instance data as context */ 921 + filp->private_data = instance; 922 + nonseekable_open(inode, filp); 923 + 924 + return 0; 925 + } 926 + 927 + static int pi433_release(struct inode *inode, struct file *filp) 928 + { 929 + struct pi433_instance *instance; 930 + struct pi433_device *device; 931 + 932 + instance = filp->private_data; 933 + device = instance->device; 934 + kfree(instance); 935 + filp->private_data = NULL; 936 + 937 + /* last close? */ 938 + device->users--; 939 + 940 + if (!device->users) { 941 + kfree(device->rx_buffer); 942 + device->rx_buffer = NULL; 943 + if (device->spi == NULL) 944 + kfree(device); 945 + } 946 + 947 + return 0; 948 + } 949 + 950 + 951 + /*-------------------------------------------------------------------------*/ 952 + 953 + static int setup_GPIOs(struct pi433_device *device) 954 + { 955 + char name[5]; 956 + int retval; 957 + int i; 958 + 959 + for (i=0; i<NUM_DIO; i++) 960 + { 961 + /* "construct" name and get the gpio descriptor */ 962 + snprintf(name, sizeof(name), "DIO%d", i); 963 + device->gpiod[i] = gpiod_get(&device->spi->dev, name, 0 /*GPIOD_IN*/); 964 + 965 + if (device->gpiod[i] == ERR_PTR(-ENOENT)) 966 + { 967 + dev_dbg(&device->spi->dev, "Could not find entry for %s. Ignoring.", name); 968 + continue; 969 + } 970 + 971 + if (device->gpiod[i] == ERR_PTR(-EBUSY)) 972 + dev_dbg(&device->spi->dev, "%s is busy.", name); 973 + 974 + if ( IS_ERR(device->gpiod[i]) ) 975 + { 976 + retval = PTR_ERR(device->gpiod[i]); 977 + /* release already allocated gpios */ 978 + for (i--; i>=0; i--) 979 + { 980 + free_irq(device->irq_num[i], device); 981 + gpiod_put(device->gpiod[i]); 982 + } 983 + return retval; 984 + } 985 + 986 + 987 + /* configure the pin */ 988 + gpiod_unexport(device->gpiod[i]); 989 + retval = gpiod_direction_input(device->gpiod[i]); 990 + if (retval) return retval; 991 + 992 + 993 + /* configure irq */ 994 + device->irq_num[i] = gpiod_to_irq(device->gpiod[i]); 995 + if (device->irq_num[i] < 0) 996 + { 997 + device->gpiod[i] = ERR_PTR(-EINVAL);//(struct gpio_desc *)device->irq_num[i]; 998 + return device->irq_num[i]; 999 + } 1000 + retval = request_irq(device->irq_num[i], 1001 + DIO_irq_handler[i], 1002 + 0, /* flags */ 1003 + name, 1004 + device); 1005 + 1006 + if (retval) 1007 + return retval; 1008 + 1009 + dev_dbg(&device->spi->dev, "%s succesfully configured", name); 1010 + } 1011 + 1012 + return 0; 1013 + } 1014 + 1015 + static void free_GPIOs(struct pi433_device *device) 1016 + { 1017 + int i; 1018 + 1019 + for (i=0; i<NUM_DIO; i++) 1020 + { 1021 + /* check if gpiod is valid */ 1022 + if ( IS_ERR(device->gpiod[i]) ) 1023 + continue; 1024 + 1025 + free_irq(device->irq_num[i], device); 1026 + gpiod_put(device->gpiod[i]); 1027 + } 1028 + return; 1029 + } 1030 + 1031 + static int pi433_get_minor(struct pi433_device *device) 1032 + { 1033 + int retval = -ENOMEM; 1034 + 1035 + mutex_lock(&minor_lock); 1036 + retval = idr_alloc(&pi433_idr, device, 0, N_PI433_MINORS, GFP_KERNEL); 1037 + if (retval >= 0) { 1038 + device->minor = retval; 1039 + retval = 0; 1040 + } else if (retval == -ENOSPC) { 1041 + dev_err(device->dev, "too many pi433 devices\n"); 1042 + retval = -EINVAL; 1043 + } 1044 + mutex_unlock(&minor_lock); 1045 + return retval; 1046 + } 1047 + 1048 + static void pi433_free_minor(struct pi433_device *dev) 1049 + { 1050 + mutex_lock(&minor_lock); 1051 + idr_remove(&pi433_idr, dev->minor); 1052 + mutex_unlock(&minor_lock); 1053 + } 1054 + /*-------------------------------------------------------------------------*/ 1055 + 1056 + static const struct file_operations pi433_fops = { 1057 + .owner = THIS_MODULE, 1058 + /* REVISIT switch to aio primitives, so that userspace 1059 + * gets more complete API coverage. It'll simplify things 1060 + * too, except for the locking. 1061 + */ 1062 + .write = pi433_write, 1063 + .read = pi433_read, 1064 + .unlocked_ioctl = pi433_ioctl, 1065 + .compat_ioctl = pi433_compat_ioctl, 1066 + .open = pi433_open, 1067 + .release = pi433_release, 1068 + .llseek = no_llseek, 1069 + }; 1070 + 1071 + /*-------------------------------------------------------------------------*/ 1072 + 1073 + static int pi433_probe(struct spi_device *spi) 1074 + { 1075 + struct pi433_device *device; 1076 + int retval; 1077 + 1078 + /* setup spi parameters */ 1079 + spi->mode = 0x00; 1080 + spi->bits_per_word = 8; 1081 + /* spi->max_speed_hz = 10000000; 1MHz already set by device tree overlay */ 1082 + 1083 + retval = spi_setup(spi); 1084 + if (retval) 1085 + { 1086 + dev_dbg(&spi->dev, "configuration of SPI interface failed!\n"); 1087 + return retval; 1088 + } 1089 + else 1090 + { 1091 + dev_dbg(&spi->dev, 1092 + "spi interface setup: mode 0x%2x, %d bits per word, %dhz max speed", 1093 + spi->mode, spi->bits_per_word, spi->max_speed_hz); 1094 + } 1095 + 1096 + /* Ping the chip by reading the version register */ 1097 + retval = spi_w8r8(spi, 0x10); 1098 + if (retval < 0) 1099 + return retval; 1100 + 1101 + switch(retval) 1102 + { 1103 + case 0x24: 1104 + dev_dbg(&spi->dev, "fonud pi433 (ver. 0x%x)", retval); 1105 + break; 1106 + default: 1107 + dev_dbg(&spi->dev, "unknown chip version: 0x%x", retval); 1108 + return -ENODEV; 1109 + } 1110 + 1111 + /* Allocate driver data */ 1112 + device = kzalloc(sizeof(*device), GFP_KERNEL); 1113 + if (!device) 1114 + return -ENOMEM; 1115 + 1116 + /* Initialize the driver data */ 1117 + device->spi = spi; 1118 + device->rx_active = false; 1119 + device->tx_active = false; 1120 + device->interrupt_rx_allowed = false; 1121 + 1122 + /* init wait queues */ 1123 + init_waitqueue_head(&device->tx_wait_queue); 1124 + init_waitqueue_head(&device->rx_wait_queue); 1125 + init_waitqueue_head(&device->fifo_wait_queue); 1126 + 1127 + /* init fifo */ 1128 + INIT_KFIFO(device->tx_fifo); 1129 + 1130 + /* init mutexes and locks */ 1131 + mutex_init(&device->tx_fifo_lock); 1132 + mutex_init(&device->rx_lock); 1133 + 1134 + /* setup GPIO (including irq_handler) for the different DIOs */ 1135 + retval = setup_GPIOs(device); 1136 + if (retval) 1137 + { 1138 + dev_dbg(&spi->dev, "setup of GPIOs failed"); 1139 + goto GPIO_failed; 1140 + } 1141 + 1142 + /* setup the radio module */ 1143 + SET_CHECKED(rf69_set_mode (spi, standby)); 1144 + SET_CHECKED(rf69_set_data_mode (spi, packet)); 1145 + SET_CHECKED(rf69_set_amplifier_0 (spi, optionOn)); 1146 + SET_CHECKED(rf69_set_amplifier_1 (spi, optionOff)); 1147 + SET_CHECKED(rf69_set_amplifier_2 (spi, optionOff)); 1148 + SET_CHECKED(rf69_set_output_power_level (spi, 13)); 1149 + SET_CHECKED(rf69_set_antenna_impedance (spi, fiftyOhm)); 1150 + 1151 + /* start tx thread */ 1152 + device->tx_task_struct = kthread_run(pi433_tx_thread, 1153 + device, 1154 + "pi433_tx_task"); 1155 + if (device->tx_task_struct < 0) 1156 + { 1157 + dev_dbg(device->dev, "start of send thread failed"); 1158 + goto send_thread_failed; 1159 + } 1160 + 1161 + /* determ minor number */ 1162 + retval = pi433_get_minor(device); 1163 + if (retval) 1164 + { 1165 + dev_dbg(device->dev, "get of minor number failed"); 1166 + goto minor_failed; 1167 + } 1168 + 1169 + /* create device */ 1170 + device->devt = MKDEV(MAJOR(pi433_dev), device->minor); 1171 + device->dev = device_create(pi433_class, 1172 + &spi->dev, 1173 + device->devt, 1174 + device, 1175 + "pi433"); 1176 + if (IS_ERR(device->dev)) { 1177 + pr_err("pi433: device register failed\n"); 1178 + retval = PTR_ERR(device->dev); 1179 + goto device_create_failed; 1180 + } 1181 + else { 1182 + dev_dbg(device->dev, 1183 + "created device for major %d, minor %d\n", 1184 + MAJOR(pi433_dev), 1185 + device->minor); 1186 + } 1187 + 1188 + /* create cdev */ 1189 + device->cdev = cdev_alloc(); 1190 + device->cdev->owner = THIS_MODULE; 1191 + cdev_init(device->cdev, &pi433_fops); 1192 + retval = cdev_add(device->cdev, device->devt, 1); 1193 + if (retval) 1194 + { 1195 + dev_dbg(device->dev, "register of cdev failed"); 1196 + goto cdev_failed; 1197 + } 1198 + 1199 + /* spi setup */ 1200 + spi_set_drvdata(spi, device); 1201 + 1202 + return 0; 1203 + 1204 + cdev_failed: 1205 + device_destroy(pi433_class, device->devt); 1206 + device_create_failed: 1207 + pi433_free_minor(device); 1208 + minor_failed: 1209 + kthread_stop(device->tx_task_struct); 1210 + send_thread_failed: 1211 + free_GPIOs(device); 1212 + GPIO_failed: 1213 + kfree(device); 1214 + 1215 + return retval; 1216 + } 1217 + 1218 + static int pi433_remove(struct spi_device *spi) 1219 + { 1220 + struct pi433_device *device = spi_get_drvdata(spi); 1221 + 1222 + /* free GPIOs */ 1223 + free_GPIOs(device); 1224 + 1225 + /* make sure ops on existing fds can abort cleanly */ 1226 + device->spi = NULL; 1227 + 1228 + kthread_stop(device->tx_task_struct); 1229 + 1230 + device_destroy(pi433_class, device->devt); 1231 + 1232 + cdev_del(device->cdev); 1233 + 1234 + pi433_free_minor(device); 1235 + 1236 + if (device->users == 0) 1237 + kfree(device); 1238 + 1239 + return 0; 1240 + } 1241 + 1242 + static const struct of_device_id pi433_dt_ids[] = { 1243 + { .compatible = "Smarthome-Wolf,pi433" }, 1244 + {}, 1245 + }; 1246 + 1247 + MODULE_DEVICE_TABLE(of, pi433_dt_ids); 1248 + 1249 + static struct spi_driver pi433_spi_driver = { 1250 + .driver = { 1251 + .name = "pi433", 1252 + .owner = THIS_MODULE, 1253 + .of_match_table = of_match_ptr(pi433_dt_ids), 1254 + }, 1255 + .probe = pi433_probe, 1256 + .remove = pi433_remove, 1257 + 1258 + /* NOTE: suspend/resume methods are not necessary here. 1259 + * We don't do anything except pass the requests to/from 1260 + * the underlying controller. The refrigerator handles 1261 + * most issues; the controller driver handles the rest. 1262 + */ 1263 + }; 1264 + 1265 + /*-------------------------------------------------------------------------*/ 1266 + 1267 + static int __init pi433_init(void) 1268 + { 1269 + int status; 1270 + 1271 + /* If MAX_MSG_SIZE is smaller then FIFO_SIZE, the driver won't 1272 + work stable - risk of buffer overflow */ 1273 + if (MAX_MSG_SIZE < FIFO_SIZE) 1274 + return -EINVAL; 1275 + 1276 + /* Claim device numbers. Then register a class 1277 + * that will key udev/mdev to add/remove /dev nodes. Last, register 1278 + * Last, register the driver which manages those device numbers. 1279 + */ 1280 + status = alloc_chrdev_region(&pi433_dev, 0 /*firstminor*/, N_PI433_MINORS /*count*/, "pi433" /*name*/); 1281 + if (status < 0) 1282 + return status; 1283 + 1284 + pi433_class = class_create(THIS_MODULE, "pi433"); 1285 + if (IS_ERR(pi433_class)) 1286 + { 1287 + unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name); 1288 + return PTR_ERR(pi433_class); 1289 + } 1290 + 1291 + status = spi_register_driver(&pi433_spi_driver); 1292 + if (status < 0) 1293 + { 1294 + class_destroy(pi433_class); 1295 + unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name); 1296 + } 1297 + 1298 + return status; 1299 + } 1300 + 1301 + module_init(pi433_init); 1302 + 1303 + static void __exit pi433_exit(void) 1304 + { 1305 + spi_unregister_driver(&pi433_spi_driver); 1306 + class_destroy(pi433_class); 1307 + unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name); 1308 + } 1309 + module_exit(pi433_exit); 1310 + 1311 + MODULE_AUTHOR("Marcus Wolf, <linux@wolf-entwicklungen.de>"); 1312 + MODULE_DESCRIPTION("Driver for Pi433"); 1313 + MODULE_LICENSE("GPL"); 1314 + MODULE_ALIAS("spi:pi433");
+152
drivers/staging/pi433/pi433_if.h
··· 1 + /* 2 + * include/linux/TODO 3 + * 4 + * userspace interface for pi433 radio module 5 + * 6 + * Pi433 is a 433MHz radio module for the Raspberry Pi. 7 + * It is based on the HopeRf Module RFM69CW. Therefore inside of this 8 + * driver, you'll find an abstraction of the rf69 chip. 9 + * 10 + * If needed, this driver could be extended, to also support other 11 + * devices, basing on HopeRfs rf69. 12 + * 13 + * The driver can also be extended, to support other modules of 14 + * HopeRf with a similar interace - e. g. RFM69HCW, RFM12, RFM95, ... 15 + * Copyright (C) 2016 Wolf-Entwicklungen 16 + * Marcus Wolf <linux@wolf-entwicklungen.de> 17 + * 18 + * This program is free software; you can redistribute it and/or modify 19 + * it under the terms of the GNU General Public License as published by 20 + * the Free Software Foundation; either version 2 of the License, or 21 + * (at your option) any later version. 22 + * 23 + * This program is distributed in the hope that it will be useful, 24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 + * GNU General Public License for more details. 27 + */ 28 + 29 + #ifndef PI433_H 30 + #define PI433_H 31 + 32 + #include <linux/types.h> 33 + #include "rf69_enum.h" 34 + 35 + /*---------------------------------------------------------------------------*/ 36 + 37 + 38 + /*---------------------------------------------------------------------------*/ 39 + 40 + /* IOCTL structs and commands */ 41 + 42 + /** 43 + * struct pi433_tx_config - describes the configuration of the radio module for sending 44 + * @frequency: 45 + * @bit_rate: 46 + * @modulation: 47 + * @data_mode: 48 + * @preamble_length: 49 + * @sync_pattern: 50 + * @tx_start_condition: 51 + * @payload_length: 52 + * @repetitions: 53 + * 54 + * ATTENTION: 55 + * If the contents of 'pi433_tx_config' ever change 56 + * incompatibly, then the ioctl number (see define below) must change. 57 + * 58 + * NOTE: struct layout is the same in 64bit and 32bit userspace. 59 + */ 60 + #define PI433_TX_CFG_IOCTL_NR 0 61 + struct pi433_tx_cfg 62 + { 63 + __u32 frequency; 64 + __u16 bit_rate; 65 + __u32 dev_frequency; 66 + enum modulation modulation; 67 + enum modShaping modShaping; 68 + 69 + enum paRamp pa_ramp; 70 + 71 + enum txStartCondition tx_start_condition; 72 + 73 + __u16 repetitions; 74 + 75 + 76 + /* packet format */ 77 + enum optionOnOff enable_preamble; 78 + enum optionOnOff enable_sync; 79 + enum optionOnOff enable_length_byte; 80 + enum optionOnOff enable_address_byte; 81 + enum optionOnOff enable_crc; 82 + 83 + __u16 preamble_length; 84 + __u8 sync_length; 85 + __u8 fixed_message_length; 86 + 87 + __u8 sync_pattern[8]; 88 + __u8 address_byte; 89 + }; 90 + 91 + 92 + /** 93 + * struct pi433_rx_config - describes the configuration of the radio module for sending 94 + * @frequency: 95 + * @bit_rate: 96 + * @modulation: 97 + * @data_mode: 98 + * @preamble_length: 99 + * @sync_pattern: 100 + * @tx_start_condition: 101 + * @payload_length: 102 + * @repetitions: 103 + * 104 + * ATTENTION: 105 + * If the contents of 'pi433_rx_config' ever change 106 + * incompatibly, then the ioctl number (see define below) must change 107 + * 108 + * NOTE: struct layout is the same in 64bit and 32bit userspace. 109 + */ 110 + #define PI433_RX_CFG_IOCTL_NR 1 111 + struct pi433_rx_cfg { 112 + __u32 frequency; 113 + __u16 bit_rate; 114 + __u32 dev_frequency; 115 + 116 + enum modulation modulation; 117 + 118 + __u8 rssi_threshold; 119 + enum thresholdDecrement thresholdDecrement; 120 + enum antennaImpedance antenna_impedance; 121 + enum lnaGain lna_gain; 122 + enum mantisse bw_mantisse; /* normal: 0x50 */ 123 + __u8 bw_exponent; /* during AFC: 0x8b */ 124 + enum dagc dagc; 125 + 126 + 127 + 128 + /* packet format */ 129 + enum optionOnOff enable_sync; 130 + enum optionOnOff enable_length_byte; /* should be used in combination with sync, only */ 131 + enum addressFiltering enable_address_filtering; /* operational with sync, only */ 132 + enum optionOnOff enable_crc; /* only operational, if sync on and fixed length or length byte is used */ 133 + 134 + __u8 sync_length; 135 + __u8 fixed_message_length; 136 + __u32 bytes_to_drop; 137 + 138 + __u8 sync_pattern[8]; 139 + __u8 node_address; 140 + __u8 broadcast_address; 141 + }; 142 + 143 + 144 + #define PI433_IOC_MAGIC 'r' 145 + 146 + #define PI433_IOC_RD_TX_CFG _IOR(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) 147 + #define PI433_IOC_WR_TX_CFG _IOW(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) 148 + 149 + #define PI433_IOC_RD_RX_CFG _IOR(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) 150 + #define PI433_IOC_WR_RX_CFG _IOW(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) 151 + 152 + #endif /* PI433_H */
+982
drivers/staging/pi433/rf69.c
··· 1 + /* 2 + * abstraction of the spi interface of HopeRf rf69 radio module 3 + * 4 + * Copyright (C) 2016 Wolf-Entwicklungen 5 + * Marcus Wolf <linux@wolf-entwicklungen.de> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + */ 17 + 18 + /* enable prosa debug info */ 19 + #undef DEBUG 20 + /* enable print of values on reg access */ 21 + #undef DEBUG_VALUES 22 + /* enable print of values on fifo access */ 23 + #undef DEBUG_FIFO_ACCESS 24 + 25 + #include <linux/types.h> 26 + #include <linux/spi/spi.h> 27 + 28 + #include "rf69.h" 29 + #include "rf69_registers.h" 30 + 31 + #define F_OSC 32000000 /* in Hz */ 32 + #define FIFO_SIZE 66 /* in byte */ 33 + 34 + /*-------------------------------------------------------------------------*/ 35 + 36 + #define READ_REG(x) rf69_read_reg (spi, x) 37 + #define WRITE_REG(x,y) rf69_write_reg(spi, x, y) 38 + #define INVALID_PARAM \ 39 + { \ 40 + dev_dbg(&spi->dev, "set: illegal input param"); \ 41 + return -EINVAL; \ 42 + } 43 + 44 + /*-------------------------------------------------------------------------*/ 45 + 46 + int rf69_set_mode(struct spi_device *spi, enum mode mode) 47 + { 48 + #ifdef DEBUG 49 + dev_dbg(&spi->dev, "set: mode"); 50 + #endif 51 + 52 + switch (mode){ 53 + case transmit: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_TRANSMIT); 54 + case receive: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_RECEIVE); 55 + case synthesizer: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_SYNTHESIZER); 56 + case standby: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_STANDBY); 57 + case mode_sleep: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_SLEEP); 58 + default: INVALID_PARAM; 59 + } 60 + 61 + // we are using packet mode, so this check is not really needed 62 + // but waiting for mode ready is necessary when going from sleep because the FIFO may not be immediately available from previous mode 63 + //while (_mode == RF69_MODE_SLEEP && (READ_REG(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); // Wait for ModeReady 64 + 65 + } 66 + 67 + int rf69_set_data_mode(struct spi_device *spi, enum dataMode dataMode) 68 + { 69 + #ifdef DEBUG 70 + dev_dbg(&spi->dev, "set: data mode"); 71 + #endif 72 + 73 + switch (dataMode) { 74 + case packet: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_PACKET); 75 + case continuous: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_CONTINUOUS); 76 + case continuousNoSync: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_CONTINUOUS_NOSYNC); 77 + default: INVALID_PARAM; 78 + } 79 + } 80 + 81 + int rf69_set_modulation(struct spi_device *spi, enum modulation modulation) 82 + { 83 + #ifdef DEBUG 84 + dev_dbg(&spi->dev, "set: modulation"); 85 + #endif 86 + 87 + switch (modulation) { 88 + case OOK: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_TYPE) | DATAMODUL_MODULATION_TYPE_OOK); 89 + case FSK: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_TYPE) | DATAMODUL_MODULATION_TYPE_FSK); 90 + default: INVALID_PARAM; 91 + } 92 + } 93 + 94 + enum modulation rf69_get_modulation(struct spi_device *spi) 95 + { 96 + u8 currentValue; 97 + 98 + #ifdef DEBUG 99 + dev_dbg(&spi->dev, "get: mode"); 100 + #endif 101 + 102 + currentValue = READ_REG(REG_DATAMODUL); 103 + 104 + switch (currentValue & MASK_DATAMODUL_MODULATION_TYPE >> 3) // TODO improvement: change 3 to define 105 + { 106 + case DATAMODUL_MODULATION_TYPE_OOK: return OOK; 107 + case DATAMODUL_MODULATION_TYPE_FSK: return FSK; 108 + default: return undefined; 109 + } 110 + } 111 + 112 + int rf69_set_modulation_shaping(struct spi_device *spi, enum modShaping modShaping) 113 + { 114 + #ifdef DEBUG 115 + dev_dbg(&spi->dev, "set: mod shaping"); 116 + #endif 117 + 118 + if (rf69_get_modulation(spi) == FSK) 119 + { 120 + switch (modShaping) { 121 + case shapingOff: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_NONE); 122 + case shaping1_0: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_1_0); 123 + case shaping0_5: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_0_3); 124 + case shaping0_3: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_0_5); 125 + default: INVALID_PARAM; 126 + } 127 + } 128 + else 129 + { 130 + switch (modShaping) { 131 + case shapingOff: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_NONE); 132 + case shapingBR: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_BR); 133 + case shaping2BR: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_2BR); 134 + default: INVALID_PARAM; 135 + } 136 + } 137 + } 138 + 139 + int rf69_set_bit_rate(struct spi_device *spi, u16 bitRate) 140 + { 141 + int retval; 142 + u32 bitRate_min; 143 + u32 bitRate_reg; 144 + u8 msb; 145 + u8 lsb; 146 + 147 + #ifdef DEBUG 148 + dev_dbg(&spi->dev, "set: bit rate"); 149 + #endif 150 + 151 + // check input value 152 + bitRate_min = F_OSC / 8388608; // 8388608 = 2^23; 153 + if (bitRate < bitRate_min) 154 + { 155 + dev_dbg(&spi->dev, "setBitRate: illegal input param"); 156 + INVALID_PARAM; 157 + } 158 + 159 + // calculate reg settings 160 + bitRate_reg = (F_OSC / bitRate); 161 + 162 + msb = (bitRate_reg&0xff00) >> 8; 163 + lsb = (bitRate_reg&0xff); 164 + 165 + // transmit to RF 69 166 + retval = WRITE_REG(REG_BITRATE_MSB, msb); 167 + if (retval) return retval; 168 + retval = WRITE_REG(REG_BITRATE_LSB, lsb); 169 + if (retval) return retval; 170 + 171 + return 0; 172 + } 173 + 174 + int rf69_set_deviation(struct spi_device *spi, u32 deviation) 175 + { 176 + int retval; 177 + // u32 f_max; TODO: Abh�ngigkeit von Bitrate beachten!! 178 + u64 f_reg; 179 + u64 f_step; 180 + u8 msb; 181 + u8 lsb; 182 + u64 factor = 1000000; // to improve precision of calculation 183 + 184 + #ifdef DEBUG 185 + dev_dbg(&spi->dev, "set: deviation"); 186 + #endif 187 + 188 + if (deviation < 600 || deviation > 500000) //TODO: Abh�ngigkeit von Bitrate beachten!! 189 + { 190 + dev_dbg(&spi->dev, "set_deviation: illegal input param"); 191 + INVALID_PARAM; 192 + } 193 + 194 + // calculat f step 195 + f_step = F_OSC * factor; 196 + do_div(f_step, 524288); // 524288 = 2^19 197 + 198 + // calculate register settings 199 + f_reg = deviation * factor; 200 + do_div(f_reg , f_step); 201 + 202 + msb = (f_reg&0xff00) >> 8; 203 + lsb = (f_reg&0xff); 204 + 205 + // check msb 206 + if (msb & !FDEVMASB_MASK) 207 + { 208 + dev_dbg(&spi->dev, "set_deviation: err in calc of msb"); 209 + INVALID_PARAM; 210 + } 211 + 212 + // write to chip 213 + retval = WRITE_REG(REG_FDEV_MSB, msb); 214 + if (retval) return retval; 215 + retval = WRITE_REG(REG_FDEV_LSB, lsb); 216 + if (retval) return retval; 217 + 218 + return 0; 219 + } 220 + 221 + int rf69_set_frequency(struct spi_device *spi, u32 frequency) 222 + { 223 + int retval; 224 + u32 f_max; 225 + u64 f_reg; 226 + u64 f_step; 227 + u8 msb; 228 + u8 mid; 229 + u8 lsb; 230 + u64 factor = 1000000; // to improve precision of calculation 231 + 232 + #ifdef DEBUG 233 + dev_dbg(&spi->dev, "set: frequency"); 234 + #endif 235 + 236 + // calculat f step 237 + f_step = F_OSC * factor; 238 + do_div(f_step, 524288); // 524288 = 2^19 239 + 240 + // check input value 241 + f_max = f_step * 8388608 / factor; 242 + if (frequency > f_max) 243 + { 244 + dev_dbg(&spi->dev, "setFrequency: illegal input param"); 245 + INVALID_PARAM; 246 + } 247 + 248 + // calculate reg settings 249 + f_reg = frequency * factor; 250 + do_div(f_reg , f_step); 251 + 252 + msb = (f_reg&0xff0000) >> 16; 253 + mid = (f_reg&0xff00) >> 8; 254 + lsb = (f_reg&0xff); 255 + 256 + // write to chip 257 + retval = WRITE_REG(REG_FRF_MSB, msb); 258 + if (retval) return retval; 259 + retval = WRITE_REG(REG_FRF_MID, mid); 260 + if (retval) return retval; 261 + retval = WRITE_REG(REG_FRF_LSB, lsb); 262 + if (retval) return retval; 263 + 264 + return 0; 265 + } 266 + 267 + int rf69_set_amplifier_0(struct spi_device *spi, enum optionOnOff optionOnOff) 268 + { 269 + #ifdef DEBUG 270 + dev_dbg(&spi->dev, "set: amp #0"); 271 + #endif 272 + 273 + switch(optionOnOff) { 274 + case optionOn: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) | MASK_PALEVEL_PA0) ); 275 + case optionOff: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_PA0) ); 276 + default: INVALID_PARAM; 277 + } 278 + } 279 + 280 + int rf69_set_amplifier_1(struct spi_device *spi, enum optionOnOff optionOnOff) 281 + { 282 + #ifdef DEBUG 283 + dev_dbg(&spi->dev, "set: amp #1"); 284 + #endif 285 + 286 + switch(optionOnOff) { 287 + case optionOn: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) | MASK_PALEVEL_PA1) ); 288 + case optionOff: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_PA1) ); 289 + default: INVALID_PARAM; 290 + } 291 + } 292 + 293 + int rf69_set_amplifier_2(struct spi_device *spi, enum optionOnOff optionOnOff) 294 + { 295 + #ifdef DEBUG 296 + dev_dbg(&spi->dev, "set: amp #2"); 297 + #endif 298 + 299 + switch(optionOnOff) { 300 + case optionOn: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) | MASK_PALEVEL_PA2) ); 301 + case optionOff: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_PA2) ); 302 + default: INVALID_PARAM; 303 + } 304 + } 305 + 306 + int rf69_set_output_power_level(struct spi_device *spi, u8 powerLevel) 307 + { 308 + #ifdef DEBUG 309 + dev_dbg(&spi->dev, "set: power level"); 310 + #endif 311 + 312 + powerLevel +=18; // TODO Abh�ngigkeit von PA0,1,2 setting 313 + 314 + // check input value 315 + if (powerLevel > 0x1f) 316 + INVALID_PARAM; 317 + 318 + // write value 319 + return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_OUTPUT_POWER) | powerLevel); 320 + } 321 + 322 + int rf69_set_pa_ramp(struct spi_device *spi, enum paRamp paRamp) 323 + { 324 + #ifdef DEBUG 325 + dev_dbg(&spi->dev, "set: pa ramp"); 326 + #endif 327 + 328 + switch(paRamp) { 329 + case ramp3400: return WRITE_REG(REG_PARAMP, PARAMP_3400); 330 + case ramp2000: return WRITE_REG(REG_PARAMP, PARAMP_2000); 331 + case ramp1000: return WRITE_REG(REG_PARAMP, PARAMP_1000); 332 + case ramp500: return WRITE_REG(REG_PARAMP, PARAMP_500); 333 + case ramp250: return WRITE_REG(REG_PARAMP, PARAMP_250); 334 + case ramp125: return WRITE_REG(REG_PARAMP, PARAMP_125); 335 + case ramp100: return WRITE_REG(REG_PARAMP, PARAMP_100); 336 + case ramp62: return WRITE_REG(REG_PARAMP, PARAMP_62); 337 + case ramp50: return WRITE_REG(REG_PARAMP, PARAMP_50); 338 + case ramp40: return WRITE_REG(REG_PARAMP, PARAMP_40); 339 + case ramp31: return WRITE_REG(REG_PARAMP, PARAMP_31); 340 + case ramp25: return WRITE_REG(REG_PARAMP, PARAMP_25); 341 + case ramp20: return WRITE_REG(REG_PARAMP, PARAMP_20); 342 + case ramp15: return WRITE_REG(REG_PARAMP, PARAMP_15); 343 + case ramp12: return WRITE_REG(REG_PARAMP, PARAMP_12); 344 + case ramp10: return WRITE_REG(REG_PARAMP, PARAMP_10); 345 + default: INVALID_PARAM; 346 + } 347 + } 348 + 349 + int rf69_set_antenna_impedance(struct spi_device *spi, enum antennaImpedance antennaImpedance) 350 + { 351 + #ifdef DEBUG 352 + dev_dbg(&spi->dev, "set: antenna impedance"); 353 + #endif 354 + 355 + switch(antennaImpedance) { 356 + case fiftyOhm: return WRITE_REG(REG_LNA, (READ_REG(REG_LNA) & ~MASK_LNA_ZIN) ); 357 + case twohundretOhm: return WRITE_REG(REG_LNA, (READ_REG(REG_LNA) | MASK_LNA_ZIN) ); 358 + default: INVALID_PARAM; 359 + } 360 + } 361 + 362 + int rf69_set_lna_gain(struct spi_device *spi, enum lnaGain lnaGain) 363 + { 364 + #ifdef DEBUG 365 + dev_dbg(&spi->dev, "set: lna gain"); 366 + #endif 367 + 368 + switch(lnaGain) { 369 + case automatic: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_AUTO) ); 370 + case max: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX) ); 371 + case maxMinus6: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_6) ); 372 + case maxMinus12: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_12) ); 373 + case maxMinus24: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_24) ); 374 + case maxMinus36: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_36) ); 375 + case maxMinus48: return WRITE_REG(REG_LNA, ( (READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_48) ); 376 + default: INVALID_PARAM; 377 + } 378 + } 379 + 380 + enum lnaGain rf69_get_lna_gain(struct spi_device *spi) 381 + { 382 + u8 currentValue; 383 + 384 + #ifdef DEBUG 385 + dev_dbg(&spi->dev, "get: lna gain"); 386 + #endif 387 + 388 + currentValue = READ_REG(REG_LNA); 389 + 390 + switch (currentValue & MASK_LNA_CURRENT_GAIN >> 3) // improvement: change 3 to define 391 + { 392 + case LNA_GAIN_AUTO: return automatic; 393 + case LNA_GAIN_MAX: return max; 394 + case LNA_GAIN_MAX_MINUS_6: return maxMinus6; 395 + case LNA_GAIN_MAX_MINUS_12: return maxMinus12; 396 + case LNA_GAIN_MAX_MINUS_24: return maxMinus24; 397 + case LNA_GAIN_MAX_MINUS_36: return maxMinus36; 398 + case LNA_GAIN_MAX_MINUS_48: return maxMinus48; 399 + default: return undefined; 400 + } 401 + } 402 + 403 + int rf69_set_dc_cut_off_frequency_intern(struct spi_device *spi ,u8 reg, enum dccPercent dccPercent) 404 + { 405 + switch (dccPercent) { 406 + case dcc16Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_16_PERCENT) ); 407 + case dcc8Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_8_PERCENT) ); 408 + case dcc4Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_4_PERCENT) ); 409 + case dcc2Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_2_PERCENT) ); 410 + case dcc1Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_1_PERCENT) ); 411 + case dcc0_5Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_0_5_PERCENT) ); 412 + case dcc0_25Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_0_25_PERCENT) ); 413 + case dcc0_125Percent: return WRITE_REG(reg, ( (READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_0_125_PERCENT) ); 414 + default: INVALID_PARAM; 415 + } 416 + } 417 + 418 + int rf69_set_dc_cut_off_frequency(struct spi_device *spi, enum dccPercent dccPercent) 419 + { 420 + #ifdef DEBUG 421 + dev_dbg(&spi->dev, "set: cut off freq"); 422 + #endif 423 + 424 + return rf69_set_dc_cut_off_frequency_intern(spi, REG_RXBW, dccPercent); 425 + } 426 + 427 + int rf69_set_dc_cut_off_frequency_during_afc(struct spi_device *spi, enum dccPercent dccPercent) 428 + { 429 + #ifdef DEBUG 430 + dev_dbg(&spi->dev, "set: cut off freq during afc"); 431 + #endif 432 + 433 + return rf69_set_dc_cut_off_frequency_intern(spi, REG_AFCBW, dccPercent); 434 + } 435 + 436 + int rf69_set_bandwidth_intern(struct spi_device *spi, u8 reg, enum mantisse mantisse, u8 exponent) 437 + { 438 + u8 newValue; 439 + 440 + // check value for mantisse and exponent 441 + if (exponent > 7) INVALID_PARAM; 442 + if ( (mantisse!=mantisse16) && 443 + (mantisse!=mantisse20) && 444 + (mantisse!=mantisse24) ) INVALID_PARAM; 445 + 446 + // read old value 447 + newValue = READ_REG(reg); 448 + 449 + // "delete" mantisse and exponent = just keep the DCC setting 450 + newValue = newValue & MASK_BW_DCC_FREQ; 451 + 452 + // add new mantisse 453 + switch(mantisse) { 454 + case mantisse16: newValue = newValue | BW_MANT_16; break; 455 + case mantisse20: newValue = newValue | BW_MANT_20; break; 456 + case mantisse24: newValue = newValue | BW_MANT_24; break; 457 + } 458 + 459 + // add new exponent 460 + newValue = newValue | exponent; 461 + 462 + // write back 463 + return WRITE_REG(reg, newValue); 464 + } 465 + 466 + int rf69_set_bandwidth(struct spi_device *spi, enum mantisse mantisse, u8 exponent) 467 + { 468 + #ifdef DEBUG 469 + dev_dbg(&spi->dev, "set: band width"); 470 + #endif 471 + 472 + return rf69_set_bandwidth_intern(spi, REG_RXBW, mantisse, exponent); 473 + } 474 + 475 + int rf69_set_bandwidth_during_afc(struct spi_device *spi, enum mantisse mantisse, u8 exponent) 476 + { 477 + #ifdef DEBUG 478 + dev_dbg(&spi->dev, "set: band width during afc"); 479 + #endif 480 + 481 + return rf69_set_bandwidth_intern(spi, REG_AFCBW, mantisse, exponent); 482 + } 483 + 484 + int rf69_set_ook_threshold_type(struct spi_device *spi, enum thresholdType thresholdType) 485 + { 486 + #ifdef DEBUG 487 + dev_dbg(&spi->dev, "set: threshold type"); 488 + #endif 489 + 490 + switch (thresholdType) 491 + { 492 + case fixed: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESTYPE) | OOKPEAK_THRESHTYPE_FIXED) ); 493 + case peak: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESTYPE) | OOKPEAK_THRESHTYPE_PEAK) ); 494 + case average: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESTYPE) | OOKPEAK_THRESHTYPE_AVERAGE) ); 495 + default: INVALID_PARAM; 496 + } 497 + } 498 + 499 + int rf69_set_ook_threshold_step(struct spi_device *spi, enum thresholdStep thresholdStep) 500 + { 501 + #ifdef DEBUG 502 + dev_dbg(&spi->dev, "set: threshold step"); 503 + #endif 504 + 505 + switch (thresholdStep) { 506 + case step_0_5db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_0_5_DB) ); 507 + case step_1_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_1_0_DB) ); 508 + case step_1_5db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_1_5_DB) ); 509 + case step_2_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_2_0_DB) ); 510 + case step_3_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_3_0_DB) ); 511 + case step_4_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_4_0_DB) ); 512 + case step_5_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_5_0_DB) ); 513 + case step_6_0db: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_6_0_DB) ); 514 + default: INVALID_PARAM; 515 + } 516 + } 517 + 518 + int rf69_set_ook_threshold_dec(struct spi_device *spi, enum thresholdDecrement thresholdDecrement) 519 + { 520 + #ifdef DEBUG 521 + dev_dbg(&spi->dev, "set: threshold decrement"); 522 + #endif 523 + 524 + switch (thresholdDecrement) { 525 + case dec_every8th: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_EVERY_8TH) ); 526 + case dec_every4th: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_EVERY_4TH) ); 527 + case dec_every2nd: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_EVERY_2ND) ); 528 + case dec_once: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_ONCE) ); 529 + case dec_twice: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_TWICE) ); 530 + case dec_4times: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_4_TIMES) ); 531 + case dec_8times: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_8_TIMES) ); 532 + case dec_16times: return WRITE_REG(REG_OOKPEAK, ( (READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_16_TIMES) ); 533 + default: INVALID_PARAM; 534 + } 535 + } 536 + 537 + int rf69_set_dio_mapping(struct spi_device *spi, u8 DIONumber, u8 value) 538 + { 539 + u8 mask; 540 + u8 shift; 541 + u8 regaddr; 542 + u8 regValue; 543 + 544 + #ifdef DEBUG 545 + dev_dbg(&spi->dev, "set: DIO mapping"); 546 + #endif 547 + 548 + // check DIO number 549 + if (DIONumber > 5) INVALID_PARAM; 550 + 551 + switch (DIONumber) { 552 + case 0: mask=MASK_DIO0; shift=SHIFT_DIO0; regaddr=REG_DIOMAPPING1; break; 553 + case 1: mask=MASK_DIO1; shift=SHIFT_DIO1; regaddr=REG_DIOMAPPING1; break; 554 + case 2: mask=MASK_DIO2; shift=SHIFT_DIO2; regaddr=REG_DIOMAPPING1; break; 555 + case 3: mask=MASK_DIO3; shift=SHIFT_DIO3; regaddr=REG_DIOMAPPING1; break; 556 + case 4: mask=MASK_DIO4; shift=SHIFT_DIO4; regaddr=REG_DIOMAPPING2; break; 557 + case 5: mask=MASK_DIO5; shift=SHIFT_DIO5; regaddr=REG_DIOMAPPING2; break; 558 + } 559 + 560 + // read reg 561 + regValue=READ_REG(regaddr); 562 + // delete old value 563 + regValue = regValue & ~mask; 564 + // add new value 565 + regValue = regValue | value << shift; 566 + // write back 567 + return WRITE_REG(regaddr,regValue); 568 + } 569 + 570 + bool rf69_get_flag(struct spi_device *spi, enum flag flag) 571 + { 572 + #ifdef DEBUG 573 + dev_dbg(&spi->dev, "get: flag"); 574 + #endif 575 + 576 + switch(flag) { 577 + case modeSwitchCompleted: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_MODE_READY); 578 + case readyToReceive: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_RX_READY); 579 + case readyToSend: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_TX_READY); 580 + case pllLocked: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_PLL_LOCK); 581 + case rssiExceededThreshold: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_RSSI); 582 + case timeout: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_TIMEOUT); 583 + case automode: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_AUTOMODE); 584 + case syncAddressMatch: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_SYNC_ADDRESS_MATCH); 585 + case fifoFull: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_FULL); 586 + /* case fifoNotEmpty: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_NOT_EMPTY); */ 587 + case fifoEmpty: return !(READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_NOT_EMPTY); 588 + case fifoLevelBelowThreshold: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_LEVEL); 589 + case fifoOverrun: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_OVERRUN); 590 + case packetSent: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_PACKET_SENT); 591 + case payloadReady: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_PAYLOAD_READY); 592 + case crcOk: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_CRC_OK); 593 + case batteryLow: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_LOW_BAT); 594 + default: return false; 595 + } 596 + } 597 + 598 + int rf69_reset_flag(struct spi_device *spi, enum flag flag) 599 + { 600 + #ifdef DEBUG 601 + dev_dbg(&spi->dev, "reset: flag"); 602 + #endif 603 + 604 + switch(flag) { 605 + case rssiExceededThreshold: return WRITE_REG(REG_IRQFLAGS1, MASK_IRQFLAGS1_RSSI); 606 + case syncAddressMatch: return WRITE_REG(REG_IRQFLAGS1, MASK_IRQFLAGS1_SYNC_ADDRESS_MATCH); 607 + case fifoOverrun: return WRITE_REG(REG_IRQFLAGS2, MASK_IRQFLAGS2_FIFO_OVERRUN); 608 + default: INVALID_PARAM; 609 + } 610 + } 611 + 612 + int rf69_set_rssi_threshold(struct spi_device *spi, u8 threshold) 613 + { 614 + #ifdef DEBUG 615 + dev_dbg(&spi->dev, "set: rssi threshold"); 616 + #endif 617 + 618 + /* no value check needed - u8 exactly matches register size */ 619 + 620 + return WRITE_REG(REG_RSSITHRESH, threshold); 621 + } 622 + 623 + int rf69_set_rx_start_timeout(struct spi_device *spi, u8 timeout) 624 + { 625 + #ifdef DEBUG 626 + dev_dbg(&spi->dev, "set: start timeout"); 627 + #endif 628 + 629 + /* no value check needed - u8 exactly matches register size */ 630 + 631 + return WRITE_REG(REG_RXTIMEOUT1, timeout); 632 + } 633 + 634 + int rf69_set_rssi_timeout(struct spi_device *spi, u8 timeout) 635 + { 636 + #ifdef DEBUG 637 + dev_dbg(&spi->dev, "set: rssi timeout"); 638 + #endif 639 + 640 + /* no value check needed - u8 exactly matches register size */ 641 + 642 + return WRITE_REG(REG_RXTIMEOUT2, timeout); 643 + } 644 + 645 + int rf69_set_preamble_length(struct spi_device *spi, u16 preambleLength) 646 + { 647 + int retval; 648 + u8 msb, lsb; 649 + 650 + #ifdef DEBUG 651 + dev_dbg(&spi->dev, "set: preample length"); 652 + #endif 653 + 654 + /* no value check needed - u16 exactly matches register size */ 655 + 656 + /* calculate reg settings */ 657 + msb = (preambleLength&0xff00) >> 8; 658 + lsb = (preambleLength&0xff); 659 + 660 + /* transmit to chip */ 661 + retval = WRITE_REG(REG_PREAMBLE_MSB, msb); 662 + if (retval) return retval; 663 + retval = WRITE_REG(REG_PREAMBLE_LSB, lsb); 664 + 665 + return retval; 666 + } 667 + 668 + int rf69_set_sync_enable(struct spi_device *spi, enum optionOnOff optionOnOff) 669 + { 670 + #ifdef DEBUG 671 + dev_dbg(&spi->dev, "set: sync enable"); 672 + #endif 673 + 674 + switch(optionOnOff) { 675 + case optionOn: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) | MASK_SYNC_CONFIG_SYNC_ON) ); 676 + case optionOff: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_SYNC_ON) ); 677 + default: INVALID_PARAM; 678 + } 679 + } 680 + 681 + int rf69_set_fifo_fill_condition(struct spi_device *spi, enum fifoFillCondition fifoFillCondition) 682 + { 683 + #ifdef DEBUG 684 + dev_dbg(&spi->dev, "set: fifo fill condition"); 685 + #endif 686 + 687 + switch(fifoFillCondition) { 688 + case always: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) | MASK_SYNC_CONFIG_FIFO_FILL_CONDITION) ); 689 + case afterSyncInterrupt: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_FIFO_FILL_CONDITION) ); 690 + default: INVALID_PARAM; 691 + } 692 + } 693 + 694 + int rf69_set_sync_size(struct spi_device *spi, u8 syncSize) 695 + { 696 + #ifdef DEBUG 697 + dev_dbg(&spi->dev, "set: sync size"); 698 + #endif 699 + 700 + // check input value 701 + if (syncSize > 0x07) 702 + INVALID_PARAM; 703 + 704 + // write value 705 + return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_SYNC_SIZE) | (syncSize << 3) ); 706 + } 707 + 708 + int rf69_set_sync_tolerance(struct spi_device *spi, u8 syncTolerance) 709 + { 710 + #ifdef DEBUG 711 + dev_dbg(&spi->dev, "set: sync tolerance"); 712 + #endif 713 + 714 + // check input value 715 + if (syncTolerance > 0x07) 716 + INVALID_PARAM; 717 + 718 + // write value 719 + return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_SYNC_SIZE) | syncTolerance); 720 + } 721 + 722 + int rf69_set_sync_values(struct spi_device *spi, u8 syncValues[8]) 723 + { 724 + int retval = 0; 725 + 726 + #ifdef DEBUG 727 + dev_dbg(&spi->dev, "set: sync values"); 728 + #endif 729 + 730 + retval += WRITE_REG(REG_SYNCVALUE1, syncValues[0]); 731 + retval += WRITE_REG(REG_SYNCVALUE2, syncValues[1]); 732 + retval += WRITE_REG(REG_SYNCVALUE3, syncValues[2]); 733 + retval += WRITE_REG(REG_SYNCVALUE4, syncValues[3]); 734 + retval += WRITE_REG(REG_SYNCVALUE5, syncValues[4]); 735 + retval += WRITE_REG(REG_SYNCVALUE6, syncValues[5]); 736 + retval += WRITE_REG(REG_SYNCVALUE7, syncValues[6]); 737 + retval += WRITE_REG(REG_SYNCVALUE8, syncValues[7]); 738 + 739 + return retval; 740 + } 741 + 742 + int rf69_set_packet_format(struct spi_device * spi, enum packetFormat packetFormat) 743 + { 744 + #ifdef DEBUG 745 + dev_dbg(&spi->dev, "set: packet format"); 746 + #endif 747 + 748 + switch(packetFormat) { 749 + case packetLengthVar: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) | MASK_PACKETCONFIG1_PAKET_FORMAT_VARIABLE) ); 750 + case packetLengthFix: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_PAKET_FORMAT_VARIABLE) ); 751 + default: INVALID_PARAM; 752 + } 753 + } 754 + 755 + int rf69_set_crc_enable(struct spi_device *spi, enum optionOnOff optionOnOff) 756 + { 757 + #ifdef DEBUG 758 + dev_dbg(&spi->dev, "set: crc enable"); 759 + #endif 760 + 761 + switch(optionOnOff) { 762 + case optionOn: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) | MASK_PACKETCONFIG1_CRC_ON) ); 763 + case optionOff: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_CRC_ON) ); 764 + default: INVALID_PARAM; 765 + } 766 + } 767 + 768 + int rf69_set_adressFiltering(struct spi_device *spi, enum addressFiltering addressFiltering) 769 + { 770 + #ifdef DEBUG 771 + dev_dbg(&spi->dev, "set: address filtering"); 772 + #endif 773 + 774 + switch (addressFiltering) { 775 + case filteringOff: return WRITE_REG(REG_PACKETCONFIG1, ( (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_ADDRESSFILTERING) | PACKETCONFIG1_ADDRESSFILTERING_OFF) ); 776 + case nodeAddress: return WRITE_REG(REG_PACKETCONFIG1, ( (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_ADDRESSFILTERING) | PACKETCONFIG1_ADDRESSFILTERING_NODE) ); 777 + case nodeOrBroadcastAddress: return WRITE_REG(REG_PACKETCONFIG1, ( (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_ADDRESSFILTERING) | PACKETCONFIG1_ADDRESSFILTERING_NODEBROADCAST) ); 778 + default: INVALID_PARAM; 779 + } 780 + } 781 + 782 + int rf69_set_payload_length(struct spi_device *spi, u8 payloadLength) 783 + { 784 + #ifdef DEBUG 785 + dev_dbg(&spi->dev, "set: payload length"); 786 + #endif 787 + 788 + return WRITE_REG(REG_PAYLOAD_LENGTH, payloadLength); 789 + } 790 + 791 + u8 rf69_get_payload_length(struct spi_device *spi) 792 + { 793 + #ifdef DEBUG 794 + dev_dbg(&spi->dev, "get: payload length"); 795 + #endif 796 + 797 + return (u8) READ_REG(REG_PAYLOAD_LENGTH); 798 + } 799 + 800 + int rf69_set_node_address(struct spi_device *spi, u8 nodeAddress) 801 + { 802 + #ifdef DEBUG 803 + dev_dbg(&spi->dev, "set: node address"); 804 + #endif 805 + 806 + return WRITE_REG(REG_NODEADRS, nodeAddress); 807 + } 808 + 809 + int rf69_set_broadcast_address(struct spi_device *spi, u8 broadcastAddress) 810 + { 811 + #ifdef DEBUG 812 + dev_dbg(&spi->dev, "set: broadcast address"); 813 + #endif 814 + 815 + return WRITE_REG(REG_BROADCASTADRS, broadcastAddress); 816 + } 817 + 818 + int rf69_set_tx_start_condition(struct spi_device *spi, enum txStartCondition txStartCondition) 819 + { 820 + #ifdef DEBUG 821 + dev_dbg(&spi->dev, "set: start condition"); 822 + #endif 823 + 824 + switch(txStartCondition) { 825 + case fifoLevel: return WRITE_REG(REG_FIFO_THRESH, (READ_REG(REG_FIFO_THRESH) & ~MASK_FIFO_THRESH_TXSTART) ); 826 + case fifoNotEmpty: return WRITE_REG(REG_FIFO_THRESH, (READ_REG(REG_FIFO_THRESH) | MASK_FIFO_THRESH_TXSTART) ); 827 + default: INVALID_PARAM; 828 + } 829 + } 830 + 831 + int rf69_set_fifo_threshold(struct spi_device *spi, u8 threshold) 832 + { 833 + int retval; 834 + 835 + #ifdef DEBUG 836 + dev_dbg(&spi->dev, "set: fifo threshold"); 837 + #endif 838 + 839 + // check input value 840 + if (threshold & 0x80) 841 + INVALID_PARAM; 842 + 843 + // write value 844 + retval = WRITE_REG(REG_FIFO_THRESH, (READ_REG(REG_FIFO_THRESH) & ~MASK_FIFO_THRESH_VALUE) | threshold); 845 + if (retval) 846 + return retval; 847 + 848 + // access the fifo to activate new threshold 849 + return rf69_read_fifo (spi, (u8*) &retval, 1); // retval used as buffer 850 + } 851 + 852 + int rf69_set_dagc(struct spi_device *spi, enum dagc dagc) 853 + { 854 + #ifdef DEBUG 855 + dev_dbg(&spi->dev, "set: dagc"); 856 + #endif 857 + 858 + switch(dagc) { 859 + case normalMode: return WRITE_REG(REG_TESTDAGC, DAGC_NORMAL); 860 + case improve: return WRITE_REG(REG_TESTDAGC, DAGC_IMPROVED_LOWBETA0); 861 + case improve4LowModulationIndex: return WRITE_REG(REG_TESTDAGC, DAGC_IMPROVED_LOWBETA1); 862 + default: INVALID_PARAM; 863 + } 864 + } 865 + 866 + /*-------------------------------------------------------------------------*/ 867 + 868 + int rf69_read_fifo (struct spi_device *spi, u8 *buffer, unsigned int size) 869 + { 870 + #ifdef DEBUG_FIFO_ACCESS 871 + int i; 872 + #endif 873 + struct spi_transfer transfer; 874 + u8 local_buffer[FIFO_SIZE + 1]; 875 + int retval; 876 + 877 + if (size > FIFO_SIZE) 878 + { 879 + #ifdef DEBUG 880 + dev_dbg(&spi->dev, "read fifo: passed in buffer bigger then internal buffer \n"); 881 + #endif 882 + return -EMSGSIZE; 883 + } 884 + 885 + /* prepare a bidirectional transfer */ 886 + local_buffer[0] = REG_FIFO; 887 + memset(&transfer, 0, sizeof(transfer)); 888 + transfer.tx_buf = local_buffer; 889 + transfer.rx_buf = local_buffer; 890 + transfer.len = size+1; 891 + 892 + retval = spi_sync_transfer(spi, &transfer, 1); 893 + 894 + #ifdef DEBUG_FIFO_ACCESS 895 + for (i=0; i<size; i++) 896 + dev_dbg(&spi->dev, "%d - 0x%x\n", i, local_buffer[i+1]); 897 + #endif 898 + 899 + memcpy(buffer, &local_buffer[1], size); // TODO: ohne memcopy w�re sch�ner 900 + 901 + return retval; 902 + } 903 + 904 + int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size) 905 + { 906 + #ifdef DEBUG_FIFO_ACCESS 907 + int i; 908 + #endif 909 + char spi_address = REG_FIFO | WRITE_BIT; 910 + u8 local_buffer[FIFO_SIZE + 1]; 911 + 912 + if (size > FIFO_SIZE) 913 + { 914 + #ifdef DEBUG 915 + dev_dbg(&spi->dev, "read fifo: passed in buffer bigger then internal buffer \n"); 916 + #endif 917 + return -EMSGSIZE; 918 + } 919 + 920 + local_buffer[0] = spi_address; 921 + memcpy(&local_buffer[1], buffer, size); // TODO: ohne memcopy w�re sch�ner 922 + 923 + #ifdef DEBUG_FIFO_ACCESS 924 + for (i=0; i<size; i++) 925 + dev_dbg(&spi->dev, "0x%x\n",buffer[i]); 926 + #endif 927 + 928 + return spi_write (spi, local_buffer, size + 1); 929 + } 930 + 931 + /*-------------------------------------------------------------------------*/ 932 + 933 + u8 rf69_read_reg(struct spi_device *spi, u8 addr) 934 + { 935 + int retval; 936 + 937 + retval = spi_w8r8(spi, addr); 938 + 939 + #ifdef DEBUG_VALUES 940 + if (retval < 0) 941 + /* should never happen, since we already checked, 942 + that module is connected. Therefore no error 943 + handling, just an optional error message... */ 944 + dev_dbg(&spi->dev, "read 0x%x FAILED\n", 945 + addr); 946 + else 947 + dev_dbg(&spi->dev, "read 0x%x from reg 0x%x\n", 948 + retval, 949 + addr); 950 + #endif 951 + 952 + return retval; 953 + } 954 + 955 + int rf69_write_reg(struct spi_device *spi, u8 addr, u8 value) 956 + { 957 + int retval; 958 + char buffer[2]; 959 + 960 + buffer[0] = addr | WRITE_BIT; 961 + buffer[1] = value; 962 + 963 + retval = spi_write(spi, &buffer, 2); 964 + 965 + #ifdef DEBUG_VALUES 966 + if (retval < 0) 967 + /* should never happen, since we already checked, 968 + that module is connected. Therefore no error 969 + handling, just an optional error message... */ 970 + dev_dbg(&spi->dev, "write 0x%x to 0x%x FAILED\n", 971 + value, 972 + addr); 973 + else 974 + dev_dbg(&spi->dev, "wrote 0x%x to reg 0x%x\n", 975 + value, 976 + addr); 977 + #endif 978 + 979 + return retval; 980 + } 981 + 982 +
+82
drivers/staging/pi433/rf69.h
··· 1 + /* 2 + * hardware abstraction/register access for HopeRf rf69 radio module 3 + * 4 + * Copyright (C) 2016 Wolf-Entwicklungen 5 + * Marcus Wolf <linux@wolf-entwicklungen.de> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + */ 17 + #ifndef RF69_H 18 + #define RF69_H 19 + 20 + #include "rf69_enum.h" 21 + #include "rf69_registers.h" 22 + 23 + #define F_OSC 32000000 /* in Hz */ 24 + #define FREQUENCY 433920000 /* in Hz, modifying this value impacts CE certification */ 25 + #define FIFO_SIZE 66 /* in byte */ 26 + #define FIFO_THRESHOLD 15 /* in byte */ 27 + 28 + int rf69_set_mode(struct spi_device *spi, enum mode mode); 29 + int rf69_set_data_mode(struct spi_device *spi, enum dataMode dataMode); 30 + int rf69_set_modulation(struct spi_device *spi, enum modulation modulation); 31 + enum modulation rf69_get_modulation(struct spi_device *spi); 32 + int rf69_set_modulation_shaping(struct spi_device *spi, enum modShaping modShaping); 33 + int rf69_set_bit_rate(struct spi_device *spi, u16 bitRate); 34 + int rf69_set_deviation(struct spi_device *spi, u32 deviation); 35 + int rf69_set_frequency(struct spi_device *spi, u32 frequency); 36 + int rf69_set_amplifier_0(struct spi_device *spi, enum optionOnOff optionOnOff); 37 + int rf69_set_amplifier_1(struct spi_device *spi, enum optionOnOff optionOnOff); 38 + int rf69_set_amplifier_2(struct spi_device *spi, enum optionOnOff optionOnOff); 39 + int rf69_set_output_power_level(struct spi_device *spi, u8 powerLevel); 40 + int rf69_set_pa_ramp(struct spi_device *spi, enum paRamp paRamp); 41 + int rf69_set_antenna_impedance(struct spi_device *spi, enum antennaImpedance antennaImpedance); 42 + int rf69_set_lna_gain(struct spi_device *spi, enum lnaGain lnaGain); 43 + enum lnaGain rf69_get_lna_gain(struct spi_device *spi); 44 + int rf69_set_dc_cut_off_frequency_intern(struct spi_device *spi, u8 reg, enum dccPercent dccPercent); 45 + int rf69_set_dc_cut_off_frequency(struct spi_device *spi, enum dccPercent dccPercent); 46 + int rf69_set_dc_cut_off_frequency_during_afc(struct spi_device *spi, enum dccPercent dccPercent); 47 + int rf69_set_bandwidth(struct spi_device *spi, enum mantisse mantisse, u8 exponent); 48 + int rf69_set_bandwidth_during_afc(struct spi_device *spi, enum mantisse mantisse, u8 exponent); 49 + int rf69_set_ook_threshold_type(struct spi_device *spi, enum thresholdType thresholdType); 50 + int rf69_set_ook_threshold_step(struct spi_device *spi, enum thresholdStep thresholdStep); 51 + int rf69_set_ook_threshold_dec(struct spi_device *spi, enum thresholdDecrement thresholdDecrement); 52 + int rf69_set_dio_mapping(struct spi_device *spi, u8 DIONumber, u8 value); 53 + bool rf69_get_flag(struct spi_device *spi, enum flag flag); 54 + int rf69_reset_flag(struct spi_device *spi, enum flag flag); 55 + int rf69_set_rssi_threshold(struct spi_device *spi, u8 threshold); 56 + int rf69_set_rx_start_timeout(struct spi_device *spi, u8 timeout); 57 + int rf69_set_rssi_timeout(struct spi_device *spi, u8 timeout); 58 + int rf69_set_preamble_length(struct spi_device *spi, u16 preambleLength); 59 + int rf69_set_sync_enable(struct spi_device *spi, enum optionOnOff optionOnOff); 60 + int rf69_set_fifo_fill_condition(struct spi_device *spi, enum fifoFillCondition fifoFillCondition); 61 + int rf69_set_sync_size(struct spi_device *spi, u8 sync_size); 62 + int rf69_set_sync_tolerance(struct spi_device *spi, u8 syncTolerance); 63 + int rf69_set_sync_values(struct spi_device *spi, u8 syncValues[8]); 64 + int rf69_set_packet_format(struct spi_device * spi, enum packetFormat packetFormat); 65 + int rf69_set_crc_enable(struct spi_device *spi, enum optionOnOff optionOnOff); 66 + int rf69_set_adressFiltering(struct spi_device *spi, enum addressFiltering addressFiltering); 67 + int rf69_set_payload_length(struct spi_device *spi, u8 payloadLength); 68 + u8 rf69_get_payload_length(struct spi_device *spi); 69 + int rf69_set_node_address(struct spi_device *spi, u8 nodeAddress); 70 + int rf69_set_broadcast_address(struct spi_device *spi, u8 broadcastAddress); 71 + int rf69_set_tx_start_condition(struct spi_device *spi, enum txStartCondition txStartCondition); 72 + int rf69_set_fifo_threshold(struct spi_device *spi, u8 threshold); 73 + int rf69_set_dagc(struct spi_device *spi, enum dagc dagc); 74 + 75 + int rf69_read_fifo (struct spi_device *spi, u8 *buffer, unsigned int size); 76 + int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size); 77 + 78 + u8 rf69_read_reg (struct spi_device *spi, u8 addr); 79 + int rf69_write_reg(struct spi_device *spi, u8 addr, u8 value); 80 + 81 + 82 + #endif
+201
drivers/staging/pi433/rf69_enum.h
··· 1 + /* 2 + * enumerations for HopeRf rf69 radio module 3 + * 4 + * Copyright (C) 2016 Wolf-Entwicklungen 5 + * Marcus Wolf <linux@wolf-entwicklungen.de> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + */ 17 + 18 + #ifndef RF69_ENUM_H 19 + #define RF69_ENUM_H 20 + 21 + enum optionOnOff 22 + { 23 + optionOff, 24 + optionOn 25 + }; 26 + 27 + enum mode 28 + { 29 + mode_sleep, 30 + standby, 31 + synthesizer, 32 + transmit, 33 + receive 34 + }; 35 + 36 + enum dataMode 37 + { 38 + packet, 39 + continuous, 40 + continuousNoSync 41 + }; 42 + 43 + enum modulation 44 + { 45 + OOK, 46 + FSK 47 + }; 48 + 49 + enum modShaping 50 + { 51 + shapingOff, 52 + shaping1_0, 53 + shaping0_5, 54 + shaping0_3, 55 + shapingBR, 56 + shaping2BR 57 + }; 58 + 59 + enum paRamp 60 + { 61 + ramp3400, 62 + ramp2000, 63 + ramp1000, 64 + ramp500, 65 + ramp250, 66 + ramp125, 67 + ramp100, 68 + ramp62, 69 + ramp50, 70 + ramp40, 71 + ramp31, 72 + ramp25, 73 + ramp20, 74 + ramp15, 75 + ramp12, 76 + ramp10 77 + }; 78 + 79 + enum antennaImpedance 80 + { 81 + fiftyOhm, 82 + twohundretOhm 83 + }; 84 + 85 + enum lnaGain 86 + { 87 + automatic, 88 + max, 89 + maxMinus6, 90 + maxMinus12, 91 + maxMinus24, 92 + maxMinus36, 93 + maxMinus48, 94 + undefined 95 + }; 96 + 97 + enum dccPercent 98 + { 99 + dcc16Percent, 100 + dcc8Percent, 101 + dcc4Percent, 102 + dcc2Percent, 103 + dcc1Percent, 104 + dcc0_5Percent, 105 + dcc0_25Percent, 106 + dcc0_125Percent 107 + }; 108 + 109 + enum mantisse 110 + { 111 + mantisse16, 112 + mantisse20, 113 + mantisse24 114 + }; 115 + 116 + enum thresholdType 117 + { 118 + fixed, 119 + peak, 120 + average 121 + }; 122 + 123 + enum thresholdStep 124 + { 125 + step_0_5db, 126 + step_1_0db, 127 + step_1_5db, 128 + step_2_0db, 129 + step_3_0db, 130 + step_4_0db, 131 + step_5_0db, 132 + step_6_0db 133 + }; 134 + 135 + enum thresholdDecrement 136 + { 137 + dec_every8th, 138 + dec_every4th, 139 + dec_every2nd, 140 + dec_once, 141 + dec_twice, 142 + dec_4times, 143 + dec_8times, 144 + dec_16times 145 + }; 146 + 147 + enum flag 148 + { 149 + modeSwitchCompleted, 150 + readyToReceive, 151 + readyToSend, 152 + pllLocked, 153 + rssiExceededThreshold, 154 + timeout, 155 + automode, 156 + syncAddressMatch, 157 + fifoFull, 158 + // fifoNotEmpty, collision with next enum; replaced by following enum... 159 + fifoEmpty, 160 + fifoLevelBelowThreshold, 161 + fifoOverrun, 162 + packetSent, 163 + payloadReady, 164 + crcOk, 165 + batteryLow 166 + }; 167 + 168 + enum fifoFillCondition 169 + { 170 + afterSyncInterrupt, 171 + always 172 + }; 173 + 174 + enum packetFormat 175 + { 176 + packetLengthFix, 177 + packetLengthVar 178 + }; 179 + 180 + enum txStartCondition 181 + { 182 + fifoLevel, 183 + fifoNotEmpty 184 + }; 185 + 186 + enum addressFiltering 187 + { 188 + filteringOff, 189 + nodeAddress, 190 + nodeOrBroadcastAddress 191 + }; 192 + 193 + enum dagc 194 + { 195 + normalMode, 196 + improve, 197 + improve4LowModulationIndex 198 + }; 199 + 200 + 201 + #endif
+489
drivers/staging/pi433/rf69_registers.h
··· 1 + /* 2 + * register description for HopeRf rf69 radio module 3 + * 4 + * Copyright (C) 2016 Wolf-Entwicklungen 5 + * Marcus Wolf <linux@wolf-entwicklungen.de> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + */ 17 + 18 + /*******************************************/ 19 + /* RF69 register addresses */ 20 + /*******************************************/ 21 + #define REG_FIFO 0x00 22 + #define REG_OPMODE 0x01 23 + #define REG_DATAMODUL 0x02 24 + #define REG_BITRATE_MSB 0x03 25 + #define REG_BITRATE_LSB 0x04 26 + #define REG_FDEV_MSB 0x05 27 + #define REG_FDEV_LSB 0x06 28 + #define REG_FRF_MSB 0x07 29 + #define REG_FRF_MID 0x08 30 + #define REG_FRF_LSB 0x09 31 + #define REG_OSC1 0x0A 32 + #define REG_AFCCTRL 0x0B 33 + #define REG_LOWBAT 0x0C 34 + #define REG_LISTEN1 0x0D 35 + #define REG_LISTEN2 0x0E 36 + #define REG_LISTEN3 0x0F 37 + #define REG_VERSION 0x10 38 + #define REG_PALEVEL 0x11 39 + #define REG_PARAMP 0x12 40 + #define REG_OCP 0x13 41 + #define REG_AGCREF 0x14 /* not available on RF69 */ 42 + #define REG_AGCTHRESH1 0x15 /* not available on RF69 */ 43 + #define REG_AGCTHRESH2 0x16 /* not available on RF69 */ 44 + #define REG_AGCTHRESH3 0x17 /* not available on RF69 */ 45 + #define REG_LNA 0x18 46 + #define REG_RXBW 0x19 47 + #define REG_AFCBW 0x1A 48 + #define REG_OOKPEAK 0x1B 49 + #define REG_OOKAVG 0x1C 50 + #define REG_OOKFIX 0x1D 51 + #define REG_AFCFEI 0x1E 52 + #define REG_AFCMSB 0x1F 53 + #define REG_AFCLSB 0x20 54 + #define REG_FEIMSB 0x21 55 + #define REG_FEILSB 0x22 56 + #define REG_RSSICONFIG 0x23 57 + #define REG_RSSIVALUE 0x24 58 + #define REG_DIOMAPPING1 0x25 59 + #define REG_DIOMAPPING2 0x26 60 + #define REG_IRQFLAGS1 0x27 61 + #define REG_IRQFLAGS2 0x28 62 + #define REG_RSSITHRESH 0x29 63 + #define REG_RXTIMEOUT1 0x2A 64 + #define REG_RXTIMEOUT2 0x2B 65 + #define REG_PREAMBLE_MSB 0x2C 66 + #define REG_PREAMBLE_LSB 0x2D 67 + #define REG_SYNC_CONFIG 0x2E 68 + #define REG_SYNCVALUE1 0x2F 69 + #define REG_SYNCVALUE2 0x30 70 + #define REG_SYNCVALUE3 0x31 71 + #define REG_SYNCVALUE4 0x32 72 + #define REG_SYNCVALUE5 0x33 73 + #define REG_SYNCVALUE6 0x34 74 + #define REG_SYNCVALUE7 0x35 75 + #define REG_SYNCVALUE8 0x36 76 + #define REG_PACKETCONFIG1 0x37 77 + #define REG_PAYLOAD_LENGTH 0x38 78 + #define REG_NODEADRS 0x39 79 + #define REG_BROADCASTADRS 0x3A 80 + #define REG_AUTOMODES 0x3B 81 + #define REG_FIFO_THRESH 0x3C 82 + #define REG_PACKETCONFIG2 0x3D 83 + #define REG_AESKEY1 0x3E 84 + #define REG_AESKEY2 0x3F 85 + #define REG_AESKEY3 0x40 86 + #define REG_AESKEY4 0x41 87 + #define REG_AESKEY5 0x42 88 + #define REG_AESKEY6 0x43 89 + #define REG_AESKEY7 0x44 90 + #define REG_AESKEY8 0x45 91 + #define REG_AESKEY9 0x46 92 + #define REG_AESKEY10 0x47 93 + #define REG_AESKEY11 0x48 94 + #define REG_AESKEY12 0x49 95 + #define REG_AESKEY13 0x4A 96 + #define REG_AESKEY14 0x4B 97 + #define REG_AESKEY15 0x4C 98 + #define REG_AESKEY16 0x4D 99 + #define REG_TEMP1 0x4E 100 + #define REG_TEMP2 0x4F 101 + #define REG_TESTPA1 0x5A /* only present on RFM69HW */ 102 + #define REG_TESTPA2 0x5C /* only present on RFM69HW */ 103 + #define REG_TESTDAGC 0x6F 104 + 105 + /******************************************************/ 106 + /* RF69/SX1231 bit definition */ 107 + /******************************************************/ 108 + /* write bit */ 109 + #define WRITE_BIT 0x80 110 + 111 + /* RegOpMode */ 112 + #define MASK_OPMODE_SEQUENCER_OFF 0x80 113 + #define MASK_OPMODE_LISTEN_ON 0x40 114 + #define MASK_OPMODE_LISTEN_ABORT 0x20 115 + #define MASK_OPMODE_MODE 0x1C 116 + 117 + #define OPMODE_MODE_SLEEP 0x00 118 + #define OPMODE_MODE_STANDBY 0x04 /* default */ 119 + #define OPMODE_MODE_SYNTHESIZER 0x08 120 + #define OPMODE_MODE_TRANSMIT 0x0C 121 + #define OPMODE_MODE_RECEIVE 0x10 122 + 123 + /* RegDataModul */ 124 + #define MASK_DATAMODUL_MODE 0x06 125 + #define MASK_DATAMODUL_MODULATION_TYPE 0x18 126 + #define MASK_DATAMODUL_MODULATION_SHAPE 0x03 127 + 128 + #define DATAMODUL_MODE_PACKET 0x00 /* default */ 129 + #define DATAMODUL_MODE_CONTINUOUS 0x40 130 + #define DATAMODUL_MODE_CONTINUOUS_NOSYNC 0x60 131 + 132 + #define DATAMODUL_MODULATION_TYPE_FSK 0x00 /* default */ 133 + #define DATAMODUL_MODULATION_TYPE_OOK 0x08 134 + 135 + #define DATAMODUL_MODULATION_SHAPE_NONE 0x00 /* default */ 136 + #define DATAMODUL_MODULATION_SHAPE_1_0 0x01 137 + #define DATAMODUL_MODULATION_SHAPE_0_5 0x02 138 + #define DATAMODUL_MODULATION_SHAPE_0_3 0x03 139 + #define DATAMODUL_MODULATION_SHAPE_BR 0x01 140 + #define DATAMODUL_MODULATION_SHAPE_2BR 0x02 141 + 142 + /* RegFDevMsb (0x05)*/ 143 + #define FDEVMASB_MASK 0x3f 144 + 145 + /* 146 + // RegOsc1 147 + #define OSC1_RCCAL_START 0x80 148 + #define OSC1_RCCAL_DONE 0x40 149 + 150 + // RegLowBat 151 + #define LOWBAT_MONITOR 0x10 152 + #define LOWBAT_ON 0x08 153 + #define LOWBAT_OFF 0x00 // Default 154 + 155 + #define LOWBAT_TRIM_1695 0x00 156 + #define LOWBAT_TRIM_1764 0x01 157 + #define LOWBAT_TRIM_1835 0x02 // Default 158 + #define LOWBAT_TRIM_1905 0x03 159 + #define LOWBAT_TRIM_1976 0x04 160 + #define LOWBAT_TRIM_2045 0x05 161 + #define LOWBAT_TRIM_2116 0x06 162 + #define LOWBAT_TRIM_2185 0x07 163 + 164 + 165 + // RegListen1 166 + #define LISTEN1_RESOL_64 0x50 167 + #define LISTEN1_RESOL_4100 0xA0 // Default 168 + #define LISTEN1_RESOL_262000 0xF0 169 + 170 + #define LISTEN1_CRITERIA_RSSI 0x00 // Default 171 + #define LISTEN1_CRITERIA_RSSIANDSYNC 0x08 172 + 173 + #define LISTEN1_END_00 0x00 174 + #define LISTEN1_END_01 0x02 // Default 175 + #define LISTEN1_END_10 0x04 176 + 177 + 178 + // RegListen2 179 + #define LISTEN2_COEFIDLE_VALUE 0xF5 // Default 180 + 181 + // RegListen3 182 + #define LISTEN3_COEFRX_VALUE 0x20 // Default 183 + */ 184 + 185 + // RegPaLevel 186 + #define MASK_PALEVEL_PA0 0x80 187 + #define MASK_PALEVEL_PA1 0x40 188 + #define MASK_PALEVEL_PA2 0x20 189 + #define MASK_PALEVEL_OUTPUT_POWER 0x1F 190 + 191 + 192 + 193 + // RegPaRamp 194 + #define PARAMP_3400 0x00 195 + #define PARAMP_2000 0x01 196 + #define PARAMP_1000 0x02 197 + #define PARAMP_500 0x03 198 + #define PARAMP_250 0x04 199 + #define PARAMP_125 0x05 200 + #define PARAMP_100 0x06 201 + #define PARAMP_62 0x07 202 + #define PARAMP_50 0x08 203 + #define PARAMP_40 0x09 /* default */ 204 + #define PARAMP_31 0x0A 205 + #define PARAMP_25 0x0B 206 + #define PARAMP_20 0x0C 207 + #define PARAMP_15 0x0D 208 + #define PARAMP_12 0x0E 209 + #define PARAMP_10 0x0F 210 + 211 + #define MASK_PARAMP 0x0F 212 + 213 + /* 214 + // RegOcp 215 + #define OCP_OFF 0x0F 216 + #define OCP_ON 0x1A // Default 217 + 218 + #define OCP_TRIM_45 0x00 219 + #define OCP_TRIM_50 0x01 220 + #define OCP_TRIM_55 0x02 221 + #define OCP_TRIM_60 0x03 222 + #define OCP_TRIM_65 0x04 223 + #define OCP_TRIM_70 0x05 224 + #define OCP_TRIM_75 0x06 225 + #define OCP_TRIM_80 0x07 226 + #define OCP_TRIM_85 0x08 227 + #define OCP_TRIM_90 0x09 228 + #define OCP_TRIM_95 0x0A 229 + #define OCP_TRIM_100 0x0B // Default 230 + #define OCP_TRIM_105 0x0C 231 + #define OCP_TRIM_110 0x0D 232 + #define OCP_TRIM_115 0x0E 233 + #define OCP_TRIM_120 0x0F 234 + */ 235 + 236 + /* RegLna (0x18) */ 237 + #define MASK_LNA_ZIN 0x80 238 + #define MASK_LNA_CURRENT_GAIN 0x38 239 + #define MASK_LNA_GAIN 0x07 240 + 241 + #define LNA_GAIN_AUTO 0x00 /* default */ 242 + #define LNA_GAIN_MAX 0x01 243 + #define LNA_GAIN_MAX_MINUS_6 0x02 244 + #define LNA_GAIN_MAX_MINUS_12 0x03 245 + #define LNA_GAIN_MAX_MINUS_24 0x04 246 + #define LNA_GAIN_MAX_MINUS_36 0x05 247 + #define LNA_GAIN_MAX_MINUS_48 0x06 248 + 249 + 250 + /* RegRxBw (0x19) and RegAfcBw (0x1A) */ 251 + #define MASK_BW_DCC_FREQ 0xE0 252 + #define MASK_BW_MANTISSE 0x18 253 + #define MASK_BW_EXPONENT 0x07 254 + 255 + #define BW_DCC_16_PERCENT 0x00 256 + #define BW_DCC_8_PERCENT 0x20 257 + #define BW_DCC_4_PERCENT 0x40 /* default */ 258 + #define BW_DCC_2_PERCENT 0x60 259 + #define BW_DCC_1_PERCENT 0x80 260 + #define BW_DCC_0_5_PERCENT 0xA0 261 + #define BW_DCC_0_25_PERCENT 0xC0 262 + #define BW_DCC_0_125_PERCENT 0xE0 263 + 264 + #define BW_MANT_16 0x00 265 + #define BW_MANT_20 0x08 266 + #define BW_MANT_24 0x10 /* default */ 267 + 268 + 269 + /* RegOokPeak (0x1B) */ 270 + #define MASK_OOKPEAK_THRESTYPE 0xc0 271 + #define MASK_OOKPEAK_THRESSTEP 0x38 272 + #define MASK_OOKPEAK_THRESDEC 0x07 273 + 274 + #define OOKPEAK_THRESHTYPE_FIXED 0x00 275 + #define OOKPEAK_THRESHTYPE_PEAK 0x40 /* default */ 276 + #define OOKPEAK_THRESHTYPE_AVERAGE 0x80 277 + 278 + #define OOKPEAK_THRESHSTEP_0_5_DB 0x00 /* default */ 279 + #define OOKPEAK_THRESHSTEP_1_0_DB 0x08 280 + #define OOKPEAK_THRESHSTEP_1_5_DB 0x10 281 + #define OOKPEAK_THRESHSTEP_2_0_DB 0x18 282 + #define OOKPEAK_THRESHSTEP_3_0_DB 0x20 283 + #define OOKPEAK_THRESHSTEP_4_0_DB 0x28 284 + #define OOKPEAK_THRESHSTEP_5_0_DB 0x30 285 + #define OOKPEAK_THRESHSTEP_6_0_DB 0x38 286 + 287 + #define OOKPEAK_THRESHDEC_ONCE 0x00 /* default */ 288 + #define OOKPEAK_THRESHDEC_EVERY_2ND 0x01 289 + #define OOKPEAK_THRESHDEC_EVERY_4TH 0x02 290 + #define OOKPEAK_THRESHDEC_EVERY_8TH 0x03 291 + #define OOKPEAK_THRESHDEC_TWICE 0x04 292 + #define OOKPEAK_THRESHDEC_4_TIMES 0x05 293 + #define OOKPEAK_THRESHDEC_8_TIMES 0x06 294 + #define OOKPEAK_THRESHDEC_16_TIMES 0x07 295 + 296 + /* 297 + // RegOokAvg 298 + #define OOKAVG_AVERAGETHRESHFILT_00 0x00 299 + #define OOKAVG_AVERAGETHRESHFILT_01 0x40 300 + #define OOKAVG_AVERAGETHRESHFILT_10 0x80 // Default 301 + #define OOKAVG_AVERAGETHRESHFILT_11 0xC0 302 + 303 + 304 + // RegAfcFei 305 + #define AFCFEI_FEI_DONE 0x40 306 + #define AFCFEI_FEI_START 0x20 307 + #define AFCFEI_AFC_DONE 0x10 308 + #define AFCFEI_AFCAUTOCLEAR_ON 0x08 309 + #define AFCFEI_AFCAUTOCLEAR_OFF 0x00 // Default 310 + 311 + #define AFCFEI_AFCAUTO_ON 0x04 312 + #define AFCFEI_AFCAUTO_OFF 0x00 // Default 313 + 314 + #define AFCFEI_AFC_CLEAR 0x02 315 + #define AFCFEI_AFC_START 0x01 316 + 317 + // RegRssiConfig 318 + #define RSSI_FASTRX_ON 0x08 319 + #define RSSI_FASTRX_OFF 0x00 // Default 320 + #define RSSI_DONE 0x02 321 + #define RSSI_START 0x01 322 + */ 323 + 324 + /* RegDioMapping1 */ 325 + #define MASK_DIO0 0xC0 326 + #define MASK_DIO1 0x30 327 + #define MASK_DIO2 0x0C 328 + #define MASK_DIO3 0x03 329 + #define SHIFT_DIO0 6 330 + #define SHIFT_DIO1 4 331 + #define SHIFT_DIO2 2 332 + #define SHIFT_DIO3 0 333 + 334 + /* RegDioMapping2 */ 335 + #define MASK_DIO4 0xC0 336 + #define MASK_DIO5 0x30 337 + #define SHIFT_DIO4 6 338 + #define SHIFT_DIO5 4 339 + 340 + /* DIO numbers */ 341 + #define DIO0 0 342 + #define DIO1 1 343 + #define DIO2 2 344 + #define DIO3 3 345 + #define DIO4 4 346 + #define DIO5 5 347 + 348 + /* DIO Mapping values (packet mode) */ 349 + #define DIO_ModeReady_DIO4 0x00 350 + #define DIO_ModeReady_DIO5 0x03 351 + #define DIO_ClkOut 0x00 352 + #define DIO_Data 0x01 353 + #define DIO_TimeOut_DIO1 0x03 354 + #define DIO_TimeOut_DIO4 0x00 355 + #define DIO_Rssi_DIO0 0x03 356 + #define DIO_Rssi_DIO3_4 0x01 357 + #define DIO_RxReady 0x02 358 + #define DIO_PLLLock 0x03 359 + #define DIO_TxReady 0x01 360 + #define DIO_FifoFull_DIO1 0x01 361 + #define DIO_FifoFull_DIO3 0x00 362 + #define DIO_SyncAddress 0x02 363 + #define DIO_FifoNotEmpty_DIO1 0x02 364 + #define DIO_FifoNotEmpty_FIO2 0x00 365 + #define DIO_Automode 0x04 366 + #define DIO_FifoLevel 0x00 367 + #define DIO_CrcOk 0x00 368 + #define DIO_PayloadReady 0x01 369 + #define DIO_PacketSent 0x00 370 + #define DIO_Dclk 0x00 371 + 372 + /* RegDioMapping2 CLK_OUT part */ 373 + #define MASK_DIOMAPPING2_CLK_OUT 0x07 374 + 375 + #define DIOMAPPING2_CLK_OUT_NO_DIV 0x00 376 + #define DIOMAPPING2_CLK_OUT_DIV_2 0x01 377 + #define DIOMAPPING2_CLK_OUT_DIV_4 0x02 378 + #define DIOMAPPING2_CLK_OUT_DIV_8 0x03 379 + #define DIOMAPPING2_CLK_OUT_DIV_16 0x04 380 + #define DIOMAPPING2_CLK_OUT_DIV_32 0x05 381 + #define DIOMAPPING2_CLK_OUT_RC 0x06 382 + #define DIOMAPPING2_CLK_OUT_OFF 0x07 /* default */ 383 + 384 + /* RegIrqFlags1 */ 385 + #define MASK_IRQFLAGS1_MODE_READY 0x80 386 + #define MASK_IRQFLAGS1_RX_READY 0x40 387 + #define MASK_IRQFLAGS1_TX_READY 0x20 388 + #define MASK_IRQFLAGS1_PLL_LOCK 0x10 389 + #define MASK_IRQFLAGS1_RSSI 0x08 390 + #define MASK_IRQFLAGS1_TIMEOUT 0x04 391 + #define MASK_IRQFLAGS1_AUTOMODE 0x02 392 + #define MASK_IRQFLAGS1_SYNC_ADDRESS_MATCH 0x01 393 + 394 + /* RegIrqFlags2 */ 395 + #define MASK_IRQFLAGS2_FIFO_FULL 0x80 396 + #define MASK_IRQFLAGS2_FIFO_NOT_EMPTY 0x40 397 + #define MASK_IRQFLAGS2_FIFO_LEVEL 0x20 398 + #define MASK_IRQFLAGS2_FIFO_OVERRUN 0x10 399 + #define MASK_IRQFLAGS2_PACKET_SENT 0x08 400 + #define MASK_IRQFLAGS2_PAYLOAD_READY 0x04 401 + #define MASK_IRQFLAGS2_CRC_OK 0x02 402 + #define MASK_IRQFLAGS2_LOW_BAT 0x01 403 + 404 + /* RegSyncConfig */ 405 + #define MASK_SYNC_CONFIG_SYNC_ON 0x80 /* default */ 406 + #define MASK_SYNC_CONFIG_FIFO_FILL_CONDITION 0x40 407 + #define MASK_SYNC_CONFIG_SYNC_SIZE 0x38 408 + #define MASK_SYNC_CONFIG_SYNC_TOLERANCE 0x07 409 + 410 + /* RegPacketConfig1 */ 411 + #define MASK_PACKETCONFIG1_PAKET_FORMAT_VARIABLE 0x80 412 + #define MASK_PACKETCONFIG1_DCFREE 0x60 413 + #define MASK_PACKETCONFIG1_CRC_ON 0x10 /* default */ 414 + #define MASK_PACKETCONFIG1_CRCAUTOCLEAR_OFF 0x08 415 + #define MASK_PACKETCONFIG1_ADDRESSFILTERING 0x06 416 + 417 + #define PACKETCONFIG1_DCFREE_OFF 0x00 /* default */ 418 + #define PACKETCONFIG1_DCFREE_MANCHESTER 0x20 419 + #define PACKETCONFIG1_DCFREE_WHITENING 0x40 420 + #define PACKETCONFIG1_ADDRESSFILTERING_OFF 0x00 /* default */ 421 + #define PACKETCONFIG1_ADDRESSFILTERING_NODE 0x02 422 + #define PACKETCONFIG1_ADDRESSFILTERING_NODEBROADCAST 0x04 423 + 424 + /* 425 + // RegAutoModes 426 + #define AUTOMODES_ENTER_OFF 0x00 // Default 427 + #define AUTOMODES_ENTER_FIFONOTEMPTY 0x20 428 + #define AUTOMODES_ENTER_FIFOLEVEL 0x40 429 + #define AUTOMODES_ENTER_CRCOK 0x60 430 + #define AUTOMODES_ENTER_PAYLOADREADY 0x80 431 + #define AUTOMODES_ENTER_SYNCADRSMATCH 0xA0 432 + #define AUTOMODES_ENTER_PACKETSENT 0xC0 433 + #define AUTOMODES_ENTER_FIFOEMPTY 0xE0 434 + 435 + #define AUTOMODES_EXIT_OFF 0x00 // Default 436 + #define AUTOMODES_EXIT_FIFOEMPTY 0x04 437 + #define AUTOMODES_EXIT_FIFOLEVEL 0x08 438 + #define AUTOMODES_EXIT_CRCOK 0x0C 439 + #define AUTOMODES_EXIT_PAYLOADREADY 0x10 440 + #define AUTOMODES_EXIT_SYNCADRSMATCH 0x14 441 + #define AUTOMODES_EXIT_PACKETSENT 0x18 442 + #define AUTOMODES_EXIT_RXTIMEOUT 0x1C 443 + 444 + #define AUTOMODES_INTERMEDIATE_SLEEP 0x00 // Default 445 + #define AUTOMODES_INTERMEDIATE_STANDBY 0x01 446 + #define AUTOMODES_INTERMEDIATE_RECEIVER 0x02 447 + #define AUTOMODES_INTERMEDIATE_TRANSMITTER 0x03 448 + 449 + */ 450 + /* RegFifoThresh (0x3c) */ 451 + #define MASK_FIFO_THRESH_TXSTART 0x80 452 + #define MASK_FIFO_THRESH_VALUE 0x7F 453 + 454 + /* 455 + 456 + // RegPacketConfig2 457 + #define PACKET2_RXRESTARTDELAY_1BIT 0x00 // Default 458 + #define PACKET2_RXRESTARTDELAY_2BITS 0x10 459 + #define PACKET2_RXRESTARTDELAY_4BITS 0x20 460 + #define PACKET2_RXRESTARTDELAY_8BITS 0x30 461 + #define PACKET2_RXRESTARTDELAY_16BITS 0x40 462 + #define PACKET2_RXRESTARTDELAY_32BITS 0x50 463 + #define PACKET2_RXRESTARTDELAY_64BITS 0x60 464 + #define PACKET2_RXRESTARTDELAY_128BITS 0x70 465 + #define PACKET2_RXRESTARTDELAY_256BITS 0x80 466 + #define PACKET2_RXRESTARTDELAY_512BITS 0x90 467 + #define PACKET2_RXRESTARTDELAY_1024BITS 0xA0 468 + #define PACKET2_RXRESTARTDELAY_2048BITS 0xB0 469 + #define PACKET2_RXRESTARTDELAY_NONE 0xC0 470 + #define PACKET2_RXRESTART 0x04 471 + 472 + #define PACKET2_AUTORXRESTART_ON 0x02 // Default 473 + #define PACKET2_AUTORXRESTART_OFF 0x00 474 + 475 + #define PACKET2_AES_ON 0x01 476 + #define PACKET2_AES_OFF 0x00 // Default 477 + 478 + 479 + // RegTemp1 480 + #define TEMP1_MEAS_START 0x08 481 + #define TEMP1_MEAS_RUNNING 0x04 482 + #define TEMP1_ADCLOWPOWER_ON 0x01 // Default 483 + #define TEMP1_ADCLOWPOWER_OFF 0x00 484 + */ 485 + 486 + // RegTestDagc (0x6F) 487 + #define DAGC_NORMAL 0x00 /* Reset value */ 488 + #define DAGC_IMPROVED_LOWBETA1 0x20 489 + #define DAGC_IMPROVED_LOWBETA0 0x30 /* Recommended val */