# How to use SPI ?

**URL:** <https://forum.sierrawireless.com/t/how-to-use-spi/8135>\
**Category:** WP Series\
**Created:** [August 24, 2015, 10:52am UTC](https://forum.sierrawireless.com/t/how-to-use-spi/8135 "2015-08-24T10:52:53Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![pla](https://avatars.discourse-cdn.com/v4/letter/p/ea5d25/32.png) [@pla](https://forum.sierrawireless.com/u/pla)\
**Post date:** [March 31, 2016, 3:20pm UTC](https://forum.sierrawireless.com/t/how-to-use-spi/8135/3 "2016-03-31T15:20:50Z")

</div>

Any news on this? I have been trying to get SPI1 running now for a while on my WP85. SPI1\_MOSI and SPI1\_SCK looks OK on scope but I cannot set the SPI1\_MRDY pin which I use as a slave select to my SPI slave. See my code snippets below.

```auto
#include "legato.h"
#include "interfaces.h"
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/sierra_spidev.h>

#define SPI_CPHA 0x01
#define SPI_CPOL 0x02

#define SPI_MODE_0 (0|0)
#define SPI_MODE_1 (0|SPI_CPHA)
#define SPI_MODE_2 (SPI_CPOL|0)
#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)

#define SPI_CS_HIGH 0x04
#define SPI_LSB_FIRST 0x08
#define SPI_3WIRE 0x10
#define SPI_LOOP 0x20
#define SPI_NO_CS 0x40
#define SPI_READY 0x80
#define SPI_TX_DUAL 0x100
#define SPI_TX_QUAD 0x200
#define SPI_RX_DUAL 0x400
#define SPI_RX_QUAD 0x800

/*===========================================================================
 * DEFINES
 *=========================================================================*/

#define FAIL_ON_ERROR(expr) do { le_result_t _result_ = (expr); LE_FATAL_IF(_result_ < 0, #expr " failed with %d", _result_); } while (0)

/*===========================================================================
 * DEFINITIONS
 *=========================================================================*/

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
static le_timer_Ref_t spiTimer; ///< Timer for spi reading
static const le_clk_Time_t spiTimerTime = { .sec = 2, .usec = 0 }; ///< Time between data monitor ticks

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

int32_t	spiFd;
static const char *device = "/dev/nrfPort";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 960000;
static uint16_t delay = 10;
static uint8_t length=16;
static uint8_t pattern[16] = {0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
							  0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xEF};
static uint32_t order;

static void transfer(int fd)
{
	int i,ret;
	uint8_t *tx;
	uint8_t *rx;

	struct spi_ioc_transfer tr;

	memset(&tr, 0, sizeof(tr));

	tr.tx_buf = 0;
	tr.rx_buf = 0;
	tr.len = length;
	tr.delay_usecs = delay;
	tr.speed_hz = speed;
	tr.bits_per_word = bits;
	tr.cs_change = true;

	/* create tx & rx buffers */
	tx=calloc(sizeof(uint8_t),length);
	rx=calloc(sizeof(uint8_t),length);
	for (i=0;i<length-1;i+=ARRAY_SIZE(pattern))
		if ((i+ARRAY_SIZE(pattern)) > length)
			memcpy(tx+i,pattern,length-i);
		else
			memcpy(tx+i,pattern,ARRAY_SIZE(pattern));

	tr.tx_buf=(unsigned long)tx;
	tr.rx_buf=(unsigned long)rx;

	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
	if (ret < 1)
		pabort("can't send spi message");

	for (ret = 0; ret < length; ret++) {
		if (!(ret % 8))
			LE_INFO(" ");
		LE_INFO("%.2X ", rx[ret]);
	}
	LE_INFO(" ");
}

// -------------------------------------------------------------------------------------------------
/**
 * Timer handler for spi update
 */
// -------------------------------------------------------------------------------------------------
static void spiTimerHandler(le_timer_Ref_t timerRef)
{
    (void)timerRef;

    //send some dummy data
    transfer(spiFd);

    LE_DEBUG("spiTimerHandler: expired %d", le_timer_GetExpiryCount(timerRef));

}

COMPONENT_INIT
{
	int ret = 0;

	LE_INFO("spiReader:Init");

    spiFd = open(device, O_RDWR);
	if (spiFd < 0)
		pabort("can't open device");

	/*
	 * spi mode
	 */

	mode = 0;

	mode |= SPI_MODE_2;

	//mode |= 0x20;	//SPI_LOOP

	ret = ioctl(spiFd, SPI_IOC_WR_MODE, &mode);
	if (ret == -1)
		pabort("can't set spi mode");

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

	/*
	 * bits per word
	 */

	bits = 8;

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

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

	/*
	 * max speed hz
	 */

	speed = 960000;

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

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

	LE_INFO("spi mode: %d\n", mode);
	LE_INFO("bits per word: %d\n", bits);
	LE_INFO("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
	LE_INFO("LSB first\n");

    spiTimer = le_timer_Create("SPI_TIMER");
    FAIL_ON_ERROR( le_timer_SetHandler(spiTimer, spiTimerHandler));
    FAIL_ON_ERROR( le_timer_SetInterval(spiTimer, spiTimerTime));
    FAIL_ON_ERROR( le_timer_SetRepeat(spiTimer, 0));
    FAIL_ON_ERROR( le_timer_Start(spiTimer));

	//close(spiFd);

}
```

---

_[View the full topic](https://forum.sierrawireless.com/t/how-to-use-spi/8135)._
