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
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
30void 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 */
36 lis->spi_trans.cpol = SPICpolIdleHigh;
37 lis->spi_trans.cpha = SPICphaEdge2;
38 lis->spi_trans.dss = SPIDss8bit;
39 lis->spi_trans.bitorder = SPIMSBFirst;
40 lis->spi_trans.cdiv = SPIDiv64;
41
42 lis->spi_trans.select = SPISelectUnselect;
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 */
53 lis->spi_trans.status = SPITransDone;
54
55 /* set default LIS302DL config options */
57
58 lis->initialized = false;
59 lis->data_available = false;
60 lis->init_status = LIS_CONF_UNINIT;
61}
62
63
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
75{
76 uint8_t reg_val = 0;
77
78 switch (lis->init_status) {
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 */
97 lis302dl_spi_write_to_reg(lis, LIS302DL_REG_CTRL_REG3, (lis->config.int_invert << 7));
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;
111 lis->spi_trans.status = SPITransDone;
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) {
143 lis->spi_trans.status = SPITransDone;
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 }
153 lis->spi_trans.status = SPITransDone;
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 {
164 lis->init_status = LIS_CONF_WHO_AM_I;
165 }
166 }
167 case SPITransDone:
168 lis->spi_trans.status = SPITransDone;
170 break;
171 default:
172 break;
173 }
174 }
175}
enum SPIStatus status
internal state of the peripheral
Definition spi.h:180
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
Definition spi_arch.c:533
@ SPICphaEdge2
CPHA = 1.
Definition spi.h:75
@ SPITransFailed
Definition spi.h:100
@ SPITransSuccess
Definition spi.h:99
@ SPITransDone
Definition spi.h:101
@ SPICpolIdleHigh
CPOL = 1.
Definition spi.h:84
@ SPISelectUnselect
slave is selected before transaction and unselected after
Definition spi.h:63
@ SPIMSBFirst
Definition spi.h:112
@ SPIDiv64
Definition spi.h:125
@ SPIDss8bit
Definition spi.h:90
SPI peripheral structure.
Definition spi.h:174
static void lis302dl_set_default_config(struct Lis302dlConfig *c)
Definition lis302dl.h:56
@ LIS_CONF_UNINIT
Definition lis302dl.h:35
@ LIS_CONF_DONE
Definition lis302dl.h:41
@ LIS_CONF_WHO_AM_I
Definition lis302dl.h:36
@ LIS_CONF_WHO_AM_I_OK
Definition lis302dl.h:37
@ LIS_CONF_ENABLE
Definition lis302dl.h:40
@ LIS_CONF_REG2
Definition lis302dl.h:38
@ LIS_CONF_REG3
Definition lis302dl.h:39
#define LIS302DL_REG_CTRL_REG3
#define LIS302DL_REG_STATUS
#define LIS302DL_WHO_AM_I
LIS302DL device identifier contained in LIS302DL_REG_WHO_AM_I.
#define LIS302DL_REG_WHO_AM_I
#define LIS302DL_REG_CTRL_REG2
#define LIS302DL_REG_CTRL_REG1
void lis302dl_spi_event(struct Lis302dl_Spi *lis)
void lis302dl_spi_read(struct Lis302dl_Spi *lis)
void lis302dl_spi_init(struct Lis302dl_Spi *lis, struct spi_periph *spi_p, uint8_t slave_idx)
void lis302dl_spi_start_configure(struct Lis302dl_Spi *lis)
static void lis302dl_spi_write_to_reg(struct Lis302dl_Spi *lis, uint8_t _reg, uint8_t _val)
static void lis302dl_spi_send_config(struct Lis302dl_Spi *lis)
Driver for LIS302DL 3-axis accelerometer from ST using SPI.
uint16_t foo
Definition main_demo5.c:58
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.