Git Product home page Git Product logo

spi-bcm283x-rtdm's Introduction

spi-bcm283x-rtdm

Real-Time SPI driver for the Broadcom BCM2835 (BCM2708) and BCM2836 (BCM2709) SoCs using the RTDM API.

Introduction

This RTDM driver is intended to provide SPI communication between a Raspberry Pi running Xenomai 3.0 (or greater, potentially) and a maximum of two slave devices.

Limitations

The driver currently only supports blocking data transfer.

Possible future improvements would be implementing interrupt-based and dma-based transfer.

Build

The provided makefile will build the module out-of-tree. If you are unfamiliar with this technique, you can read the related documentation at https://www.kernel.org/doc/Documentation/kbuild/modules.txt. This requires that you provide, as an argument, the location of the sources of an already built Xenomai-enabled kernel.

Start by retrieving the source of the driver.

$ git clone https://github.com/nicolas-schurando/spi-bcm283x-rtdm.git

Then build against your already built kernel source.

$ make ARCH=arm CROSS_COMPILER=/path-to-gcc/prefix- KERNEL_DIR=/path-to-kernel-sources

Upon success, the release sub-folder will be populated with the generated kernel module.

Usage

Copy the generated kernel module onto the target and load it with the following command.

$ sudo insmod spi-bcm283x-rtdm.ko

The system log should display something like:

[   59.577534] bcm283x_spi_rtdm_init: Starting driver ...
[   59.577582] bcm2835_init: Found device-tree node /soc.
[   59.577615] bcm2835_init: /soc/ranges = 0x7e000000 0x3f000000 0x01000000.
[   59.577638] bcm2835_init: Using device-tree values.
[   59.577998] mapmem: mapping 0x3f000000 for gpio succeded to 0xbe000000
[   59.578867] bcm283x_spi_rtdm_init: Device spidev0.0 registered without errors.
[   59.579362] bcm283x_spi_rtdm_init: Device spidev0.1 registered without errors.

Once loaded, the driver will expose the two devices listed below. The number before the dot refers to the SPI interface and the number after the dot corresponds to the chip select pin. The Raspberry Pi only exposes the SPI0 interface, with CS0 and CS1.

  • /dev/rtdm/spidev0.0
  • /dev/rtdm/spidev0.1

The driver uses hard-coded values for the Pi 1, but needs to fetch information from the device tree if running on a Pi 2. For the latter, make sure that you compiled the kernel with device-tree enabled, and that you used the mkknlimg tool to add the DT-compatibility trailer.

Finally, below are a few relevant lines that should help you make use of the driver inside a Xenomai application.

/* RTDM header */
#include <rtdm/rtdm.h>

/* BCM283x SPI RTDM driver header */
#include "spi-bcm283x-rtdm.h"

/** Transmit buffer */
static uint8_t tx_buffer[BCM283X_SPI_BUFFER_SIZE_MAX];

/** Receive buffer */
static uint8_t rx_buffer[BCM283X_SPI_BUFFER_SIZE_MAX];

/** Handle to the bcm283x rtdm spi driver instance. */
static int device_handle = -1;

/**
 * Open and configure device
 * @return 0 in case of success, a negative value otherwise.
 */
int open_device() {

	int res;
	int value;

	/* Open device */
	res = open("/dev/rtdm/spidev0.0", O_RDWR);
	if (res < 0) {
		printf("%s: Could not open spi device, open has failed with %d (%s).", __FUNCTION__, errno, strerror(errno));
		return;
	} else {
		printf("%s: Device opened.", __FUNCTION__);
		device_handle = res;
	}

	/* Configure device */
	value = BCM283X_SPI_BIT_ORDER_MSBFIRST;
	res = ioctl(device_handle, BCM283X_SPI_SET_BIT_ORDER, &value);
	if (res < 0) {
		printf("%s: Could not configure bit order, ioctl has failed with %d (%s).", __FUNCTION__, errno, strerror(errno));
		device_handle = NULL;
		return -1;
	}
	value = BCM283X_SPI_DATA_MODE_0;
	res = ioctl(device_handle, BCM283X_SPI_SET_DATA_MODE, &value);
	if (res < 0) {
		printf("%s: Could not configure data mode, ioctl has failed with %d (%s).", __FUNCTION__, errno, strerror(errno));
		device_handle = NULL;
		return -1;
	}
	value = BCM283X_SPI_SPEED_8MHz;
	res = ioctl(device_handle, BCM283X_SPI_SET_SPEED, &value);
	if (res < 0) {
		printf("%s: Could not configure bus speed, ioctl has failed with %d (%s).", __FUNCTION__, errno, strerror(errno));
		device_handle = NULL;
		return -1;
	}
	value = BCM283X_SPI_CS_POL_LOW;
	res = ioctl(device_handle, BCM283X_SPI_SET_CS_POLARITY, &value);
	if (res < 0) {
		printf("%s: Could not configure chip select polarity, ioctl has failed with %d (%s).", __FUNCTION__, errno, strerror(errno));
		device_handle = NULL;
		return -1;
	}

	printf("%s: Device sucessfully configured.", __FUNCTION__);
	return 0;

}

int main() {

	int res;

	/* Open device */
	res = open_device();
	if (res < 0) {
		printf("%s: Could not open device, exiting.", __FUNCTION__);
		return -1;
	}

	/* Do stuff */
	while (...) {
		ssize_t size;

		/* Write from tx buffer */
		size = write(device_handle, (const void *) tx_buffer, spi_frame_size);

		/* Receive to rx buffer */
		memset(rx_buffer, 0, 1024);
		size = read(device_handle, (void *) rx_buffer, spi_frame_size);

		/* ... */
	}

}

Credits

This code should be considered as a wrapper around the great user-space bcm2835 library written by Mike McCauley and available at http://www.airspayce.com/mikem/bcm2835/.

His code underwent only minor modifications, in order to make it compatible with kernel-space.

Both the original work and this driver are licensed under the GNU General Public License version 2 (GPLv2).

Comments, issues, and contributions are welcome.

Author Nicolas Schurando ([email protected]).

spi-bcm283x-rtdm's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

spi-bcm283x-rtdm's Issues

The environment

Hi nicolas, this is exactly what I'm looking for!!! Thanks.
Could you please provide more details about the environment?
Like ubuntuMATE16.04 on raspberry pi3 with xenomai v-3.0.3 .. etc
( Which I'm looking for ;p). Now I try to use this for controlling an ARM cpu based 5DOF robot.
If any progress will let you know!

Cheers

Can't copy the generated kernel module

Hey
Could you please tell me how can i copy the generated kernel module onto the target, i read the build documentation several times and i couldn't understand.
Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.