1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#ifndef HDF_USB_DATA_FIFO_H 17094332d3Sopenharmony_ci#define HDF_USB_DATA_FIFO_H 18094332d3Sopenharmony_ci 19094332d3Sopenharmony_ci#include "hdf_base.h" 20094332d3Sopenharmony_ci#include "hdf_log.h" 21094332d3Sopenharmony_ci 22094332d3Sopenharmony_ci#ifndef MIN 23094332d3Sopenharmony_ci#define MIN(a, b) ((a) < (b) ? (a) : (b)) 24094332d3Sopenharmony_ci#endif 25094332d3Sopenharmony_ci 26094332d3Sopenharmony_ci#ifndef MAX 27094332d3Sopenharmony_ci#define MAX(a, b) ((a) > (b) ? (a) : (b)) 28094332d3Sopenharmony_ci#endif 29094332d3Sopenharmony_ci 30094332d3Sopenharmony_cistruct DataFifo { 31094332d3Sopenharmony_ci uint32_t rdIdx; 32094332d3Sopenharmony_ci uint32_t wrIdx; 33094332d3Sopenharmony_ci uint32_t size; 34094332d3Sopenharmony_ci void *data; 35094332d3Sopenharmony_ci}; 36094332d3Sopenharmony_ci 37094332d3Sopenharmony_ci/* DataFifo Helper function */ 38094332d3Sopenharmony_cistatic inline void DataFifoInit(struct DataFifo *fifo, uint32_t size, void *data) 39094332d3Sopenharmony_ci{ 40094332d3Sopenharmony_ci if (size == 0) { 41094332d3Sopenharmony_ci HDF_LOGE("%{public}s: Fifo size is zero", __func__); 42094332d3Sopenharmony_ci return; 43094332d3Sopenharmony_ci } 44094332d3Sopenharmony_ci fifo->rdIdx = 0; 45094332d3Sopenharmony_ci fifo->wrIdx = 0; 46094332d3Sopenharmony_ci fifo->size = size; 47094332d3Sopenharmony_ci fifo->data = data; 48094332d3Sopenharmony_ci} 49094332d3Sopenharmony_ci 50094332d3Sopenharmony_cistatic inline bool DataFifoIsInitialized(struct DataFifo *fifo) 51094332d3Sopenharmony_ci{ 52094332d3Sopenharmony_ci return fifo->size != 0; 53094332d3Sopenharmony_ci} 54094332d3Sopenharmony_ci 55094332d3Sopenharmony_cistatic inline void DataFifoReset(struct DataFifo *fifo) 56094332d3Sopenharmony_ci{ 57094332d3Sopenharmony_ci fifo->rdIdx = fifo->wrIdx = 0; 58094332d3Sopenharmony_ci} 59094332d3Sopenharmony_ci 60094332d3Sopenharmony_cistatic inline uint32_t DataFifoLen(struct DataFifo *fifo) 61094332d3Sopenharmony_ci{ 62094332d3Sopenharmony_ci return fifo->wrIdx - fifo->rdIdx; 63094332d3Sopenharmony_ci} 64094332d3Sopenharmony_ci 65094332d3Sopenharmony_cistatic inline bool DataFifoIsEmpty(struct DataFifo *fifo) 66094332d3Sopenharmony_ci{ 67094332d3Sopenharmony_ci return fifo->wrIdx == fifo->rdIdx; 68094332d3Sopenharmony_ci} 69094332d3Sopenharmony_ci 70094332d3Sopenharmony_cistatic inline bool DataFifoIsFull(struct DataFifo *fifo) 71094332d3Sopenharmony_ci{ 72094332d3Sopenharmony_ci return DataFifoLen(fifo) > (fifo->size - 1); 73094332d3Sopenharmony_ci} 74094332d3Sopenharmony_ci 75094332d3Sopenharmony_cistatic inline uint32_t DataFifoAvailSize(struct DataFifo *fifo) 76094332d3Sopenharmony_ci{ 77094332d3Sopenharmony_ci return fifo->size - DataFifoLen(fifo); 78094332d3Sopenharmony_ci} 79094332d3Sopenharmony_ci 80094332d3Sopenharmony_cistatic inline void DataFifoSkip(struct DataFifo *fifo, uint32_t size) 81094332d3Sopenharmony_ci{ 82094332d3Sopenharmony_ci fifo->rdIdx += size; 83094332d3Sopenharmony_ci} 84094332d3Sopenharmony_ci 85094332d3Sopenharmony_cistatic inline uint32_t DataFifoWrite(struct DataFifo *fifo, uint8_t *data, uint32_t size) 86094332d3Sopenharmony_ci{ 87094332d3Sopenharmony_ci uint32_t mask = fifo->size - 1; 88094332d3Sopenharmony_ci uint8_t *buf = (uint8_t *)fifo->data; 89094332d3Sopenharmony_ci uint8_t *end; 90094332d3Sopenharmony_ci 91094332d3Sopenharmony_ci size = MIN(size, DataFifoAvailSize(fifo)); 92094332d3Sopenharmony_ci end = data + size; 93094332d3Sopenharmony_ci while (data < end) { 94094332d3Sopenharmony_ci buf[fifo->wrIdx++ & mask] = *data++; 95094332d3Sopenharmony_ci } 96094332d3Sopenharmony_ci return size; 97094332d3Sopenharmony_ci} 98094332d3Sopenharmony_ci 99094332d3Sopenharmony_cistatic inline uint32_t DataFifoRead(struct DataFifo *fifo, uint8_t *data, uint32_t size) 100094332d3Sopenharmony_ci{ 101094332d3Sopenharmony_ci uint32_t mask = fifo->size - 1; 102094332d3Sopenharmony_ci uint8_t *buf = (uint8_t *)fifo->data; 103094332d3Sopenharmony_ci uint8_t *end; 104094332d3Sopenharmony_ci 105094332d3Sopenharmony_ci size = MIN(size, DataFifoLen(fifo)); 106094332d3Sopenharmony_ci end = data + size; 107094332d3Sopenharmony_ci while (data < end) { 108094332d3Sopenharmony_ci *data++ = buf[fifo->rdIdx++ & mask]; 109094332d3Sopenharmony_ci } 110094332d3Sopenharmony_ci return size; 111094332d3Sopenharmony_ci} 112094332d3Sopenharmony_ci 113094332d3Sopenharmony_ci#endif /* HDF_USB_DATA_FIFO_H */ 114