Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
spi_arch.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2014 Felix Ruess <felix.ruess@gmail.com>
3 *
4 * This file is part of paparazzi.
5 *
6 * paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with paparazzi; see the file COPYING. If not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20
26#include <stdio.h>
27#include <unistd.h>
28#include <stdlib.h>
29#include <fcntl.h>
30#include <string.h>
31
32#include <sys/ioctl.h>
33#include <linux/spi/spidev.h>
34
35#include "mcu_periph/spi.h"
36#include BOARD_CONFIG
37
38
40{
41 /* for now we assume that each SPI device has it's SLAVE CS already set up
42 * e.g. in pin muxing of BBB
43 */
44}
45
46#pragma GCC diagnostic push
47#pragma GCC diagnostic ignored "-Wcast-qual"
48bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
49{
50 int fd = (int)p->reg_addr;
51
53 memset(&xfer, 0, sizeof xfer);
54
55 /* length in bytes of transaction */
56 uint16_t buf_len = Max(t->input_length, t->output_length);
57
58 // temp buffers, used if necessary
59 uint8_t tx_buf[buf_len], rx_buf[buf_len];
60 memset(tx_buf, 0, buf_len);
61 memset(rx_buf, 0, buf_len);
62
63 /* handle transactions with different input/output length */
64 if (buf_len > t->output_length) {
65 /* copy bytes to transmit to larger buffer, rest filled with zero */
66 memcpy(tx_buf, (void *)t->output_buf, t->output_length);
67 xfer.tx_buf = (unsigned long)tx_buf;
68 } else {
69 xfer.tx_buf = (unsigned long)t->output_buf;
70 }
71
72 if (buf_len > t->input_length) {
73 xfer.rx_buf = (unsigned long)rx_buf;
74 } else {
75 xfer.rx_buf = (unsigned long)t->input_buf;
76 }
77
78 xfer.len = buf_len;
79 /* fixed speed of 1Mhz for now, use SPIClockDiv?? */
80 xfer.speed_hz = (uint32_t)p->init_struct;
81 xfer.delay_usecs = 0;
82 if (t->dss == SPIDss16bit) {
83 xfer.bits_per_word = 16;
84 } else {
85 xfer.bits_per_word = 8;
86 }
87 if (t->select == SPISelectUnselect || t->select == SPIUnselect) {
88 xfer.cs_change = 1;
89 }
90
91 if (ioctl(fd, SPI_IOC_MESSAGE(1), &xfer) < 0) {
92 t->status = SPITransFailed;
93 return false;
94 }
95
96 /* copy received data if we had to use an extra rx_buffer */
97 if (buf_len > t->input_length) {
98 memcpy((void *)t->input_buf, rx_buf, t->input_length);
99 }
100
101 t->status = SPITransSuccess;
102 return true;
103}
104#pragma GCC diagnostic pop
105
107{
108 // not implemented
109 return false;
110}
111
113{
114 // not implemented
115 return false;
116}
117
118
119#if USE_SPI0
120
121#ifndef SPI0_MODE
122#define SPI0_MODE (SPI_CPOL | SPI_CPHA)
123#endif
124
125#ifndef SPI0_LSB_FIRST
126#define SPI0_LSB_FIRST 0
127#endif
128
129#ifndef SPI0_BITS_PER_WORD
130#define SPI0_BITS_PER_WORD 8
131#endif
132
133#ifndef SPI0_MAX_SPEED_HZ
134#define SPI0_MAX_SPEED_HZ 1000000
135#endif
136
138{
139 int fd = open("/dev/spidev1.0", O_RDWR);
140
141 if (fd < 0) {
142 perror("Could not open SPI device /dev/spidev1.0");
144 return;
145 }
146 spi0.reg_addr = (void *)fd;
147
148 /* spi mode */
149 unsigned char spi_mode = SPI0_MODE;
150 if (ioctl(fd, SPI_IOC_WR_MODE, &spi_mode) < 0) {
151 perror("SPI0: can't set spi mode");
152 }
153
154 /* set to MSB first */
155 unsigned char spi_order = SPI0_LSB_FIRST;
157 perror("SPI0: can't set spi bit justification");
158 }
159
160 /* bits per word default to 8 */
163 perror("SPI0: can't set bits per word");
164 }
165
166 /* max speed in hz, 1MHz for now */
167 unsigned int spi_speed = SPI0_MAX_SPEED_HZ;
169 perror("SPI0: can't set max speed hz");
170 }
172}
173#endif /* USE_SPI0 */
174
175#if USE_SPI1
176
177#ifndef SPI1_MODE
178#define SPI1_MODE (SPI_CPOL | SPI_CPHA)
179#endif
180
181#ifndef SPI1_LSB_FIRST
182#define SPI1_LSB_FIRST 0
183#endif
184
185#ifndef SPI1_BITS_PER_WORD
186#define SPI1_BITS_PER_WORD 8
187#endif
188
189#ifndef SPI1_MAX_SPEED_HZ
190#define SPI1_MAX_SPEED_HZ 1000000
191#endif
192
194{
195 int fd = open("/dev/spidev1.1", O_RDWR);
196
197 if (fd < 0) {
198 perror("Could not open SPI device /dev/spidev1.1");
199 spi1.reg_addr = NULL;
200 return;
201 }
202 spi1.reg_addr = (void *)fd;
203
204 /* spi mode */
205 unsigned char spi_mode = SPI1_MODE;
206 if (ioctl(fd, SPI_IOC_WR_MODE, &spi_mode) < 0) {
207 perror("SPI1: can't set spi mode");
208 }
209
210 /* set to MSB first */
211 unsigned char spi_order = SPI1_LSB_FIRST;
213 perror("SPI1: can't set spi bit justification");
214 }
215
216 /* bits per word default to 8 */
219 perror("SPI1: can't set bits per word");
220 }
221
222 /* max speed in hz, 1MHz for now */
223 unsigned int spi_speed = SPI1_MAX_SPEED_HZ;
225 perror("SPI1: can't set max speed hz");
226 }
227 spi1.init_struct = (void *)SPI1_MAX_SPEED_HZ;
228}
229#endif /* USE_SPI1 */
void * reg_addr
Definition spi.h:183
void * init_struct
Definition spi.h:184
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
Definition spi_arch.c:533
bool spi_lock(struct spi_periph *p, uint8_t slave)
spi_lock() function
Definition spi_arch.c:681
void spi1_arch_init(void)
Architecture dependent SPI1 initialization.
Definition spi_arch.c:423
void spi0_arch_init(void)
Architecture dependent SPI0 initialization.
Definition spi_arch.c:137
struct spi_periph spi0
Definition spi.c:35
process_rx_dma_interrupt & spi1
receive transferred over DMA
Definition spi_arch.c:967
bool spi_resume(struct spi_periph *p, uint8_t slave)
spi_resume() function
Definition spi_arch.c:695
void spi_init_slaves(void)
spi_init_slaves() function
Definition spi_arch.c:709
@ SPITransFailed
Definition spi.h:100
@ SPITransSuccess
Definition spi.h:99
@ SPISelectUnselect
slave is selected before transaction and unselected after
Definition spi.h:63
@ SPIUnselect
slave is not selected but unselected after transaction
Definition spi.h:65
@ SPIDss16bit
Definition spi.h:91
SPI peripheral structure.
Definition spi.h:174
SPI transaction structure.
Definition spi.h:148
static float p[2][2]
#define SPI1_BITS_PER_WORD
Definition spi_arch.c:186
#define SPI0_LSB_FIRST
Definition spi_arch.c:126
#define SPI1_MAX_SPEED_HZ
Definition spi_arch.c:190
#define SPI1_LSB_FIRST
Definition spi_arch.c:182
#define SPI0_MAX_SPEED_HZ
Definition spi_arch.c:134
#define SPI1_MODE
Definition spi_arch.c:178
#define SPI0_MODE
Definition spi_arch.c:122
#define SPI0_BITS_PER_WORD
Definition spi_arch.c:130
uint16_t foo
Definition main_demo5.c:58
int fd
Definition serial.c:26
Architecture independent SPI (Serial Peripheral Interface) API.
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.