/* ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. This file is part of ChibiOS/RT. ChibiOS/RT is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. ChibiOS/RT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** * @addtogroup IOQueues * @{ */ #ifndef _QUEUES_H_ #define _QUEUES_H_ /** Queue notification callback type.*/ typedef void (*t_qnotify)(void); /** Returned by the queue functions if the operation is successful.*/ #define Q_OK RDY_OK /** Returned by the queue functions if a timeout occurs.*/ #define Q_TIMEOUT RDY_TIMEOUT /** Returned by the queue functions if the queue is reset.*/ #define Q_RESET RDY_RESET /** Returned by the queue functions if the queue is empty.*/ #define Q_EMPTY -3 /** Returned by the queue functions if the queue is full.*/ #define Q_FULL -4 #ifdef CH_USE_QUEUES /** * I/O queue structure, it is used by both Input and Output Queues, * the difference is on how the semaphore is initialized. */ typedef struct { /** Pointer to the queue buffer.*/ BYTE8 *q_buffer; /** Pointer to the first location after the buffer.*/ BYTE8 *q_top; /** Write pointer.*/ BYTE8 *q_wrptr; /** Read pointer.*/ BYTE8 *q_rdptr; /** Counter semaphore.*/ Semaphore q_sem; /** Data notification callback.*/ t_qnotify q_notify; } Queue; /** Returns the queue's buffer size.*/ #define chQSize(q) \ ((q)->q_top - (q)->q_buffer) /** Returns the used space if used on an Input Queue and the empty space if * used on an Output Queue.*/ #define chQSpace(q) \ ((q)->q_sem.s_cnt) /** Evaluates to TRUE if the specified Input Queue is empty.*/ #define chIQIsEmpty(q) \ (chQSpace(q) <= 0) /** Evaluates to TRUE if the specified Input Queue is full.*/ #define chIQIsFull(q) \ (chQSpace(q) >= chQSize(q)) /** Evaluates to TRUE if the specified Output Queue is empty.*/ #define chOQIsEmpty(q) \ (chQSpace(q) >= chQSize(q)) /** Evaluates to TRUE if the specified Output Queue is full.*/ #define chOQIsFull(q) \ (chQSpace(q) <= 0) #ifdef __cplusplus extern "C" { #endif /* * Input Queues functions. An Input Queue is usually written into by an * interrupt handler and read from a thread. */ void chIQInit(Queue *qp, BYTE8 *buffer, t_size size, t_qnotify inotify); void chIQReset(Queue *qp); t_msg chIQPutI(Queue *qp, BYTE8 b); t_msg chIQGet(Queue *qp); t_size chIQRead(Queue *qp, BYTE8 *buffer, t_size n); #ifdef CH_USE_QUEUES_TIMEOUT t_msg chIQGetTimeout(Queue *qp, t_time time); #endif /* * Output Queues functions. An Output Queue is usually written into by a * thread and read from an interrupt handler. */ void chOQInit(Queue *queue, BYTE8 *buffer, t_size size, t_qnotify onotify); void chOQReset(Queue *queue); void chOQPut(Queue *queue, BYTE8 b); t_msg chOQGetI(Queue *queue); t_size chOQWrite(Queue *queue, BYTE8 *buffer, t_size n); #ifdef __cplusplus } #endif #endif /* CH_USE_QUEUES */ #ifdef CH_USE_QUEUES_HALFDUPLEX /** * Half duplex queue structure. */ typedef struct { /** Pointer to the queue buffer.*/ BYTE8 *hdq_buffer; /** Pointer to the first location after the buffer.*/ BYTE8 *hdq_top; /** Write pointer.*/ BYTE8 *hdq_wrptr; /** Read pointer.*/ BYTE8 *hdq_rdptr; /** Input counter semaphore.*/ Semaphore hdq_isem; /** Output counter semaphore.*/ Semaphore hdq_osem; /** Input data notification callback.*/ t_qnotify hdq_inotify; /** Output data notification callback.*/ t_qnotify hdq_onotify; } HalfDuplexQueue; /** Returns the queue's buffer size.*/ #define chHDQSize(q) \ ((q)->hdq_top - (q)->hdq_buffer) /** Returns the queue space when in transmission mode.*/ #define chHDQEmptySpace(q) \ ((q)->hdq_osem.s_cnt) /** Returns the number of the bytes in the queue when in receive mode.*/ #define chHDQFilledSpace(q) \ ((q)->hdq_isem.s_cnt) /** Evaluates to TRUE if the queue is in transmit mode.*/ #define chHDQIsTransmitting(q) \ (chHDQEmptySpace(q) < chHDQSize(q)) /** Evaluates to TRUE if the queue is in receive mode.*/ #define chHDQIsReceiving(q) \ (chHDQEmptySpaceQ(q) >= chHDQSize(q)) /** Evaluates to TRUE if the receive queue is full.*/ #define chHDQIsFullReceive(q) \ (chHDQFilledSpace(q) >= chHDQSize(q)) #ifdef __cplusplus extern "C" { #endif void chHDQInit(HalfDuplexQueue *qp, BYTE8 *buffer, t_size size, t_qnotify inotify, t_qnotify onotify); t_msg chHDQGetReceive(HalfDuplexQueue *qp); void chHDQPutTransmit(HalfDuplexQueue *qp, BYTE8 b); t_msg chHDQGetTransmitI(HalfDuplexQueue *qp); t_msg chHDQPutReceiveI(HalfDuplexQueue *qp, BYTE8 b); #ifdef CH_USE_QUEUES_TIMEOUT t_msg chHDQGetReceiveTimeout(HalfDuplexQueue *qp, t_time time); #endif #ifdef __cplusplus } #endif #endif /* CH_USE_QUEUES_HALFDUPLEX */ #endif /* _QUEUES_H_ */ /** @} */