Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / colonet / testing / robot_routine_reg_test / ring_buffer.h @ 13

History | View | Annotate | Download (3.35 KB)

1
/** @file Include macros to create a ring buffer. Originally written for 15-410.
2
 *  Modified for use in ATMega128 serial driver
3
 *
4
 *        @author Cornell Wright (cgwright)
5
 *        @author Jason P. Winters (jpwinter)
6
 *
7
 *        @bugs None known.
8
 */
9

    
10

    
11
#ifndef _RING_BUFFER_H
12
#define _RING_BUFFER_H
13

    
14
/** @brief Creates the struct for a new ring buffer. This just expands to a
15
 *        structure definition and thus should be invoked in the global context.
16
 *
17
 *        @param struct_name Name of the ring buffer struct.
18
 *
19
 *        @param size The size of the buffer to create.
20
 *
21
 *        @param type The type of object that the queue is to hold.
22
 *
23
 *        @param ... Name or names of the instance or instances of the ring buffer(s)
24
 *        to be created.
25
 */
26
#define RING_BUFFER_NEW(struct_name, size, type, ...)        \
27
        struct struct_name {        \
28
                type queue[size];        \
29
                uint8_t start;                        \
30
                uint8_t end;                        \
31
        } __VA_ARGS__
32

    
33
#define RING_BUFFER_BIT_NEW(struct_name, size, ...)        \
34
        struct struct_name {        \
35
                int8_t queue[(size / 8) + 1];        \
36
                uint16_t start;        \
37
                uint16_t end;        \
38
        } __VA_ARGS__
39

    
40
/** @brief Sets the specified ring buffer to be empty.
41
 *
42
 *        @param buf The ring buffer to make empty.
43
 */
44
#define RING_BUFFER_CLEAR(buf)        \
45
        do {                                                \
46
                (buf).start = 0;                \
47
                (buf).end = 0;                        \
48
        } while (0)
49

    
50
#define RING_BUFFER_BIT_CLEAR(buf) RING_BUFFER_CLEAR(buf)
51
/** @brief Returns true if the ring buffer specified is empty.
52
 *
53
 *        @param buf The buffer to check emptiness of.
54
 */
55
#define RING_BUFFER_EMPTY(buf) ((buf).start == (buf).end)
56

    
57

    
58

    
59
#define RING_BUFFER_BIT_EMPTY(buf) RING_BUFFER_EMPTY(buf)
60

    
61

    
62
/** @brief Returns true if the ring buffer specified is full.
63
 *
64
 *        @param buf The buffer to check fullness of.
65
 */
66
#define RING_BUFFER_FULL(buf)        \
67
                (((buf).end + 1) % sizeof((buf).queue) == (buf).start)
68

    
69
#define RING_BUFFER_BIT_FULL(buf) RING_BUFFER_FULL(buf)
70

    
71
/** @brief Adds val to ring buffer buf. Note that val must be of the type
72
 *        used in creating the ring buffer to prevent the compiler from spewing
73
 *        confusing errors. Also, this assumes that the ring buffer is not full.
74
 *
75
 *        @param buf The ring buffer to add to.
76
 *        @param val The value to add.
77
 */
78
#define RING_BUFFER_ADD(buf, val)                \
79
        do {                                                                \
80
                (buf).queue[(buf).end] = val;        \
81
                (buf).end = ((buf).end + 1) % sizeof((buf).queue);        \
82
        } while (0)
83

    
84
#define RING_BUFFER_BIT_ADD(buf, val)        \
85
        do {                                                                \
86
                if (val) {                                                \
87
                        (buf).queue[((buf).end >> 3) & 0xff] |= _BV((buf).end & 0x7);        \
88
                }                                                                \
89
                else {                                                        \
90
                        (buf).queue[((buf).end >> 3) & 0xff] &= ~_BV((buf).end & 0x7);        \
91
                }                                                                \
92
                (buf).end = ((buf).end + 1) % (sizeof((buf).queue) << 3);                        \
93
        } while (0)
94

    
95

    
96
/** @brief Removes the value at the head of the ring buffer and puts it in
97
 *        val_ret. Note that val_ret must be the same type used in creating the ring
98
 *        buffer to prevent the compiler from spewing confusing errors. Also, this
99
 *        assumes that the ring buffer is not empty.
100
 *
101
 *        @param buf The ring buffer to remove from.
102
 *        @param val_ret Where to put the value removed from the head of the ring
103
 *        buffer.
104
 */
105
#define RING_BUFFER_REMOVE(buf, val_ret)        \
106
        do {        \
107
                (val_ret) = (buf).queue[(buf).start];        \
108
                (buf).start = ((buf).start + 1) % sizeof((buf).queue);        \
109
        } while (0)
110

    
111
#define RING_BUFFER_BIT_REMOVE(buf, val_ret)        \
112
        do {        \
113
                (val_ret) = ((buf).queue[((buf).start >> 3) & 0xff] & _BV((buf).start & 0x7)) ? 1 : 0;        \
114
                (buf).start = ((buf).start + 1) % (sizeof((buf).queue) << 3);        \
115
        } while (0)
116

    
117
#endif /* _RING_BUFFER_H */
118