FreeEMS  0.2.0-SNAPSHOT-285-g028e24c
Macros | Functions | Variables
commsCore.h File Reference
#include "packetTypes.h"
#include "unitTestIDs.h"
Include dependency graph for commsCore.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define EXTERN   extern
#define TX_MAX_PAYLOAD_SIZE   (TX_BUFFER_SIZE - 32)
#define START_BYTE   0xAA
#define ESCAPE_BYTE   0xBB
#define STOP_BYTE   0xCC
#define ESCAPED_START_BYTE   0x55
#define ESCAPED_ESCAPE_BYTE   0x44
#define ESCAPED_STOP_BYTE   0x33
#define COM_SET_SCI0_INTERFACE_ID   BIT0
#define COM_SET_CAN0_INTERFACE_ID   BIT1
#define COM_SET_SPARE2_INTERFACE_ID   BIT2
#define COM_SET_SPARE3_INTERFACE_ID   BIT3
#define COM_SET_SPARE4_INTERFACE_ID   BIT4
#define COM_SET_SPARE5_INTERFACE_ID   BIT5
#define COM_SET_SPARE6_INTERFACE_ID   BIT6
#define COM_SET_SPARE7_INTERFACE_ID   BIT7
#define COM_CLEAR_SCI0_INTERFACE_ID   NBIT0
#define COM_CLEAR_CAN0_INTERFACE_ID   NBIT1
#define COM_CLEAR_SPARE2_INTERFACE_ID   NBIT2
#define COM_CLEAR_SPARE3_INTERFACE_ID   NBIT3
#define COM_CLEAR_SPARE4_INTERFACE_ID   NBIT4
#define COM_CLEAR_SPARE5_INTERFACE_ID   NBIT5
#define COM_CLEAR_SPARE6_INTERFACE_ID   NBIT6
#define COM_CLEAR_SPARE7_INTERFACE_ID   NBIT7
#define CLEAR_ALL_SOURCE_ID_FLAGS   ZEROS
#define RX_READY_TO_PROCESS   BIT1
#define RX_SCI_ESCAPED_NEXT   BIT2
#define RX_CLEAR_READY_TO_PROCESS   NBIT1
#define RX_SCI_NOT_ESCAPED_NEXT   NBIT2
#define SCICR2_RX_ENABLE   BIT2
#define SCICR2_TX_ENABLE   BIT3
#define SCICR2_RX_ISR_ENABLE   BIT5
#define SCICR2_TX_ISR_ENABLE   BIT7
#define SCICR2_RX_DISABLE   NBIT2
#define SCICR2_TX_DISABLE   NBIT3
#define SCICR2_RX_ISR_DISABLE   NBIT5
#define SCICR2_TX_ISR_DISABLE   NBIT7
#define HEADER_HAS_LENGTH   BIT0
#define HEADER_IS_NACK   BIT1
#define HEADER_HAS_SEQUENCE   BIT2
#define HEADER_RESERVED_E   BIT3
#define HEADER_RESERVED_D   BIT4
#define HEADER_RESERVED_C   BIT5
#define HEADER_RESERVED_B   BIT6
#define HEADER_RESERVED_A   BIT7
#define asyncDatalogOff   0x00
 Logs by polling only, reduces CPU load a little but gives much lower data rate.
#define asyncDatalogBasic   0x01
 Good old default log, always contains the normal stuff, good for most people, most of the time.
#define asyncDatalogScratchPad   0x02
 User log of anything, any subset of a block allowed, start offset, size, content pointers/flags.
#define asyncDatalogStructs   0x03
 Key structs, or subsets of them, or chunk to chunk, streamed, more efficient than scratch pad and bigger if needed.
#define asyncDatalogPosition   0x04
 Record a buffer of position information, send when full: http://forum.diyefi.org/viewtopic.php?f=8&t=1339.
#define asyncDatalogBlockBytes   0x05
 Populate a large block with bytes as fast as possible, send when full.
#define asyncDatalogBlockWords   0x06
 Populate a large block with bytes as fast as possible, send when full.
#define asyncDatalogBlockLongs   0x07
 Populate a large block with bytes as fast as possible, send when full.
#define asyncDatalogStreamByte   0x08
 Send out a single byte as often as possible, ~1kHz with occasional ~3ms gaps from math running instead.
#define asyncDatalogStreamWord   0x09
 Send out a single word as often as possible, ~1kHz with occasional ~3ms gaps from math running instead.
#define asyncDatalogStreamLong   0x0A
 Send out a single long as often as possible, ~1kHz with occasional ~3ms gaps from math running instead.
#define asyncDatalogLastType   asyncDatalogStreamLong

Functions

void decodePacketAndRespond (void) TEXT
 Decode a packet and respond.
void resetReceiveState (unsigned char) FPAGE_FE
 Reset Receive State.
void finaliseAndSend (unsigned short) FPAGE_FE
 Finalise a packet and send it.
unsigned short populateBasicDatalog (void) FPAGE_FE
 Populate a basic datalog packet.

Variables

EXTERN unsigned char * TXBufferCurrentPositionHandler
EXTERN unsigned char * TXBufferCurrentPositionCAN0
EXTERN unsigned char * TXBufferCurrentPositionSCI0
EXTERN unsigned char TXBufferInUseFlags
EXTERN unsigned char RXBufferContentSourceID
EXTERN unsigned char RXStateFlags
EXTERN unsigned char * RXBufferCurrentPosition
EXTERN unsigned short RXCalculatedPayloadLength
EXTERN unsigned char RXHeaderFlags
EXTERN unsigned char * TXHeaderFlags
EXTERN unsigned short RXHeaderPayloadID
EXTERN unsigned short RXHeaderPayloadLength
 TODO.

Detailed Description

Definition in file commsCore.h.

Macro Definition Documentation

#define EXTERN   extern

Definition at line 48 of file commsCore.h.

#define TX_MAX_PAYLOAD_SIZE   (TX_BUFFER_SIZE - 32)

Definition at line 53 of file commsCore.h.

Referenced by decodePacketAndRespond().

#define START_BYTE   0xAA

Definition at line 78 of file commsCore.h.

Referenced by finaliseAndSend(), and SCI0ISR().

#define ESCAPE_BYTE   0xBB

Definition at line 79 of file commsCore.h.

Referenced by SCI0ISR().

#define STOP_BYTE   0xCC

Definition at line 80 of file commsCore.h.

Referenced by SCI0ISR().

#define ESCAPED_START_BYTE   0x55

Definition at line 82 of file commsCore.h.

Referenced by SCI0ISR().

#define ESCAPED_ESCAPE_BYTE   0x44

Definition at line 83 of file commsCore.h.

Referenced by SCI0ISR().

#define ESCAPED_STOP_BYTE   0x33

Definition at line 84 of file commsCore.h.

Referenced by SCI0ISR().

#define COM_SET_SCI0_INTERFACE_ID   BIT0

Definition at line 88 of file commsCore.h.

Referenced by decodePacketAndRespond(), finaliseAndSend(), main(), resetReceiveState(), and SCI0ISR().

#define COM_SET_CAN0_INTERFACE_ID   BIT1

Definition at line 89 of file commsCore.h.

Referenced by finaliseAndSend(), and resetReceiveState().

#define COM_SET_SPARE2_INTERFACE_ID   BIT2

Definition at line 90 of file commsCore.h.

Referenced by finaliseAndSend().

#define COM_SET_SPARE3_INTERFACE_ID   BIT3

Definition at line 91 of file commsCore.h.

Referenced by finaliseAndSend().

#define COM_SET_SPARE4_INTERFACE_ID   BIT4

Definition at line 92 of file commsCore.h.

Referenced by finaliseAndSend().

#define COM_SET_SPARE5_INTERFACE_ID   BIT5

Definition at line 93 of file commsCore.h.

Referenced by finaliseAndSend().

#define COM_SET_SPARE6_INTERFACE_ID   BIT6

Definition at line 94 of file commsCore.h.

Referenced by finaliseAndSend().

#define COM_SET_SPARE7_INTERFACE_ID   BIT7

Definition at line 95 of file commsCore.h.

Referenced by finaliseAndSend().

#define COM_CLEAR_SCI0_INTERFACE_ID   NBIT0

Definition at line 96 of file commsCore.h.

Referenced by SCI0ISR().

#define COM_CLEAR_CAN0_INTERFACE_ID   NBIT1

Definition at line 97 of file commsCore.h.

Referenced by finaliseAndSend().

#define COM_CLEAR_SPARE2_INTERFACE_ID   NBIT2

Definition at line 98 of file commsCore.h.

Referenced by finaliseAndSend().

#define COM_CLEAR_SPARE3_INTERFACE_ID   NBIT3

Definition at line 99 of file commsCore.h.

Referenced by finaliseAndSend().

#define COM_CLEAR_SPARE4_INTERFACE_ID   NBIT4

Definition at line 100 of file commsCore.h.

Referenced by finaliseAndSend().

#define COM_CLEAR_SPARE5_INTERFACE_ID   NBIT5

Definition at line 101 of file commsCore.h.

Referenced by finaliseAndSend().

#define COM_CLEAR_SPARE6_INTERFACE_ID   NBIT6

Definition at line 102 of file commsCore.h.

Referenced by finaliseAndSend().

#define COM_CLEAR_SPARE7_INTERFACE_ID   NBIT7

Definition at line 103 of file commsCore.h.

Referenced by finaliseAndSend().

#define CLEAR_ALL_SOURCE_ID_FLAGS   ZEROS

Definition at line 104 of file commsCore.h.

Referenced by decodePacketAndRespond(), and SCI0ISR().

#define RX_READY_TO_PROCESS   BIT1

Definition at line 113 of file commsCore.h.

Referenced by main(), and SCI0ISR().

#define RX_SCI_ESCAPED_NEXT   BIT2

Definition at line 114 of file commsCore.h.

Referenced by SCI0ISR().

#define RX_CLEAR_READY_TO_PROCESS   NBIT1

Definition at line 117 of file commsCore.h.

Referenced by main().

#define RX_SCI_NOT_ESCAPED_NEXT   NBIT2

Definition at line 118 of file commsCore.h.

Referenced by SCI0ISR().

#define SCICR2_RX_ENABLE   BIT2

Definition at line 127 of file commsCore.h.

#define SCICR2_TX_ENABLE   BIT3

Definition at line 128 of file commsCore.h.

Referenced by finaliseAndSend().

#define SCICR2_RX_ISR_ENABLE   BIT5

Definition at line 129 of file commsCore.h.

Referenced by resetReceiveState(), and SCI0ISR().

#define SCICR2_TX_ISR_ENABLE   BIT7

Definition at line 130 of file commsCore.h.

Referenced by finaliseAndSend(), and SCI0ISR().

#define SCICR2_RX_DISABLE   NBIT2

Definition at line 131 of file commsCore.h.

#define SCICR2_TX_DISABLE   NBIT3

Definition at line 132 of file commsCore.h.

Referenced by SCI0ISR().

#define SCICR2_RX_ISR_DISABLE   NBIT5

Definition at line 133 of file commsCore.h.

Referenced by resetReceiveState(), and SCI0ISR().

#define SCICR2_TX_ISR_DISABLE   NBIT7

Definition at line 134 of file commsCore.h.

Referenced by SCI0ISR().

#define HEADER_HAS_LENGTH   BIT0

Definition at line 157 of file commsCore.h.

Referenced by decodePacketAndRespond(), and main().

#define HEADER_IS_NACK   BIT1

Definition at line 158 of file commsCore.h.

Referenced by finaliseAndSend().

#define HEADER_HAS_SEQUENCE   BIT2

Definition at line 159 of file commsCore.h.

Referenced by decodePacketAndRespond().

#define HEADER_RESERVED_E   BIT3

Definition at line 160 of file commsCore.h.

#define HEADER_RESERVED_D   BIT4

Definition at line 161 of file commsCore.h.

#define HEADER_RESERVED_C   BIT5

Definition at line 162 of file commsCore.h.

#define HEADER_RESERVED_B   BIT6

Definition at line 163 of file commsCore.h.

#define HEADER_RESERVED_A   BIT7

Definition at line 164 of file commsCore.h.

#define asyncDatalogOff   0x00

Logs by polling only, reduces CPU load a little but gives much lower data rate.

Definition at line 167 of file commsCore.h.

Referenced by main().

#define asyncDatalogBasic   0x01

Good old default log, always contains the normal stuff, good for most people, most of the time.

Definition at line 168 of file commsCore.h.

Referenced by main().

#define asyncDatalogScratchPad   0x02

User log of anything, any subset of a block allowed, start offset, size, content pointers/flags.

Definition at line 169 of file commsCore.h.

Referenced by main().

#define asyncDatalogStructs   0x03

Key structs, or subsets of them, or chunk to chunk, streamed, more efficient than scratch pad and bigger if needed.

Definition at line 170 of file commsCore.h.

Referenced by main().

#define asyncDatalogPosition   0x04

Record a buffer of position information, send when full: http://forum.diyefi.org/viewtopic.php?f=8&t=1339.

Definition at line 171 of file commsCore.h.

Referenced by main().

#define asyncDatalogBlockBytes   0x05

Populate a large block with bytes as fast as possible, send when full.

Definition at line 172 of file commsCore.h.

Referenced by main().

#define asyncDatalogBlockWords   0x06

Populate a large block with bytes as fast as possible, send when full.

Definition at line 173 of file commsCore.h.

Referenced by main().

#define asyncDatalogBlockLongs   0x07

Populate a large block with bytes as fast as possible, send when full.

Definition at line 174 of file commsCore.h.

Referenced by main().

#define asyncDatalogStreamByte   0x08

Send out a single byte as often as possible, ~1kHz with occasional ~3ms gaps from math running instead.

Definition at line 175 of file commsCore.h.

Referenced by main().

#define asyncDatalogStreamWord   0x09

Send out a single word as often as possible, ~1kHz with occasional ~3ms gaps from math running instead.

Definition at line 176 of file commsCore.h.

Referenced by main().

#define asyncDatalogStreamLong   0x0A

Send out a single long as often as possible, ~1kHz with occasional ~3ms gaps from math running instead.

Definition at line 177 of file commsCore.h.

Referenced by main().

#define asyncDatalogLastType   asyncDatalogStreamLong

Definition at line 178 of file commsCore.h.

Referenced by decodePacketAndRespond().

Function Documentation

void decodePacketAndRespond ( void  )

Decode a packet and respond.

This is the core function that controls which functionality is run when a packet is received in full by the ISR code and control is passed back to the main loop code. The vast majority of communications action happens here.

TODO

Todo:
factor this out into validation delegation function once the number of types increases somewhat

TODO

Todo:
factor this out into validation delegation function once the number of types increases somewhat

TODO

Todo:
test all things listed below:

Definition at line 207 of file commsCore.c.

References _start(), ARMCOP, asyncDatalogLastType, ATOMIC_END, ATOMIC_START, attemptToWriteToReadOnlyBlock, BENCH_TEST_NAME, BENCH_TEST_ON, benchTestAlreadyRunning, benchTestNotRunningToBump, benchTestNotRunningToStop, block_is_2dus_table, block_is_indexable, block_is_main_table, block_is_read_only, buildTimeAndDate, builtByName, bumpingByZeroMakesNoSense, burnBlockFromRamToFlash, checksum(), CLEAR_ALL_SOURCE_ID_FLAGS, clearCountersAndFlagsToZero, Clocks, COM_SET_SCI0_INTERFACE_ID, compare(), compilerVersion, COPCTL, coreStatusA, CoreVars, Counters, KeyUserDebug::currentEvent, decoderMaxCodeTime, decoderName, DerivedVars, doesNotMakeSenseToRetrievePartially, DerivedVar::Dwell, ectSwitchOnCodeTime, finaliseAndSend(), firmwareVersion, FLAG_AND_INC_FLAGGABLE, FLAG_SERIAL_CHECKSUM_MISMATCHES_OFFSET, FLAG_SERIAL_PACKETS_UNDER_LENGTH_OFFSET, KeyUserDebug::flaggableFlags, KeyUserDebug::flaggableFlags2, Flaggables, Flaggables2, blockDetails::flags, blockDetails::FlashAddress, blockDetails::FlashPage, HEADER_HAS_LENGTH, HEADER_HAS_SEQUENCE, init(), interfaceVersion, invalidEventsPerCycle, invalidMemoryActionForID, invalidNumberOfCycles, invalidPayloadID, invalidSizeOffsetCombination, KeyUserDebugs, lookupBlockDetails(), lookupTwoDTableUS(), MEMORY_WRITE_ERROR, noChannelsConfiguredToTest, noSuchAsyncDatalogType, noSuchUnitTestID, operatingSystem, outputEventDelayFinalPeriod, outputEventInputEventNumbers, outputEventPulseWidthsMath, packetSizeWrongForTestMode, packetTooShortForSpecifiedFields, payloadLengthHeaderMismatch, payloadLengthTypeMismatch, payloadNotEqualToSpecifiedValue, payloadShorterThanRequiredForTest, populateBasicDatalog(), PPAGE, PPAGE_MIN, blockDetails::RAMAddress, blockDetails::RAMPage, DerivedVar::RefPW, requestBuiltByName, requestCompilerVersion, requestDatalogPacket, requestDecoderName, requestEchoPacketReturn, requestedAddressDisallowed, requestedFlashPageInvalid, requestedLengthTooLarge, requestedRAMPageInvalid, requestFirmwareBuildDate, requestFirmwareVersion, requestHardSystemReset, requestInterfaceVersion, requestMaxPacketSize, requestOperatingSystem, requestReInitOfSystem, requestSoftSystemReset, requestSupportEmail, requestUnitTestOverSerial, resetReceiveState(), retrieveArbitraryMemory, retrieveBlockFromFlash, retrieveBlockFromRAM, retrieveListOfLocationIDs, retrieveLocationIDDetails, RPAGE, RPAGE_MIN, CoreVar::RPM, RX_BUFFER_SIZE, RXBufferCurrentPosition, RXCalculatedPayloadLength, RXHeaderFlags, RXHeaderPayloadID, RXHeaderPayloadLength, KeyUserDebug::serialAndCommsCodeErrors, setAsyncDatalogType, blockDetails::size, startBenchTestSequence, stringCopy(), supportEmail, TEST_MODE_BUMP_UP_CYCLES, TEST_MODE_DODGY_MISSING_TOOTH, TEST_MODE_ITERATIONS, TEST_MODE_STOP, testEmptyTest, testEventsPerCycle, testMode, testNumberOfCycles, testNumberOfMissing, testTicksPerEvent, testTwoDTableUSLookup, thisIsNotTheBenchTestDecoder, TIE, Clock::timeoutADCreadingClock, tooManyEventsPerCycleMissingTth, tooShortOfAnEventPeriod, tooShortOfAPulseWidthToTest, TX_MAX_PAYLOAD_SIZE, TXBufferCurrentPositionCAN0, TXBufferCurrentPositionHandler, TXBufferCurrentPositionSCI0, TXBufferInUseFlags, TXHeaderFlags, uncheckedTableManipulationNotAllowed, unimplementedTestMode, unrecognisedPayloadID, updateBlockInFlash, updateBlockInRAM, validateMainTable(), validateTwoDTable(), and writeBlock().

Referenced by main().

{
/* Extract and build up the header fields */
TXBufferCurrentPositionHandler = (unsigned char*)&TXBuffer;
/* Initialised here such that override is possible */
TXBufferCurrentPositionSCI0 = (unsigned char*)&TXBuffer;
TXBufferCurrentPositionCAN0 = (unsigned char*)&TXBuffer;
// How big was the packet that we got back
unsigned short RXPacketLengthReceived = (unsigned short)RXBufferCurrentPosition - (unsigned short)&RXBuffer;
/* Check that the packet is big enough for header,ID,checksum */
if(RXPacketLengthReceived < 4){
return;
}
/* Pull out the received checksum and calculate the real one, then check */
unsigned char RXReceivedChecksum = (unsigned char)*(RXBufferCurrentPosition - 1);
unsigned char RXCalculatedChecksum = checksum((unsigned char*)&RXBuffer, RXPacketLengthReceived - 1);
if(RXCalculatedChecksum != RXReceivedChecksum){
return;
}
/* Start this off as full packet length and build down to the actual length */
RXCalculatedPayloadLength = RXPacketLengthReceived;
/* Grab the RX header flags out of the RX buffer */
RXBufferCurrentPosition = (unsigned char*)&RXBuffer;
/* Flag that we are transmitting! */
// SCI0 only for now...
/* Load a blank header into the TX buffer ready for masking */
/* Grab the payload ID for processing and load the return ID */
/* Check that the length is sufficient for the fields configured. Packets
* that are too long will be caught and rejected on an individual payload
* ID basis as the information required to handle that is not available at
* this point. Packets that are too short are rejected immediately!
*/
if(((RXHeaderFlags & HEADER_HAS_LENGTH) && (RXHeaderFlags & HEADER_HAS_SEQUENCE) && (RXPacketLengthReceived < 7))
|| ((RXHeaderFlags & HEADER_HAS_LENGTH) && (RXPacketLengthReceived < 6))
|| ((RXHeaderFlags & HEADER_HAS_SEQUENCE) && (RXPacketLengthReceived < 5))){
return;
}
/* Subtract checksum to get final length */
}
if(RXHeaderFlags & HEADER_HAS_LENGTH){
/* Already subtracted one for checksum */
return;
}
}
/* Calculate the position of the end of the stored packet for later use as a buffer */
void* leftOverBuffer = (void*)((unsigned short)&RXBuffer + RXPacketLengthReceived);
unsigned short errorID = 0;
/* This is where all the communication logic resides.
*
* Please Note: Length and its flag should be set by each return packet
* type handler if required or desired. If an ack has been requested,
* ensure the negative ack flag is set if the operation failed.
*/
// FreeEMS Core Comms Interface cases
{
break;
}
/* This type must have a length field, set that up */
*((unsigned short*)TXBufferCurrentPositionHandler) = sizeof(interfaceVersion);
/* Load the body into place */
break;
}
{
break;
}
/* This type must have a length field, set that up */
*((unsigned short*)TXBufferCurrentPositionHandler) = sizeof(firmwareVersion);
/* Load the body into place */
break;
}
{
break;
}
/* Load the size into place */
break;
}
{
/* This type must have a length field, set that up */
*((unsigned short*)TXBufferCurrentPositionHandler) = RXPacketLengthReceived;
/* Load the body into place */
memcpy((void*)TXBufferCurrentPositionHandler, (void*)&RXBuffer, RXPacketLengthReceived);
/* Note, there is no overflow check here because the TX buffer is slightly */
/* bigger than the RX buffer and there is overflow checking for receives anyway. */
TXBufferCurrentPositionHandler += RXPacketLengthReceived;
break;
}
{
}else{ // Perform soft system reset
_start();
}
break;
}
{
}else{
/* This is how the serial monitor does it. */
COPCTL = 0x01; /* Arm with shortest time */
ARMCOP = 0xFF; /* Write bad value, should cause immediate reset */
/* Using _start() only resets the app ignoring the monitor switch. It does not work */
/* properly because the location of _start is not the master reset vector location. */
}
break;
}
{
}else{
init();
}
break;
}
// FreeEMS Vanilla Firmware Specific cases
{
break;
}
unsigned short zeroCounter;
unsigned char* counterPointer;
counterPointer = (unsigned char*) &Counters;
for(zeroCounter = 0;zeroCounter < sizeof(Counter);zeroCounter++){
*counterPointer = 0;
counterPointer++;
}
counterPointer = (unsigned char*) &Flaggables;
for(zeroCounter = 0;zeroCounter < sizeof(Flaggable);zeroCounter++){
*counterPointer = 0;
counterPointer++;
}
counterPointer = (unsigned char*) &Flaggables2;
for(zeroCounter = 0;zeroCounter < sizeof(Flaggable2);zeroCounter++){
*counterPointer = 0;
counterPointer++;
}
break;
}
{
break;
}
unsigned char* stringToSend = 0;
switch (RXHeaderPayloadID) {
stringToSend = (unsigned char*)builtByName;
break;
stringToSend = (unsigned char*)supportEmail;
break;
stringToSend = (unsigned char*)decoderName;
break;
stringToSend = (unsigned char*)buildTimeAndDate;
break;
stringToSend = (unsigned char*)compilerVersion;
break;
stringToSend = (unsigned char*)operatingSystem;
break;
}
/* This type must have a length field, set that up and load the body into place at the same time */
*((unsigned short*)TXBufferCurrentPositionHandler) = stringCopy((TXBufferCurrentPositionHandler + 2), stringToSend);
// Update with length field and string length.
break;
}
{
// Subtract six to allow for the locationID, size, offset
break;
}
// Extract the RAM location ID
unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
// Extract the offset to place the data at
unsigned short offset = *((unsigned short*)RXBufferCurrentPosition);
// Extract the size of the data to be stored
unsigned short size = *((unsigned short*)RXBufferCurrentPosition);
// Look up the memory location details
blockDetails details;
lookupBlockDetails(locationID, &details);
// Don't let anyone write to running variables unless we are running BenchTest firmware!
if((details.flags & block_is_read_only) && compare((unsigned char*)&decoderName, (unsigned char*)BENCH_TEST_NAME, sizeof(BENCH_TEST_NAME))){
break;
}
// Subtract six to allow for the locationID, size, offset
if((RXCalculatedPayloadLength - 6) != size){
break;
}
// If either of these is zero then this block is not in RAM!
if((details.RAMPage == 0) || (details.RAMAddress == 0)){
break;
}
// Check that size and offset describe a region that is not out of bounds
if((size == 0) || (offset > (details.size - 1)) || (size > (details.size - offset))){
break;
}
// Don't allow sub region manipulation where it does not make sense or is unsafe.
if((size != details.size) && !(details.flags & block_is_indexable)){
break;
}
// Save page values for restore
unsigned char oldRamPage = RPAGE;
// Set the viewable RAM page
RPAGE = details.RAMPage;
/// TODO @todo factor this out into validation delegation function once the number of types increases somewhat
//
if((details.flags & block_is_main_table) || (details.flags & block_is_2dus_table)){
void* bufferToCheck;
// For sub regions, construct an image for verification
if(size != details.size){
// Copy data from destination location to buffer
memcpy(leftOverBuffer, details.RAMAddress, details.size);
// Copy data from rx buffer to buffer over writing old data
memcpy(leftOverBuffer + offset, RXBufferCurrentPosition, size);
bufferToCheck = leftOverBuffer;
}else{
bufferToCheck = RXBufferCurrentPosition;
}
// Verify all tables
if(details.flags & block_is_main_table){
errorID = validateMainTable((mainTable*)bufferToCheck);
}else if(details.flags & block_is_2dus_table){
errorID = validateTwoDTable((twoDTableUS*)bufferToCheck);
}// TODO add other table types here
// If the validation failed, report it
if(errorID != 0){
RPAGE = oldRamPage; // Restore the original RAM page, even when getting an error condition.
break;
}
}
// Copy from the RX buffer to the block of RAM
memcpy((unsigned char*)(details.RAMAddress + offset), RXBufferCurrentPosition, size);
// Check that the write was successful
unsigned char index = compare(RXBufferCurrentPosition, (unsigned char*)(details.RAMAddress + offset), size);
// Restore the original RAM and flash pages
RPAGE = oldRamPage;
if(index != 0){
errorID = MEMORY_WRITE_ERROR;
}
break;
}
{
// Subtract six to allow for the locationID, size, offset
break;
}
// Extract the RAM location ID
unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
// Extract the offset to place the data at
unsigned short offset = *((unsigned short*)RXBufferCurrentPosition);
// Extract the size of the data to be stored
unsigned short size = *((unsigned short*)RXBufferCurrentPosition);
// Look up the memory location details
blockDetails details;
lookupBlockDetails(locationID, &details);
// Subtract six to allow for the locationID, size, offset
if((RXCalculatedPayloadLength - 6) != size){
break;
}
// If either of these is zero then this block is not in flash!
if((details.FlashPage == 0) || (details.FlashAddress == 0)){
break;
}
// Check that size and offset describe a region that is not out of bounds
if((size == 0) || (offset > (details.size - 1)) || (size > (details.size - offset))){
break;
}
// Don't allow sub region manipulation where it does not make sense or is unsafe.
if((size != details.size) && !(details.flags & block_is_indexable)){
break;
}
/// TODO @todo factor this out into validation delegation function once the number of types increases somewhat
//
if((details.flags & block_is_main_table) || (details.flags & block_is_2dus_table)){
void* bufferToCheck;
// For sub regions, construct an image for verification
if(size != details.size){
/* Save page value for restore and set the visible page */
unsigned char oldFlashPage = PPAGE;
PPAGE = details.FlashPage;
// Copy data from destination location to buffer
memcpy(leftOverBuffer, details.FlashAddress, details.size);
/* Restore the original flash page */
PPAGE = oldFlashPage;
// Copy data from rx buffer to buffer over writing old data
memcpy(leftOverBuffer + offset, RXBufferCurrentPosition, size);
bufferToCheck = leftOverBuffer;
}else{
bufferToCheck = RXBufferCurrentPosition;
}
// Verify all tables
if(details.flags & block_is_main_table){
errorID = validateMainTable((mainTable*)bufferToCheck);
}else if(details.flags & block_is_2dus_table){
errorID = validateTwoDTable((twoDTableUS*)bufferToCheck);
}// TODO add other table types here
// If the validation failed, report it
if(errorID != 0){
break;
}
}
/* Copy the flash details and populate the RAM details with the buffer location */
blockDetails burnDetails;
burnDetails.FlashPage = details.FlashPage;
burnDetails.FlashAddress = details.FlashAddress + offset;
burnDetails.RAMPage = RPAGE;
burnDetails.size = size;
/* Copy from the RX buffer to the block of flash */
errorID = writeBlock(&burnDetails, leftOverBuffer);
if(errorID != 0){
break;
}
/* If present in RAM, update that too */
if((details.RAMPage != 0) && (details.RAMAddress != 0)){
/* Save page values for restore */
unsigned char oldRamPage = RPAGE;
/* Set the viewable RAM page */
RPAGE = details.RAMPage;
/* Copy from the RX buffer to the block of RAM */
memcpy((unsigned char*)(details.RAMAddress + offset), RXBufferCurrentPosition, size);
/* Check that the write was successful */
unsigned char index = compare(RXBufferCurrentPosition, (unsigned char*)(details.RAMAddress + offset), size);
/* Restore the original RAM and flash pages */
RPAGE = oldRamPage;
if(index != 0){
errorID = MEMORY_WRITE_ERROR;
}
}
break;
}
{
break;
}
// Extract the RAM location ID
unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
// Extract the offset to place the data at
unsigned short offset = *((unsigned short*)RXBufferCurrentPosition);
// Extract the size of the data to be stored
unsigned short size = *((unsigned short*)RXBufferCurrentPosition);
/* Look up the memory location details */
blockDetails details;
lookupBlockDetails(locationID, &details);
if((details.RAMPage == 0) || (details.RAMAddress == 0)){
break;
}
// Special behaviour for size of zero which returns the whole block
if((size == 0) && (offset == 0)){
size = details.size;
}
// Check that size and offset describe a region that is not out of bounds
if((size == 0) || (offset > (details.size - 1)) || (size > (details.size - offset))){
break;
}
// Don't allow sub region retrieval where it does not make sense or is unsafe. (keep it symmetric for djandruczyk)
if((size != details.size) && !(details.flags & block_is_indexable)){
break;
}
// This type must have a length field, set that up
*((unsigned short*)TXBufferCurrentPositionHandler) = size;
/* Save page value for restore and set the visible page */
unsigned char oldRamPage = RPAGE;
RPAGE = details.RAMPage;
/* Copy the block of RAM to the TX buffer */
memcpy(TXBufferCurrentPositionHandler, (unsigned char*)(details.RAMAddress + offset), size);
/* Restore the original RAM and flash pages */
RPAGE = oldRamPage;
break;
}
{
break;
}
// Extract the RAM location ID
unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
// Extract the offset to place the data at
unsigned short offset = *((unsigned short*)RXBufferCurrentPosition);
// Extract the size of the data to be stored
unsigned short size = *((unsigned short*)RXBufferCurrentPosition);
/* Look up the memory location details */
blockDetails details;
lookupBlockDetails(locationID, &details);
if((details.FlashPage == 0) || (details.FlashAddress == 0)){
break;
}
// Special behaviour for size of zero which returns the whole block
if((size == 0) && (offset == 0)){
size = details.size;
}
// Check that size and offset describe a region that is not out of bounds
if((size == 0) || (offset > (details.size - 1)) || (size > (details.size - offset))){
break;
}
// Don't allow sub region retrieval where it does not make sense or is unsafe. (keep it symmetric for djandruczyk)
if((size != details.size) && !(details.flags & block_is_indexable)){
break;
}
// This type must have a length field, set that up
*((unsigned short*)TXBufferCurrentPositionHandler) = size;
/* Save page value for restore and set the visible page */
unsigned char oldFlashPage = PPAGE;
PPAGE = details.FlashPage;
/* Copy the block of flash to the TX buffer */
memcpy(TXBufferCurrentPositionHandler, (unsigned char*)(details.FlashAddress + offset), size);
/* Restore the original RAM and flash pages */
PPAGE = oldFlashPage;
break;
}
{
break;
}
// Extract the RAM location ID
unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
// Extract the offset to place the data at
unsigned short offset = *((unsigned short*)RXBufferCurrentPosition);
// Extract the size of the data to be stored
unsigned short size = *((unsigned short*)RXBufferCurrentPosition);
/* Look up the memory location details */
blockDetails details;
lookupBlockDetails(locationID, &details);
/* Check that all data we need is present */
if((details.RAMPage == 0) || (details.RAMAddress == 0) || (details.FlashPage == 0) || (details.FlashAddress == 0)){
break;
}
// Special behaviour for size of zero which burns the whole block
if((size == 0) && (offset == 0)){
size = details.size;
}
// Check that size and offset describe a region that is not out of bounds
if((size == 0) || (offset > (details.size - 1)) || (size > (details.size - offset))){
break;
}
// Don't allow sub region retrieval where it does not make sense or is unsafe. (keep it symmetric for djandruczyk)
if((size != details.size) && !(details.flags & block_is_indexable)){
break;
}
// adjust details block to feed to represent the subsection of ram and flash that we want to burn down.
details.RAMAddress += offset;
details.FlashAddress += offset;
details.size = size;
/* Write the block down from RAM to Flash */
errorID = writeBlock(&details, leftOverBuffer);
break;
}
case requestDatalogPacket: // Set type through standard configuration methods
{
break;
}
/* Set the length field up */
unsigned short* localLength = (unsigned short*)TXBufferCurrentPositionHandler;
/* Fill out the log and send */
*localLength = populateBasicDatalog();
break;
}
{
break;
}
unsigned char newDatalogType = *((unsigned char*)RXBufferCurrentPosition);
if(newDatalogType > asyncDatalogLastType){
break;
}
TablesB.SmallTablesB.loggingSettings.datalogStreamType = newDatalogType;
break;
}
{
break;
}
unsigned short length = *((unsigned short*)RXBufferCurrentPosition);
// Make sure the buffer can handle the block
if(length > TX_MAX_PAYLOAD_SIZE){
break;
}
void* address = (void*) *((unsigned short*)RXBufferCurrentPosition);
// Ensure we don't try to read past the end of the address space
if(((unsigned short)address) <= ((0xFFFF - length) + 1)){
// TODO Possibly check and limit ranges
break;
}
unsigned char RAMPage = *((unsigned char*)RXBufferCurrentPosition);
// Ensure RAM page is valid. Being too high is not possible.
if(RAMPage < RPAGE_MIN){
break;
}
unsigned char FlashPage = *((unsigned char*)RXBufferCurrentPosition);
// Ensure Flash page is valid. Being too high is not possible.
if(FlashPage < PPAGE_MIN){
break;
}
/* This type must have a length field, set that up */
*((unsigned short*)TXBufferCurrentPositionHandler) = length + 6;
/* Put the request payload into the reply */
*((unsigned short*)TXBufferCurrentPositionHandler) = (unsigned short) address;
*((unsigned short*)TXBufferCurrentPositionHandler) = length;
*((unsigned char*)TXBufferCurrentPositionHandler) = RAMPage;
*((unsigned char*)TXBufferCurrentPositionHandler) = FlashPage;
/* Load the body into place */
memcpy((void*)TXBufferCurrentPositionHandler, address, length);
break;
}
{
break;
}
// Extract the type of list that we want
unsigned char listType = *((unsigned char*)RXBufferCurrentPosition);
// Extract the mask for the qualities that we want
unsigned short blockDetailsMask = *((unsigned short*)RXBufferCurrentPosition);
// This type must have a length field, set that up
unsigned short * listLength = (unsigned short*)TXBufferCurrentPositionHandler;
// Zero the counter before we start, woops!
*listLength = 0;
unsigned long locationID;
blockDetails details;
for(locationID = 0;locationID < 65536;locationID++){
unsigned short locationIDDoesntExist;
locationIDDoesntExist = lookupBlockDetails((unsigned short)locationID, &details);
if(!locationIDDoesntExist){
if((listType == 0x00) || // get all
((listType == 0x01) && (details.flags & blockDetailsMask)) || // get OR of bits
((listType == 0x02) && (!(~(details.flags) & blockDetailsMask)))){ // get AND of bits
*((unsigned short*)TXBufferCurrentPositionHandler) = (unsigned short)locationID;
TXBufferCurrentPositionHandler += 2;
*listLength += 2;
}
}
}
break;
}
{
break;
}
// Extract the RAM location ID
unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
// This type must have a length field, set that up
*((unsigned short*)TXBufferCurrentPositionHandler) = sizeof(blockDetails);
// Write straight to output buffer to save time/code
if(errorID != 0){
break;
}
// Adjust TX buffer position if successful
break;
}
{
/*
* The idea here is to call this function with arguments, and data
* and have the result sent back for comparison with an expected
* result that isn't divulged to the firmware.
*
* It is intended that all testable functions be callable through
* this mechanism and that any number of test executions can be
* performed by an external suite using different parameters and
* data sets and matching expected results.
*
* The usual error mechanism shall be used to indicate some sort of
* either internal or test failure and returned errors shall be
* suitably descriptive to allow diagnosis and fixing of issues.
*/
// Must at least have test ID
break;
}
// grab unit test ID from payload
unsigned short unitTestID = *((unsigned short*)RXBufferCurrentPosition);
switch(unitTestID){
{
// Must be only the ID
break;
}
*((unsigned short*)TXBufferCurrentPositionHandler) = unitTestID;
break;
}
{
// ID + Value + Table
if(RXCalculatedPayloadLength != (2 + 2 + sizeof(twoDTableUS))){
break;
}
unsigned short Value = *((unsigned short*)RXBufferCurrentPosition);
unsigned short result = lookupTwoDTableUS(Table, Value);
*((unsigned short*)TXBufferCurrentPositionHandler) = result;
break;
}
// http://issues.freeems.org/view.php?id=156
//
/// TODO @todo test all things listed below:
// lookupPagedMainTableCellValue - pass this RPAGE so that it remains unchanged
// validateMainTable
// validateTwoDTable
// set table values - leave this till last, currently unused by mtx, likely to be removed anyway
// generateDerivedVars - convert to pointers, remove headers, privatise a lot of data!
// calculateFuelAndIgnition - ditto
// scheduling algorithm - ditto
// safeAdd
// safeTrim
// safeScale
// sleep (milliseconds)
// sleepMicro (microseconds)
// checksum
// stringCopy
// compare
// utils that can't be checked: sampleLoopADC sampleBlockADC sampleEachADC - can check for how long each takes! adjustPWM (test only anyway), resetToNonRunningState and setupPagedRAM (would interfere with functioning of device)
// init code may be able to be partially checked
// most other code at this stage is ISR code, flash writing code, or could interfere with the running of the engine
// more testable code will appear with time, such as the HAL layer, and most accessory functions.
default:
{
errorID = noSuchUnitTestID;
}
// each case:
// checks length, fails if wrong
// parses data into args
// calls function on data/args
// assembles response OR sets error
// breaks
}
break;
}
{
// see TODO on include at top and modify this line appropriately
if(!(compare((unsigned char*)&decoderName, (unsigned char*)BENCH_TEST_NAME, sizeof(BENCH_TEST_NAME)))){
break;
}
unsigned char localTestMode = *((unsigned char*)RXBufferCurrentPosition); //1; // The only mode, for now.
if(localTestMode > TEST_MODE_BUMP_UP_CYCLES){
break;
}else if((localTestMode == TEST_MODE_STOP) && (RXCalculatedPayloadLength == 1)){
break;
}
// Ensure we succeed at stopping it as quickly as possible.
// Stash mid-test details for return
*((unsigned short*)TXBufferCurrentPositionHandler) = testNumberOfCycles; // Save and return the remaining cycle count
*((unsigned char*)TXBufferCurrentPositionHandler) = KeyUserDebugs.currentEvent; // Save the current event for the ultra-fussy
// Setup the test to stop ASAP
KeyUserDebugs.currentEvent = testEventsPerCycle - 1; // Gets incremented then compared with testEventsPerCycle
testNumberOfCycles = 1; // Gets decremented then compared with zero
break;
}else if((localTestMode == TEST_MODE_BUMP_UP_CYCLES) && (RXCalculatedPayloadLength == 2)){
break;
}
// Get bump value from payload
unsigned char bumpCycles = *((unsigned char*)RXBufferCurrentPosition); //1; // The only mode, for now.
if(bumpCycles == 0){
break;
}
// Bump count by value from payload
testNumberOfCycles += bumpCycles;
// Given that this function is only for situations when A it's getting near to
// zero and B the user is watching, not checking for overflow is reasonable.
*((unsigned char*)TXBufferCurrentPositionHandler) = bumpCycles; // Return the bump size for achaelogical purposes
break;
}else if((localTestMode == TEST_MODE_ITERATIONS) && (RXCalculatedPayloadLength == 24)){
testMode = localTestMode;
// do nothing to fall through, or move other code into here
}else{
break;
}
if(coreStatusA & BENCH_TEST_ON){
break;
}
// Parse the values and return all but the test packet type
testEventsPerCycle = *((unsigned char*)RXBufferCurrentPosition); //100; // @ 10ms = 1s
break;
}
testNumberOfCycles = *((unsigned short*)RXBufferCurrentPosition); //20; // @ 1s = 20s
break;
}
testTicksPerEvent = *((unsigned short*)RXBufferCurrentPosition); //12500; // @ 0.8us = 10ms
break;
}
// Pluck the arrays out of the packet for the loop below
unsigned char* testEventNumbers = RXBufferCurrentPosition;
unsigned short* testPulseWidths = (unsigned short*)RXBufferCurrentPosition;
memcpy((void*)TXBufferCurrentPositionHandler, (void*)testEventNumbers, 18);
// Reset the clock for reading timeout
Clocks.timeoutADCreadingClock = 0; // make this optional, such that we can use real inputs to determine pw and/or dwell.
// Validate and transfer the per-channel data
unsigned char channel;
unsigned char configuredChannels = 6;
for(channel = 0;channel < 6;channel++){
if(testPulseWidths[channel] > ectSwitchOnCodeTime){ // See next block for warning.
// use as-is
outputEventPulseWidthsMath[channel] = testPulseWidths[channel];
outputEventInputEventNumbers[channel] = testEventNumbers[channel];
}else if(testPulseWidths[channel] > 3){
// less than the code time, and not special, error!
// Warning, PWs close to this could be slightly longer than requested, that will change in later revisions.
break;
}else if(testPulseWidths[channel] == 3){
testMode++; // Dirty hack to avoid dealing with Dave for the time being.
}else if(testPulseWidths[channel] == 2){
// use the dwell from the core maths and input vars.
outputEventInputEventNumbers[channel] = testEventNumbers[channel];
}else if(testPulseWidths[channel] == 1){
// use the reference pulse width from the core maths and input vars.
outputEventInputEventNumbers[channel] = testEventNumbers[channel];
}else{ // is zero
// Set this channel to zero for and therefore off, don't set this channel.
outputEventInputEventNumbers[channel] = 0xFF; // Off.
configuredChannels--;
}
}
if(configuredChannels == 0){
break;
}
if(errorID == 0){
// Let the first iteration roll it over to zero.
KeyUserDebugs.currentEvent = 0xFF; // Needs to be here in case of multiple runs, init is not sufficient
if(testEventsPerCycle <= 127){
}else{
break;
}
// Store the time per event in RPM such that it can be updated dynamically
// The channels to use rely on the defaults from initialisers! Custom builds can break BenchTest mode!
// Un-schedule anything that got scheduled
break;
}
// Trigger decoder interrupt to fire thus starting the loop!
TIE = 0x01; // The ISR does the rest!
// Nothing went wrong, now set flag.
}else{
break;
}
/* http://issues.freeems.org/view.php?id=155
*
* The following block has been left in, as I still do not know why it won't work as intended:
*
* - It should fire all 6 output pins with a 52ms duration pulse, exactly once.
* - The SAME code run from anywhere else (pre main loop, in main loop, in rtc, in decoder) works fine, just not here in commsCore.c
* - The interrupts run, but the pin doesn't change state, despite the registers being configured correctly
*
* I've tried quite a bit:
*
* - Moving this code around
* - Checking memory definitions
* - Completely rewriting the output ISR
* - Adding significant debug to output ISR
* - Checking for register contents in output ISR
* - Checking for key things modified in this file
* - General head scratching and confused searching
*/
// outputEventPinNumbers[0] = 0; // 1 ign
// outputEventPinNumbers[1] = 1; // 2 ign
// outputEventPinNumbers[2] = 2; // 3 ign/1 fuel
// outputEventPinNumbers[3] = 3; // 4 ign/2 fuel
// outputEventPinNumbers[4] = 4; // 3 fuel
// outputEventPinNumbers[5] = 5; // 4 fuel
// outputEventDelayFinalPeriod[0] = decoderMaxCodeTime;
// outputEventDelayFinalPeriod[1] = decoderMaxCodeTime;
// outputEventDelayFinalPeriod[2] = decoderMaxCodeTime;
// outputEventDelayFinalPeriod[3] = decoderMaxCodeTime;
// outputEventDelayFinalPeriod[4] = decoderMaxCodeTime;
// outputEventDelayFinalPeriod[5] = decoderMaxCodeTime;
// outputEventPulseWidthsMath[0] = SHORTMAX;
// outputEventPulseWidthsMath[1] = SHORTMAX;
// outputEventPulseWidthsMath[2] = SHORTMAX;
// outputEventPulseWidthsMath[3] = SHORTMAX;
// outputEventPulseWidthsMath[4] = SHORTMAX;
// outputEventPulseWidthsMath[5] = SHORTMAX;
//
// unsigned short edgeTimeStamp = TCNT;
// // call sched output with args
// LongTime timeStamp;
// /* Install the low word */
// timeStamp.timeShorts[1] = edgeTimeStamp;
// /* Find out what our timer value means and put it in the high word */
// if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */
// timeStamp.timeShorts[0] = timerExtensionClock + 1;
// }else{
// timeStamp.timeShorts[0] = timerExtensionClock;
// }
//
// schedulePortTPin(0, timeStamp);
// schedulePortTPin(1, timeStamp);
// schedulePortTPin(2, timeStamp);
// schedulePortTPin(3, timeStamp);
// schedulePortTPin(4, timeStamp);
// schedulePortTPin(5, timeStamp);
//
// sleep(1000);
}else{
}
break;
}
default:
{
if((RXHeaderPayloadID % 2) == 1){
errorID = invalidPayloadID;
}else{
}
break;
}
}
// Always reply, if errorID is zero it's just an ack.
finaliseAndSend(errorID);
/* Switch reception back on now that we are done with the received data */
}

Here is the call graph for this function:

Here is the caller graph for this function:

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 finaliseAndSend ( unsigned short  errorID)

Finalise a packet and send it.

This functions job is to finalise the main loop part of the packet sending process. It configures the pos/neg ack header bit, adds the code if neg, runs a checksum over the packet data and tags it to the end before configuring the various ISRs that need to send the data out.

Definition at line 141 of file commsCore.c.

References checksum(), COM_CLEAR_CAN0_INTERFACE_ID, COM_CLEAR_SPARE2_INTERFACE_ID, COM_CLEAR_SPARE3_INTERFACE_ID, COM_CLEAR_SPARE4_INTERFACE_ID, COM_CLEAR_SPARE5_INTERFACE_ID, COM_CLEAR_SPARE6_INTERFACE_ID, COM_CLEAR_SPARE7_INTERFACE_ID, COM_SET_CAN0_INTERFACE_ID, COM_SET_SCI0_INTERFACE_ID, COM_SET_SPARE2_INTERFACE_ID, COM_SET_SPARE3_INTERFACE_ID, COM_SET_SPARE4_INTERFACE_ID, COM_SET_SPARE5_INTERFACE_ID, COM_SET_SPARE6_INTERFACE_ID, COM_SET_SPARE7_INTERFACE_ID, HEADER_IS_NACK, SCI0CR2, SCI0DRL, SCICR2_TX_ENABLE, SCICR2_TX_ISR_ENABLE, START_BYTE, TXBufferCurrentPositionHandler, TXBufferInUseFlags, and TXHeaderFlags.

Referenced by decodePacketAndRespond(), and main().

{
if(errorID != 0){
*((unsigned short*)TXBufferCurrentPositionHandler) = errorID;
}
/* Tag the checksum on the end */
*TXBufferCurrentPositionHandler = checksum((unsigned char*)&TXBuffer, ((unsigned short)TXBufferCurrentPositionHandler - (unsigned short)&TXBuffer));
/* Send it out on all the channels required. */
/* SCI0 - Main serial interface */
/* Initiate transmission */
/* Note : Order Is Important! */
/* TX empty flag is already set, so we must clear it by writing out before enabling the interrupt */
}
/* CAN0 - Main CAN interface */
// just clear up front for now
}
/* spare2 */
// just clear up front for now
}
/* spare3 */
// just clear up front for now
}
/* spare4 */
// just clear up front for now
}
/* spare5 */
// just clear up front for now
}
/* spare6 */
// just clear up front for now
}
/* spare7 */
// just clear up front for now
}
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned short populateBasicDatalog ( void  )

Populate a basic datalog packet.

Todo:
TODO this is pulling in the system string.h not the m68hc1x version, and functions other than memcpy do not work because they are not in crt1.o or other included-by-default libs

Copies various chunks of data to the transmission buffer and truncates to the configured length. If changing this, update the maxBasicDatalogLength.

Todo:
TODO setup proper sequence and clock with some sort of differential measurement log to log. insert in front of actual data because these are part of the log itself.

Definition at line 63 of file commsCore.c.

References KeyUserDebug::clockIn8thsOfAMilli, KeyUserDebug::clockInMilliSeconds, Clocks, KeyUserDebug::coreStatusA, coreStatusA, KeyUserDebugs, Clock::realTimeClockMain, Clock::realTimeClockMillis, KeyUserDebug::tempClock, and TXBufferCurrentPositionHandler.

Referenced by decodePacketAndRespond(), and main().

{
/// @todo TODO setup proper sequence and clock with some sort of differential measurement log to log. insert in front of actual data because these are part of the log itself.
unsigned short confSize = 0;
unsigned char chunkLimit = TablesB.SmallTablesB.loggingSettings.firstChunk + TablesB.SmallTablesB.loggingSettings.numberOfChunks;
unsigned char chunks;
for(chunks=TablesB.SmallTablesB.loggingSettings.firstChunk;chunks<chunkLimit;chunks++){
unsigned short localSize = TablesB.SmallTablesB.loggingSettings.logChunks[chunks].size;
confSize += localSize;
if(confSize > 2048){
confSize -= localSize;
break;
}
memcpy(TXBufferCurrentPositionHandler, TablesB.SmallTablesB.loggingSettings.logChunks[chunks].address, localSize);
}
// After copying data, otherwise tempClock is NEVER zero and reset detection does NOT work
return confSize;
}

Here is the caller graph for this function:

Variable Documentation

EXTERN unsigned char* TXBufferCurrentPositionHandler
EXTERN unsigned char* TXBufferCurrentPositionCAN0

Definition at line 68 of file commsCore.h.

Referenced by decodePacketAndRespond(), and main().

EXTERN unsigned char* TXBufferCurrentPositionSCI0

Definition at line 69 of file commsCore.h.

Referenced by decodePacketAndRespond(), main(), and SCI0ISR().

EXTERN unsigned char TXBufferInUseFlags

Definition at line 73 of file commsCore.h.

Referenced by decodePacketAndRespond(), finaliseAndSend(), main(), and SCI0ISR().

EXTERN unsigned char RXBufferContentSourceID

Definition at line 74 of file commsCore.h.

Referenced by resetReceiveState(), and SCI0ISR().

EXTERN unsigned char RXStateFlags

Definition at line 108 of file commsCore.h.

Referenced by main(), resetReceiveState(), and SCI0ISR().

EXTERN unsigned char* RXBufferCurrentPosition

Definition at line 109 of file commsCore.h.

Referenced by decodePacketAndRespond(), resetReceiveState(), and SCI0ISR().

EXTERN unsigned short RXCalculatedPayloadLength

Definition at line 110 of file commsCore.h.

Referenced by decodePacketAndRespond().

EXTERN unsigned char RXHeaderFlags

Definition at line 147 of file commsCore.h.

Referenced by decodePacketAndRespond().

EXTERN unsigned char* TXHeaderFlags

Definition at line 148 of file commsCore.h.

Referenced by decodePacketAndRespond(), and finaliseAndSend().

EXTERN unsigned short RXHeaderPayloadID

Definition at line 149 of file commsCore.h.

Referenced by decodePacketAndRespond().

EXTERN unsigned short RXHeaderPayloadLength

TODO.

Todo:
why global?

Definition at line 150 of file commsCore.h.

Referenced by decodePacketAndRespond().