KM3NeT CLB  2.0
KM3NeT CLB v2 Embedded Software
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
spi.h
Go to the documentation of this file.
1 /*
2  * KM3NeT CLB v2 Firmware
3  * ----------------------
4  *
5  * Copyright 2013 KM3NeT Collaboration
6  *
7  * All Rights Reserved.
8  *
9  *
10  * File : spi.h
11  * Created : 22 mrt. 2013
12  * Author : Vincent van Beveren
13  */
14 
15 
16 #ifndef SPI_H_
17 #define SPI_H_
18 
19 /**
20  * @file
21  *
22  * @ingroup wbdrivers
23  *
24  *
25  * This driver wraps the functions of the OpenCores SPI master. The driver allows for multiple
26  * SPI devices in memory, thus the specific SPI device must be provided with every call.
27  *
28  * @see dev_soc.h
29  *
30  * The following code demonstrates how to use the SPI device, using a fictive SPI slave. So its
31  * not so much what it does, but more how it does it. This should of course be translated to your
32  * specific SPI slaves' need.
33  * @code
34  *
35  * // Initialize default, no auto slave select, 1 MBit.
36  * const SpiInit init = SPI_DEFAULT_INIT;
37  *
38  * // initialize SPI device.
39  * if (!spiInit(SPI, &init)) {
40  * errPrint(true);
41  * return;
42  * }
43  *
44  * // ! fictive SPI slave command build up.
45  * const int cmdSize = 33;
46  * uint8_t bufIn[cmdSize];
47  * uint8_t bufOut[cmdSize];
48  * bufIn[0] = 0x32; // fictive read packet command
49  *
50  * spiSelect(3); // select slave no. 3 (fictive device).
51  *
52  * if (!spiTxRx(SPI, bufIn, bufOut, packetSize)) {
53  * spiDeselect();
54  * errPrint(true);
55  * return;
56  * }
57  * spiDeselect();
58  * printf("Success! received a packet!");
59  *
60  * @endcode
61  */
62 
63 #include <stdint.h>
64 #include <stdbool.h>
65 
66 #include "cfg_soc.h"
67 #include "lm32soc/dev_spi.h"
68 #include "errorcode.h"
69 
70 
71 
72 #define SPI_MAX_BYTES 16 ///< The maximum bytes the SPI driver can transfer at a time
73 #define SPI_MAX_SLAVE 8 ///< Maximum number of slaves (0 - SPI_MAX_SLAVE - 1)
74 
75 /// Minimum SPI bitrate
76 #define SPI_MIN_BITRATE ( WISHBONE_FREQ / ( ( SPI_DIV_MASK + 1 ) * 2 ) )
77 /// Maximum SPI bitrate
78 #define SPI_MAX_BITRATE ( WISHBONE_FREQ / 2 )
79 
80 #define E_SPI_TIMEOUT ( E_SPI + 1 ) ///< SPI transmission timeout
81 #define E_SPI_TIMEOUT_DESCR "SPI transmission timeout"
82 
83 /**
84  * SPI initialization structure.
85  *
86  * See OpenCores SPI device documentation for more information. Note that only byte-sized
87  * transfers are supported by this driver.
88  *
89  * @attention SPI modes 2 and 3 are not well supported!
90  */
91 typedef struct
92 {
93  uint32_t bitrate; ///< Bit-rate.
94  uint8_t mode; ///< SPI mode (0 - 3, see Wikipedia, 0 - default).
95  bool lsbFirst; ///< Transfer LSB first.
96  bool intEnable; ///< Interrupts enabled (not implemented yet).
97  bool autoSlaveSelect; ///< Auto slave select.
98 
99 } SpiInit;
100 
101 /**
102  * Default initialization structure.
103  */
104 #define SPI_DEFAULT_INIT \
105  { \
106  .bitrate = 1000000, \
107  .mode = 0, \
108  .lsbFirst = false, \
109  .intEnable = false, \
110  .autoSlaveSelect = false \
111  }
112 
113 
114 /**
115  * Initializes the specified SPI device with the specified parameters.
116  *
117  * @param dev The SPI device.
118  * @param init The initialization structure.
119  *
120  * @retval true Operation was a success.
121  * @retval false Operation failed, check errCode() for the error code.
122  */
123 bool spiInit(SPI_Device * dev, SpiInit * init);
124 
125 /**
126  * Transfers a specific number of bytes in a synchronous way. Note that the underlying SPI device
127  * can at most send SPI_MAX_BYTES. When the length of the data to transmit exceeds this value,
128  * multiple transmits will be issued.
129  *
130  * @note function will exit after all bytes have been send and received.
131  * @note if auto slave select is enabled, each SPI_MAX_BYTES the SS will be selected and
132  * deselected.
133  * @note If both dataIn and dataOut are *both* 0 (NULL), its assumed data from address 0
134  * is going to be written to the SPI flash. This indeed happens on a core dump.
135  *
136  * @param dev The WB device.
137  * @param dataIn The data to receive, may be NULL to send dummy data.
138  * @param dataOut The data to transmit, may be NULL to not receive data.
139  * @param len The no of bytes to transmit and receive.
140  *
141  * @retval true Operation was a success.
142  * @retval false Operation failed, check errCode() for the error code.
143  */
144 bool spiTxRx(SPI_Device * dev, uint8_t * dataIn, uint8_t * dataOut, int len);
145 
146 /**
147  * Start a asynchronous SPI transmission.
148  *
149  * @param dev The SPI device.
150  * @param dataIn The buffer to write
151  * @param len The length of of the data to send. May not exceed SPI_MAX_BYTES.
152  */
153 void spiAsyncTx(SPI_Device * dev, uint8_t * dataIn, int length);
154 
155 /**
156  * Returns whether or not the SPI driver is busy tranceiving data.
157  *
158  * @param dev The device to query.
159  * @retval true Its busy
160  * @retval false Its ready.
161  */
162 bool spiASyncBusy(SPI_Device * dev);
163 
164 /**
165  * Last lenght of data transmitted. Can be used for asynchronous communciation.
166  *
167  * @param dev The SPIdevice.
168  * @return The no of bytes which can be read.
169  */
170 int spiASyncLength(SPI_Device * dev);
171 
172 /**
173  * Reads the data received in the previous transmission.
174  *
175  * @param dev The device to read.
176  * @param dataOut The buffer to write into
177  *
178  * @retval true All went ok.
179  * @retval false Failed, see errCode() for error.
180  *
181  */
182 void spiASyncRx(SPI_Device * dev, uint8_t * dataOut);
183 
184 /**
185  * Selects a specific slave.
186  *
187  * @param dev The WB SPI device.
188  * @param slaveNo The selected slave number.
189  */
190 void spiSelect(SPI_Device * dev, uint32_t slaveNo);
191 
192 /**
193  * Deselects all slaves.
194  *
195  * @param dev The WB SPI device.
196  */
197 void spiDeselect(SPI_Device * dev);
198 
199 
200 #endif /* SPI_H_ */
SPI initialization structure.
Definition: spi.h:91
Defines the configuration of the LM32 SOC for the CLBv2.
uint8_t mode
SPI mode (0 - 3, see Wikipedia, 0 - default).
Definition: spi.h:94
bool lsbFirst
Transfer LSB first.
Definition: spi.h:95
void spiSelect(SPI_Device *dev, uint32_t slaveNo)
Selects a specific slave.
Definition: spi.c:204
Structure defines OpenCores SPI Device.
Definition: dev_spi.h:57
void spiASyncRx(SPI_Device *dev, uint8_t *dataOut)
Reads the data received in the previous transmission.
Definition: spi.c:143
int spiASyncLength(SPI_Device *dev)
Last lenght of data transmitted.
Definition: spi.c:137
bool spiASyncBusy(SPI_Device *dev)
Returns whether or not the SPI driver is busy tranceiving data.
Definition: spi.c:132
uint32_t bitrate
Bit-rate.
Definition: spi.h:93
bool spiInit(SPI_Device *dev, SpiInit *init)
Initializes the specified SPI device with the specified parameters.
Definition: spi.c:39
void spiAsyncTx(SPI_Device *dev, uint8_t *dataIn, int length)
Start a asynchronous SPI transmission.
Definition: spi.c:89
void spiDeselect(SPI_Device *dev)
Deselects all slaves.
Definition: spi.c:212
This module is responsible for distributing error codes.
bool autoSlaveSelect
Auto slave select.
Definition: spi.h:97
bool spiTxRx(SPI_Device *dev, uint8_t *dataIn, uint8_t *dataOut, int len)
Transfers a specific number of bytes in a synchronous way.
Definition: spi.c:192
OpenCores SPI device.
bool intEnable
Interrupts enabled (not implemented yet).
Definition: spi.h:96