Paparazzi UAS  v5.14.0_stable-0-g3f680d1
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
lis302dl_spi.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 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, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
29 
30 void lis302dl_spi_init(struct Lis302dl_Spi *lis, struct spi_periph *spi_p, uint8_t slave_idx)
31 {
32  /* set spi_peripheral */
33  lis->spi_p = spi_p;
34 
35  /* configure spi transaction */
38  lis->spi_trans.dss = SPIDss8bit;
40  lis->spi_trans.cdiv = SPIDiv64;
41 
43  lis->spi_trans.slave_idx = slave_idx;
44  lis->spi_trans.output_length = 2;
45  lis->spi_trans.input_length = 8;
46  // callback currently unused
47  lis->spi_trans.before_cb = NULL;
48  lis->spi_trans.after_cb = NULL;
49  lis->spi_trans.input_buf = &(lis->rx_buf[0]);
50  lis->spi_trans.output_buf = &(lis->tx_buf[0]);
51 
52  /* set inital status: Success or Done */
54 
55  /* set default LIS302DL config options */
57 
58  lis->initialized = false;
59  lis->data_available = false;
61 }
62 
63 
64 static void lis302dl_spi_write_to_reg(struct Lis302dl_Spi *lis, uint8_t _reg, uint8_t _val)
65 {
66  lis->spi_trans.output_length = 2;
67  lis->spi_trans.input_length = 0;
68  lis->tx_buf[0] = _reg;
69  lis->tx_buf[1] = _val;
70  spi_submit(lis->spi_p, &(lis->spi_trans));
71 }
72 
73 // Configuration function called once before normal use
74 static void lis302dl_spi_send_config(struct Lis302dl_Spi *lis)
75 {
76  uint8_t reg_val = 0;
77 
78  switch (lis->init_status) {
79  case LIS_CONF_WHO_AM_I:
80  /* query device id */
81  lis->spi_trans.output_length = 1;
82  lis->spi_trans.input_length = 2;
83  /* set read bit then reg address */
84  lis->tx_buf[0] = (1 << 7 | LIS302DL_REG_WHO_AM_I);
85  if (spi_submit(lis->spi_p, &(lis->spi_trans))) {
86  lis->init_status++;
87  }
88  break;
89  case LIS_CONF_REG2:
90  /* set SPI mode, Filtered Data Selection */
91  reg_val = (lis->config.spi_3_wire << 7) | (lis->config.filt_data << 4);
93  lis->init_status++;
94  break;
95  case LIS_CONF_REG3:
96  /* Interrupt active high/low */
98  lis->init_status++;
99  break;
100  case LIS_CONF_ENABLE:
101  /* set data rate, range, enable measurement, is in standby after power up */
102  reg_val = (lis->config.rate << 7) |
103  (1 << 6) | // Power Down Control to active mode
104  (lis->config.range << 5) |
105  0x5; // enable z,y,x axes
107  lis->init_status++;
108  break;
109  case LIS_CONF_DONE:
110  lis->initialized = true;
112  break;
113  default:
114  break;
115  }
116 }
117 
119 {
120  if (lis->init_status == LIS_CONF_UNINIT) {
121  lis->init_status++;
122  if (lis->spi_trans.status == SPITransSuccess || lis->spi_trans.status == SPITransDone) {
124  }
125  }
126 }
127 
129 {
130  if (lis->initialized && lis->spi_trans.status == SPITransDone) {
131  lis->spi_trans.output_length = 1;
132  lis->spi_trans.input_length = 8;
133  /* set read bit and multiple byte bit, then address */
134  lis->tx_buf[0] = (1 << 7 | 1 << 6 | LIS302DL_REG_STATUS);
135  spi_submit(lis->spi_p, &(lis->spi_trans));
136  }
137 }
138 
140 {
141  if (lis->initialized) {
142  if (lis->spi_trans.status == SPITransFailed) {
144  } else if (lis->spi_trans.status == SPITransSuccess) {
145  // Successfull reading
146  if (bit_is_set(lis->rx_buf[1], 3)) {
147  // new xyz data available
148  lis->data.vect.x = lis->rx_buf[3];
149  lis->data.vect.y = lis->rx_buf[5];
150  lis->data.vect.z = lis->rx_buf[7];
151  lis->data_available = true;
152  }
154  }
155  } else if (lis->init_status != LIS_CONF_UNINIT) { // Configuring but not yet initialized
156  switch (lis->spi_trans.status) {
157  case SPITransFailed:
158  lis->init_status--; // Retry config (TODO max retry)
159  case SPITransSuccess:
160  if (lis->init_status == LIS_CONF_WHO_AM_I_OK) {
161  if (lis->rx_buf[1] == LIS302DL_WHO_AM_I) {
162  lis->init_status++;
163  } else {
165  }
166  }
167  case SPITransDone:
170  break;
171  default:
172  break;
173  }
174  }
175 }
enum SPIClockPolarity cpol
clock polarity control
Definition: spi.h:149
bool filt_data
Filtered Data Selection.
Definition: lis302dl.h:51
#define LIS302DL_REG_STATUS
Definition: lis302dl_regs.h:36
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
Definition: spi.h:153
uint16_t output_length
number of data words to write
Definition: spi.h:146
struct spi_periph * spi_p
Definition: lis302dl_spi.h:40
CPHA = 1.
Definition: spi.h:69
static void lis302dl_set_default_config(struct Lis302dlConfig *c)
Definition: lis302dl.h:56
static void lis302dl_spi_write_to_reg(struct Lis302dl_Spi *lis, uint8_t _reg, uint8_t _val)
Definition: lis302dl_spi.c:64
enum Lis302dlConfStatus init_status
init status
Definition: lis302dl_spi.h:44
#define LIS302DL_WHO_AM_I
LIS302DL device identifier contained in LIS302DL_REG_WHO_AM_I.
Definition: lis302dl_regs.h:42
bool int_invert
Invert Interrupt FALSE: active high, TRUE: active low.
Definition: lis302dl.h:45
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
Definition: spi_arch.c:458
CPOL = 1.
Definition: spi.h:78
enum SPIBitOrder bitorder
MSB/LSB order.
Definition: spi.h:152
void lis302dl_spi_init(struct Lis302dl_Spi *lis, struct spi_periph *spi_p, uint8_t slave_idx)
Definition: lis302dl_spi.c:30
#define LIS302DL_REG_CTRL_REG2
Definition: lis302dl_regs.h:34
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
Definition: spi.h:144
struct spi_transaction spi_trans
Definition: lis302dl_spi.h:41
enum SPISlaveSelect select
slave selection behavior
Definition: spi.h:148
#define LIS302DL_REG_CTRL_REG1
Definition: lis302dl_regs.h:33
void lis302dl_spi_read(struct Lis302dl_Spi *lis)
Definition: lis302dl_spi.c:128
enum SPIClockPhase cpha
clock phase control
Definition: spi.h:150
enum Lis302dlRates rate
Data Output Rate.
Definition: lis302dl.h:53
SPI peripheral structure.
Definition: spi.h:168
static void lis302dl_spi_send_config(struct Lis302dl_Spi *lis)
Definition: lis302dl_spi.c:74
Definition: spi.h:84
volatile bool data_available
data ready flag
Definition: lis302dl_spi.h:46
SPICallback after_cb
NULL or function called after the transaction.
Definition: spi.h:155
enum Lis302dlRanges range
g Range
Definition: lis302dl.h:52
#define LIS302DL_REG_WHO_AM_I
Definition: lis302dl_regs.h:32
Driver for LIS302DL 3-axis accelerometer from ST using SPI.
volatile uint8_t rx_buf[8]
Definition: lis302dl_spi.h:43
uint16_t input_length
number of data words to read
Definition: spi.h:145
unsigned char uint8_t
Definition: types.h:14
struct Lis302dlConfig config
Definition: lis302dl_spi.h:51
slave is selected before transaction and unselected after
Definition: spi.h:57
void lis302dl_spi_start_configure(struct Lis302dl_Spi *lis)
Definition: lis302dl_spi.c:118
union Lis302dl_Spi::@307 data
enum SPIDataSizeSelect dss
data transfer word size
Definition: spi.h:151
bool initialized
config done flag
Definition: lis302dl_spi.h:45
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
Definition: spi.h:147
Definition: spi.h:119
volatile uint8_t * input_buf
pointer to receive buffer for DMA
Definition: spi.h:143
SPICallback before_cb
NULL or function called before the transaction.
Definition: spi.h:154
#define LIS302DL_REG_CTRL_REG3
Definition: lis302dl_regs.h:35
volatile uint8_t tx_buf[2]
Definition: lis302dl_spi.h:42
void lis302dl_spi_event(struct Lis302dl_Spi *lis)
Definition: lis302dl_spi.c:139
bool spi_3_wire
Set 3-wire SPI mode, if FALSE: 4-wire SPI mode.
Definition: lis302dl.h:46
enum SPITransactionStatus status
Definition: spi.h:156