oa
[aversive.git] / modules / devices / encoders / encoders_spi / encoders_spi.c
1 /*  
2  *  Copyright Droids Corporation (2009)
3  * 
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  *  Revision : $Id: encoders_spi.c,v 1.1.2.3 2009-04-07 20:00:46 zer0 Exp $
19  *
20  *  Olivier MATZ <zer0@droids-corp.org>
21  */
22
23 /* This modules handles encoders: values are read through a SPI
24  * interface. Basically, frames are formatted with 4 words of 16 bits,
25  * describing the values of the 4 encoders. */
26
27 #ifndef HOST_VERSION
28
29 #include <string.h>
30
31 #include <aversive.h>
32 #include <aversive/parts.h>
33
34 #include <spi.h>
35
36 #include <encoders_spi.h>
37 #include <encoders_spi_config.h>
38
39 static int32_t g_encoders_spi_values[ENCODERS_SPI_NUMBER];
40 static int16_t g_encoders_spi_previous[ENCODERS_SPI_NUMBER];
41
42
43 /* Initialisation of encoders, variables */
44 void encoders_spi_init(void)
45 {
46         memset(g_encoders_spi_previous, 0, sizeof(g_encoders_spi_previous));
47         spi_register_ss_line(&ENCODERS_SPI_SS_PORT, ENCODERS_SPI_SS_BIT);
48         spi_init(SPI_MODE_MASTER, ENCODERS_SPI_FORMAT, ENCODERS_SPI_CLK_RATE);
49         spi_set_data_order(ENCODERS_SPI_DATA_ORDER);
50         encoders_spi_manage(NULL);
51         memset(g_encoders_spi_values, 0, sizeof(g_encoders_spi_values));
52 }
53
54
55 /* Update encoders values */
56 void encoders_spi_manage(__attribute__((unused)) void *dummy)
57 {
58         union {
59                 struct {
60                         uint8_t u8_lsb;
61                         uint8_t u8_msb;
62                 } s;
63                 int16_t s16;
64         } enc;
65         uint8_t i;
66         int16_t diff;
67         uint8_t flags;
68
69         spi_slave_select(0);
70         for (i=0; i<ENCODERS_SPI_NUMBER; i++) {
71                 enc.s.u8_lsb = spi_receive_byte();
72                 enc.s.u8_msb = spi_receive_byte();
73                 diff = enc.s16 - g_encoders_spi_previous[i];
74                 g_encoders_spi_previous[i] = enc.s16;
75                 IRQ_LOCK(flags);
76                 g_encoders_spi_values[i] += diff;
77                 IRQ_UNLOCK(flags);
78         }
79         spi_slave_deselect(0);
80 }
81
82
83
84 /* Extract encoder value */
85 int32_t encoders_spi_get_value(void *encoder)
86 {
87         int32_t value;
88         uint8_t flags;
89
90         IRQ_LOCK(flags);
91         value = g_encoders_spi_values[(int)encoder];
92         IRQ_UNLOCK(flags);
93
94         return value;
95 }
96
97 /* Set an encoder value */
98 void encoders_spi_set_value(void *encoder, int32_t val)
99 {
100         uint8_t flags;
101
102         IRQ_LOCK(flags);
103         g_encoders_spi_values[(int)encoder] = val;
104         IRQ_UNLOCK(flags);
105 }
106
107 #endif