// UART Transmit Complete Interrupt Function void uartTransmitService(u08 nUart) { // check if buffered tx is enabled if(uartBufferedTx[nUart]) { // check if there's data left in the buffer if(uartTxBuffer[nUart].datalength) { // send byte from top of buffer if(nUart) outb(UDR1, bufferGetFromFront(&uartTxBuffer[1]) ); else outb(UDR0, bufferGetFromFront(&uartTxBuffer[0]) ); } else { // no data left uartBufferedTx[nUart] = FALSE; // return to ready state uartReadyTx[nUart] = TRUE; } } else { // we're using single-byte tx mode // indicate transmit complete, back to ready uartReadyTx[nUart] = TRUE; } }
void uartSendTxBuffer(u08 nUart) { // turn on buffered transmit uartBufferedTx[nUart] = TRUE; // send the first byte to get things going by interrupts uartSendByte(nUart, bufferGetFromFront(&uartTxBuffer[nUart])); }
// start transmission of the current uart Tx buffer contents void uartSendTxBuffer(void) { // turn on buffered transmit uartBufferedTx = TRUE; // send the first byte to get things going by interrupts uartSendByte(bufferGetFromFront(&uartTxBuffer)); }
void uartSendTxBuffer(void) { while (uartTxBuffer.datalength) { loop_until_bit_is_set(UCSRA, UDRE); UDR = bufferGetFromFront(&uartTxBuffer); } }
// UART Transmit Complete Interrupt Function void uartTransmitService(u08 nUart) { assert(nUart < 4); // check if buffered tx is enabled if(uartBufferedTx[nUart]) { // check if there's data left in the buffer if(uartTxBuffer[nUart].datalength) { // send byte from top of buffer switch (nUart) { case 0: outb(UDR0, bufferGetFromFront(&uartTxBuffer[0]) ); break; case 1: outb(UDR1, bufferGetFromFront(&uartTxBuffer[1]) ); break; case 2: outb(UDR2, bufferGetFromFront(&uartTxBuffer[2]) ); break; case 3: outb(UDR3, bufferGetFromFront(&uartTxBuffer[3]) ); break; default: break; } } else { // no data left uartBufferedTx[nUart] = FALSE; // return to ready state uartReadyTx[nUart] = TRUE; } } else { // we're using single-byte tx mode // indicate transmit complete, back to ready uartReadyTx[nUart] = TRUE; } }
u08 uartReceiveByte(u08 nUart, u08* rxData) { assert(nUart < 4); // make sure we have a receive buffer if(uartRxBuffer[nUart].size) { // make sure we have data if(uartRxBuffer[nUart].datalength) { // get byte from beginning of buffer *rxData = bufferGetFromFront(&uartRxBuffer[nUart]); return TRUE; } else return FALSE; // no data } else return FALSE; // no buffer }
//! gets a byte (if available) from the uart receive buffer u08 uartswReceiveByte(u08* rxData) { // make sure we have a receive buffer if(uartswRxBuffer.size) { // make sure we have data if(uartswRxBuffer.datalength) { // get byte from beginning of buffer *rxData = bufferGetFromFront(&uartswRxBuffer); return TRUE; } else { // no data return FALSE; } } else { // no buffer return FALSE; } }
// process buffer containing STX/ETX packets unsigned char stxetxProcess(cBuffer* rxBuffer) { unsigned char foundpacket = FALSE; unsigned short i; unsigned char length, checksum; //unsigned char type; // process the buffer // go through buffer looking for packets // the STX must be located at least STXETX_HEADERLENGTH+STXETX_TRAILERLENGTH from end // otherwise we must not have a complete packet while( rxBuffer->datalength >= ((uint16_t)STXETX_HEADERLENGTH+(uint16_t)STXETX_TRAILERLENGTH) ) { // look for a potential start of packet if(bufferGetAtIndex(rxBuffer, 0) == STX) { // if this is a start, then get the length length = bufferGetAtIndex(rxBuffer, STXETX_LENGTHOFFSET); // now we must have at least STXETX_HEADERLENGTH+length+STXETX_TRAILERLENGTH in buffer to continue if(rxBuffer->datalength >= ((uint16_t)STXETX_HEADERLENGTH+length+(uint16_t)STXETX_TRAILERLENGTH)) { // check to see if ETX is in the right position if(bufferGetAtIndex(rxBuffer, STXETX_HEADERLENGTH+length+STXETX_TRAILERLENGTH-1) == ETX) { // found potential packet // test checksum checksum = 0; // sum data between STX and ETX, not including checksum itself // (uint16_t) casting needed to avoid unsigned/signed mismatch for(i = 0; i<((uint16_t)STXETX_HEADERLENGTH+length+(uint16_t)STXETX_TRAILERLENGTH-(uint16_t)STXETX_NOETXSTXCHECKSUM); i++) { checksum += bufferGetAtIndex(rxBuffer, i+STXETX_STATUSOFFSET); } // compare checksums if(checksum == bufferGetAtIndex(rxBuffer, STXETX_CHECKSUMOFFSET+length)) { //we have a packet! foundpacket = TRUE; // copy data to buffer // (don't copy STX, ETX, or CHECKSUM) for(i = 0; i < ((uint16_t)STXETX_HEADERLENGTH+length-1); i++) { stxetxRxPacket[i] = bufferGetAtIndex(rxBuffer, i+1); } // debug //rprintf("STXETX Received packet type: 0x%x\n", bufferGetAtIndex(rxBuffer, STXETX_TYPEOFFSET)); // dump this packet from the bufferDumpFromFront(rxBuffer, STXETX_HEADERLENGTH+length+STXETX_TRAILERLENGTH); // done with this processing session break; } else { // checksum bad //rprintf("STXETX Received packet with bad checksum\r\n"); // for now, we dump these // dump this STX bufferGetFromFront(rxBuffer); } } else { // no ETX or ETX in wrong position // dump this STX bufferGetFromFront(rxBuffer); } } else { // not enough data in buffer to decode pending packet // wait until next time break; } } else { // this is not a start, dump it bufferGetFromFront(rxBuffer); } } // check if receive buffer is full with no packets decoding // (ie. deadlocked on garbage data or packet that exceeds buffer size) if(!bufferIsNotFull(rxBuffer)) { // dump receive buffer contents to relieve deadlock bufferFlush(rxBuffer); } return foundpacket; }
uint8_t nmeaProcess(cBuffer* rxBuffer) { uint8_t foundpacket = NMEA_NODATA; uint8_t startFlag = FALSE; //uint8_t data; uint16_t i,j; // process the receive buffer // go through buffer looking for packets while(rxBuffer->datalength) { // look for a start of NMEA packet if(bufferGetAtIndex(rxBuffer,0) == '$') { // found start startFlag = TRUE; // when start is found, we leave it intact in the receive buffer // in case the full NMEA string is not completely received. The // start will be detected in the next nmeaProcess iteration. // done looking for start break; } else bufferGetFromFront(rxBuffer); } // if we detected a start, look for end of packet if(startFlag) { for(i=1; i<(rxBuffer->datalength)-1; i++) { // check for end of NMEA packet <CR><LF> if((bufferGetAtIndex(rxBuffer,i) == '\r') && (bufferGetAtIndex(rxBuffer,i+1) == '\n')) { // have a packet end // dump initial '$' bufferGetFromFront(rxBuffer); // copy packet to NmeaPacket for(j=0; j<(i-1); j++) { // although NMEA strings should be 80 characters or less, // receive buffer errors can generate erroneous packets. // Protect against packet buffer overflow if(j<(NMEA_BUFFERSIZE-1)) NmeaPacket[j] = bufferGetFromFront(rxBuffer); else bufferGetFromFront(rxBuffer); } // null terminate it NmeaPacket[j] = 0; // dump <CR><LF> from rxBuffer bufferGetFromFront(rxBuffer); bufferGetFromFront(rxBuffer); #ifdef NMEA_DEBUG_PKT rprintf("Rx NMEA packet type: "); rprintfStrLen(NmeaPacket, 0, 5); rprintfStrLen(NmeaPacket, 5, (i-1)-5); rprintfCRLF(); #endif // found a packet // done with this processing session foundpacket = NMEA_UNKNOWN; break; } } } if(foundpacket) { // check message type and process appropriately if(!strncmp(NmeaPacket, "GPGGA", 5)) { // process packet of this type nmeaProcessGPGGA(NmeaPacket); // report packet type foundpacket = NMEA_GPGGA; } else if(!strncmp(NmeaPacket, "GPVTG", 5)) { // process packet of this type nmeaProcessGPVTG(NmeaPacket); // report packet type foundpacket = NMEA_GPVTG; } } else if(rxBuffer->datalength >= rxBuffer->size) { // if we found no packet, and the buffer is full // we're logjammed, flush entire buffer bufferFlush(rxBuffer); } return foundpacket; }
u08 tsipProcess(cBuffer* rxBuffer) { u08 foundpacket = FALSE; u08 startFlag = FALSE; u08 data; u08 i,j,k; u08 TsipPacketIdx; // process the receive buffer // go through buffer looking for packets while(rxBuffer->datalength > 1) { // look for a potential start of TSIP packet if(bufferGetAtIndex(rxBuffer,0) == DLE) { // make sure the next byte is not DLE or ETX data = bufferGetAtIndex(rxBuffer,1); if((data != DLE) && (data != ETX)) { // found potential start startFlag = TRUE; // done looking for start break; } } else // not DLE, dump character from buffer bufferGetFromFront(rxBuffer); } // if we detected a start, look for end of packet if(startFlag) { for(i=1; i<(rxBuffer->datalength)-1; i++) { // check for potential end of TSIP packet if((bufferGetAtIndex(rxBuffer,i) == DLE) && (bufferGetAtIndex(rxBuffer,i+1) == ETX)) { // have a packet end // dump initial DLE bufferGetFromFront(rxBuffer); // copy data to TsipPacket TsipPacketIdx = 0; for(j=0; j<(i-1); j++) { data = bufferGetFromFront(rxBuffer); if(data == DLE) { if(bufferGetAtIndex(rxBuffer,0) == DLE) { // found double-DLE escape sequence, skip one of them bufferGetFromFront(rxBuffer); j++; } } TsipPacket[TsipPacketIdx++] = data; } // dump ending DLE+ETX bufferGetFromFront(rxBuffer); bufferGetFromFront(rxBuffer); // found a packet if(debug) { rprintf("Rx TSIP packet type: 0x%x len: %d rawlen: %d\r\n", TsipPacket[0], TsipPacketIdx, i); for(k=0; k<TsipPacketIdx; k++) { rprintfu08(TsipPacket[k]); rprintfChar(' '); } //rprintfu08(bufferGetFromFront(rxBuffer)); rprintfChar(' '); //rprintfu08(bufferGetFromFront(rxBuffer)); rprintfChar(' '); rprintfCRLF(); } // done with this processing session foundpacket = TRUE; break; } } } if(foundpacket) { // switch on the packet type switch(TsipPacket[0]) { case TSIPTYPE_GPSTIME: tsipProcessGPSTIME(TsipPacket); break; case TSIPTYPE_POSFIX_XYZ_SP: tsipProcessPOSFIX_XYZ_SP(TsipPacket); break; case TSIPTYPE_VELFIX_XYZ: tsipProcessVELFIX_XYZ(TsipPacket); break; case TSIPTYPE_POSFIX_LLA_SP: tsipProcessPOSFIX_LLA_SP(TsipPacket); break; case TSIPTYPE_VELFIX_ENU: tsipProcessVELFIX_ENU(TsipPacket); break; case TSIPTYPE_RAWDATA: break; default: //if(debug) rprintf("Unhandled TSIP packet type: 0x%x\r\n",TsipPacket[0]); break; } } return foundpacket; }
int uart2GetByte(void) { if(uartRxBuffer[2].datalength) // check if character is available return bufferGetFromFront(&uartRxBuffer[2]); // return character return -1; }
u08 mitelgpsProcess(cBuffer* rxBuffer) { u08 foundpacket = FALSE; u08 startFlag = FALSE; u08 checksum = 0; u08 packetType; u16 i,j; // process the receive buffer // go through buffer looking for packets while(rxBuffer->datalength > 1) { // look for a start of Mitel GPS STX/ETX packet if(bufferGetAtIndex(rxBuffer,0) == STX) { // found start startFlag = TRUE; // done looking for start break; } else // not STX, dump character from buffer bufferGetFromFront(rxBuffer); } // if we detected a start, look for end of packet if(startFlag) { for(i=1; i<(rxBuffer->datalength); i++) { // check for end of Mitel GPS STX/ETX packet if(bufferGetAtIndex(rxBuffer,i) == ETX) { // have a packet end // dump initial STX bufferGetFromFront(rxBuffer); // copy data to MitelGpsPacket for(j=0; j<(i-1); j++) { MitelGpsPacket[j] = bufferGetFromFront(rxBuffer); checksum ^= MitelGpsPacket[j]; } // null-terminate copied string MitelGpsPacket[j] = 0; // dump ending ETX bufferGetFromFront(rxBuffer); // verify checksum // undo checksum summing of the checksum itself checksum ^= MitelGpsPacket[j-2]; checksum ^= MitelGpsPacket[j-1]; if( checksum == convertAsciiHexToInt(&MitelGpsPacket[j-2], 2) ) { // found a good packet if(debug & MITELGPS_DEBUG_PKTPARSE) { rprintf("Rx Mitel GPS packet type: %c%c%c len: %d\r\n", MitelGpsPacket[0], MitelGpsPacket[1], MitelGpsPacket[2], j); rprintfStr(MitelGpsPacket); rprintfCRLF(); } // done with this processing session foundpacket = TRUE; break; } else { if(debug & MITELGPS_DEBUG_PKTPARSE) { rprintf("Rx Mitel GPS packet type: %c%c%c len: %d Bad Checksum Rcvd: 0x%c%c Calc: 0x%x\r\n", MitelGpsPacket[0], MitelGpsPacket[1], MitelGpsPacket[2], j, MitelGpsPacket[j-2], MitelGpsPacket[j-1], checksum); } } } } } // handle and direct the received packet if(foundpacket) { // switch on the packet type packetType = convertAsciiHexToInt(&MitelGpsPacket[1], 2); switch( packetType ) { case MITELTYPE_NAVDATAGND: mitelgpsProcessNAVDATAGND(MitelGpsPacket); break; case MITELTYPE_CHNLSTATGND: mitelgpsProcessCHNLSTATGND(MitelGpsPacket); break; case MITELTYPE_NAVDATA: mitelgpsProcessNAVDATA(MitelGpsPacket); break; case MITELTYPE_RAWDATA: mitelgpsProcessRAWDATA(MitelGpsPacket); break; case MITELTYPE_CHNLSTAT: mitelgpsProcessCHNLSTAT(MitelGpsPacket); break; case MITELTYPE_RELNAVECEF: break; case MITELTYPE_RELNAVRTN: break; default: if(debug & MITELGPS_DEBUG_PKTPARSE) rprintf("Unhandled Mitel GPS packet type: 0x%x\r\n", packetType); break; } } return foundpacket; }
void ProcessSpeaker(void) { u08 static state = 0; u08 sound; if (GetMessage(MSG_BEEP_STOP)) { state = 0; SPEAKER_ON = 0; return; } switch (state) { case 0: if (GetMessage(MSG_BEEP)) state = 1; break; case 1: sound = bufferGetFromFront(&speakerBuffer); if (sound == LONG_BEEP) { state = 2; SPEAKER_ON = 1; StartTimer(TIMER_SPEAKER); } else if (sound == SHORT_BEEP) { state = 3; SPEAKER_ON = 1; StartTimer(TIMER_SPEAKER); } else if (sound == CLICK) { state = 5; SPEAKER_ON = 1; StartTimer(TIMER_SPEAKER); } else if (sound == 0) { SPEAKER_ON = 0; state = 0; } break; case 2: if (GetTimer(TIMER_SPEAKER) >= 500 * msec) { state = 4; StartTimer(TIMER_SPEAKER); SPEAKER_ON = 0; } break; case 3: if (GetTimer(TIMER_SPEAKER) >= 20 * msec) { state = 4; StartTimer(TIMER_SPEAKER); SPEAKER_ON = 0; } break; case 4: if (GetTimer(TIMER_SPEAKER) >= 100 * msec) { state = 1; PauseTimer(TIMER_SPEAKER); } break; case 5: if (GetTimer(TIMER_SPEAKER) >= 1 * msec) { state = 4; StartTimer(TIMER_SPEAKER); SPEAKER_ON = 0; } break; default: break; } }