]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/include/rpp/can.h
Make the RPP layer thread safe
[pes-rpp/rpp-lib.git] / rpp / include / rpp / can.h
1 /**
2  * CAN Bus Communication RPP API header file.
3  *
4  * @file can.h
5  *
6  * @copyright Copyright (C) 2013, 2014 Czech Technical University in Prague
7  *
8  * @author Carlos Jenkins <carlos@jenkins.co.cr>
9  * @author Michal Sojka <sojkam1@fel.cvut.cz>
10  */
11
12
13 #ifndef __RPP_CAN_H
14 #define __RPP_CAN_H
15
16
17 /**
18  * Hardware object identifier.
19  */
20 typedef uint16_t rpp_can_hw_obj;
21
22 /**
23  * CAN frame
24  */
25 struct rpp_can_pdu {
26         uint32_t id;                /**< Message ID */
27         uint8_t dlc;                /**< Length of the data in bytes */
28         uint8_t data[8];            /**< Message payload */
29 };
30
31 /**
32  * CAN frame type selector
33  */
34 enum rpp_can_frame_type {
35         RPP_CAN_STANDARD,           /**< 11b message ID and mask */
36         RPP_CAN_EXTENDED,           /**< 29b message ID and mask */
37         RPP_CAN_MIXED,              /**< Allows the receive message object
38                                      * to receive both types of CAN
39                                      * frames. This value is invalid for
40                                      * transmit message objects. */
41 };
42
43 /**
44  * Timing parameters calculation method
45  */
46 enum rpp_can_timing_calculation {
47         RPP_CAN_TIMING_CALC_MANUAL, /**< Timing parameters are specified manually.  */
48         RPP_CAN_TIMING_CALC_AUTO    /**< Timing parameters are calculated automatically from desired baudrate. */
49 };
50
51 /**
52  * CAN transmit message object configuration.
53  *
54  * Stores all necessary parameters for configuring one transmit message object.
55  *
56  * The @a msg_obj index must be unique among all RX and TX message
57  * objects for the same controller.
58  *
59  */
60 struct rpp_can_tx_config {
61         enum rpp_can_frame_type type;   /**< Type of the frame to be transmitted */
62         uint8_t controller;             /**< CAN controller index (1-3) */
63         uint8_t msg_obj;                /**< Index of message object
64                                         * (mailbox) to use (1-64) */
65 };
66
67 /**
68  * CAN receive message object configuration.
69  *
70  * Stores all necessary parameters for configuring one receive message object.
71  *
72  * The @a msg_obj index must be unique among all RX and TX message
73  * objects for the same controller.
74  *
75  * The @a id and the @a mask define acceptance filter and its range
76  * depends on the frame type.
77  *
78  */
79 struct rpp_can_rx_config {
80         enum rpp_can_frame_type type;   /**< Type of the received CAN frames */
81         uint8_t controller; /**< CAN controller index (1-3) */
82         uint8_t msg_obj;    /**< Index of message object (mailbox) to use (1-64) */
83         uint32_t id;        /**< Acceptance filter message ID */
84         uint32_t mask;      /**< Acceptance filter mask */
85 };
86
87 /**
88  * CAN controller configuration.
89  *
90  * Holds information needed to configure a CAN controller. The
91  * information here depends on the value of @a timing_calc_method. If
92  * @a timing_calc_method is @a RPP_CAN_TIMING_CALC_MANUAL, @a
93  * timing_config must point to a structure with the timing parameters,
94  * otherwise the @a baudrate and @a clk has to be set.
95  *
96  * If timing_calc_method is RPP_CAN_TIMING_CALC_AUTO, the
97  * @a timing_config may be NULL and the timing parameters are calculated
98  * by an algorithm from @a baudrate and @a clk values.
99  *
100  */
101 struct rpp_can_ctrl_config {
102         uint32_t baudrate;  /**< Desired baudrate in bits per second */
103         uint32_t clk;       /**< Clock frequency of the CAN module in Hz */
104         enum rpp_can_timing_calculation timing_calc_method; /**< Manual/automatic timing calculation selector */
105         struct rpp_can_timing_cfg *timing_config; /**< CAN timing parameters */
106 };
107
108 /**
109  * CAN bit timing specification.
110  *
111  * Specifies parameters for manual configuration of CAN controller
112  * timing. These parameters determine (among others) the used
113  * baudrate.
114  *
115  * tQ below stands for time quantum and equals to CLK/@a brp.
116  */
117 struct rpp_can_timing_cfg {
118         uint16_t brp;       /**< Baudrate prescaler (1-64) in CLKs. */
119         uint8_t prop_seg;   /**< Length of the propagation segment (1-8) in tQ */
120         uint8_t phase_seg1; /**< Length of the phase buffer segment 1 (1-8) in tQ */
121         uint8_t phase_seg2; /**< Length of the phase buffer segment 2 (1-8) in tQ */
122         uint8_t sjw;        /**< Synchronization jump width (1-4) in tQ */
123 };
124
125 /**
126  * Information about the calculated CAN bit timing.
127  *
128  * Specifies the precision of the calculated bit timing, the time
129  * quantum length and the position of the sample point in the frame.
130  *
131  * The data from this structure can be used for debugging purposes.
132  */
133 struct rpp_can_calculated_timing_info {
134         uint32_t tq;        /**< Length of the time quantum (tQ) in ns */
135         uint32_t error;     /**< Error rate from desired baudrate */
136         int sampl_pt;       /**< Sample point delay from the start of the frame in ns */
137 };
138
139 /**
140  * Calculated CAN bit timing.
141  *
142  * Specifies the calculated CAN bit timing and some additional information
143  * about the precision and other additional parameters of the resulting baudrate.
144  */
145 struct rpp_can_calculated_timing {
146         struct rpp_can_timing_cfg timing_base_cfg;          /**< Base parameters of the calculated CAN bit timing */
147         struct rpp_can_calculated_timing_info timing_info;  /**< Additional information about the calculated baudrate */
148 };
149
150 /**
151  * Root of the CAN configuration.
152  *
153  * Contains pointers to arrays of RX message objects, TX message
154  * objects and configurations of all the CAN controllers.
155  */
156 struct rpp_can_config {
157         uint16_t num_tx_obj;    /**< Number of configured message objects in @a tx_config */
158         uint16_t num_rx_obj;    /**< Number of configured message objects in @a rx_config */
159         struct rpp_can_tx_config *tx_config; /**< Array of configurations of transmit message objects */
160         struct rpp_can_rx_config *rx_config; /**< Array of configurations of receive message objects */
161         struct rpp_can_ctrl_config *ctrl;    /**< Array of 3 CAN controller configurations */
162 };
163
164 /** Flag signalizing reception of EFF frame. */
165 #define CAN_EFF_FLAG 0x80000000U
166
167 /**
168  * CAN module initialization.
169  *
170  * Call this method before using this module.
171  *
172  * This function is not thread safe. Do not call it from multiple threads.
173  *
174  * @param[in] config Configuration of CAN controllers and message objects
175  *
176  * @return @c SUCCESS if initialization was successful,\n
177  *         @c FAILURE otherwise.
178  */
179 int8_t rpp_can_init(const struct rpp_can_config *config);
180
181 /**
182  * Submit a CAN message for transmission.
183  *
184  * The function is thread safe, unless compiled with -DRPP_THREADSAFE=0
185  *
186  * Data pointed by @a pdu is copied to the given message object for
187  * transmission. A successful call to this function also resets the TX
188  * pending flag that can be retrieved with rpp_can_check_tx_pend().
189  *
190  * When the previously submitted transmission request is pending when
191  * this function is invoked again, the pending message is replaced by
192  * the new message. If this is not desired, the caller should only
193  * call this function when rpp_can_check_tx_pend() signals that no
194  * request is pending.
195  *
196  * @param[in] hw_obj Index of the hardware object to use for
197  * transmission. It is an index to rpp_can_config.tx_config.
198  *
199  * @param[in] pdu Message to send.
200  *
201  * @return @c SUCCESS if the message was successfully submitted for transmission,\n
202  *         @c -RPP_EINVAL if invalid hw_obj was specified.
203  *
204  */
205 int8_t rpp_can_write(rpp_can_hw_obj hw_obj, const struct rpp_can_pdu *pdu);
206
207 /**
208  * Checks whether message transmission is pending.
209  *
210  * The function is thread safe, unless compiled with -DRPP_THREADSAFE=0
211  *
212  * Call this function to check whether a message previously submitted
213  * for transmission with rpp_can_write() still waits for transmission
214  * or has already been transmitted to the bus.
215  * @param[in] hw_obj Hardware object to be checked.
216  * @param[out] tx_pend Where to store the TX pending flag. Its
217  * value will be @c true if a message waits for transmission and @c
218  * false otherwise.
219  * @return @c SUCCESS if @a tx_pend was updated with the requested value,\n
220  *             @c FAILURE if an error was detected.
221  */
222 int8_t rpp_can_check_tx_pend(rpp_can_hw_obj hw_obj, bool *tx_pend);
223
224 /**
225  * Read a message from a message object.
226  *
227  * The function is thread safe, unless compiled with -DRPP_THREADSAFE=0
228  *
229  * Data in the given message object is copied to @a pdu. A successful
230  * call to this function also clears the indication that can be
231  * retrieved with rpp_can_check_rx_ind().
232  *
233  * @param[in] hw_obj Hardware object to be read. It is an index to
234  * rpp_can_config.rx_config.
235  * @param[out] pdu Where to store the read message.
236  *
237  * @return @li @c SUCCESS if the message was succesfully copied out
238  *                from the message object,
239  *         @li @c -RPP_ENODATA if no data was received,\n
240  *         @li @c -RPP_EINVAL if @a hw_obj is invalid.
241  */
242 int8_t rpp_can_read(rpp_can_hw_obj hw_obj, struct rpp_can_pdu *pdu);
243
244 /**
245  * Checks whether a message was received by the message object.
246  *
247  * The function is thread safe, unless compiled with -DRPP_THREADSAFE=0
248  *
249  * @param[in] hw_obj Hardware object to be checked.
250  * @param[out] rx_ind Where to store the RX indication flag. Its value
251  * will be @c true if a message was received, @c false otherwise.
252  *
253  * @return @c SUCCESS if @a rx_ind was updated with the requested value,\n
254  *         @c FAILURE if an error was detected.
255  */
256 int8_t rpp_can_check_rx_ind(rpp_can_hw_obj hw_obj, bool *rx_ind);
257
258 #endif /* __RPP_CAN_H */