Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hello! live your driver! #10

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export ARCH ?= arm
export CROSS_COMPILE ?= arm-linux-gnueabihf-
#export ARCH ?= arm
#export CROSS_COMPILE ?= arm-linux-gnueabihf-

obj-m += nrf24.o

Expand All @@ -9,7 +9,7 @@ CFLAGS_nrf24_if.o := -DDEBUG
CFLAGS_nrf24_hal.o := -DDEBUG
CFLAGS_nrf24_sysfs.o := -DDEBUG

KERNEL_DIR ?= ../linux
KERNEL_DIR ?= /lib/modules/`uname -r`/build

all:
make -C $(KERNEL_DIR) M=$(PWD) modules
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# nrf24

MY FORK OF https://github.com/mciupak/nrf24

* Fixed MAkefile for generic non static options, so can build on more machines unedited
* Made tx and rx address the same on nrf0 nrf0.0 nrf0.0 because my nrf24 network all is equal
* switched spinlock to mutex, gpiod_set_value now gpiod_set_value_cansleep, and threaded irq so it will work over sleepable busses like my ftdi mpsse usb to spi driver/ft2232h
* added check to write_wait_queue, so now we can control c out of it if hardware issue or no ack, before it was frozen
* added the spi device id table so tll enumerate on newer kernel versions
* Added sysfs options for set/get rf channel
* added working device tree example devicetree/rf24.dts
* added install-modules.sh script
* added nrf-kernel-fix this is helpful because the driver tends to (at least random amount of times) start with incorrect address and or channel number, this is fixed with setting the correct channel/address. That said even when it starts with correct settings it most likely wwont work without again setting the address and channel numbers. Unfortunatly it has been observed if another radio sends to it before you can set them it will keep it from functioning correctly. Last but not least usually norf0.0 can send but not receive (hrm maybe remembering backwards rx but no tx? anywho one or the other) but nrf0.1 works fine for both.

HELPFULL HINTS;
* if dmesg shows the msg/address size changing from 5 to 2 or 10 or only shows 2 or 10 and it isnt working the gpio is most likely not setup correctly (almost certainly ce pin in this scenerio)
* After running the nrf-kernel-fix script (or custom variation) make sure to send before trying to receive, dunno why but it need that order, also make sue you have a radio to send the ack because without that ack on first transmit most likely wont work until reboot.
* If using a usb to spi driver make sure to disable sleeping on the usb ports/hubs/devices

Original README.md Follows;

This is a Linux Device Driver for nRF24L01+ radio module.

## Fatures
Expand Down
70 changes: 70 additions & 0 deletions devicetree/rf24.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Device Tree overlay for PiScreen 3.5" display shield by Ozzmaker
*
*/

/dts-v1/;
/plugin/;

/ {
compatible = "brcm,bcm2835\0brcm,bcm2835\0brcm,bcm2708\0brcm,bcm2709";

fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
};
};

fragment@1 {
target = <&spidev0>;
__overlay__ {
status = "disabled";
};
};

fragment@2 {
target = <&spidev1>;
__overlay__ {
status = "disabled";
};
};

fragment@3 {
target = <&gpio>;
__overlay__ {
nrf0_pins: nrf0_pins {
brcm,pins = <24 25>;
brcm,function = <0 1>; /* in out */
};
};
};

fragment@4 {
target = <&spi0>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";


nrf0: nrf0@0 {
compatible = "nordic,nrf24";
reg = <0>; /* CS0 */
pinctrl-names = "default";
pinctrl-0 = <&nrf0_pins>;
interrupt-parent = <&gpio>;
interrupts = <24 0x2>; /* falling edge */
irq-gpio = <&gpio 24 0>;
ce-gpio = <&gpio 25 0>;
spi-max-frequency = <5000000>;
status = "okay";
};
};
};

__overrides__ {
int_pin = <&nrf0>, "interrupts:0", <&nrf0_pins>, "brcm,pins:0";
speed = <&nrf0>, "spi-max-frequency:0";
};
};
8 changes: 8 additions & 0 deletions install-module.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash
sudo modprobe -r nrf24
sudo mkdir -p /lib/modules/$(uname -r)/updates/dkms
sudo rm /lib/modules/$(uname -r)/updates/dkms/nrf24.ko
sudo cp nrf24.ko /lib/modules/$(uname -r)/updates/dkms/nrf24.ko
sudo depmod
sudo modprobe nrf24
echo 70 | sudo tee -a /sys/module/nrf24/drivers/spi\:nrf24/spi0.0/nrf24/nrf0/nrf0.0/chan
56 changes: 56 additions & 0 deletions nrf-kernel-fix
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/bin/bash
echo "nrf0 tx address b4 "
sudo cat /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/tx_address
echo 0xE1F0F0F0F0 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/tx_address
echo "nrf0 tx address after "
sudo cat /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/tx_address
echo "nrf0.0 address b4 "
sudo cat /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.0/address
echo 0xE1F0F0F0F0 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.0/address
echo "nrf0.0 address after "
sudo cat /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.0/address
echo "nrf0.1 address b4 "
sudo cat /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.1/address
echo 0xE1F0F0F0F0 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.1/address
echo "nrf0.1 address after "
sudo cat /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.1/address
echo "nrf rf chan b4 "
sudo cat /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.0/chan
echo 70 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.0/chan
echo "nrf rf chan after "
sudo cat /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.0/chan
#echo 0xE1F0F0F0F0 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/tx_address
#echo 0xE1F0F0F0F0 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.0/address
#echo 70 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.0/chan

#echo 0xF0F0F0F0E1 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.1/address
#echo 70 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.1/chan
#echo 0xE1F0F0F0F0 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.1/address
#echo 70 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.1/chan

#echo 0xF0F0F0F0E1 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/tx_address
#echo 0xF0F0F0F0E1 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.0/address
#echo 70 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.0/chan

#echo 0xF0F0F0F0E1 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.1/address
#echo 70 > /sys/module/nrf24/drivers/spi\:nrf24/spi16.0/nrf24/nrf0/nrf0.1/chan
echo "nrf0 tx_address "
sudo cat /sys/class/nrf24/nrf0/tx_address
echo -e "above line should read 0xE1F0F0F0F0 \n"
echo "nrf0.0 address "
sudo cat /sys/class/nrf24/nrf0/nrf0.0/address
echo -e "above line should read 0xE1F0F0F0F0 \n"
echo "nrf0.1 address "
sudo cat /sys/class/nrf24/nrf0/nrf0.1/address
echo -e "above line should read 0xE1F0F0F0F0 \n"

echo 'on' > '/sys/bus/usb/devices/usb3/power/control'
echo 'on' > '/sys/bus/usb/devices/usb2/power/control'
echo 'on' > '/sys/bus/usb/devices/usb1/power/control'
echo 'on' > '/sys/bus/usb/devices/4-1/power/control'
echo 'on' > '/sys/bus/usb/devices/1-1.4/power/control'
echo 'on' > '/sys/bus/usb/devices/usb4/power/control'
echo 'on' > '/sys/bus/usb/devices/3-1/power/control'

chmod ou+wr /dev/nrf*

2 changes: 2 additions & 0 deletions nrf24.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/Part/nrf24-kernel-driver/nrf24_if.o /Part/nrf24-kernel-driver/nrf24_hal.o /Part/nrf24-kernel-driver/nrf24_sysfs.o

11 changes: 8 additions & 3 deletions nrf24_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,11 @@ ssize_t nrf24_set_rf_channel(struct spi_device *spi, u8 channel)
return nrf24_write_reg(spi, RF_CH, channel);
}

ssize_t nrf24_get_rf_channel(struct spi_device *spi)
{
return nrf24_read_reg(spi, RF_CH);
}

ssize_t nrf24_power_up(struct spi_device *spi)
{
ssize_t config;
Expand Down Expand Up @@ -596,8 +601,8 @@ ssize_t nrf24_get_rx_pl_w(struct spi_device *spi)
ssize_t nrf24_soft_reset(struct spi_device *spi)
{
ssize_t ret;
u8 addr0[5] = {0xE7, 0xE7, 0xE7, 0xE7, 0xE7};
u8 addr1[5] = {0xC2, 0xC2, 0xC2, 0xC2, 0xC2};
u8 addr0[5] = {0xf0, 0xf0, 0xf0, 0xf0, 0xe1};
u8 addr1[5] = {0xf0, 0xf0, 0xf0, 0xf0, 0xe1};

ret = nrf24_write_reg(spi, CONFIG, 0x08);
if (ret < 0)
Expand All @@ -614,7 +619,7 @@ ssize_t nrf24_soft_reset(struct spi_device *spi)
ret = nrf24_write_reg(spi, SETUP_RETR, 0x03);
if (ret < 0)
return ret;
ret = nrf24_write_reg(spi, RF_CH, 0x02);
ret = nrf24_write_reg(spi, RF_CH, 0x46);
if (ret < 0)
return ret;
ret = nrf24_write_reg(spi, RF_SETUP, 0x07);
Expand Down
1 change: 1 addition & 0 deletions nrf24_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ ssize_t nrf24_set_rf_power(struct spi_device *spi, enum nrf24_rf_power rf_pwr);
ssize_t nrf24_get_rf_power(struct spi_device *spi);
ssize_t nrf24_set_rx_pload_width(struct spi_device *spi, u8 pipe_no, u8 plw);
ssize_t nrf24_set_rf_channel(struct spi_device *spi, u8 channel);
ssize_t nrf24_get_rf_channel(struct spi_device *spi);
ssize_t nrf24_write_tx_pload(struct spi_device *dev, u8 *buf, u8 length);
ssize_t nrf24_write_tx_pload_noack(struct spi_device *dev, u8 *buf, u8 length);
ssize_t nrf24_read_rx_pload(struct spi_device *spi, u8 *buf);
Expand Down
40 changes: 30 additions & 10 deletions nrf24_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/poll.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/gpio.h>

#include "nrf24_if.h"
#include "nrf24_sysfs.h"
Expand All @@ -41,12 +42,16 @@ ATTRIBUTE_GROUPS(nrf24);

static void nrf24_ce_hi(struct nrf24_device *device)
{
gpiod_set_value(device->ce, 1);

gpiod_set_value_cansleep(device->ce, 1);

}

static void nrf24_ce_lo(struct nrf24_device *device)
{
gpiod_set_value(device->ce, 0);

gpiod_set_value_cansleep(device->ce, 0);

}

static struct nrf24_pipe *nrf24_pipe_by_id(struct nrf24_device *device, int id)
Expand Down Expand Up @@ -289,14 +294,13 @@ static void nrf24_isr_work_handler(struct work_struct *work)

static irqreturn_t nrf24_isr(int irq, void *dev_id)
{
unsigned long flags;
struct nrf24_device *device = dev_id;

spin_lock_irqsave(&device->lock, flags);
mutex_lock(&device->lock);

schedule_work(&device->isr_work);

spin_unlock_irqrestore(&device->lock, flags);
mutex_unlock(&device->lock);

return IRQ_HANDLED;
}
Expand All @@ -313,6 +317,7 @@ static ssize_t nrf24_read(struct file *filp,

p = filp->private_data;


if (kfifo_is_empty(&p->rx_fifo)) {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
Expand Down Expand Up @@ -340,7 +345,7 @@ static ssize_t nrf24_write(struct file *filp,
struct nrf24_pipe *p;
struct nrf24_tx_data data;
ssize_t copied = 0;

int ret;
p = filp->private_data;
data.pipe = p;
device = to_nrf24_device(p->dev->parent);
Expand All @@ -366,7 +371,9 @@ static ssize_t nrf24_write(struct file *filp,
wake_up_interruptible(&device->tx_wait_queue);

p->write_done = false;
wait_event_interruptible(p->write_wait_queue, p->write_done);
ret = wait_event_interruptible(p->write_wait_queue, p->write_done);
if (ret < 0)
return 1;
copied += p->sent;
}
size -= data.size;
Expand Down Expand Up @@ -545,11 +552,13 @@ static int nrf24_gpio_setup(struct nrf24_device *device)

nrf24_ce_lo(device);

ret = request_irq(device->spi->irq,
ret = request_threaded_irq(device->spi->irq,
nrf24_isr,
0,
IRQF_TRIGGER_FALLING,
dev_name(&device->dev),
device);

if (ret < 0) {
gpiod_put(device->ce);
return ret;
Expand Down Expand Up @@ -609,7 +618,7 @@ static struct nrf24_device *nrf24_dev_init(struct spi_device *spi)
INIT_WORK(&device->isr_work, nrf24_isr_work_handler);
INIT_WORK(&device->rx_work, nrf24_rx_work_handler);
INIT_KFIFO(device->tx_fifo);
spin_lock_init(&device->lock);
mutex_init(&device->lock);
mutex_init(&device->tx_fifo_mutex);

INIT_LIST_HEAD(&device->pipes);
Expand Down Expand Up @@ -769,14 +778,18 @@ static int nrf24_remove(struct spi_device *spi)
{
struct nrf24_device *device = spi_get_drvdata(spi);

dev_info(&device->dev, "Nrf being removed\n");

nrf24_gpio_free(device);

kthread_stop(device->tx_task_struct);

nrf24_destroy_devices(device);

device_unregister(&device->dev);


dev_info(&device->dev, "Nrf successfully removed\n");

return 0;
}

Expand All @@ -787,12 +800,19 @@ static const struct of_device_id nrf24_dt_ids[] = {

MODULE_DEVICE_TABLE(of, nrf24_dt_ids);

static const struct spi_device_id nrf24_spi_ids[] = {
{ .name = "nrf24", },
{},
};
MODULE_DEVICE_TABLE(spi, nrf24_spi_ids);

static struct spi_driver nrf24_spi_driver = {
.driver = {
.name = "nrf24",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(nrf24_dt_ids),
},
.id_table = nrf24_spi_ids,
.probe = nrf24_probe,
.remove = nrf24_remove,
};
Expand Down
3 changes: 2 additions & 1 deletion nrf24_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct nrf24_device {
struct nrf24_device_cfg cfg;

/* for irqsave */
spinlock_t lock;
struct mutex lock;

struct work_struct isr_work;
struct work_struct rx_work;
Expand All @@ -83,6 +83,7 @@ struct nrf24_device {

};


#define to_nrf24_device(device) container_of(device, struct nrf24_device, dev)


Expand Down
Loading