Skip to content

Commit

Permalink
Merge pull request #1 from felicitus/master
Browse files Browse the repository at this point in the history
Added initial linux SPI implementation
  • Loading branch information
pl4nkton committed May 13, 2014
2 parents e49ecec + 02082f4 commit 8e5d7e5
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 5 deletions.
8 changes: 7 additions & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
2014-05-10
------------------------------------------------------------------------

Added initial Linux SPI implementation to use the library on a
Raspberry Pi or other Linux based SPI-capable platforms.

------------------------------------------------------------------------

2012-01-28

* included rfm12_read_interrupt_flags_inline() again for performance
reasons (interrupt handler might be to slow on 115200 Baud otherwise)
* clear interrupt flag before checking status (there is a glitch sometimes
while the int line goes high, which triggers another interrupt otherweise,
while the int line goes high, which triggers another interrupt otherwise,
which also hurts performance
* LNA controllable over rfm12_livectrl

Expand Down
3 changes: 3 additions & 0 deletions src/include/rfm12_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define SS_ASSERT() PORT_SS &= ~(1<<BIT_SS)
#define SS_RELEASE() PORT_SS |= (1<<BIT_SS)

#ifdef __PLATFORM_AVR__

#if RFM12_SPI_SOFTWARE
/* @description Actual sending function to send raw data to the Module
Expand Down Expand Up @@ -135,3 +136,5 @@ static void spi_init(void) {
SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0); //SPI Master, clk/16
#endif
}

#endif
107 changes: 107 additions & 0 deletions src/include/rfm12_spi_linux.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#ifdef __PLATFORM_LINUX__
#include <linux/spi/spidev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdlib.h>
#include <getopt.h>
#include <stdio.h>
#include <byteswap.h>
#include <unistd.h>

static const char *device = "/dev/spidev0.1";
static int fd;
static uint8_t mode = 0;
static uint8_t bits = 8;
static uint32_t speed = 250000;

static void pabort(const char *s)
{
perror(s);
abort();
}


static void spi_init(void) {
int ret = 0;

fd = open(device, O_RDWR);

if (fd < 0) {
pabort("driver not loaded? can't open device");
}
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
pabort("can't set spi mode");

ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
pabort("can't get spi mode");

/*
* bits per word
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't set bits per word");

ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't get bits per word");

/*
* max speed hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't set max speed hz");

ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't get max speed hz");
}

static uint16_t rfm12_read(uint16_t address) {
int ret;

uint8_t rx[2];
uint8_t tx[2];

tx[0] = (uint8_t) (address >> 8);
tx[1] = (uint8_t) (address & 0xFF);

rx[0] = 0;
rx[1] = 0;

struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = 2,
.delay_usecs = 0,
.speed_hz = speed,
.bits_per_word = bits,
};

ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);

if (ret < 1)
pabort("can't send spi message");


return ((uint16_t)rx[0] << 8) + rx[1];
}

static void rfm12_data(uint16_t d) {
uint8_t buffer[2];
buffer[0] = (uint8_t) (d >> 8);
buffer[1] = (uint8_t) (d & 0xff);

write(fd, buffer, sizeof(buffer));
}

static uint8_t rfm12_read_int_flags_inline(void) {
uint16_t ret = rfm12_read(0x0000);

return ret >> 8;
}

#endif
34 changes: 30 additions & 4 deletions src/rfm12.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,14 @@
/************************
* standard includes
*/
#ifdef __PLATFORM_AVR__
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <avr/pgmspace.h>
#endif

#include <string.h>



/************************
Expand Down Expand Up @@ -85,6 +89,7 @@ rfm12_control_t ctrl;

/* include spi functions into here */
#include "include/rfm12_spi.c"
#include "include/rfm12_spi_linux.c"

/*
* include control / init functions into here
Expand Down Expand Up @@ -142,7 +147,9 @@ ISR(RFM12_INT_VECT, ISR_NOBLOCK)

do {
//clear AVR int flag
#ifdef __PLATFORM_AVR__
RFM12_INT_FLAG = (1<<RFM12_FLAG_BIT);
#endif

//first we read the first byte of the status register
//to get the interrupt flags
Expand Down Expand Up @@ -646,7 +653,11 @@ rfm12_start_tx(uint8_t type, uint8_t length) {
//set TX Power, frequency shift
#define RFM12_CMD_TXCONF_DEFAULT (RFM12_CMD_TXCONF | RFM12_POWER | RFM12_TXCONF_FS_CALC(FSK_SHIFT) )

#ifdef __PLATFORM_AVR__
static const uint16_t init_cmds[] PROGMEM = {
#else
static const uint16_t init_cmds[] = {
#endif
//defined above (so shadow register is inited with same value)
RFM12_CMD_CFG_DEFAULT,

Expand Down Expand Up @@ -708,8 +719,10 @@ static const uint16_t init_cmds[] PROGMEM = {
*/
void rfm12_init(void) {
//initialize spi
#ifdef __PLATFORM_AVR__
SS_RELEASE();
DDR_SS |= (1<<BIT_SS);
#endif
spi_init();

//typically sets DDR registers for RFM12BP TX/RX pin
Expand Down Expand Up @@ -756,9 +769,17 @@ void rfm12_init(void) {

//write all the initialisation values to rfm12
uint8_t x;
for (x = 0; x < ( sizeof(init_cmds) / 2) ; x++) {
rfm12_data(pgm_read_word(&init_cmds[x]));
}

#ifdef __PLATFORM_AVR__

for (x = 0; x < ( sizeof(init_cmds) / 2) ; x++) {
rfm12_data(pgm_read_word(&init_cmds[x]));
}
#else
for (x = 0; x < ( sizeof(init_cmds) / 2) ; x++) {
rfm12_data(init_cmds[x]);
}
#endif

#ifdef RX_ENTER_HOOK
RX_ENTER_HOOK;
Expand All @@ -774,11 +795,16 @@ void rfm12_init(void) {
#endif

//setup interrupt for falling edge trigger
#ifdef __PLATFORM_AVR__
RFM12_INT_SETUP();
#endif

//clear int flag
rfm12_read(RFM12_CMD_STATUS);

#ifdef __PLATFORM_AVR__
RFM12_INT_FLAG = (1<<RFM12_FLAG_BIT);
#endif

//init receiver fifo, we now begin receiving.
rfm12_data(CLEAR_FIFO);
Expand Down
4 changes: 4 additions & 0 deletions src/rfm12.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
#ifndef _RFM12_H
#define _RFM12_H

#ifdef __PLATFORM_LINUX__
#include <stdint.h>
#endif

//this was missing, but is very important to set the config options for structs and such
#include "include/rfm12_core.h"

Expand Down

0 comments on commit 8e5d7e5

Please sign in to comment.