TX and RX FIFO. RX FIFO was tested. TX FIFO not fully tested.
Dependents: STM32F030R8_SOMO-14D
MessageQueue.cpp
- Committer:
- issaiass
- Date:
- 2015-03-13
- Revision:
- 0:35d1a2c4fb6d
File content as of revision 0:35d1a2c4fb6d:
/* ******************************************************************************* * CERES CONTROLS * PANAMA, REPULIC OF PANAMA * * File : MessageQueue.cpp * Programmer(s) : Rangel Alvarado * Language : ANSI-C * Description : Function prototypes of serial Tx and Rx, buffer and utils. * * Note : Dependancies of mbed libraries... * - Serial * RX Buffer fully developed * TX Buffer is not fully implemented, can't change IRQ from * TX Empty to other interrupt without be hardware specific. * ---------------------------------------------------------------------------- * HISTORY * DD MM AA * 09 03 15 Created. * 09 03 15 Modified. * 12 03 15 Import to mbed platform. ******************************************************************************* */ /* ******************************************************************************* * INCLUDE FILES ******************************************************************************* */ #include "includes.h" /* General Include file */ Serial ser(MSG_TX_PIN, MSG_RX_PIN); /* Serial Port configuration */ /* ******************************************************************************* * DATA TYPES ******************************************************************************* */ MSG_BUF MsgFifo; /* Call a buffer */ /* ******************************************************************************* * * CONFIGURE RECEIVER INTERRUPT * * Description : Configure a function to attach an interrupt for the receiver * Arguments : msgfunc pointer to the function to call * Return : None * Notes : Character arrived interrupt ******************************************************************************* */ void MsgRxISRCfg(void (*msgfunc)(void)) { ser.attach(msgfunc, Serial::RxIrq); /* Attach a function to RX ISR */ } /* ******************************************************************************* * * CONFIGURE TRANSMITTER INTERRUPT * * Description : Configure a function to attach an interrupt for transmitter * Arguments : msgfunc pointer to the function to call * Return : None * Notes : TX Empty Interrupt only ******************************************************************************* */ void MsgTxISRCfg(void (*msgfunc)(void)) { ser.attach(msgfunc, Serial::TxIrq); /* Attach a function to TX ISR */ } /* ******************************************************************************* * * GENERATE CHECKSUM FROM THE BUFFER * * Description : Get an array and calculate the CRC8 * Arguments : pdata pointer to the data to analyze * size the lenght of the array to calculate the checksum * Return : A byte that represents the checksum of the array * Notes : None ******************************************************************************* */ INT8U MsgChkSum(INT8U *pdata, INT8U size) { INT8U i; /* Iterator */ INT8U crc; /* CRC calculator */ crc = 0; /* Initialize CRC result */ for (i = 0; i < size; i++) /* Iterate from the first to last */ crc += *pdata++; /* Sum the last and next byte */ crc ^= 0xFF; /* XOR the value */ return (crc); /* return the CRC result */ } /* ******************************************************************************* * * INITIALIZE THE TRANSMISSION AND RECEIVER BUFFER * * Description : Default values for the TX and RX Buffer * Arguments : None * Return : None * Notes : None ******************************************************************************* */ void MsgBufInit(void) { MsgFifo.MsgRxBufHd = 0; /* Buffer RX head at position 0 */ MsgFifo.MsgRxBufTl = 0; /* Buffer RX tail at position 0 */ MsgFifo.MsgRxBufCtr = 0; /* Buffer RX counter at 0 */ MsgFifo.MsgTxBufHd = 0; /* Buffer TX head at position 0 */ MsgFifo.MsgTxBufTl = 0; /* Buffer TX tail at position 0 */ MsgFifo.MsgTxBufCtr = 0; /* Buffer TX counter at 0 */ } /* ******************************************************************************* * * RECEIVE A BYTE FROM THE SERIAL PORT * * Description : Read a byte * Arguments : None * Return : The received byte from the serial port * Notes : None ******************************************************************************* */ INT8U MsgGet(void) { return(ser.getc()); /* Return the byte from serial */ } /* ******************************************************************************* * * GET A BYTE FROM THE RECEIVER BUFFER * * Description : Get a byte from the buffer * Arguments : None * Return : Returns a byte from the receiver buffer * Notes : None ******************************************************************************* */ INT8U MsgGetChar(void) { INT8U temp; /* Temporal for byte return */ temp = 0; /* Initialize return data */ OS_ENTER_CRITICAL(); /* Disable Global Interrupts */ if (MsgFifo.MsgRxBufCtr > 0) { /* If there is something on FIFO */ MsgFifo.MsgRxBufCtr--; /* Substract quantity on RX FIFO */ temp = MsgFifo.MsgRxBuf[MsgFifo.MsgRxBufTl++]; /* Get from RX Buffer */ if (MsgFifo.MsgRxBufTl == MSG_RX_MAX_CHAR) /* If RX FIFO is Full */ MsgFifo.MsgRxBufTl = 0; /* No characters to extract */ } OS_EXIT_CRITICAL(); /* Enable Global Interrupts */ return (temp); /* Return the data */ } /* ******************************************************************************* * * INSERT A BYTE ON THE RX BUFFER * * Description : Insert a byte in the RX buffer * Arguments : data a byte that holds the character to insert * Return : None * Notes : None ******************************************************************************* */ void MsgPutRxChar(INT8U data) { if (MsgFifo.MsgRxBufCtr < MSG_RX_MAX_CHAR) { /* If is still space on FIFO */ MsgFifo.MsgRxBufCtr++; /* Increase the size by one */ MsgFifo.MsgRxBuf[MsgFifo.MsgRxBufHd++] = data; /* Insert the byte */ if (MsgFifo.MsgRxBufHd == MSG_RX_MAX_CHAR) /* If FIFO is Full */ MsgFifo.MsgRxBufHd = 0; /* Insertion FIFO restored to 0 */ } } /* ******************************************************************************* * * CHECK IF RECEIVER BUFFER EMPTY * * Description : Check if is still space on the RX FIFO * Arguments : None * Return : TRUE if FIFO is empty * FALSE if FIFO is not empty * Notes : None ******************************************************************************* */ BOOLEAN MsgRxBufEmpty(void) { INT8U status; /* a status byte flag */ status = FALSE; /* Initialy false */ if (MsgFifo.MsgRxBufCtr == 0) /* If isn't a byte on the buffer */ status = TRUE; /* TRUE, flag that is empty */ return (status); /* return current state of FIFO */ } /* ******************************************************************************* * * GET A LINE FROM THE INPUT DATA BUFFER * * Description : Read bytes up to encounter the <CR> character * Arguments : pdata pointer that holds the data to read * Return : None * Notes : None ******************************************************************************* */ void MsgGetLine(INT8U *pdata) { INT8U data; /* Character for data */ data = 0; /* Initialize the data */ do { data = MsgGetChar(); /* Get one byte */ if (data != '\r' && data) /* Analys if is <CR> */ *pdata++ = data; /* Move to the array or pointer */ } while (data); /* Repeato until is something */ } /* ******************************************************************************* * * DISABLE THE RECEIVER INTERRUPT * * Description : Disables the receiver interrupt * Arguments : None * Return : None * Notes : Dependancy on MsgRxISRCfg() ******************************************************************************* */ void MsgRxIntDis(void) { MsgRxISRCfg(NULL); /* NULL pointer to RX ISR */ } /* ******************************************************************************* * * ENABLES THE RECEIVER INTERRUPT * * Description : Enables the receiver interrupt * Arguments : pfunc pointer to function (callback) to the ISR * Return : None * Notes : Dependancy on MsgRxISRCfg() ******************************************************************************* */ void MsgRxIntEn(void (*pfunc)(void)) { MsgRxISRCfg(pfunc); /* Pointer to the enabled func */ } /* ******************************************************************************* * * CLEAN THE RX BUFFER * * Description : Return the RX buffer to the initial values * Arguments : None * Return : None * Notes : None ******************************************************************************* */ void MsgRxBufFlush(void) { MsgFifo.MsgRxBufHd = 0; /* Return head to beginning */ MsgFifo.MsgRxBufTl = 0; /* Return tail to beginning */ MsgFifo.MsgRxBufCtr = 0; /* Return counter to beginning */ } /* ******************************************************************************* * * PUT A BYTE OUT OF THE SERIAL PORT * * Description : Sends a byte through serial * Arguments : data the byte to send * Return : None * Notes : None ******************************************************************************* */ void MsgPut(INT8U data) { ser.putc(data); /* Send a byte */ } /* ******************************************************************************* * * PUT A BYTE ON THE TRANSMITTER BUFFER * * Description : Sends a byte to the transmitter buffer * Arguments : data the byte to send to the FIFO * Return : None * Notes : None ******************************************************************************* */ void MsgPutChar(INT8U data) { if(!MsgTxBufFull()) { /* If the buffer is not full */ OS_ENTER_CRITICAL(); /* Disable global interrupts */ MsgFifo.MsgTxBufCtr++; /* Increase the FIFO counter */ MsgFifo.MsgTxBuf[MsgFifo.MsgTxBufHd++] = data; /* Insert the data */ if(MsgFifo.MsgTxBufHd == MSG_TX_MAX_CHAR) { /* If TX FIFO isn't full */ MsgFifo.MsgTxBufHd = 0; /* FIFO head is initialized */ } if (MsgFifo.MsgTxBufCtr == 1) { /* If is the first byte */ // MsgTxIntEn(); /* Enable transmitter interrupt */ } OS_EXIT_CRITICAL(); /* Enable global interrupts */ } } /* ******************************************************************************* * * PUT A LINE THROUGH THE SERIAL PORT * * Description : Sends a line of characters to the serial port * Arguments : pdata the array or pointer holder of the data to send * Return : None * Notes : None ******************************************************************************* */ void MsgPutLine(INT8U *pdata) { INT8U data; /* Data to send */ data = 0; /* Initialize data */ while (*pdata != '\0') { /* Up to string end */ data = *pdata++; /* Get the data to send */ // MsgPutChar(data); MsgPut(data); /* Put the data out of the MCU */ } } /* ******************************************************************************* * * CHECKS IF THE TRANSMITTER BUFFER IS FULL * * Description : Check the status of the transmitter buffer * Arguments : None * Return : TRUE if transmitter buffer is full * FALSE if transmitter buffer is empty * Notes : None ******************************************************************************* */ BOOLEAN MsgTxBufFull(void) { INT8U status; /* A status byte for the buffer */ status = FALSE; /* Initialize the status flag */ if(MsgFifo.MsgTxBufCtr >= MSG_TX_MAX_CHAR) {/* If the buffer is full */ status = TRUE; /* The buffer is full, flag it */ } return status; /* Return the current status */ } /* ******************************************************************************* * * DISABLES TRANSMITTER INTERRUPTS * * Description : Disable the transmitter interrupt * Arguments : None * Return : None * Notes : None ******************************************************************************* */ void MsgTxIntDis(void) { MsgTxISRCfg(NULL); /* Disable the TX interrupt */ } /* ******************************************************************************* * * ENABLES TRANSMITTER INTERRUPTS * * Description : Enable the transmitter interrupt * Arguments : pfunc pointer to function (callback) to the ISR * Return : None * Notes : None ******************************************************************************* */ void MsgTxIntEn(void (*pfunc)(void)) { MsgTxISRCfg(pfunc); /* Enables the TX interrupt */ } /* ******************************************************************************* * * GET THE BYTES FROM THE BUFFER TO TRANSMIT * * Description : Get the byte from the TX buffer if exists * Arguments : None * Return : A byte from the buffer to transmitt * Notes : If there is no byte to transmit, a NULL (0) will be sent ******************************************************************************* */ INT8U MsgGetTxChar(void) { INT8U data; /* Data byte */ if(MsgFifo.MsgTxBufCtr > 0) { /* If there is something to send*/ MsgFifo.MsgTxBufCtr--; /* Decrease the byte counter */ data = MsgFifo.MsgTxBuf[MsgFifo.MsgTxBufTl++]; /* Get from the buffer */ if(MsgFifo.MsgTxBufTl == MSG_TX_MAX_CHAR) { /* If is the max char */ MsgFifo.MsgTxBufTl = 0; /* Return the buffer to initial */ } return data; /* Return the data */ } else { /* Otherwise */ return NULL; /* Return a NULL (0) character */ } }