1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef HDF_USB_DATA_FIFO_H
17#define HDF_USB_DATA_FIFO_H
18
19#include "hdf_base.h"
20
21struct DataFifo {
22    uint32_t rdIdx;
23    uint32_t wrIdx;
24    uint32_t size;
25    void *data;
26};
27
28#ifndef MIN
29inline int32_t MIN(int32_t a, int32_t b)
30{
31    return ((a) < (b) ? (a) : (b));
32}
33#endif
34
35#ifndef MAX
36inline int32_t MAX(int32_t a, int32_t b)
37{
38    return ((a) > (b) ? (a) : (b));
39}
40#endif
41
42/* DataFifo Helper function */
43inline void DataFifoInit(struct DataFifo *fifo, uint32_t size, void *data)
44{
45    fifo->rdIdx = 0;
46    fifo->wrIdx = 0;
47    fifo->size = size;
48    fifo->data = data;
49}
50
51inline bool DataFifoIsInitialized(struct DataFifo * const fifo)
52{
53    return fifo->size != 0;
54}
55
56inline void DataFifoReset(struct DataFifo * const fifo)
57{
58    fifo->rdIdx = fifo->wrIdx = 0;
59}
60
61inline uint32_t DataFifoLen(struct DataFifo * const fifo)
62{
63    return fifo->wrIdx - fifo->rdIdx;
64}
65
66inline bool DataFifoIsEmpty(struct DataFifo * const fifo)
67{
68    return fifo->wrIdx == fifo->rdIdx;
69}
70
71inline bool DataFifoIsFull(struct DataFifo * const fifo)
72{
73    return DataFifoLen(fifo) > (fifo->size - 1);
74}
75
76inline uint32_t DataFifoAvailSize(struct DataFifo * const fifo)
77{
78    return fifo->size - DataFifoLen(fifo);
79}
80
81inline void DataFifoSkip(struct DataFifo * const fifo, uint32_t size)
82{
83    fifo->rdIdx += size;
84}
85
86inline uint32_t DataFifoWrite(struct DataFifo *fifo, uint8_t *data, uint32_t size)
87{
88    uint32_t mask = fifo->size - 1;
89    uint8_t *buf = (uint8_t *)fifo->data;
90    uint8_t *end;
91
92    size = MIN(size, DataFifoAvailSize(fifo));
93    end = data + size;
94    while (data < end) {
95        buf[fifo->wrIdx++ & mask] = *data++;
96    }
97    return size;
98}
99
100inline uint32_t DataFifoRead(struct DataFifo *fifo, uint8_t *data, uint32_t size)
101{
102    uint32_t mask = fifo->size - 1;
103    uint8_t *buf = (uint8_t *)fifo->data;
104    uint8_t *end;
105
106    size = MIN(size, DataFifoLen(fifo));
107    end = data + size;
108    while (data < end) {
109        *data++ = buf[fifo->rdIdx++ & mask];
110    }
111    return size;
112}
113
114#endif /* HDF_USB_DATA_FIFO_H */
115