Project

General

Profile

Statistics
| Revision:

root / branches / autonomous_recharging / code / projects / autonomous_recharging / archs / ring_buffer.h @ 955

History | View | Annotate | Download (4.29 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
#ifndef _RING_BUFFER_H
11
#define _RING_BUFFER_H
12

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

    
33

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

    
41
/** @brief Initializes the ring buffer, setting its size to the correct value
42
 *
43
 *        @param buf The ring buffer to initialize.
44
 *
45
 *  @param size The size of the ring buffer (in array elements)
46
 */
47
#define RING_BUFFER_INIT(buf, size)                         \
48
        do {                                                                                \
49
                (buf).buffer_size = size;                                \
50
        } while(0)
51

    
52
#define RING_BUFFER_BIT_INIT(buf, size)                 \
53
        do {                                                                                \
54
                (buf).buffer_size = size;                                \
55
        } while(0)
56
        
57

    
58
/** @brief Sets the specified ring buffer to be empty.
59
 *
60
 *        @param buf The ring buffer to make empty.
61
 */
62
#define RING_BUFFER_CLEAR(buf)        \
63
        do {                                                \
64
                (buf).start = 0;                \
65
                (buf).end = 0;                        \
66
        } while (0)
67

    
68
#define RING_BUFFER_BIT_CLEAR(buf) RING_BUFFER_CLEAR(buf)
69
/** @brief Returns true if the ring buffer specified is empty.
70
 *
71
 *        @param buf The buffer to check emptiness of.
72
 */
73
#define RING_BUFFER_EMPTY(buf) ((buf).start == (buf).end)
74

    
75

    
76

    
77
#define RING_BUFFER_BIT_EMPTY(buf) RING_BUFFER_EMPTY(buf)
78

    
79

    
80
/** @brief Returns true if the ring buffer specified is full.
81
 *
82
 *        @param buf The buffer to check fullness of.
83
 */
84
#define RING_BUFFER_FULL(buf)        \
85
                (((buf).end + 1) % (buf).buffer_size == (buf).start)
86

    
87
#define RING_BUFFER_BIT_FULL(buf) RING_BUFFER_FULL(buf)
88

    
89
/** @brief Adds val to ring buffer buf. Note that val must be of the type
90
 *        used in creating the ring buffer to prevent the compiler from spewing
91
 *        confusing errors. Also, this assumes that the ring buffer is not full.
92
 *
93
 *        @param buf The ring buffer to add to.
94
 *        @param val The value to add.
95
 */
96
#define RING_BUFFER_ADD(buf, val)                \
97
        do {                                                                \
98
                (buf).queue[(buf).end] = val;        \
99
                (buf).end = ((buf).end + 1) % (buf).buffer_size;        \
100
        } while (0)
101

    
102
#define RING_BUFFER_BIT_ADD(buf, val)        \
103
        do {                                                                \
104
                if (val) {                                                \
105
                        (buf).queue[((buf).end >> 3) & 0xff] |= _BV((buf).end & 0x7);        \
106
                }                                                                \
107
                else {                                                        \
108
                        (buf).queue[((buf).end >> 3) & 0xff] &= ~_BV((buf).end & 0x7);        \
109
                }                                                                \
110
                (buf).end = ((buf).end + 1) % ((buf).buffer_size) << 3);                        \
111
        } while (0)
112

    
113

    
114
/** @brief Removes the value at the head of the ring buffer and puts it in
115
 *        val_ret. Note that val_ret must be the same type used in creating the ring
116
 *        buffer to prevent the compiler from spewing confusing errors. Also, this
117
 *        assumes that the ring buffer is not empty.
118
 *
119
 *        @param buf The ring buffer to remove from.
120
 *        @param val_ret Where to put the value removed from the head of the ring
121
 *        buffer.
122
 */
123
#define RING_BUFFER_REMOVE(buf, val_ret)        \
124
        do {        \
125
                (val_ret) = (buf).queue[(buf).start];        \
126
                (buf).start = ((buf).start + 1) % (buf).buffer_size;        \
127
        } while (0)
128

    
129
#define RING_BUFFER_BIT_REMOVE(buf, val_ret)        \
130
        do {        \
131
                (val_ret) = ((buf).queue[((buf).start >> 3) & 0xff] & _BV((buf).start & 0x7)) ? 1 : 0;        \
132
                (buf).start = ((buf).start + 1) % ((buf).buffer_size << 3);        \
133
        } while (0)
134

    
135
/** @brief Checks the value at the head of the ring buffer without removing it
136
 *  and puts it into val_ret. Note that val_ret must be the same type used in
137
 *  creating the ring buffer to prevent the compiler from spewing confusing
138
 *  errors. Also, this assumes that the ring buffer is not empty.
139
 *
140
 *  @param buf The ring buffer to check from
141
 *  @param val_ret where to put the value checked from the head of the ring
142
 */
143
 #define RING_BUFFER_PEEK(buf, val_ret)  \
144
  do { \
145
    (val_ret) = (buf).queue[(buf).start]; \
146
  } while(0)
147

    
148
#endif /* _RING_BUFFER_H */
149