remove CVS
[aversive.git] / modules / comm / spi / spi.h
1 /*  
2  *  Copyright Droids Corporation (2008)
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  */
19
20 /*
21  * Author : Julien LE GUEN - jlg@jleguen.info
22  */
23
24 /*
25  *  -- INFO --
26  *      This module enable the use of the SPI hardware
27  *      on some AVRs. For now, only MASTER mode is available.
28  *      You can have as many slaves as you want, as long as you
29  *      don't confuse them by trying to speak to several at the same time.
30  *
31  *      BIG WARNING: If you use /SS as a slave selector, always
32  *      register it using spi_register_ss_line() *before* calling
33  *      spi_init(). Read carrefully the datasheet, especially the
34  *      paragraph "SS Pin Functionnality" in SPI section. In master
35  *      mode, the SS pin must be configured as an output OR driven
36  *      high by an external circuitry.
37  *
38  *  -- USAGE --
39  *      So you have one (or several) device(s) that want to speak to your
40  *      shiny AVR over SPI ?
41  *      This is fairly easy. First, summon this module with spi_init().
42  *      You can configure
43  *       - the FORMAT of the link (sample on rising or falling edge, ...)
44  *       - the RATE of the connection (you set the prescaler dividing the CPU clock)
45  *      You can also set the data order (MSB or LSB first on the link)
46  *      
47  *      After that you can register your devices using spi_register_ss_line();
48  *      This returns you a device identifier you can use with spi_slave_[de]select();
49  *
50  *      Remember to ALWAYS select your slave before talking to it, and deselect if
51  *      once your are done.
52  */
53
54
55
56 #ifndef _SPI_H_
57 #define _SPI_H_
58
59 #include <stdint.h>
60
61 /* SPI modes */
62 typedef enum {
63         SPI_MODE_UNINIT,        /* not initialized */
64         SPI_MODE_MASTER         /* for now, only master mode as
65                                  * slave mode cannot be tested */
66 } spi_mode_t;
67
68
69 /* SPI transfert format 
70  * This defines the SCK phase and polarity.
71  * For instance in FORMAT_0, data lines are set on the falling edge
72  * of SCK, and sampled on its rising edge. This determines the order
73  * in which sampling and setting occurs.
74  * For more information on SPI formats, please see your CPU datasheet.
75  */
76 typedef enum {  
77         SPI_FORMAT_0 = 0x00,                  /* Sample rising  Setup falling */
78         SPI_FORMAT_1 = _BV(CPHA),             /* Setup rising   Sample falling */
79         SPI_FORMAT_2 = _BV(CPOL),             /* Sample falling Setup rising */
80         SPI_FORMAT_3 = _BV(CPHA) | _BV(CPOL), /* Setup falling  Sample rising*/
81 } spi_format_t;
82
83
84 /* SPI Clock Rate
85  * This code the values for SPI2X (high nibble), SPR1 and SPR0 (low nibble)
86  * f_sck = f_osc / SPI_CLK_RATE_xx
87  */
88 typedef enum {
89         SPI_CLK_RATE_2 =        0x10,
90         SPI_CLK_RATE_4 =        0x00,
91         SPI_CLK_RATE_8 =        0x11,
92         SPI_CLK_RATE_16 =       0x01,
93         SPI_CLK_RATE_32 =       0x12,
94         SPI_CLK_RATE_64 =       0x02,
95         SPI_CLK_RATE_128 =      0x03
96 } spi_clk_rate_t;
97
98
99 /* 
100  * Data order (bits order)
101  * order is either SPI_LSB_FIRST or SPI_MSB_FIRST
102  * Default is MSB first
103  */
104 #define SPI_MSB_FIRST   0
105 #define SPI_LSB_FIRST   1
106 void spi_set_data_order(uint8_t order);
107
108
109
110
111 /* Initialize the SPI
112  * mode is SPI_MODE_MASTER (slave is not implemented)
113  * format defines the transfert format (see above)
114  * clk_rate defines the frequency of SCK line (f_sck = f_osc / clk_rate)
115  */
116 void spi_init(spi_mode_t mode, spi_format_t format, spi_clk_rate_t clk_rate);
117
118
119 /*
120  *      Returns the state of the SPI
121  */
122 spi_mode_t spi_get_mode(void);
123
124
125 /* 
126  * Register a pin as SS line
127  * Returns a unique identifier, or -1 on error
128  * There is always the physical SS line registered as 0
129  */
130 int8_t spi_register_ss_line(volatile uint8_t *port, uint8_t bitnum);
131
132
133 /*
134  *      Sends a byte (and receive one at the same time)
135  *      Returns the received byte
136  *      Wait for the end of transmission
137  */
138 uint8_t spi_send_and_receive_byte(uint8_t byte);
139
140
141 /*
142  *      Sends a byte, discards the received one.
143  *      Do NOT wait for the end of transmission
144  */
145 void spi_send_byte(uint8_t byte);
146
147 /*
148  *      Receives a byte (sends a NULL)
149  */
150 uint8_t spi_receive_byte(void);
151
152 /*
153  *      Select or Deselect the SS line
154  *      The SPI standard defines that only ONE slave can
155  *      be selected at any time. An internal mecanism prevents
156  *      the selection of several slaves at the same time, but
157  *      this is not completely foolproof.
158  *
159  *      /!\ Behavior is NOT ASSURED if you mess with SS lines
160  *      outside of this module, so PLEASE use these setters. /!\
161  *
162  *      This function returns EBUSY if there is already a selected slave
163  */
164 uint8_t spi_slave_select(uint8_t slave);
165
166 /*
167  *      Inconditionnaly releases the line.
168  */
169 void spi_slave_deselect(uint8_t slave);
170
171 /*
172  *      Display SS lines
173  */
174 void spi_display_ss_lines(void);
175
176
177 #endif /* _SPI_H_ */
178