/*----------------------------------------------------------------------------* * NAME * ProcessDataSentIndication * * DESCRIPTION * This function process the data sent indication. * * RETURNS * Nothing * *----------------------------------------------------------------------------*/ extern void ProcessDataSentIndication(bool result) { uint8 data[SERIAL_RX_DATA_LENGTH] = {0}; if(result) { /* Data sent was a success, pop the sent data from the buffer. */ BQPopBytes(data, length_data_peeked,SEND_QUEUE_ID); length_data_peeked = 0; } /* Send more data. */ processRxData(); }
void interruptFuncs::uart0rxtx_isr() { gotoState( ST_RECEIVING ); UART0::clearInterrupts( uart::configOptions::interrupts::receiveInt ); buffRx[rxCount] = UART0::receiveByte(); rxCount++; if ( rxCount >= BUFF_RX_SIZE ) { // Has received an entire packet, then, process it rxCount = 0; processRxData(); gotoState( ST_IDLE ); } }
static uint16 uartRxDataCallback(void *p_rx_buffer, uint16 length, uint16 *p_additional_req_data_length) { if ( length > 0 ) { /* First copy all the bytes received into the byte queue */ BQForceQueueBytes((const uint8 *)p_rx_buffer, length,SEND_QUEUE_ID); } /* Inform the UART driver that we'd like to receive another byte when it * becomes available */ *p_additional_req_data_length = (uint16)NUMBER_OF_BYTES_RECEIVED_NEXT; if(!IsAppWaitingForRadioEvent()) { /* Send data */ processRxData(); } /* Return the number of bytes that have been processed */ return length; }
/* The main loop for the modem object. Must be called frequently. Handles UART transfers and multi-block transfers. Returns NULL or a pointer to a received datapack object. */ void HeliumModem::loop(void) { uint8_t ch; static uint8_t stuffed=0; static uint16_t cnt; static uint8_t *ptr; // Check if radio module has data for us. while (serport->available()) { ch = serport->read(); // See if we're starting a new frame (in case state is incorrect) if (ch == SOF_CHAR) { stuffed = 0; ppFrame.state = sof; if (ppFrame.payload) { //free(ppFrame.payload); ppFrame.payload = 0; } } // Check for stuffed char if (ch == ESC_CHAR) { // See if we have two or more ESC's in a row if (stuffed) // Already unstuffing, this is two ESC_CHAR's in a row // User is exiting PP mode return; // Un-stuff next char stuffed = 1; continue; } // Un-stuff the char if (stuffed) { switch (ch) { case SOF_ESC: ch = SOF_CHAR; break; case EOF_ESC: ch = EOF_CHAR; break; case ESC_ESC: ch = ESC_CHAR; break; default: // Very bad, wrong char, throw out everything if (ppFrame.payload) { // Free the buffer //free(ppFrame.payload); ppFrame.payload = 0; } // Start over ppFrame.state = sof; break; } stuffed = false; } // Add a char to the frame switch (ppFrame.state) { case sof: // Waiting for sof if (ch == SOF_CHAR) ppFrame.state = sstate_t((int)ppFrame.state + 1); break; case len1: // length low byte ppFrame.length = ch; ppFrame.state = sstate_t((int)ppFrame.state + 1); break; case len2: // length high byte ppFrame.length += ((uint16_t)ch) << 8; ppFrame.state = sstate_t((int)ppFrame.state + 1); // Save length to count so we can count the payload as it comes cnt = ppFrame.length; // Allocate a buffer for payload ptr = 0; if (cnt) { if (cnt > PP_FRAME_SIZE) // Too big ppFrame.state = sof; else ppFrame.payload = ptr = ppPayload;; } else // No payload, quit now ppFrame.state = eof; break; case payload: // Save the char in buffer *ptr++ = ch; cnt--; if (!cnt) // Done with payload, move on ppFrame.state = sstate_t((int)ppFrame.state + 1); break; case eof: if (ch == EOF_CHAR) { // Process this frame in application code processRxData(ppFrame.payload, ppFrame.length); // Clear the memory pointer ppFrame.payload = 0; } else { // Oops, this isn't right, free the buffer //free(ppFrame.payload); ppFrame.payload = 0; } // Ready for next serial frame ppFrame.state = sof; // Prepare for next frame, buffer to be freed by stack ppFrame.payload = 0; break; default: break; } } }