-
Notifications
You must be signed in to change notification settings - Fork 18
/
fifo.h
132 lines (104 loc) · 3.64 KB
/
fifo.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#ifndef __FIFO_H__
#define __FIFO_H__
#include <stdint.h>
template <class Type, const size_t Size=8> // size must be (!) a power of 2 like 4, 8, 16, 32, etc.
class FIFO
{ public:
static const size_t Len = Size;
static const size_t PtrMask = Size-1;
Type Data[Len];
size_t ReadPtr;
size_t WritePtr;
public:
void Clear(void) // clear all stored data
{ ReadPtr=0; WritePtr=0; }
size_t Write(Type Byte) // write a single element
{ size_t Ptr=WritePtr;
Data[Ptr]=Byte;
Ptr++; Ptr&=PtrMask;
if(Ptr==ReadPtr) return 0;
WritePtr=Ptr; return 1; }
bool isFull(void) const // if FIFO full ?
{ size_t Ptr=WritePtr;
Ptr++; Ptr&=PtrMask;
return Ptr==ReadPtr; }
size_t Free(void) const // number of free elements: how much can you write into te FIFO
{ return ((ReadPtr-WritePtr-1)&PtrMask); }
size_t Full(void) const // number of stored elements: how much you can read from the FIFO
{ return ((WritePtr-ReadPtr)&PtrMask); }
Type *getWrite(void) // get pointer to the next element which can be written
{ return Data+WritePtr; }
size_t Write(void) // advance the write pointer: to be used with getWrite()
{ size_t Ptr=WritePtr;
Ptr++; Ptr&=PtrMask;
if(Ptr==ReadPtr) return 0;
WritePtr=Ptr; return 1; }
size_t Read(Type &Byte) // read a single element
{ size_t Ptr=ReadPtr;
if(Ptr==WritePtr) return 0;
Byte=Data[Ptr];
Ptr++; Ptr&=PtrMask;
ReadPtr=Ptr; return 1; }
void Read(void)
{ size_t Ptr=ReadPtr;
if(Ptr==WritePtr) return;
Ptr++; Ptr&=PtrMask;
ReadPtr=Ptr; }
Type *getRead(void)
{ if(ReadPtr==WritePtr) return 0;
return Data+ReadPtr; }
Type *getRead(size_t Idx)
{ if(Idx>=Full()) return 0;
size_t Ptr=(ReadPtr+Idx)&PtrMask;
return Data+Ptr; }
size_t getReadBlock(Type *&Byte) // get a pointer to the first element and the number of consecutive elements available for read
{ if(ReadPtr==WritePtr) { Byte=0; return 0; }
Byte = Data+ReadPtr;
if(ReadPtr<WritePtr) return WritePtr-ReadPtr;
return Size-ReadPtr; }
void flushReadBlock(size_t Len) // flush the elements which were already read: to be used after getReadBlock()
{ ReadPtr+=Len; ReadPtr&=PtrMask; }
bool isEmpty(void) const // is the FIFO all empty ?
{ return ReadPtr==WritePtr; }
size_t Write(const Type *Data, size_t Len) // write a block of elements into the FIFO (could possibly be smarter than colling single Write many times)
{ size_t Idx;
for(Idx=0; Idx<Len; Idx++)
{ if(Write(Data[Idx])==0) break; }
return Idx; }
/*
Type Read(void)
{ uint16_t Ptr=ReadPtr;
if(Ptr==WritePtr) return 0x00;
uint8_t Byte=Data[Ptr];
Ptr++; Ptr&=PtrMask;
ReadPtr=Ptr; return Byte; }
uint16_t ReadReady(void) const
{ return ReadPtr!=WritePtr; }
uint8_t WriteReady(void) const
{ uint8_t Ptr=WritePtr;
Ptr++; Ptr&=PtrMask;
return Ptr!=ReadPtr; }
*/
} ;
template <class Type, const uint8_t Size=8> // size must be (!) a power of 2 like 4, 8, 16, 32, etc.
class Delay
{ public:
static const uint8_t Len = Size;
static const uint8_t PtrMask = Size-1;
Type Data[Len];
uint8_t Ptr;
public:
void Clear(Type Zero=0)
{ for(uint8_t Idx=0; Idx<Len; Idx++)
Data[Idx]=Zero;
Ptr=0; }
Type Input(Type Inp)
{ Ptr--; Ptr&=PtrMask;
Type Out=Data[Ptr];
Data[Ptr]=Inp;
return Out; }
Type & operator[](uint8_t Idx)
{ Idx = Ptr-Idx; Idx&=PtrMask;
return Data[Idx]; }
} ;
#endif // __FIFO_H__