FreeEMS  0.2.0-SNAPSHOT-285-g028e24c
Macros | Functions
commsISRs.c File Reference

Send and receive bytes serially. More...

#include "inc/freeEMS.h"
#include "inc/interrupts.h"
#include "inc/utils.h"
#include "inc/commsCore.h"
#include "inc/commsISRs.h"
Include dependency graph for commsISRs.c:

Go to the source code of this file.

Macros

#define COMMSISRS_C

Functions

void resetReceiveState (unsigned char sourceIDState)
 Reset Receive State.
void SCI0ISR ()
 Serial Communication Interface 0 ISR.

Detailed Description

Send and receive bytes serially.

This file contains the code for both send and receive of serial bytes through the UART SCI0 device. It is purely interrupt driven and controlled by a set of register and non-register flags that are toggled both inside and outside this file. Some additional helper functions are also kept here.

Todo:
TODO SCI0ISR() needs to be split into some hash defines and an include file that formats it to be the ISR for a specific channel.

Definition in file commsISRs.c.

Macro Definition Documentation

#define COMMSISRS_C

Definition at line 43 of file commsISRs.c.

Function Documentation

void resetReceiveState ( unsigned char  sourceIDState)

Reset Receive State.

Reset communications reception to the state provided.

Todo:
TODO this is in the wrong file!! Either move the header declaration or move the function!
Parameters
sourceIDStateis the state to apply to the RX buffer state variable.
Todo:
TODO CAN0CTL1 &= CANCTL1_RX_DISABLE;
Todo:
TODO CAN0CTL1 &= CANCTL1_RX_ISR_DISABLE;
Todo:
TODO CAN0CTL1 |= CANCTL1_RX_ENABLE;
Todo:
TODO CAN0CTL1 |= CANCTL1_RX_ISR_ENABLE;

Definition at line 64 of file commsISRs.c.

References COM_SET_CAN0_INTERFACE_ID, COM_SET_SCI0_INTERFACE_ID, RXBufferContentSourceID, RXBufferCurrentPosition, RXStateFlags, SCI0CR2, SCI0DRL, SCI0SR1, SCICR2_RX_ISR_DISABLE, and SCICR2_RX_ISR_ENABLE.

Referenced by decodePacketAndRespond(), and SCI0ISR().

{
/* Set the receive buffer pointer to the beginning */
RXBufferCurrentPosition = (unsigned char*)&RXBuffer;
/* Zero the flags */
/* Set the source ID state (clear all or all but one flag(s)) */
RXBufferContentSourceID = sourceIDState;
/* Which ever interface we are setting is the one we came from. By definition */
/* it must be on and we want it to stay on, so just turn off all the others. */
if(sourceIDState & COM_SET_SCI0_INTERFACE_ID){
/* Turn off all others here */
/// @todo TODO CAN0CTL1 &= CANCTL1_RX_DISABLE;
/// @todo TODO CAN0CTL1 &= CANCTL1_RX_ISR_DISABLE;
/* SPI ? I2C ? SCI1 ? */
}else if(sourceIDState & COM_SET_CAN0_INTERFACE_ID){
/* Turn off all others here */
/* Only SCI for now */
/* SPI ? I2C ? SCI1 ? */
}else{ /* If clearing all flags then enable RX on all interfaces */
/* Only SCI for now */
unsigned char devnull; // Is there a better way to do this?
devnull = SCI0SR1; // Reading the flags combined with...
devnull = SCI0DRL; // ...reading the data clears the flags
/// @todo TODO CAN0CTL1 |= CANCTL1_RX_ENABLE;
/// @todo TODO CAN0CTL1 |= CANCTL1_RX_ISR_ENABLE;
/* SPI ? I2C ? SCI1 ? */
}
}

Here is the caller graph for this function:

void SCI0ISR ( void  )

Serial Communication Interface 0 ISR.

SCI0 ISR handles all interrupts for SCI0 by reading flags and acting appropriately. Its functions are to send raw bytes out over the wire from a buffer and to receive bytes from the wire un-escape them, checksum them and store them in a buffer.

Todo:

TODO Move this code into an include file much like the fuel interrupts such that it can be used for multiple UART SCI devices without duplication.

TODO Fix the init code such that this doesn't run at boot without a serail device attached. Clear buffer maybe? or flag clearing/isr enabling ordering?

Definition at line 109 of file commsISRs.c.

References BIT4, BIT7, CLEAR_ALL_SOURCE_ID_FLAGS, COM_CLEAR_SCI0_INTERFACE_ID, COM_SET_SCI0_INTERFACE_ID, coreStatusA, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, ESCAPE_BYTE, ESCAPED_ESCAPE_BYTE, ESCAPED_START_BYTE, ESCAPED_STOP_BYTE, FLAG_AND_INC_FLAGGABLE, FLAG_SERIAL_ESCAPE_PAIR_MISMATCHES_OFFSET, FLAG_SERIAL_FRAMING_ERRORS_OFFSET, FLAG_SERIAL_NOISE_ERRORS_OFFSET, FLAG_SERIAL_OVERRUN_ERRORS_OFFSET, FLAG_SERIAL_PACKETS_OVER_LENGTH_OFFSET, FLAG_SERIAL_PARITY_ERRORS_OFFSET, FLAG_SERIAL_STARTS_INSIDE_A_PACKET_OFFSET, KeyUserDebugs, NBIT4, NBIT7, PORTB, resetReceiveState(), RX_BUFFER_SIZE, RX_READY_TO_PROCESS, RX_SCI_ESCAPED_NEXT, RX_SCI_NOT_ESCAPED_NEXT, RXBufferContentSourceID, RXBufferCurrentPosition, RXStateFlags, SCI0CR2, SCI0DRL, SCI0SR1, SCICR2_RX_ISR_DISABLE, SCICR2_RX_ISR_ENABLE, SCICR2_TX_DISABLE, SCICR2_TX_ISR_DISABLE, SCICR2_TX_ISR_ENABLE, SCISR1_RX_FRAMING, SCISR1_RX_NOISE, SCISR1_RX_OVERRUN, SCISR1_RX_PARITY, SCISR1_RX_REGISTER_FULL, SCISR1_TX_REGISTER_EMPTY, KeyUserDebug::serialAndCommsCodeErrors, KeyUserDebug::serialHardwareErrors, KeyUserDebug::serialOverrunErrors, START_BYTE, STOP_BYTE, TXBufferCurrentPositionHandler, TXBufferCurrentPositionSCI0, TXBufferInUseFlags, and TXByteEscaped.

{
// OK before flag reading because cleared when SCI0DRL accessed (R or W)
/* Read the flags register */
unsigned char flags = SCI0SR1;
/* Note: Combined with reading or writing the data register this also clears the flags. */
/* If either of these flags is set, we need to read the data to clear the flag */
/* Grab the received byte from the register to clear the flag, whether we want the data or not */
unsigned char rawByte = SCI0DRL;
/* If the RX interrupt is enabled do something useful */
/* If there is noise on the receive line record it */
if(flags & SCISR1_RX_NOISE){
}
/* If a framing error occurs record it */
if(flags & SCISR1_RX_FRAMING){
}
/* If a parity error occurs record it */
if(flags & SCISR1_RX_PARITY){
}
/* If an overrun occurs record it */
if(flags & SCISR1_RX_OVERRUN){
}
}else{ // Process the received data
/* Look for a start byte to indicate a new packet */
if(rawByte == START_BYTE){
/* If another interface is using it (Note, clear flag, not normal) */
/* Turn off our reception */
}else{
/* If we are using it */
/* Increment the counter */
}
/* Reset to us using it unless someone else was */
resetReceiveState(COM_SET_SCI0_INTERFACE_ID);
}
}else if((unsigned short)RXBufferCurrentPosition >= ((unsigned short)&RXBuffer + RX_BUFFER_SIZE)){
/* Buffer was full, record and reset */
/* Clear escaped byte next flag, thanks Karsten! ((~ != !) == (! ~= ~)) == LOL */
if(rawByte == ESCAPED_ESCAPE_BYTE){
}else if(rawByte == ESCAPED_START_BYTE){
}else if(rawByte == ESCAPED_STOP_BYTE){
}else{
/* Otherwise reset and record as data is bad */
}
}else if(rawByte == ESCAPE_BYTE){
/* Drop the escape and set the flag to indicate that the next byte should be un-escaped. */
}else if(rawByte == STOP_BYTE){
/* Turn off reception */
}else{
}
} /* ELSE: Do nothing : drop the byte */
}
}
}
/* If the TX interrupt is enabled check the register empty flag. */
/* Get the byte to be sent from the buffer */
unsigned char rawValue = *TXBufferCurrentPositionSCI0;
if(TXByteEscaped == 0){
/* If the raw value needs to be escaped */
if(rawValue == ESCAPE_BYTE){
}else if(rawValue == START_BYTE){
}else if(rawValue == STOP_BYTE){
}else{ /* Otherwise just send it */
SCI0DRL = rawValue;
}
}else{
}
}else{ /* Length is zero */
/* Turn off transmission interrupt */
/* Clear the TX in progress flag */
}else{
/* Send the stop byte */
}
}
}
}

Here is the call graph for this function: