Skip to content
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
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ This project implements a Linux device driver for the Texas Instruments CC1101 r

The CC1101 is a general purpose packet radio that operates in the Sub-GHz Industrial, Scientific and Medical (ISM) bands (315/433/868/915 MHz).

This driver allows the use of inexpensive CC1101 Serial Peripheral Interface (SPI) modules, which can be directly interfaced to the Pi's GPIOs. A kernel module allows the CC1101 to operate using hardware interrupts instead of polling, which increases the accuracy of packet reception.
This driver allows the use of inexpensive CC1101 Serial Peripheral Interface (SPI) modules, which can be directly interfaced to the Pi's GPIOs. A kernel module allows the CC1101 to operate using hardware interrupts instead of polling, which increases the accuracy of packet reception.

A [Python module](https://github.com/28757B2/cc1101-python) also exists to configure the driver and receive and transmit packets.

Use of this software is at your own risk. You are responsible for complying with local laws and regulations.

## Supported Features
The driver supports a subset of the CC1101 hardware's features and provides a high-level interface to the device that does not require setting of the individual hardware registers.
The driver supports a subset of the CC1101 hardware's features and provides a high-level interface to the device that does not require setting of the individual hardware registers.

* Frequencies - 300-348/387-464/778-928 MHz
* Modulation - OOK/2FSK/4FSK/GFSK/MSK
* Data Rate - 0.6 - 500 kBaud
* Data Rate - 0.6 - 500 kBaud
* RX Bandwidth - 58 - 812 kHz
* Arbitrary packet length RX/TX
* Sync word or carrier sense triggered RX
Expand All @@ -34,7 +34,7 @@ The following connections should be made between the CC1101 module and the Raspb
| GDO2 | 22 |
| GND | 25 |

A second radio can be connected to SPI bus 0 using the second chip enable pin:
A second radio can be connected to SPI bus 0 using the second chip enable pin:

| CC1101 Pin | Raspberry Pi GPIO |
|------------|-------------------|
Expand Down Expand Up @@ -64,13 +64,13 @@ sudo dkms build -m cc1101 -v 1.4.0
sudo dkms install -m cc1101 -v 1.4.0

# Enable SPI
sudo sed -i "s/^#dtparam=spi=on$/dtparam=spi=on/" /boot/config.txt
sudo sed -i "s/^#dtparam=spi=on$/dtparam=spi=on/" /boot/firmware/config.txt

# Compile Device Tree overlay
sudo dtc -@ -I dts -O dtb -o /boot/overlays/cc1101.dtbo cc1101.dts

# Enable Device Tree overlay
echo "dtoverlay=cc1101" | sudo tee -a /boot/config.txt
echo "dtoverlay=cc1101" | sudo tee -a /boot/firmware/config.txt

# Enable module loading at boot
echo "cc1101" | sudo tee -a /etc/modules
Expand All @@ -82,7 +82,7 @@ echo 'SUBSYSTEM=="cc1101", OWNER="pi", GROUP="pi", MODE="0660"' | sudo tee -a /e
reboot
```

After rebooting, entries should appear in the `dmesg` output depending on where the CC1101 is attached:
After rebooting, entries should appear in the `dmesg` output depending onconfig where the CC1101 is attached:

[ 726.808248] cc1101 spi0.1: Device not found (Partnum: 0x00, Version: 0x00)
[ 726.809093] cc1101 spi0.0: Ready (Partnum: 0x00, Version: 0x14)
Expand Down Expand Up @@ -149,6 +149,6 @@ To enable debug messages:

# Raspberry Pi OS
sudo modprobe cc1101 debug=1

# Ubuntu
echo "module cc1101 +p" > /sys/kernel/debug/dynamic_debug/control
32 changes: 16 additions & 16 deletions cc1101_chrdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ static DEFINE_MUTEX(device_list_lock);
/*
* Handler for open events to /dev/cc1101.x.x
* Only one handle is allowed to transmit, receive or configure the device at a time
* Operations will block until /dev/cc1101.x.x is closed
* Operations will block until /dev/cc1101.x.x is closed
*/
static int chrdev_open(struct inode *inode, struct file *file)
{
cc1101_t* cc1101 = NULL;
int device_index;

// Search the device list for the cc1101 struct relating to the chardev
if(mutex_lock_interruptible(&device_list_lock) != 0) {
return -EBUSY;
Expand All @@ -68,7 +68,7 @@ static int chrdev_open(struct inode *inode, struct file *file)
}
}
}

mutex_unlock(&device_list_lock);

// This should never occur - a chardev shouldn't be created without a CC1101 being present
Expand Down Expand Up @@ -100,7 +100,7 @@ static int chrdev_release(struct inode *inode, struct file *file)
/*
* Handler for iotcl commands to /dev/cc1101.x.x
* IOCTLs can be used to set and get the TX and RX config, reset the device
* and retrieve the contents of the CC1101's registers
* and retrieve the contents of the CC1101's registers
*/
static long chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
Expand Down Expand Up @@ -172,7 +172,7 @@ static long chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

// Write the configuration to the device
cc1101_config_apply_rx(cc1101);

// Enter RX mode on the device
cc1101_rx(cc1101);

Expand Down Expand Up @@ -212,7 +212,7 @@ static long chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
ret = 0;
#else
ret = -EPERM;
#endif
#endif
break;

// Returns the TX config configured in the driver to userspace
Expand Down Expand Up @@ -306,16 +306,16 @@ static ssize_t chrdev_read(struct file *file, char __user *buf, size_t len, loff

/*
* Handler for write events to /dev/cc1101.x.x
* Written bytes are transmitted by the CC1101 according the TX config
* Written bytes are transmitted by the CC1101 according the TX config
*/
static ssize_t chrdev_write(struct file *file, const char __user *buf, size_t len, loff_t *off)
{
#ifndef RXONLY
cc1101_t* cc1101 = file->private_data;
ssize_t ret;
unsigned char *tx_bytes;


// Check the number of bytes to be transmitted are allowed
if (len > max_packet_size) {
ret = -EMSGSIZE;
Expand Down Expand Up @@ -359,7 +359,7 @@ static ssize_t chrdev_write(struct file *file, const char __user *buf, size_t le
return ret;
#else
return -EPERM;
#endif
#endif
}

/*
Expand All @@ -368,7 +368,7 @@ static ssize_t chrdev_write(struct file *file, const char __user *buf, size_t le
int cc1101_chrdev_add_device(cc1101_t * cc1101) {
int ret;
int device_index;

mutex_lock(&device_list_lock);

// Search for a free minor number
Expand Down Expand Up @@ -402,8 +402,8 @@ int cc1101_chrdev_add_device(cc1101_t * cc1101) {
void cc1101_chrdev_remove_device(cc1101_t * cc1101) {
mutex_lock(&device_list_lock);

// Destroy the character device and remove the entry from the device list
device_destroy(dev_class, cc1101->devt);
// Destroy the character device and remove the entry from the device list
device_destroy(dev_class, cc1101->devt);
device_list[MINOR(cc1101->devt)] = NULL;

mutex_unlock(&device_list_lock);
Expand Down Expand Up @@ -431,8 +431,8 @@ int cc1101_chrdev_setup(struct spi_driver* cc1101_driver)
if (ret < 0) {
goto err_register;
}

dev_class = class_create(THIS_MODULE, "cc1101");
// per https://github.com/28757B2/cc1101-driver/issues/8#issuecomment-2179558238
dev_class = class_create("cc1101");
if (IS_ERR(dev_class)) {
ret = PTR_ERR(dev_class);
goto err_class_create;
Expand Down Expand Up @@ -462,4 +462,4 @@ void cc1101_chrdev_teardown(struct spi_driver* cc1101_driver)
spi_unregister_driver(cc1101_driver);
class_destroy(dev_class);
unregister_chrdev(SPI_MAJOR_NUMBER, cc1101_driver->driver.name);
}
}
10 changes: 4 additions & 6 deletions cc1101_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ static int cc1101_spi_probe(struct spi_device *spi)

// Reset the device, which will place it in idle and load the default config
cc1101_reset(cc1101);

// Get the GPIO associated with the device in device tree
gpio = devm_gpiod_get_index(&spi->dev, "int", 0, GPIOD_IN);
if (IS_ERR(gpio))
Expand Down Expand Up @@ -117,7 +117,7 @@ static int cc1101_spi_probe(struct spi_device *spi)
/*
* Function called on module removal for each CC1101 entry in device tree
*/
static int cc1101_spi_remove(struct spi_device *spi)
static void cc1101_spi_remove(struct spi_device *spi)
{
cc1101_t* cc1101;
cc1101 = spi_get_drvdata(spi);
Expand All @@ -131,9 +131,7 @@ static int cc1101_spi_remove(struct spi_device *spi)
// Remove /dev/cc1101.x.x
cc1101_chrdev_remove_device(cc1101);
CC1101_INFO(cc1101, "Removed");
return 0;
}

/*
* Register the module to handle cc1101 entries in device tree
*/
Expand Down Expand Up @@ -162,7 +160,7 @@ static struct spi_driver cc1101_driver = {
.id_table = cc1101_id
};

/*
/*
* Functions executed on module insertion/removal
* Setup/remove the CC1101 character device class
*/
Expand All @@ -179,7 +177,7 @@ static int __init cc1101_init(void)
module_init(cc1101_init);

static void __exit cc1101_exit(void)
{
{
cc1101_chrdev_teardown(&cc1101_driver);
}
module_exit(cc1101_exit);
Expand Down