#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.
Defines | |
#define | COMMSISRS_C |
Functions | |
void | sendAndIncrement (unsigned char rawValue) |
void | receiveAndIncrement (const unsigned char value) |
void | resetReceiveState (unsigned char sourceIDState) |
void | SCI0ISR (void) |
#define COMMSISRS_C |
Definition at line 24 of file commsISRs.c.
void receiveAndIncrement | ( | const unsigned char | value | ) | [inline] |
Definition at line 46 of file commsISRs.c.
References RXBufferCurrentPosition, RXCalculatedChecksum, and RXPacketLengthReceived.
Referenced by SCI0ISR().
00046 { 00047 *RXBufferCurrentPosition = value; 00048 RXCalculatedChecksum += value; 00049 RXBufferCurrentPosition++; 00050 RXPacketLengthReceived++; 00051 }
void resetReceiveState | ( | unsigned char | sourceIDState | ) |
Definition at line 55 of file commsISRs.c.
References COM_SET_CAN0_INTERFACE_ID, COM_SET_SCI0_INTERFACE_ID, RXBufferContentSourceID, RXBufferCurrentPosition, RXCalculatedChecksum, RXPacketLengthReceived, RXStateFlags, SCI0CR2, SCICR2_RX_DISABLE, SCICR2_RX_ENABLE, SCICR2_RX_ISR_DISABLE, and SCICR2_RX_ISR_ENABLE.
Referenced by decodePacketAndRespond(), and SCI0ISR().
00055 { // WRONG 00056 /* Set the receive buffer pointer to the beginning */ 00057 RXBufferCurrentPosition = (unsigned char*)&RXBuffer; 00058 00059 /* Zero the flags, buffer length and checksum */ 00060 RXPacketLengthReceived = 0; 00061 RXCalculatedChecksum = 0; 00062 RXStateFlags = 0; 00063 00064 /* Set the source ID state (clear all or all but one flag(s)) */ 00065 RXBufferContentSourceID = sourceIDState; 00066 00067 /* Which ever interface we are setting is the one we came from. By definition */ 00068 /* it must be on and we want it to stay on, so just turn off all the others. */ 00069 if(sourceIDState & COM_SET_SCI0_INTERFACE_ID){ 00070 /* Turn off all others here */ 00071 // TODO CAN0CTL1 &= CANCTL1_RX_DISABLE; 00072 // TODO CAN0CTL1 &= CANCTL1_RX_ISR_DISABLE; 00073 /* SPI ? I2C ? SCI1 ? */ 00074 }else if(sourceIDState & COM_SET_CAN0_INTERFACE_ID){ 00075 /* Turn off all others here */ 00076 /* Only SCI for now */ 00077 SCI0CR2 &= SCICR2_RX_DISABLE; 00078 SCI0CR2 &= SCICR2_RX_ISR_DISABLE; 00079 /* SPI ? I2C ? SCI1 ? */ 00080 }else{ /* If clearing all flags then enable RX on all interfaces */ 00081 /* Only SCI for now */ 00082 SCI0CR2 |= SCICR2_RX_ENABLE; 00083 SCI0CR2 |= SCICR2_RX_ISR_ENABLE; 00084 // TODO CAN0CTL1 |= CANCTL1_RX_ENABLE; 00085 // TODO CAN0CTL1 |= CANCTL1_RX_ISR_ENABLE; 00086 /* SPI ? I2C ? SCI1 ? */ 00087 } 00088 }
void SCI0ISR | ( | void | ) |
Definition at line 92 of file commsISRs.c.
References BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, CLEAR_ALL_SOURCE_ID_FLAGS, COM_CLEAR_SCI0_INTERFACE_ID, COM_SET_SCI0_INTERFACE_ID, Counter::commsChecksumMismatches, Counters, ESCAPE_BYTE, ESCAPED_ESCAPE_BYTE, ESCAPED_START_BYTE, ESCAPED_STOP_BYTE, PORTA, PORTB, receiveAndIncrement(), resetReceiveState(), RuntimeVars, RX_BUFFER_SIZE, RX_READY_TO_PROCESS, RX_SCI_ESCAPED_NEXT, RX_SCI_NOT_ESCAPED_NEXT, RXBufferContentSourceID, RXBufferCurrentPosition, RXCalculatedChecksum, RXPacketLengthReceived, RXStateFlags, SCI0CR2, SCI0DRL, SCI0SR1, SCICR2_RX_DISABLE, SCICR2_RX_ISR_DISABLE, SCICR2_RX_ISR_ENABLE, 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, sendAndIncrement(), Counter::serialEscapePairMismatches, Counter::serialFramingErrors, RuntimeVar::serialISRRuntime, Counter::serialNoiseErrors, Counter::serialOverrunErrors, Counter::serialPacketsOverLength, Counter::serialParityErrors, Counter::serialStartsInsideAPacket, START_BYTE, STOP_BYTE, TCNT, TXBufferCurrentPositionSCI0, TXBufferInUseFlags, TXByteEscaped, and TXPacketLengthToSendSCI0.
00092 { 00093 /* Read the flags register */ 00094 unsigned char flags = SCI0SR1; 00095 /* Note: Combined with reading or writing the data register this also clears the flags. */ 00096 00097 /* Start counting */ 00098 unsigned short start = TCNT; 00099 00100 /* If the RX interrupt is enabled check RX related flags */ 00101 if(SCI0CR2 & SCICR2_RX_ISR_ENABLE){ 00102 /* Grab the received byte from the register */ 00103 unsigned char rawByte = SCI0DRL; 00104 00105 PORTB |= BIT0; 00106 00107 /* Record error conditions always */ 00108 unsigned char resetOnError = 0; 00109 /* If there is noise on the receive line record it */ 00110 if(flags & SCISR1_RX_NOISE){ 00111 Counters.serialNoiseErrors++; 00112 resetOnError++; 00113 }/* If an overrun occurs record it */ 00114 if(flags & SCISR1_RX_OVERRUN){ 00115 Counters.serialOverrunErrors++; 00116 resetOnError++; 00117 }/* If a framing error occurs record it */ 00118 if(flags & SCISR1_RX_FRAMING){ 00119 Counters.serialFramingErrors++; 00120 resetOnError++; 00121 }/* If a parity error occurs record it */ 00122 if(flags & SCISR1_RX_PARITY){ 00123 Counters.serialParityErrors++; 00124 resetOnError++; 00125 } 00126 00127 /* Drop out because of error flags */ 00128 if(resetOnError){ 00129 resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS); 00130 PORTB |= BIT1; 00131 return; 00132 } 00133 00134 /* If there is data waiting to be received */ 00135 if(flags & SCISR1_RX_REGISTER_FULL){ 00136 PORTB |= BIT2; 00137 /* Look for a start bresetReceiveStateyte to indicate a new packet */ 00138 if(rawByte == START_BYTE){ 00139 PORTB |= BIT3; 00140 /* If another interface is using it (Note, clear flag, not normal) */ 00141 if(RXBufferContentSourceID & COM_CLEAR_SCI0_INTERFACE_ID){ 00142 /* Turn off our reception */ 00143 SCI0CR2 &= SCICR2_RX_DISABLE; 00144 SCI0CR2 &= SCICR2_RX_ISR_DISABLE; 00145 PORTB |= BIT4; 00146 }else{ 00147 PORTB |= BIT5; 00148 /* If we are using it */ 00149 if(RXBufferContentSourceID & COM_SET_SCI0_INTERFACE_ID){ 00150 /* Increment the counter */ 00151 Counters.serialStartsInsideAPacket++; 00152 } 00153 /* Reset to us using it unless someone else was */ 00154 resetReceiveState(COM_SET_SCI0_INTERFACE_ID); 00155 } 00156 }else if(RXPacketLengthReceived >= RX_BUFFER_SIZE){ 00157 /* Buffer was full, record and reset */ 00158 Counters.serialPacketsOverLength++; 00159 resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS); 00160 PORTB |= BIT6; 00161 }else if(RXBufferContentSourceID & COM_SET_SCI0_INTERFACE_ID){ 00162 if(RXStateFlags & RX_SCI_ESCAPED_NEXT){ 00163 PORTB |= BIT7; 00164 /* Clear escaped byte next flag, thanks Karsten! ((~ != !) == (! ~= ~)) == LOL */ 00165 RXStateFlags &= RX_SCI_NOT_ESCAPED_NEXT; 00166 00167 if(rawByte == ESCAPED_ESCAPE_BYTE){ 00168 /* Store and checksum escape byte */ 00169 receiveAndIncrement(ESCAPE_BYTE); 00170 }else if(rawByte == ESCAPED_START_BYTE){ 00171 /* Store and checksum start byte */ 00172 receiveAndIncrement(START_BYTE); 00173 }else if(rawByte == ESCAPED_STOP_BYTE){ 00174 /* Store and checksum stop byte */ 00175 receiveAndIncrement(STOP_BYTE); 00176 }else{ 00177 /* Otherwise reset and record as data is bad */ 00178 resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS); 00179 Counters.serialEscapePairMismatches++; 00180 } 00181 }else if(rawByte == ESCAPE_BYTE){ 00182 PORTA |= BIT0; 00183 /* Set flag to indicate that the next byte should be un-escaped. */ 00184 RXStateFlags |= RX_SCI_ESCAPED_NEXT; 00185 }else if(rawByte == STOP_BYTE){ 00186 PORTA |= BIT1; 00187 /* Turn off reception */ 00188 SCI0CR2 &= SCICR2_RX_DISABLE; 00189 SCI0CR2 &= SCICR2_RX_ISR_DISABLE; 00190 00191 /* Bring the checksum back to where it should be */ 00192 unsigned char RXReceivedChecksum = (unsigned char)*(RXBufferCurrentPosition - 1); 00193 RXCalculatedChecksum -= RXReceivedChecksum; 00194 00195 /* Check that the checksum matches */ 00196 if(RXCalculatedChecksum == RXReceivedChecksum){ 00197 /* If it's OK set process flag */ 00198 RXStateFlags |= RX_READY_TO_PROCESS; 00199 PORTA |= BIT2; 00200 }else{ 00201 PORTA |= BIT3; 00202 /* Otherwise reset the state and record it */ 00203 resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS); 00204 Counters.commsChecksumMismatches++; 00205 } 00206 }else{ 00207 PORTA |= BIT4; 00208 /* If it isn't special process it! */ 00209 receiveAndIncrement(rawByte); 00210 } 00211 }else{ 00212 /* Do nothing : drop the byte */ 00213 PORTA |= BIT5; 00214 } 00215 } 00216 } 00217 00218 /* If the TX interrupt is enabled check the register empty flag. */ 00219 if((SCI0CR2 & SCICR2_TX_ISR_ENABLE) && (flags & SCISR1_TX_REGISTER_EMPTY)){ 00220 /* Get the byte to be sent from the buffer */ 00221 unsigned char rawValue = *TXBufferCurrentPositionSCI0; 00222 00223 if(TXPacketLengthToSendSCI0 > 0){ 00224 if(TXByteEscaped == 0){ 00225 /* If the raw value needs to be escaped */ 00226 if(rawValue == ESCAPE_BYTE){ 00227 SCI0DRL = ESCAPE_BYTE; 00228 TXByteEscaped = ESCAPED_ESCAPE_BYTE; 00229 }else if(rawValue == START_BYTE){ 00230 SCI0DRL = ESCAPE_BYTE; 00231 TXByteEscaped = ESCAPED_START_BYTE; 00232 }else if(rawValue == STOP_BYTE){ 00233 SCI0DRL = ESCAPE_BYTE; 00234 TXByteEscaped = ESCAPED_STOP_BYTE; 00235 }else{ /* Otherwise just send it */ 00236 sendAndIncrement(rawValue); 00237 } 00238 }else{ 00239 sendAndIncrement(TXByteEscaped); 00240 TXByteEscaped = 0; 00241 } 00242 }else{ /* Length is zero */ 00243 /* Turn off transmission interrupt */ 00244 SCI0CR2 &= SCICR2_TX_ISR_DISABLE; 00245 /* Send the stop byte */ 00246 SCI0DRL = STOP_BYTE; 00247 /* Clear the TX in progress flag */ 00248 TXBufferInUseFlags &= COM_CLEAR_SCI0_INTERFACE_ID; 00249 } 00250 } 00251 00252 /* Record how long the operation took */ 00253 RuntimeVars.serialISRRuntime = TCNT - start; 00254 }
Here is the call graph for this function:
void sendAndIncrement | ( | unsigned char | rawValue | ) | [inline] |
Definition at line 38 of file commsISRs.c.
References SCI0DRL, TXBufferCurrentPositionSCI0, and TXPacketLengthToSendSCI0.
Referenced by SCI0ISR().
00038 { 00039 SCI0DRL = rawValue; 00040 TXPacketLengthToSendSCI0--; 00041 TXBufferCurrentPositionSCI0++; 00042 }