Contiki 2.5
mspi-drv.h
Go to the documentation of this file.
1 /* Copyright (c) 2010, Ulf Kulau
2  *
3  * Permission is hereby granted, free of charge, to any person
4  * obtaining a copy of this software and associated documentation
5  * files (the "Software"), to deal in the Software without
6  * restriction, including without limitation the rights to use,
7  * copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following
10  * conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 /**
26  * \addtogroup Drivers
27  * @{
28  *
29  * \defgroup mspi_driver Master SPI Bus Driver (MSPI)
30  *
31  * <p>There are a lot of possibilities to realize a Serial Peripheral Interface (SPI) with the
32  * ATmega1284p, but the hardware SPI is used by the transceiver chip AT86rf230. In combination
33  * with contiki it is not possible to build up an SPI Bus with this hardware SPI.
34  * A software SPI would be a solution, but the ATmega1284p provides another opportunity. The MSPI
35  * (Maser SPI) is an alternative function of the USART. There are two independent hardware USART,
36  * so it is possible to use one for the default debug RS232 interface, while the other one is
37  * free to be used as an MSPI. The only difference between an normal SPI and the MSPI is, that
38  * MSPI only supports slaves on the bus.</p>
39  * @{
40  *
41  */
42 
43 /**
44  * \file
45  * MSPI driver definitions
46  * \author
47  * Ulf Kulau <kulau@ibr.cs.tu-bs.de>
48  */
49 
50 
51 #ifndef MSPIDRV_H_
52 #define MSPIDRV_H_
53 
54 #include <avr/io.h>
55 /*!
56  * Enable or disable the MSPI-Bus Manager.
57  *
58  * \note The...
59  */
60 #define MSPI_BUS_MANAGER 1
61 #if MSPI_BUS_MANAGER
62 #include "mspi-mgr.h"
63 #endif
64 
65 #define MSPI_USART0 0
66 #define MSPI_USART1 1
67 /*\cond*/
68 #define MSPI_ENABLE (0xC0)
69 #define MSPI_DISABLE (0x06)
70 #define MSPI_CS_DISABLE 0
71 #define MSPI_DUMMY_BYTE 0xFF
72 /*\endcond*/
73 
74 
75 #define MSPI_CS_PORT PORTA
76 #define MSPI_CS_PORT_DDR DDRA
77 #define MSPI_CS_PIN_0 PORTA5
78 #define MSPI_CS_PIN_1 PORTA6
79 #define MSPI_CS_PIN_2 PORTA7
80 
81 /*!
82  * This array holds the BCD for the 8 possible SPI devices, because the few amount
83  * of port-pins made it necessary to use a BCD-Decimal-Encoder. The first item
84  * (chip_select[0]) disables chip select. The other (chip_select[1] ...
85  * chip_select[7]) holds the MSPI_SC_PORT information for the specific SPI device.
86  *
87  * \note This is a special solution for the raven based ibr sensor node. If you want
88  * to use this driver for other applications, feel free to change the chip select
89  * management
90  */
91 static uint8_t cs_bcd[8] = {
92  /*Chip Select Disable*/
93  (0xFF & (0 << MSPI_CS_PIN_0) & (0 << MSPI_CS_PIN_1) & (0 << MSPI_CS_PIN_2)),
94  /*Chip Select Enable for specific SPI device (1...7)*/
95  (0x00 | (1 << MSPI_CS_PIN_0) | (0 << MSPI_CS_PIN_1) | (0 << MSPI_CS_PIN_2)), //1
96  (0x00 | (0 << MSPI_CS_PIN_0) | (1 << MSPI_CS_PIN_1) | (0 << MSPI_CS_PIN_2)), //2
97  (0x00 | (1 << MSPI_CS_PIN_0) | (1 << MSPI_CS_PIN_1) | (0 << MSPI_CS_PIN_2)), //3
98  (0x00 | (0 << MSPI_CS_PIN_0) | (0 << MSPI_CS_PIN_1) | (1 << MSPI_CS_PIN_2)), //4
99  (0x00 | (1 << MSPI_CS_PIN_0) | (0 << MSPI_CS_PIN_1) | (1 << MSPI_CS_PIN_2)), //5
100  (0x00 | (0 << MSPI_CS_PIN_0) | (1 << MSPI_CS_PIN_1) | (1 << MSPI_CS_PIN_2)), //6
101  (0x00 | (1 << MSPI_CS_PIN_0) | (1 << MSPI_CS_PIN_1) | (1 << MSPI_CS_PIN_2)) //7
102 
103 };
104 
105 /********************************************************************
106  * MSPI mode:
107  ********************************************************************/
108 
109 /*!
110  * MSPI Mode 0
111  * \note <ul>
112  * <li> Leading Edge: Sample (Rising Edge)
113  * <li> Trailing Edge: Setup (Falling Edge)
114  * </ul>
115  */
116 #define MSPI_MODE_0 (0x00)
117 /*!
118  * MSPI Mode 1
119  * \note <ul>
120  * <li> Leading Edge: Setup (Rising Edge)
121  * <li> Trailing Edge: Sample (Falling Edge)
122  * </ul>
123  */
124 #define MSPI_MODE_1 (0x02)
125 /*!
126  * MSPI Mode 2
127  * \note <ul>
128  * <li> Leading Edge: Sample (Falling Edge)
129  * <li> Trailing Edge: Setup (Rising Edge)
130  * </ul>
131  */
132 #define MSPI_MODE_2 (0x01)
133 /*!
134  * MSPI Mode 3
135  * \note <ul>
136  * <li> Leading Edge: Setup (Falling Edge)
137  * <li> Trailing Edge: Sample (Rising Edge)
138  * </ul>
139  */
140 #define MSPI_MODE_3 (0x03)
141 
142 /********************************************************************
143  * MSPI BAUD Rate:
144  ********************************************************************/
145 
146 /*!
147  * Maximum MSPI Baud Rate [bps]
148  * \note The maximum baud rate is f_osc/2
149  */
150 #define MSPI_BAUD_MAX (0x00)
151 /*!
152  * 2Mbps MSPI Baud Rate
153  * \note Assumption: f_osc = 8 MHz
154  */
155 #define MSPI_BAUD_2MBPS (0x01)
156 /*!
157  * 1Mbps MSPI Baud Rate
158  * \note Assumption: f_osc = 8 MHz
159  */
160 #define MSPI_BAUD_1MBPS (0x03)
161 
162 
163 typedef struct {
164  /*!
165  * MSPI Baud Rate Register (USART0/USART1)
166  */
167  volatile uint16_t * UBRRn;
168  /*!
169  * MSPI Serial Clock Pin Data Direction Register (USART0/USART1)
170  */
171  volatile uint8_t * XCKn_DDR; //Uart0 = DDRB //Uart1 = DDRD
172  /*!
173  * MSPI Serial Clock Pin (USART0/USART1)
174  */
175  volatile uint8_t XCKn; //Uart0 = PORTB0 //Uart1 = PORTD4
176  /*!
177  * MSPIM Control and Status Register A (USART0/USART1)
178  */
179  volatile uint8_t * UCSRnA;
180  /*!
181  * MSPIM Control and Status Register B (USART0/USART1)
182  */
183  volatile uint8_t * UCSRnB;
184  /*!
185  * MSPIM Control and Status Register C (USART0/USART1)
186  */
187  volatile uint8_t * UCSRnC;
188  /*!
189  * MSPI I/O Data Register (USART0/USART1)
190  */
191  volatile uint8_t * UDRn;
192 } usart_t;
193 
194 static usart_t usart_ports[2] = {
195  { // MSPI UART0
196  &UBRR0,
197  &DDRB,
198  PORTB0,
199  &UCSR0A,
200  &UCSR0B,
201  &UCSR0C,
202  &UDR0
203  },
204 
205  { // MSPI UART1
206  &UBRR1,
207  &DDRD,
208  PORTD4,
209  &UCSR1A,
210  &UCSR1B,
211  &UCSR1C,
212  &UDR1
213  }
214 };
215 
216 /**
217  * \brief Initialize the selected USART in the MSPI mode
218  *
219  * \param mode Select the (M)SPI mode (MSPI_MODE_0 ...
220  * MSPI_MODE_3)
221  * \param baud The MSPI BAUD rate. Sometimes it is necessary
222  * to reduce the SCK. Use MSPI_BAUD_MAX in common case.
223  *
224  */
225 void mspi_init(uint8_t cs, uint8_t mode, uint16_t baud);
226 
227 /**
228  * \brief This function can be use either to transmit or receive
229  * data via spi.
230  *
231  * \param data <ul>
232  * <li>When use this function to transmit: Data byte, which
233  * has to be transmit.
234  * <li>When use this function to receive: Data value don't
235  * care. (Dummy Byte, e.g. 0xFF)
236  * </ul>
237  * \return <li>When use this function to transmit: The return value
238  * doesn't care
239  * <li>When use this function to receive: Received data
240  * from the spi slave
241  * </ul>
242  *
243  * \note The various devices along the SPI Bus are separated by the
244  * Chip Select (cs). The assignment of the SPI-devices depends on
245  * the hardware wiring. The correct chip select an spi configuration
246  * will be done by the spi-bus.manager. Otherwise please ensure,
247  * which Chip Select and spi bus configuration belong to which
248  * SPI device.
249  */
250 uint8_t mspi_transceive(uint8_t data);
251 
252 /**
253  * \brief This function enables the chip select by setting the
254  * needed I/O pins (BCD-Code)
255  *
256  * \param cs Chip Select: Device ID
257  */
258 void mspi_chip_select(uint8_t cs);
259 
260 /**
261  * \brief This function disables the chip select
262  *
263  * \param cs Chip Select: Device ID
264  */
265 void mspi_chip_release(uint8_t cs);
266 
267 /**
268  * \brief This function will set all MSPI registers to their
269  * default values.
270  */
271 void mspi_deinit(void);
272 
273 #endif /* MSPIDRV_H_ */