1 |
/*! \file buffer.c \brief Multipurpose byte buffer structure and methods. */ |
1 |
/*! \file buffer.c \brief Multipurpose byte buffer structure and methods. */ |
2 |
//***************************************************************************** |
2 |
//***************************************************************************** |
3 |
// |
3 |
// |
4 |
// File Name : 'buffer.c' |
4 |
// File Name : 'buffer.c' |
5 |
// Title : Multipurpose byte buffer structure and methods |
5 |
// Title : Multipurpose byte buffer structure and methods |
6 |
// Author : Pascal Stang - Copyright (C) 2001-2002 |
6 |
// Author : Pascal Stang - Copyright (C) 2001-2002 |
7 |
// Created : 9/23/2001 |
7 |
// Created : 9/23/2001 |
8 |
// Revised : 9/23/2001 |
8 |
// Revised : 9/23/2001 |
9 |
// Version : 1.0 |
9 |
// Version : 1.0 |
10 |
// Target MCU : any |
10 |
// Target MCU : any |
11 |
// Editor Tabs : 4 |
11 |
// Editor Tabs : 4 |
12 |
// |
12 |
// |
13 |
// This code is distributed under the GNU Public License |
13 |
// This code is distributed under the GNU Public License |
14 |
// which can be found at http://www.gnu.org/licenses/gpl.txt |
14 |
// which can be found at http://www.gnu.org/licenses/gpl.txt |
15 |
// |
15 |
// |
16 |
//***************************************************************************** |
16 |
//***************************************************************************** |
17 |
|
17 |
|
18 |
#include "buffer.h" |
18 |
#include "buffer.h" |
19 |
#include "global.h" |
19 |
#include "global.h" |
20 |
#include "avr/io.h" |
20 |
#include "avr/io.h" |
21 |
|
21 |
|
22 |
#ifndef CRITICAL_SECTION_START |
22 |
#ifndef CRITICAL_SECTION_START |
23 |
#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli() |
23 |
#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli() |
24 |
#define CRITICAL_SECTION_END SREG = _sreg |
24 |
#define CRITICAL_SECTION_END SREG = _sreg |
25 |
#endif |
25 |
#endif |
26 |
|
26 |
|
27 |
// global variables |
27 |
// global variables |
28 |
|
28 |
|
29 |
// initialization |
29 |
// initialization |
30 |
|
30 |
|
31 |
void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size) |
31 |
void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size) |
32 |
{ |
32 |
{ |
33 |
// begin critical section |
33 |
// begin critical section |
34 |
CRITICAL_SECTION_START; |
34 |
CRITICAL_SECTION_START; |
35 |
// set start pointer of the buffer |
35 |
// set start pointer of the buffer |
36 |
buffer->dataptr = start; |
36 |
buffer->dataptr = start; |
37 |
buffer->size = size; |
37 |
buffer->size = size; |
38 |
// initialize index and length |
38 |
// initialize index and length |
39 |
buffer->dataindex = 0; |
39 |
buffer->dataindex = 0; |
40 |
buffer->datalength = 0; |
40 |
buffer->datalength = 0; |
41 |
// end critical section |
41 |
// end critical section |
42 |
CRITICAL_SECTION_END; |
42 |
CRITICAL_SECTION_END; |
43 |
} |
43 |
} |
44 |
|
44 |
|
45 |
// access routines |
45 |
// access routines |
46 |
unsigned char bufferGetFromFront(cBuffer* buffer) |
46 |
unsigned char bufferGetFromFront(cBuffer* buffer) |
47 |
{ |
47 |
{ |
48 |
unsigned char data = 0; |
48 |
unsigned char data = 0; |
49 |
// begin critical section |
49 |
// begin critical section |
50 |
CRITICAL_SECTION_START; |
50 |
CRITICAL_SECTION_START; |
51 |
// check to see if there's data in the buffer |
51 |
// check to see if there's data in the buffer |
52 |
if(buffer->datalength) |
52 |
if(buffer->datalength) |
53 |
{ |
53 |
{ |
54 |
// get the first character from buffer |
54 |
// get the first character from buffer |
55 |
data = buffer->dataptr[buffer->dataindex]; |
55 |
data = buffer->dataptr[buffer->dataindex]; |
56 |
// move index down and decrement length |
56 |
// move index down and decrement length |
57 |
buffer->dataindex++; |
57 |
buffer->dataindex++; |
58 |
if(buffer->dataindex >= buffer->size) |
58 |
if(buffer->dataindex >= buffer->size) |
59 |
{ |
59 |
{ |
60 |
buffer->dataindex -= buffer->size; |
60 |
buffer->dataindex -= buffer->size; |
61 |
} |
61 |
} |
62 |
buffer->datalength--; |
62 |
buffer->datalength--; |
63 |
} |
63 |
} |
64 |
// end critical section |
64 |
// end critical section |
65 |
CRITICAL_SECTION_END; |
65 |
CRITICAL_SECTION_END; |
66 |
// return |
66 |
// return |
67 |
return data; |
67 |
return data; |
68 |
} |
68 |
} |
69 |
|
69 |
|
70 |
void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes) |
70 |
void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes) |
71 |
{ |
71 |
{ |
72 |
// begin critical section |
72 |
// begin critical section |
73 |
CRITICAL_SECTION_START; |
73 |
CRITICAL_SECTION_START; |
74 |
// dump numbytes from the front of the buffer |
74 |
// dump numbytes from the front of the buffer |
75 |
// are we dumping less than the entire buffer? |
75 |
// are we dumping less than the entire buffer? |
76 |
if(numbytes < buffer->datalength) |
76 |
if(numbytes < buffer->datalength) |
77 |
{ |
77 |
{ |
78 |
// move index down by numbytes and decrement length by numbytes |
78 |
// move index down by numbytes and decrement length by numbytes |
79 |
buffer->dataindex += numbytes; |
79 |
buffer->dataindex += numbytes; |
80 |
if(buffer->dataindex >= buffer->size) |
80 |
if(buffer->dataindex >= buffer->size) |
81 |
{ |
81 |
{ |
82 |
buffer->dataindex -= buffer->size; |
82 |
buffer->dataindex -= buffer->size; |
83 |
} |
83 |
} |
84 |
buffer->datalength -= numbytes; |
84 |
buffer->datalength -= numbytes; |
85 |
} |
85 |
} |
86 |
else |
86 |
else |
87 |
{ |
87 |
{ |
88 |
// flush the whole buffer |
88 |
// flush the whole buffer |
89 |
buffer->datalength = 0; |
89 |
buffer->datalength = 0; |
90 |
} |
90 |
} |
91 |
// end critical section |
91 |
// end critical section |
92 |
CRITICAL_SECTION_END; |
92 |
CRITICAL_SECTION_END; |
93 |
} |
93 |
} |
94 |
|
94 |
|
95 |
unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index) |
95 |
unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index) |
96 |
{ |
96 |
{ |
97 |
// begin critical section |
97 |
// begin critical section |
98 |
CRITICAL_SECTION_START; |
98 |
CRITICAL_SECTION_START; |
99 |
// return character at index in buffer |
99 |
// return character at index in buffer |
100 |
unsigned char data = buffer->dataptr[(buffer->dataindex+index)%(buffer->size)]; |
100 |
unsigned char data = buffer->dataptr[(buffer->dataindex+index)%(buffer->size)]; |
101 |
// end critical section |
101 |
// end critical section |
102 |
CRITICAL_SECTION_END; |
102 |
CRITICAL_SECTION_END; |
103 |
return data; |
103 |
return data; |
104 |
} |
104 |
} |
105 |
|
105 |
|
106 |
unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data) |
106 |
unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data) |
107 |
{ |
107 |
{ |
108 |
// begin critical section |
108 |
// begin critical section |
109 |
CRITICAL_SECTION_START; |
109 |
CRITICAL_SECTION_START; |
110 |
// make sure the buffer has room |
110 |
// make sure the buffer has room |
111 |
if(buffer->datalength < buffer->size) |
111 |
if(buffer->datalength < buffer->size) |
112 |
{ |
112 |
{ |
113 |
// save data byte at end of buffer |
113 |
// save data byte at end of buffer |
114 |
buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = data; |
114 |
buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = data; |
115 |
// increment the length |
115 |
// increment the length |
116 |
buffer->datalength++; |
116 |
buffer->datalength++; |
117 |
// end critical section |
117 |
// end critical section |
118 |
CRITICAL_SECTION_END; |
118 |
CRITICAL_SECTION_END; |
119 |
// return success |
119 |
// return success |
120 |
return -1; |
120 |
return -1; |
121 |
} |
121 |
} |
122 |
// end critical section |
122 |
// end critical section |
123 |
CRITICAL_SECTION_END; |
123 |
CRITICAL_SECTION_END; |
124 |
// return failure |
124 |
// return failure |
125 |
return 0; |
125 |
return 0; |
126 |
} |
126 |
} |
127 |
|
127 |
|
128 |
unsigned short bufferIsNotFull(cBuffer* buffer) |
128 |
unsigned short bufferIsNotFull(cBuffer* buffer) |
129 |
{ |
129 |
{ |
130 |
// begin critical section |
130 |
// begin critical section |
131 |
CRITICAL_SECTION_START; |
131 |
CRITICAL_SECTION_START; |
132 |
// check to see if the buffer has room |
132 |
// check to see if the buffer has room |
133 |
// return true if there is room |
133 |
// return true if there is room |
134 |
unsigned short bytesleft = (buffer->size - buffer->datalength); |
134 |
unsigned short bytesleft = (buffer->size - buffer->datalength); |
135 |
// end critical section |
135 |
// end critical section |
136 |
CRITICAL_SECTION_END; |
136 |
CRITICAL_SECTION_END; |
137 |
return bytesleft; |
137 |
return bytesleft; |
138 |
} |
138 |
} |
139 |
|
139 |
|
140 |
void bufferFlush(cBuffer* buffer) |
140 |
void bufferFlush(cBuffer* buffer) |
141 |
{ |
141 |
{ |
142 |
// begin critical section |
142 |
// begin critical section |
143 |
CRITICAL_SECTION_START; |
143 |
CRITICAL_SECTION_START; |
144 |
// flush contents of the buffer |
144 |
// flush contents of the buffer |
145 |
buffer->datalength = 0; |
145 |
buffer->datalength = 0; |
146 |
// end critical section |
146 |
// end critical section |
147 |
CRITICAL_SECTION_END; |
147 |
CRITICAL_SECTION_END; |
148 |
} |
148 |
} |
149 |
|
149 |
|