Library to easily communicate with XBee modules.

Dependencies:   DigiLogger

Dependents:   WaterLogger XbeeGateway XBee_Cooker ProjetReceiver ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FrameBuffer.cpp Source File

FrameBuffer.cpp

00001 /**
00002  * Copyright (c) 2015 Digi International Inc.,
00003  * All rights not expressly granted are reserved.
00004  *
00005  * This Source Code Form is subject to the terms of the Mozilla Public
00006  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
00007  * You can obtain one at http://mozilla.org/MPL/2.0/.
00008  *
00009  * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
00010  * =======================================================================
00011  */
00012 
00013 #include "FrameBuffer.h"
00014 #include "Utils/Debug.h"
00015 
00016 #if !(defined AVOID_DISABLE_IRQS)
00017 #define disable_irq() __disable_irq()
00018 #define enable_irq() __enable_irq()
00019 #else
00020 #define disable_irq()
00021 #define enable_irq()
00022 #endif
00023 
00024 FrameBuffer::FrameBuffer(uint8_t size, uint16_t max_payload_len) : _size(size), _head(0), _tail(0), _dropped_frames(0)
00025 {
00026     _frm_buf = new buf_element_t[_size];
00027 
00028     assert(_frm_buf != NULL);
00029 
00030     for (int i = 0; i < _size; i++) {
00031         _frm_buf[i].frame = new ApiFrame(max_payload_len - 1);
00032         _frm_buf[i].status = FrameStatusFree;
00033     }
00034 }
00035 
00036 FrameBuffer::~FrameBuffer()
00037 {
00038     for (int i = 0; i < _size; i++) {
00039         delete _frm_buf[i].frame;
00040     }
00041 
00042     delete _frm_buf;
00043 }
00044 
00045 ApiFrame *FrameBuffer::get_next_free_frame(void)
00046 {
00047     uint8_t i = _head;
00048     ApiFrame *ret = NULL;
00049 
00050     do {
00051         if (_frm_buf[i].status == FrameStatusFree || _frm_buf[i].status == FrameStatusComplete) {
00052             if (_frm_buf[i].status == FrameStatusComplete) {
00053                 _dropped_frames++;
00054             }
00055             _frm_buf[i].status = FrameStatusAssigned;
00056             ret = _frm_buf[i].frame;
00057             _head = ++i % _size;
00058             break;
00059         }
00060         i++;
00061         i = i % _size;
00062     } while (i != _head);
00063 
00064     return ret;
00065 }
00066 
00067 bool FrameBuffer::complete_frame(ApiFrame *frame)
00068 {
00069     bool ret = false;
00070 
00071     for (int i = 0; i < _size; i++) {
00072         if (_frm_buf[i].frame == frame) {
00073             _frm_buf[i].status = FrameStatusComplete;
00074             ret = true;
00075             break;
00076         }
00077     }
00078 
00079     return ret;
00080 }
00081 
00082 ApiFrame *FrameBuffer::get_next_complete_frame(void)
00083 {
00084     uint8_t i = _tail;
00085     ApiFrame *ret = NULL;
00086 
00087     do {
00088         disable_irq();
00089         if (_frm_buf[i].status == FrameStatusComplete) {
00090             _frm_buf[i].status = FrameStatusAssigned;
00091             enable_irq();
00092             ret = _frm_buf[i].frame;
00093             _tail = ++i % _size;
00094             break;
00095         }
00096         enable_irq();
00097         i++;
00098         i = i % _size;
00099     } while (i != _tail);
00100 
00101     return ret;
00102 }
00103 
00104 bool FrameBuffer::free_frame(ApiFrame *frame)
00105 {
00106     bool ret = false;
00107 
00108     for (int i = 0; i < _size; i++) {
00109         if (_frm_buf[i].frame == frame) {
00110             _frm_buf[i].status = FrameStatusFree;
00111             ret = true;
00112             break;
00113         }
00114     }
00115 
00116     return ret;
00117 }
00118 
00119 uint32_t FrameBuffer::get_dropped_frames_count(void)
00120 {
00121     const uint32_t dropped_frames = _dropped_frames;
00122 
00123     _dropped_frames = 0;
00124 
00125     return dropped_frames;
00126 }