/* Copyright Statement: * * This software/firmware and related documentation ("Autochips Software") are * protected under relevant copyright laws. The information contained herein * is confidential and proprietary to Autochips Inc. and/or its licensors. * Without the prior written permission of Autochips inc. and/or its licensors, * any reproduction, modification, use or disclosure of Autochips Software, * and information contained herein, in whole or in part, shall be strictly prohibited. * * Copyright(C) 2016, Autochips ( All rights reserved. ) * * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE") * RECEIVED FROM Autochips AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON * AN "AS-IS" BASIS ONLY. Autochips EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. * NEITHER DOES Autochips PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR * SUPPLIED WITH THE Autochips SOFTWARE, AND BUYER AGREES TO LO0 ONLY TO SUCH * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. Autochips SHALL ALSO * NOT BE RESPONSIBLE FOR ANY Autochips SOFTWARE RELEASES MADE TO BUYER'S * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. * * BUYER'S SOLE AND EXCLUSIVE REMEDY AND Autochips'S ENTIRE AND CUMULATIVE * LIABILITY WITH RESPECT TO THE Autochips SOFTWARE RELEASED HEREUNDER WILL BE, * AT Autochips'S OPTION, TO REVISE OR REPLACE THE Autochips SOFTWARE AT ISSUE, * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO * * Autochips FOR SUCH Autochips SOFTWARE AT ISSUE. * * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC). *****************************************************************************/ /* Includes ------------------------------------------------------------------*/ #include #include "fifo.h" #include #define minimum(x, y) (((x) < (y))? (x) : (y)) /************************************************************************ Function : Description : Init the fifo structure. _fifo : reference to _fifo struct. size : size of the fifo. retval 1 if memory allocation fails or 0. Change history: Note: Author: Date: Jan-10-2013 ************************************************************************/ uint8_t fifo_Init(fifo_TypeDef * _fifo, uint8_t* data, uint32_t size) { /* check for a valid pointer */ if (_fifo == NULL) { return 1; } /* if fifo size is null nothing to do */ if ( size == 0) { memset((uint8_t *)_fifo, 0x00, sizeof(fifo_TypeDef)); return 1; } else { /* allocate fifo space. */ _fifo->baseAddr = data; if (_fifo->baseAddr == NULL) { /* memory allocation failure. */ #ifdef SZ_LOG putLine(); putString("----> Malloc Fail!"); #endif return 1; } else { memset((uint8_t *)_fifo->baseAddr, 0x00, sizeof(uint8_t) * size); /* tail = head --> empty fifo */ _fifo->head = 0; _fifo->tail = 0; _fifo->size = size; return 0; } } } /************************************************************************ Function : Description : DeInit the fifo structure. _fifo : reference to _fifo struct. Change history: Note: Author: Date: Jan-10-2013 ************************************************************************/ uint8_t fifo_DeInit(fifo_TypeDef * _fifo) { uint8_t status = 1; if (_fifo == NULL) { status = 1; } else { if (_fifo->baseAddr != NULL) { /* optional (clear memory region) */ memset((uint8_t *)_fifo->baseAddr, 0x00, _fifo->size); memset((uint8_t *)_fifo, 0x00, sizeof(fifo_TypeDef)); status = 0; } else { /* FiFo invalid base address. */ status = 1; } } return status; } /************************************************************************ Function : Description : Reset the fifo structure. _fifo : reference to _fifo struct. Change history: Note: Author: Date: Jan-10-2013 ************************************************************************/ uint8_t fifo_Reset(fifo_TypeDef * _fifo) { if (_fifo == NULL) { return 1; } else { if (_fifo->baseAddr != NULL) { /* optional (clear memory region) */ memset((uint8_t *)_fifo->baseAddr, 0x00, _fifo->size); _fifo->head = 0; _fifo->tail = 0; return 0; } else { /* FiFo invalid base address. */ return 1; } } } /************************************************************************ Function : Description : returns how much data is stored in the fifo. _fifo : reference to _fifo struct. Change history: Note: Author: Date: Jan-10-2013 ************************************************************************/ uint32_t fifo_GetLen(fifo_TypeDef * _fifo) { if (_fifo == NULL) { return 0; } else { return (_fifo->tail - _fifo->head); } } /************************************************************************ Function : Description : returns how much free sapce in the fifo. _fifo : reference to _fifo struct. Change history: Note: Author: Date: Jan-10-2013 ************************************************************************/ uint32_t fifo_GetFreeSpace(fifo_TypeDef * _fifo) { if (_fifo == NULL) { return 0; } else { return (_fifo->size - (_fifo->tail - _fifo->head)); } } /************************************************************************ Function : Description : returns SET if the FIFO is full. _fifo : reference to _fifo struct. Change history: Note: Author: Date: Jan-10-2013 ************************************************************************/ uint8_t fifo_NotFull(fifo_TypeDef * _fifo) { if (_fifo == NULL) { return 0; } else { return ((_fifo->tail - _fifo->head) != _fifo->size) ? 1 : 0; } } /************************************************************************ Function : Description : Insert data to the fifo. _fifo : reference to _fifo struct. data : reference to data buffer. len : data buffer length. Change history: Note: Author: Date: Jan-10-2013 ************************************************************************/ uint32_t fifo_insert(fifo_TypeDef * _fifo, uint8_t *data, uint32_t len) { uint32_t real_len; uint32_t offset; uint32_t end; offset = _fifo->size - (_fifo->tail - _fifo->head); /*Actual size of data we can write*/ real_len = minimum(len, offset); /*Offset of write pointer*/ offset = _fifo->tail % _fifo->size; /*End position before buffer being warpped*/ end = minimum(real_len, _fifo->size - offset); /*Copy data to buffer before warp*/ memcpy(_fifo->baseAddr + offset, data, end); /*Copy data to buffer after warp*/ memcpy(_fifo->baseAddr, data + end, real_len - end); _fifo->tail += real_len; return real_len; } /************************************************************************ Function : Description : Retrieve data from the fifo. _fifo : reference to _fifo struct. data : reference to data buffer. len : data buffer length. Change history: Note: Author: Date: Jan-10-2013 ************************************************************************/ uint32_t fifo_retrieve(fifo_TypeDef * _fifo, uint8_t *data, uint32_t len) { uint32_t real_len; uint32_t offset; uint32_t end; offset = _fifo->tail- _fifo->head; real_len = minimum(len, offset); //得到偏移量 offset = _fifo->head % _fifo->size; end = minimum(real_len, _fifo->size - offset); memcpy(data, _fifo->baseAddr + offset, end); memcpy(data + end, _fifo->baseAddr, real_len - end); _fifo->head += real_len; return real_len; } /***************************************************************************** * 函数名: 串口通道帧尾获取函数 * 函数功能: 获取当前帧帧尾所在地址 * 输入参数: _fifo - fifo结构体 * 输入参数: data-帧尾结束符 * 返回数据: fifo中接收到的数据到字节data第一次出现的长度 *****************************************************************************/ uint32_t Fifo_strchr(fifo_TypeDef * _fifo, uint8_t data) { uint32_t remaining = 0; uint32_t len = 0; uint32_t head; head = _fifo->head; remaining = _fifo->tail- head; head = head % _fifo->size; while(remaining) { len++; if(data == *((_fifo->baseAddr + head))) { return len; } head++; remaining--; head %= _fifo->size; } return 0; }