/** * @brief Get a complete frame from USART2 (nonblocking) * @param buf Buffer for data (data will be null terminated for easier string manipulation) * @param len Length not including terminator character * @retval 0 Received frame * @retval 1 No frame in buffer * @retval 2 Frame error * TODO Add maximum length checking so as not to overflow */ int COMM_GetFrame(uint8_t* buf, uint8_t* len) { uint8_t c; *len = 0; // zero out length variable if (gotFrame) { while (1) { // no more data and terminator wasn't reached => error if (FIFO_IsEmpty(&rxFifo)) { *len = 0; println("Invalid frame"); return 2; } FIFO_Pop(&rxFifo, &c); buf[(*len)++] = c; // if end of frame if (c == COMM_TERMINATOR) { (*len)--; // length without terminator character buf[*len] = 0; // USART terminator character converted to NULL terminator break; } } gotFrame--; return 0; } else { return 1; } }
/** * @brief IRQ handler for USART2 */ void USART2_IRQHandler(void) { // If transmit buffer empty interrupt if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET) { uint8_t c; if (FIFO_Pop(&txFifo,&c) == 0) { // If buffer not empty USART_SendData(USART2, c); // Send data } else { // Turn off TXE interrupt USART_ITConfig(USART2, USART_IT_TXE, DISABLE); } } // If RX buffer not empty interrupt if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { uint8_t c = USART_ReceiveData(USART2); // Get data from UART uint8_t res = FIFO_Push(&rxFifo, c); // Put data in RX buffer // Checking res to ensure no buffer overflow occurred if ((c == UART2_TERMINATOR) && (res == 0)) { gotFrame++; } } }
/** * @brief Callback for transmitting data to lower layer * @param c Transmitted data * @retval 0 There is no more data in buffer (stop transmitting) * @retval 1 Valid data in c */ uint8_t COMM_TxCallback(uint8_t* c) { if (FIFO_Pop(&txFifo, c) == 0) { // If buffer not empty return 1; } else { return 0; } }
/** * @brief Get a char from USART2 * @return Received char. * @warning Blocking function! Waits until char is received. */ char COMM_Getc(void) { uint8_t c; while (FIFO_IsEmpty(&rxFifo) == 1); // wait until buffer is not empty // buffer not empty => char was received FIFO_Pop(&rxFifo,&c); // Get data from RX buffer return c; }
/** * @brief Callback for transmitting data to lower layer * @param c Transmitted data * @retval 0 There is no more data in buffer (stop transmitting) * @retval 1 Valid data in c */ int COMM_TxCallback(char* buf) { if (FIFO_IsEmpty(&txFifo)) { return 0; } // get all the data at one go int i = 0; while (!FIFO_Pop(&txFifo, buf+i)) { i++; } return i; }
/** * @brief Get a char from USART2 * @return Received char. * @warning Blocking function! */ uint8_t USART2_Getc(void) { uint8_t c; while (FIFO_IsEmpty(&rxFifo) == 1); // wait until buffer is not empty // buffer not empty => char was received USART_ITConfig(USART2, USART_IT_RXNE, DISABLE); // disable RX interrupt FIFO_Pop(&rxFifo,&c); // Get data from RX buffer USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // enable RX interrupt return c; }
void USART3_IRQHandler(void) { if(USART_GetITStatus(USART3, USART_IT_TXE) != RESET) { while(!FIFO_IsEmpty(usart3_tx_fifo)) { uint8_t tx_data; FIFO_Pop(usart3_tx_fifo, &tx_data); while (USART_GetFlagStatus(USART3,USART_FLAG_TC) == RESET); USART_SendData(USART3, tx_data); } USART_ITConfig(USART3, USART_IT_TXE, DISABLE); } else if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) { uint8_t rx_data = USART_ReceiveData(USART3); } }