LEDComm  1.0
ledcomm.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, 2014 Kevin L. Pauba
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25  * OF SUCH DAMAGE.
26  *
27  * This file is part of the LEDComm Driver for ChibiOS/RT.
28  *
29  * Author: Kevin L. Pauba <klpauba@gmail.com>
30  *
31  */
32 
33 /**
34  * @file ledcomm.h
35  * @brief LEDComm Driver macros and structures.
36  *
37  * @addtogroup LEDComm
38  * @{
39  */
40 
41 #ifndef _LEDCOMM_H_
42 #define _LEDCOMM_H_
43 
44 #include "ledcommconf.h"
45 
46 /*===========================================================================*/
47 /* Driver constants. */
48 /*===========================================================================*/
49 
50 /**
51  * @name LEDComm status flags
52  * @{
53  */
54 #define LD_PARITY_ERROR 32 /**< @brief Parity error happened. */
55 #define LD_FRAMING_ERROR 64 /**< @brief Framing error happened. */
56 #define LD_OVERRUN_ERROR 128 /**< @brief Overflow happened. */
57 #define LD_LINK_UP 256 /**< @brief Link detected. */
58 #define LD_LINK_DOWN 512 /**< @brief No link detected. */
59 /** @} */
60 /** @} */
61 
62 #define MARK 0
63 #define SPACE 1
64 #define STOP 2
65 #define NONE 3
66 
67 /*===========================================================================*/
68 /* Driver pre-compile time settings. */
69 /*===========================================================================*/
70 /**
71  * @name Configuration options
72  * @{
73  */
74 #if !defined(LEDCOMM_USE_LCOM1) || defined(__DOXYGEN__)
75 #define LEDCOMM_USE_LCOM1 TRUE
76 #endif
77 
78 #if !defined(LEDCOMM_USE_LCOM2) || defined(__DOXYGEN__)
79 #define LEDCOMM_USE_LCOM2 FALSE
80 #endif
81 
82 #if !defined(LEDCOMM_BUFFERS_SIZE) || defined(__DOXYGEN__)
83 #define LEDCOMM_BUFFERS_SIZE 16
84 #endif
85 /** @} */
86 
87 #define LEDCOMM_DEFAULT_SYNCS 18 /**< @brief Number of MARKs before considering the link is "up". */
88 #define LEDCOMM_DEFAULT_THRESHOLD 3000 /**< @brief Maximum number of hal ticks for a "shine". */
89 
90 #define LEDCOMM_DATA_BITS8 0 /**< @brief 8 data bits per character. */
91 #define LEDCOMM_DATA_BITS7 1 /**< @brief 7 data bits per character (default). */
92 #if !defined(LEDCOMM_DEFAULT_DATA_BITS) || defined(__DOXYGEN__)
93 #define LEDCOMM_DEFAULT_DATA_BITS LEDCOMM_DATA_BITS7
94 #endif
95 
96 #define LEDCOMM_PARITY_NONE 0 /**< @brief Disable parity generation/detection (default). */
97 #define LEDCOMM_PARITY 1 /**< @brief Enable parity generation/detection. */
98 #if !defined(LEDCOMM_DEFAULT_PARITY) || defined(__DOXYGEN__)
99 #define LEDCOMM_DEFAULT_PARITY LEDCOMM_PARITY_NONE
100 #endif
101 
102 #define LEDCOMM_PARITY_EVEN 0 /**< @brief Use even parity (default). */
103 #define LEDCOMM_PARITY_ODD 1 /**< @brief Use off parity. */
104 #define LEDCOMM_PARITY_SPACE 2 /**< @brief Use space parity. */
105 #define LEDCOMM_PARITY_MARK 3 /**< @brief Use mark parity. */
106 #if !defined(LEDCOMM_DEFAULT_PARITY_TYPE) || defined(__DOXYGEN__)
107 #define LEDCOMM_DEFAULT_PARITY_TYPE LEDCOMM_PARITY_EVEN
108 #endif
109 
110 /** @} */
111 
112 /*===========================================================================*/
113 /* Derived constants and error checks. */
114 /*===========================================================================*/
115 
116 /*===========================================================================*/
117 /* Driver data structures and types. */
118 /*===========================================================================*/
119 /**
120  * @brief @p LEDCommDriver specific data.
121  */
122 #define _ledcomm_driver_data \
123  _base_asynchronous_channel_data \
124  /* Driver state.*/ \
125  ldstate_t state; \
126  /* Input queue.*/ \
127  InputQueue iqueue; \
128  /* Output queue.*/ \
129  OutputQueue oqueue; \
130  /* Input circular buffer.*/ \
131  uint8_t ib[LEDCOMM_BUFFERS_SIZE]; \
132  /* Output circular buffer.*/ \
133  uint8_t ob[LEDCOMM_BUFFERS_SIZE]; \
134  /* End of the mandatory fields.*/ \
135  ioportid_t anode_port; \
136  ioportmask_t anode_pad; \
137  ioportid_t cathode_port; \
138  ioportmask_t cathode_pad; \
139  uint16_t threshold; /* The highest number of elapsed HAL ticks that represents a 'shine' */ \
140  uint8_t syncs:5; /* The number of MARKs received so far */ \
141  uint8_t data_bits:1; /* 0=8bits, 1=7bits */ \
142  uint8_t parity:1; /* 0=no parity, 1=parity */ \
143  uint8_t parity_type:2; /* 0=even, 1=odd, 2=space, 3=mark */ \
144  uint8_t parity_flag:1; /* 1=send/receive parity bit */ \
145  uint8_t enable:1; /* Enable LED comm */ \
146  uint8_t link:1; /* 1=link is up */ \
147  uint8_t txrdy:1; /* 1=ready to transmit */ \
148  uint8_t rxrdy:1; /* 1=ready to receive */ \
149  uint8_t txbit:2; /* 0=MARK, 1=SPACE, 2=STOP */ \
150  uint8_t tx_bits:4; /* The remaining number of bits to transmit */ \
151  uint8_t rx_bits:4; /* The remaining number of bits to receive */ \
152  uint8_t tx_char; /* The character that is being transmitted */ \
153  uint8_t rx_char; /* The received character */ \
154  uint16_t rx_register; /* A shift register holding the bits of the character we're currently receiving */ \
155  uint32_t c; /* The number of HAL ticks at the start of LED detection */ \
156  uint8_t count; /* A sequence counter */
157 
158 /**
159  * @brief LEDComm Driver configuration structure.
160  * @details An instance of this structure must be passed to @p lcommStart()
161  * in order to configure and start LEDComm driver operations.
162  * @note This structure has some content that is architecture dependent, each driver
163  * implementation defines its own version and the custom static
164  * initializers.
165  */
166 typedef struct {
167  ioportid_t anode_port; /**< @brief The port where the LED anode is connected. */
168  ioportmask_t anode_pad; /**< @brief The pad where the LED anode is connected. */
169  ioportid_t cathode_port; /**< @brief The port where the LED cathode is connected. */
170  ioportmask_t cathode_pad; /**< @brief The pad where the LED cathode is connected. */
171  uint32_t cathode_extmode; /**< @brief The processor-specific EXT mode used to configure the extcfg table */
172  uint16_t threshold; /**< @brief The highest number of elapsed HAL ticks that represents
173  * a 'shine' -- try @p LEDCOMM_DEFAULT_THRESHOLD (3000)
174  */
175  uint8_t data_bits:1; /**< @brief @p LEDCOMM_DATA_BITS8 or @p LEDCOMM_DATA_BITS7 */
176  uint8_t parity:1; /**< @brief @p LEDCOMM_PARITY or @p LEDCOMM_PARITY_NONE */
177  uint8_t parity_type:2; /**< @brief One of @p LEDCOMM_PARITY_EVEN, @p LEDCOMM_PARITY_ODD,
178  * @p LEDCOMM_PARITY_MARK or @p LEDCOMM_PARITY_SPACE
179  */
180  /* End of the mandatory fields.*/
182 
183 /**
184  * @brief Driver state machine possible states.
185  */
186 typedef enum {
187  LD_UNINIT = 0, /**< @brief Not initialized. */
188  LD_STOP = 1, /**< @brief Stopped. */
189  LD_READY = 2 /**< @brief Ready. */
190 } ldstate_t;
191 
192 /**
193  * @brief Structure representing a LEDComm driver.
194  */
196 
197 /**
198  * @brief @p LEDCommDriver specific methods.
199  */
200 #define _ledcomm_driver_methods \
201  _base_asynchronous_channel_methods
202 
203 /**
204  * @extends BaseAsynchronousChannelVMT
205  *
206  * @brief @p LEDCommDriver virtual methods table.
207  */
210 };
211 
212 /**
213  * @extends BaseAsynchronousChannel
214  *
215  * @brief Full duplex LEDComm driver class.
216  * @details This class extends @p BaseAsynchronousChannel by adding physical
217  * I/O queues.
218  */
220  /** @brief Virtual Methods Table.*/
221  const struct LEDCommDriverVMT *vmt;
223 };
224 
225 /*===========================================================================*/
226 /* Driver macros. */
227 /*===========================================================================*/
228 
229 /**
230  * @name Macro Functions
231  * @{
232  */
233 /**
234  * @brief Direct write to a @p LEDCommDriver.
235  * @note This function bypasses the indirect access to the channel and
236  * writes directly on the output queue. This is faster but cannot
237  * be used to write to different channels implementations.
238  *
239  * @see chnPutTimeout()
240  *
241  * @api
242  */
243 #define ldPut(ldp, b) chOQPut(&(ldp)->oqueue, b)
244 
245 /**
246  * @brief Direct write to a @p LEDCommDriver with timeout specification.
247  * @note This function bypasses the indirect access to the channel and
248  * writes directly on the output queue. This is faster but cannot
249  * be used to write to different channels implementations.
250  *
251  * @see chnPutTimeout()
252  *
253  * @api
254  */
255 #define ldPutTimeout(ldp, b, t) chOQPutTimeout(&(ldp)->oqueue, b, t)
256 
257 /**
258  * @brief Direct read from a @p LEDCommDriver.
259  * @note This function bypasses the indirect access to the channel and
260  * reads directly from the input queue. This is faster but cannot
261  * be used to read from different channels implementations.
262  *
263  * @see chnGetTimeout()
264  *
265  * @api
266  */
267 #define ldGet(ldp) chIQGet(&(ldp)->iqueue)
268 
269 /**
270  * @brief Direct read from a @p LEDCommDriver with timeout specification.
271  * @note This function bypasses the indirect access to the channel and
272  * reads directly from the input queue. This is faster but cannot
273  * be used to read from different channels implementations.
274  *
275  * @see chnGetTimeout()
276  *
277  * @api
278  */
279 #define ldGetTimeout(ldp, t) chIQGetTimeout(&(ldp)->iqueue, t)
280 
281 /**
282  * @brief Direct blocking write to a @p LEDCommDriver.
283  * @note This function bypasses the indirect access to the channel and
284  * writes directly to the output queue. This is faster but cannot
285  * be used to write from different channels implementations.
286  *
287  * @see chnWrite()
288  *
289  * @api
290  */
291 #define ldWrite(ldp, b, n) \
292  chOQWriteTimeout(&(ldp)->oqueue, b, n, TIME_INFINITE)
293 
294 /**
295  * @brief Direct blocking write to a @p LEDCommDriver with timeout
296  * specification.
297  * @note This function bypasses the indirect access to the channel and
298  * writes directly to the output queue. This is faster but cannot
299  * be used to write to different channels implementations.
300  *
301  * @see chnWriteTimeout()
302  *
303  * @api
304  */
305 #define ldWriteTimeout(ldp, b, n, t) \
306  chOQWriteTimeout(&(ldp)->oqueue, b, n, t)
307 
308 /**
309  * @brief Direct non-blocking write to a @p LEDCommDriver.
310  * @note This function bypasses the indirect access to the channel and
311  * writes directly to the output queue. This is faster but cannot
312  * be used to write to different channels implementations.
313  *
314  * @see chnWriteTimeout()
315  *
316  * @api
317  */
318 #define ldAsynchronousWrite(ldp, b, n) \
319  chOQWriteTimeout(&(ldp)->oqueue, b, n, TIME_IMMEDIATE)
320 
321 /**
322  * @brief Direct blocking read from a @p LEDCommDriver.
323  * @note This function bypasses the indirect access to the channel and
324  * reads directly from the input queue. This is faster but cannot
325  * be used to read from different channels implementations.
326  *
327  * @see chnRead()
328  *
329  * @api
330  */
331 #define ldRead(ldp, b, n) \
332  chIQReadTimeout(&(ldp)->iqueue, b, n, TIME_INFINITE)
333 
334 /**
335  * @brief Direct blocking read from a @p LEDCommDriver with timeout
336  * specification.
337  * @note This function bypasses the indirect access to the channel and
338  * reads directly from the input queue. This is faster but cannot
339  * be used to read from different channels implementations.
340  *
341  * @see chnReadTimeout()
342  *
343  * @api
344  */
345 #define ldReadTimeout(ldp, b, n, t) \
346  chIQReadTimeout(&(ldp)->iqueue, b, n, t)
347 
348 /**
349  * @brief Direct non-blocking read from a @p LEDCommDriver.
350  * @note This function bypasses the indirect access to the channel and
351  * reads directly from the input queue. This is faster but cannot
352  * be used to read from different channels implementations.
353  *
354  * @see chnReadTimeout()
355  *
356  * @api
357  */
358 #define ldAsynchronousRead(ldp, b, n) \
359  chIQReadTimeout(&(ldp)->iqueue, b, n, TIME_IMMEDIATE)
360 /** @} */
361 
362 /*===========================================================================*/
363 /* External declarations. */
364 /*===========================================================================*/
365 
366 #if LEDCOMM_USE_LCOM1 && !defined(__DOXYGEN__)
367 extern LEDCommDriver_t LCOM1;
368 #endif
369 #if LEDCOMM_USE_LCOM2 && !defined(__DOXYGEN__)
370 extern LEDCommDriver_t LCOM2;
371 #endif
372 
373 #if LEDCOMM_USE_GPTD1 && !defined(__DOXYGEN__)
374 #define GPTD_LEDComm GPTD1
375 #endif
376 
377 #if LEDCOMM_USE_GPTD2 && !defined(__DOXYGEN__)
378 #define GPTD_LEDComm GPTD2
379 #endif
380 
381 #if LEDCOMM_USE_EXTD1 && !defined(__DOXYGEN__)
382 #define EXTD_LEDComm EXTD1
383 #endif
384 
385 #if LEDCOMM_USE_EXTD2 && !defined(__DOXYGEN__)
386 #define EXTD_LEDComm EXTD2
387 #endif
388 
389 
390 #ifdef __cplusplus
391 extern "C" {
392 #endif
393  void ldInit(void);
394  void ldObjectInit(LEDCommDriver_t *ldp, qnotify_t inotify, qnotify_t onotify);
395  void ldStart(LEDCommDriver_t *ldp, const LEDCommConfig_t *config);
396  void ldStop(LEDCommDriver_t *ldp);
397  void ldIncomingDataI(LEDCommDriver_t *ldp, uint8_t b);
398  msg_t ldRequestDataI(LEDCommDriver_t *ldp);
399  inline bool_t isLinkUp(LEDCommDriver_t *l);
400  inline bool_t isLinkDown(LEDCommDriver_t *l);
401  inline void linkUp(LEDCommDriver_t *l);
402  inline void linkDown(LEDCommDriver_t *l);
403  void ledCommSerialHandler(LEDCommDriver_t *ldp);
404 #ifdef __cplusplus
405 }
406 #endif
407 
408 #endif /* _LEDCOMM_H_ */
409 
410 /** @} */
#define _ledcomm_driver_data
LEDCommDriver specific data.
Definition: ledcomm.h:122
void ldStart(LEDCommDriver_t *ldp, const LEDCommConfig_t *config)
Configures and starts the driver.
Definition: ledcomm.c:341
ioportid_t cathode_port
The port where the LED cathode is connected.
Definition: ledcomm.h:169
ldstate_t
Driver state machine possible states.
Definition: ledcomm.h:186
ioportid_t anode_port
The port where the LED anode is connected.
Definition: ledcomm.h:167
uint16_t threshold
The highest number of elapsed HAL ticks that represents a 'shine' – try LEDCOMM_DEFAULT_THRESHOLD (3...
Definition: ledcomm.h:172
Ready.
Definition: ledcomm.h:189
uint32_t cathode_extmode
The processor-specific EXT mode used to configure the extcfg table.
Definition: ledcomm.h:171
LEDComm configuration header.
void ldStop(LEDCommDriver_t *ldp)
Stops the driver.
Definition: ledcomm.c:413
LEDCommDriver virtual methods table.
Definition: ledcomm.h:208
#define _ledcomm_driver_methods
LEDCommDriver specific methods.
Definition: ledcomm.h:200
void ldInit(void)
LEDComm Driver initialization.
Definition: ledcomm.c:296
LEDComm Driver configuration structure.
Definition: ledcomm.h:166
msg_t ldRequestDataI(LEDCommDriver_t *ldp)
Handles outgoing data.
Definition: ledcomm.c:474
Not initialized.
Definition: ledcomm.h:187
void ldObjectInit(LEDCommDriver_t *ldp, qnotify_t inotify, qnotify_t onotify)
Initializes a generic full duplex driver object.
Definition: ledcomm.c:322
void ldIncomingDataI(LEDCommDriver_t *ldp, uint8_t b)
Handles incoming data.
Definition: ledcomm.c:445
const struct LEDCommDriverVMT * vmt
Virtual Methods Table.
Definition: ledcomm.h:221
Full duplex LEDComm driver class.
Definition: ledcomm.h:219
ioportmask_t cathode_pad
The pad where the LED cathode is connected.
Definition: ledcomm.h:170
ioportmask_t anode_pad
The pad where the LED anode is connected.
Definition: ledcomm.h:168
Stopped.
Definition: ledcomm.h:188