commsCore.c File Reference

Core communications functions. More...

#include "inc/freeEMS.h"
#include "inc/flashWrite.h"
#include "inc/interrupts.h"
#include "inc/utils.h"
#include "inc/tableLookup.h"
#include "inc/blockDetailsLookup.h"
#include "inc/commsCore.h"
#include <string.h>

Include dependency graph for commsCore.c:

Go to the source code of this file.

Defines

#define COMMSCORE_C

Functions

void populateBasicDatalog ()
 Populate a basic datalog packet.
void checksumAndSend ()
 Checksum a packet and send it.
void decodePacketAndRespond ()
 Decode a packet and respond.
void sendErrorIfClear (unsigned short errorID)
 Send an error if buffer free.
void sendErrorBusyWait (unsigned short errorID)
 Send an error even if we must wait.
void sendErrorInternal (unsigned short errorCode)
 Send an error.
void sendDebugIfClear (unsigned char *message)
 Send a debug message if buffer free.
void sendDebugBusyWait (unsigned char *message)
void sendDebugInternal (unsigned char *message)
 Send a debug message.
void sendAckIfRequired ()
 Send an ack if required.


Detailed Description

Core communications functions.

This file contains most of the core comms functionality. Currently that is only for UART serial style communication. It is already too big and needs to be split up somewhat. This will happen fairly soon during the serial refactoring and protocol fine tuning.

Todo:
TODO function to setup a packet and send it fn(populateBodyFunctionPointer(), header, other, fields, here, and, use, or, not, within){}

TODO factor many things into functions and move the receive delegator to its own file

Author:
Fred Cooke

Definition in file commsCore.c.


Define Documentation

#define COMMSCORE_C

Definition at line 43 of file commsCore.c.


Function Documentation

void checksumAndSend ( void   ) 

Checksum a packet and send it.

This functions job is to finalise the main loop part of the packet sending process. It 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.

Author:
Fred Cooke
Bug:
http://freeems.aaronb.info/tracker/view.php?id=81
Todo:
TODO fix the double/none start byte bug and remove the hack!

Definition at line 146 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, SCI0CR2, SCI0DRL, SCI0SR1, SCICR2_TX_ISR_ENABLE, START_BYTE, TXBufferCurrentPositionHandler, TXBufferInUseFlags, TXPacketLengthToSendCAN0, and TXPacketLengthToSendSCI0.

Referenced by decodePacketAndRespond(), main(), sendDebugInternal(), and sendErrorInternal().

00146                       {
00147     /* Get the length from the pointer */
00148     unsigned short TXPacketLengthToSend = (unsigned short)TXBufferCurrentPositionHandler - (unsigned short)&TXBuffer;
00149 
00150     /* Tag the checksum on the end */
00151     *TXBufferCurrentPositionHandler = checksum((unsigned char*)&TXBuffer, TXPacketLengthToSend);
00152     TXPacketLengthToSend++;
00153 
00154     /* Send it out on all the channels required. */
00155 
00156     /* SCI0 - Main serial interface */
00157     if(TXBufferInUseFlags & COM_SET_SCI0_INTERFACE_ID){
00158         /* Copy numbers to interface specific vars */
00159         TXPacketLengthToSendSCI0 = TXPacketLengthToSend;
00160         TXPacketLengthToSendCAN0 = TXPacketLengthToSend;
00161 
00162         /* Queue preamble by clearing and then setting transmit enable  */
00163         /* See section 11.4.5.2 of the xdp512 specification document    */
00164         //SCI0CR2 &= SCICR2_TX_DISABLE;
00165         //SCI0CR2 |= SCICR2_TX_ENABLE;
00166 
00167         /* Initiate transmission */
00168         SCI0DRL = START_BYTE;
00169         while(!(SCI0SR1 & 0x80)){/* Wait for ever until able to send then move on */}
00170         SCI0DRL = START_BYTE; // nasty hack that works... means at least one and most 2 starts are sent so stuff works, but is messy... there must be a better way.
00171 
00172         /* Note : Order Is Important! */
00173         /* TX empty flag is already set, so we must clear it by writing out before enabling the interrupt */
00174         SCI0CR2 |= SCICR2_TX_ISR_ENABLE;
00175     }
00176     /* CAN0 - Main CAN interface */
00177     if(TXBufferInUseFlags & COM_SET_CAN0_INTERFACE_ID){
00178         // just clear up front for now
00179         TXBufferInUseFlags &= COM_CLEAR_CAN0_INTERFACE_ID;
00180     }
00181     /* spare2 */
00182     if(TXBufferInUseFlags & COM_SET_SPARE2_INTERFACE_ID){
00183         // just clear up front for now
00184         TXBufferInUseFlags &= COM_CLEAR_SPARE2_INTERFACE_ID;
00185     }
00186     /* spare3 */
00187     if(TXBufferInUseFlags & COM_SET_SPARE3_INTERFACE_ID){
00188         // just clear up front for now
00189         TXBufferInUseFlags &= COM_CLEAR_SPARE3_INTERFACE_ID;
00190     }
00191     /* spare4 */
00192     if(TXBufferInUseFlags & COM_SET_SPARE4_INTERFACE_ID){
00193         // just clear up front for now
00194         TXBufferInUseFlags &= COM_CLEAR_SPARE4_INTERFACE_ID;
00195     }
00196     /* spare5 */
00197     if(TXBufferInUseFlags & COM_SET_SPARE5_INTERFACE_ID){
00198         // just clear up front for now
00199         TXBufferInUseFlags &= COM_CLEAR_SPARE5_INTERFACE_ID;
00200     }
00201     /* spare6 */
00202     if(TXBufferInUseFlags & COM_SET_SPARE6_INTERFACE_ID){
00203         // just clear up front for now
00204         TXBufferInUseFlags &= COM_CLEAR_SPARE6_INTERFACE_ID;
00205     }
00206     /* spare7 */
00207     if(TXBufferInUseFlags & COM_SET_SPARE7_INTERFACE_ID){
00208         // just clear up front for now
00209         TXBufferInUseFlags &= COM_CLEAR_SPARE7_INTERFACE_ID;
00210     }
00211 }

Here is the call graph for this function:

void decodePacketAndRespond ( void   ) 

Decode a packet and respond.

This is the core function that controls what 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.

Author:
Fred Cooke

Definition at line 222 of file commsCore.c.

References adjust2dTableAxis, adjust2dTableCell, adjustMainTableCell, adjustMainTableLoadAxis, adjustMainTableRPMAxis, ARMCOP, asyncDatalogBasic, asyncDatalogOff, asyncDatalogType, BIT0, burnAllBlocksOfFlash, burnBlockFromRamToFlash, checksumAndSend(), CLEAR_ALL_SOURCE_ID_FLAGS, COM_SET_SCI0_INTERFACE_ID, configuredBasicDatalogLength, COPCTL, datalogLengthExceedsMax, eraseAllBlocksFromFlash, eraseSector(), firmwareVersion, fixedConfigs1, blockDetails::FlashAddress, blockDetails::FlashPage, forwardPacketOverCAN, forwardPacketOverOtherUART, HEADER_HAS_ACK, HEADER_HAS_ADDRS, HEADER_HAS_LENGTH, HEADER_IS_PROTO, interfaceVersionAndType, invalidFirmwarePayloadID, invalidIDForMainTableAction, invalidIDForTwoDTableAction, invalidMemoryActionForID, invalidProtocolPayloadID, lookupBlockDetails(), MAINTABLE_MAX_LOAD_LENGTH, MAINTABLE_MAX_MAIN_LENGTH, MAINTABLE_MAX_RPM_LENGTH, maxBasicDatalogLength, serialSetting::networkAddress, noSuchAsyncDatalogType, payloadLengthHeaderMismatch, payloadLengthTypeMismatch, populateBasicDatalog(), PORTK, PPAGE, blockDetails::RAMAddress, blockDetails::RAMPage, replaceBlockInFlash, replaceBlockInRAM, requestBasicDatalog, requestConfigurableDatalog, requestEchoPacketReturn, requestFirmwareVersion, requestHardSystemReset, requestInterfaceVersion, requestMaxPacketSize, requestSoftSystemReset, resetReceiveState(), retrieveBlockFromFlash, retrieveBlockFromRAM, RPAGE, RX_BUFFER_SIZE, RXBufferCurrentPosition, RXCalculatedPayloadLength, RXHeaderFlags, RXHeaderPayloadID, RXHeaderPayloadLength, RXHeaderSourceAddress, RXPacketLengthReceived, sendAckIfRequired(), sendDebugInternal(), sendErrorInternal(), fixedConfig1::serialSettings, setAsyncDatalogType, setPagedMainTableCellValue(), setPagedMainTableLoadValue(), setPagedMainTableRPMValue(), setPagedTwoDTableAxisValue(), setPagedTwoDTableCellValue(), blockDetails::size, sourceAddressIsBroadcast, sourceAddressIsDuplicate, TXBufferCurrentPositionCAN0, TXBufferCurrentPositionHandler, TXBufferCurrentPositionSCI0, TXBufferInUseFlags, unimplementedFunction, unrecognisedFirmwarePayloadID, unrecognisedProtocolPayloadID, validateMainTable(), validateTwoDTable(), writeBlock(), and writeSector().

Referenced by main().

00222                              {
00223     /* Extract and build up the header fields */
00224     RXBufferCurrentPosition = (unsigned char*)&RXBuffer;
00225     TXBufferCurrentPositionHandler = (unsigned char*)&TXBuffer;
00226 
00227     /* Initialised here such that override is possible */
00228     TXBufferCurrentPositionSCI0 = (unsigned char*)&TXBuffer;
00229     TXBufferCurrentPositionCAN0 = (unsigned char*)&TXBuffer;
00230 
00231     /* Start this off as full packet length and build down to the actual length */
00232     RXCalculatedPayloadLength = RXPacketLengthReceived;
00233 
00234     /* Grab the RX header flags out of the RX buffer */
00235     RXHeaderFlags = *RXBufferCurrentPosition;
00236     RXBufferCurrentPosition++;
00237     RXCalculatedPayloadLength--;
00238 
00239     /* Flag that we are transmitting! */
00240     TXBufferInUseFlags |= COM_SET_SCI0_INTERFACE_ID;
00241     // SCI0 only for now...
00242 
00243     /* Load a blank header into the TX buffer ready for masking */
00244     unsigned char* TXHeaderFlags = TXBufferCurrentPositionHandler;
00245     *TXHeaderFlags = 0;
00246     TXBufferCurrentPositionHandler++;
00247 
00248     /* Grab the payload ID for processing and load the return ID */
00249     RXHeaderPayloadID = *((unsigned short*)RXBufferCurrentPosition);
00250     *((unsigned short*)TXBufferCurrentPositionHandler) = RXHeaderPayloadID + 1;
00251     RXBufferCurrentPosition += 2;
00252     TXBufferCurrentPositionHandler += 2;
00253     RXCalculatedPayloadLength -= 2;
00254 
00255     /* If there is an ack, copy it to the return packet */
00256     if(RXHeaderFlags & HEADER_HAS_ACK){
00257         *TXBufferCurrentPositionHandler = *RXBufferCurrentPosition;
00258         *TXHeaderFlags |= HEADER_HAS_ACK;
00259         RXBufferCurrentPosition++;
00260         TXBufferCurrentPositionHandler++;
00261         RXCalculatedPayloadLength--;
00262     }
00263 
00264     /* If the header has addresses, check them and if OK copy them */
00265     if(RXHeaderFlags & HEADER_HAS_ADDRS){
00266         /* Check the destination address against our address */
00267         if(*RXBufferCurrentPosition != fixedConfigs1.serialSettings.networkAddress){
00268             /* Addresses do not match, discard packet without error */
00269             resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS);
00270             TXBufferInUseFlags = 0;
00271             return;
00272         }
00273         RXBufferCurrentPosition++;
00274 
00275         /* Save and check the source address */
00276         RXHeaderSourceAddress = *RXBufferCurrentPosition;
00277         RXBufferCurrentPosition++;
00278         if(RXHeaderSourceAddress == 0){
00279             sendErrorInternal(sourceAddressIsBroadcast);
00280             resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS);
00281             return;
00282         }
00283         if(RXHeaderSourceAddress == fixedConfigs1.serialSettings.networkAddress){
00284             sendErrorInternal(sourceAddressIsDuplicate);
00285             resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS);
00286             return;
00287         }
00288 
00289         /* All is well, setup reply addresses */
00290         *TXHeaderFlags |= HEADER_HAS_ADDRS;
00291         /* TX destination = RX source */
00292         *TXBufferCurrentPositionHandler = RXHeaderSourceAddress;
00293         TXBufferCurrentPositionHandler++;
00294         /* TX source = our address */
00295         *TXBufferCurrentPositionHandler = fixedConfigs1.serialSettings.networkAddress;
00296         TXBufferCurrentPositionHandler++;
00297         /* Decrement for both at once to save a cycle */
00298         RXCalculatedPayloadLength -= 2;
00299     }
00300 
00301     /* Subtract checksum to get final length */
00302     RXCalculatedPayloadLength--;
00303 
00304     /* Grab the length if available */
00305     if(RXHeaderFlags & HEADER_HAS_LENGTH){
00306         RXHeaderPayloadLength = *((unsigned short*)RXBufferCurrentPosition);
00307         RXBufferCurrentPosition += 2;
00308         RXCalculatedPayloadLength -= 2;
00309         /* Already subtracted one for checksum */
00310         if(RXHeaderPayloadLength != RXCalculatedPayloadLength){
00311             sendErrorInternal(payloadLengthHeaderMismatch);
00312             resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS);
00313             return;
00314         }
00315     }
00316 
00317     /* Please Note :                                                            */
00318     /* length (and it's flag) should be set by each return packet type handler if required or desired.  */
00319     /* If an ack has been requested, ensure the negative ack flag is set if the opration failed.        */
00320 
00321     /* Perform the requested action based on payload ID */
00322     if (RXHeaderFlags & HEADER_IS_PROTO){ /* Protocol payload types */
00323         /* Set the return type to be protocol too */
00324         *TXHeaderFlags |= HEADER_IS_PROTO;
00325 
00326         switch (RXHeaderPayloadID){
00327         case requestInterfaceVersion:
00328         {
00329             if(RXCalculatedPayloadLength != 0){
00330                 sendErrorInternal(payloadLengthTypeMismatch);
00331                 break;
00332             }
00333 
00334             /* This type must have a length field, set that up */
00335             *((unsigned short*)TXBufferCurrentPositionHandler) = sizeof(interfaceVersionAndType);
00336             *TXHeaderFlags |= HEADER_HAS_LENGTH;
00337             TXBufferCurrentPositionHandler += 2;
00338             /* Load the body into place */
00339             memcpy((void*)TXBufferCurrentPositionHandler, (void*)&interfaceVersionAndType, sizeof(interfaceVersionAndType));
00340             TXBufferCurrentPositionHandler += sizeof(interfaceVersionAndType);
00341             checksumAndSend();
00342             break;
00343         }
00344         case requestFirmwareVersion:
00345         {
00346             if(RXCalculatedPayloadLength != 0){
00347                 sendErrorInternal(payloadLengthTypeMismatch);
00348                 break;
00349             }
00350             /* This type must have a length field, set that up */
00351             *((unsigned short*)TXBufferCurrentPositionHandler) = sizeof(firmwareVersion);
00352             *TXHeaderFlags |= HEADER_HAS_LENGTH;
00353             TXBufferCurrentPositionHandler += 2;
00354             /* Load the body into place */
00355             memcpy((void*)TXBufferCurrentPositionHandler, (void*)&firmwareVersion, sizeof(firmwareVersion));
00356             TXBufferCurrentPositionHandler += sizeof(firmwareVersion);
00357             checksumAndSend();
00358             break;
00359         }
00360         case requestMaxPacketSize:
00361         {
00362             if(RXCalculatedPayloadLength != 0){
00363                 sendErrorInternal(payloadLengthTypeMismatch);
00364                 break;
00365             }
00366             /* Load the size into place */
00367             *((unsigned short*)TXBufferCurrentPositionHandler) = RX_BUFFER_SIZE;
00368             TXBufferCurrentPositionHandler += 2;
00369             checksumAndSend();
00370             break;
00371         }
00372         case requestEchoPacketReturn:
00373         {
00374             /* This type must have a length field, set that up */
00375             *((unsigned short*)TXBufferCurrentPositionHandler) = RXPacketLengthReceived;
00376             *TXHeaderFlags |= HEADER_HAS_LENGTH;
00377             TXBufferCurrentPositionHandler += 2;
00378             /* Load the body into place */
00379             memcpy((void*)TXBufferCurrentPositionHandler, (void*)&RXBuffer, RXPacketLengthReceived);
00380             /* Note, there is no overflow check here because the TX buffer is slightly       */
00381             /* bigger than the RX buffer and there is overflow checking for receives anyway. */
00382             TXBufferCurrentPositionHandler += RXPacketLengthReceived;
00383             checksumAndSend();
00384             break;
00385         }
00386         case requestSoftSystemReset:
00387         {
00388             // hack to allow datalog on/off from the orange button (thank christ I asked for that button when I did)
00389             if(asyncDatalogType){
00390                 asyncDatalogType = asyncDatalogOff;
00391             }else{
00392                 asyncDatalogType = asyncDatalogBasic;
00393             }
00394             sendAckIfRequired(); // TODO implement
00395             break;
00396 
00397 //          // hack to use soft reset to request registers
00398 //          /* This type must have a length field, set that up */
00399 //          *((unsigned short*)TXBufferCurrentPositionHandler) = memdumplength;
00400 //          *TXHeaderFlags |= HEADER_HAS_LENGTH;
00401 //          TXBufferCurrentPositionHandler += 2;
00402 //          /* Load the body into place */
00403 //          memcpy((void*)TXBufferCurrentPositionHandler, memdumpaddr, memdumplength);
00404 //          TXBufferCurrentPositionHandler += memdumplength;
00405 //          memdumpaddr += memdumplength;
00406 //          checksumAndSend();
00407 //          break;
00408 
00409 //          if(RXCalculatedPayloadLength != 0){
00410 //              sendErrorInternal(payloadLengthTypeMismatch);
00411 //              break;
00412 //          }
00413 //          /* Perform soft system reset */
00414 //          _start();
00415         }
00416         case requestHardSystemReset:
00417         {
00418             if(RXCalculatedPayloadLength != 0){
00419                 sendErrorInternal(payloadLengthTypeMismatch);
00420                 break;
00421             }
00422 
00423             /* This is how the serial monitor does it. */
00424             COPCTL = 0x01; /* Arm with shortest time */
00425             ARMCOP = 0xFF; /* Write bad value, should cause immediate reset */
00426             /* Using _start() only resets the app ignoring the monitor switch. It does not work */
00427             /* properly because the location of _start is not the master reset vector location. */
00428         }
00429         default:
00430         {
00431             if((RXHeaderPayloadID % 2) == 1){
00432                 sendErrorInternal(invalidProtocolPayloadID);
00433             }else{
00434                 sendErrorInternal(unrecognisedProtocolPayloadID);
00435             }
00436         }
00437         }
00438     }else{ /* Otherwise firmware payload types */
00439         switch (RXHeaderPayloadID) {
00440         case replaceBlockInRAM:
00441         {
00442             /* Extract the ram location ID from the received data */
00443             unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
00444             RXBufferCurrentPosition += 2;
00445 
00446             /* Look up the memory location details */
00447             blockDetails details;
00448             lookupBlockDetails(locationID, &details);
00449 
00450             /* Subtract two to allow for the locationID */
00451             if((RXCalculatedPayloadLength - 2) != details.size){
00452                 sendErrorInternal(payloadLengthTypeMismatch);
00453                 break;
00454             }
00455 
00456             if((details.RAMPage == 0) || (details.RAMAddress == 0)){
00457                 sendErrorInternal(invalidMemoryActionForID);
00458                 break;
00459             }
00460 
00461             // TODO factor this out into validation delegation function once the number of types increases somewhat
00462             unsigned short errorID = 0;
00463             if(locationID < 16){
00464 //              mainTable aTable;
00465                 errorID = validateMainTable((mainTable*)RXBufferCurrentPosition);
00466             }else if((locationID > 399) && (locationID < 900)){
00467 //              twoDTableUS aTable;
00468                 errorID = validateTwoDTable((twoDTableUS*)RXBufferCurrentPosition);
00469             }// TODO add other table types here
00470             /* If the validation failed, report it */
00471             if(errorID != 0){
00472                 sendErrorInternal(errorID);
00473                 break;
00474             }
00475 
00476             /* Save page values for restore */
00477             unsigned char oldRamPage = RPAGE;
00478             /* Set the viewable ram page */
00479             RPAGE = details.RAMPage;
00480             /* Copy from the RX buffer to the block of ram */
00481             memcpy(details.RAMAddress, RXBufferCurrentPosition, details.size);
00482             /* Restore the original ram and flash pages */
00483             RPAGE = oldRamPage;
00484 
00485             sendAckIfRequired(); // TODO implement
00486             break;
00487         }
00488         case replaceBlockInFlash:
00489         {
00490             /* Extract the ram location ID from the received data */
00491             unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
00492             RXBufferCurrentPosition += 2;
00493 
00494             /* Look up the memory location details */
00495             blockDetails details;
00496             lookupBlockDetails(locationID, &details);
00497 
00498             /* Subtract two to allow for the locationID */
00499             if((RXCalculatedPayloadLength - 2) != details.size){
00500                 sendErrorInternal(payloadLengthTypeMismatch);
00501                 break;
00502             }
00503 
00504             if((details.FlashPage == 0) || (details.FlashAddress == 0)){
00505                 sendErrorInternal(invalidMemoryActionForID);
00506                 break;
00507             }
00508 
00509             // TODO factor this out into validation delegation function once the number of types increases somewhat
00510             unsigned short errorID = 0;
00511             if(locationID < 16){
00512 //              mainTable aTable;
00513                 errorID = validateMainTable((mainTable*)RXBufferCurrentPosition);
00514             }else if((locationID > 399) && (locationID < 900)){
00515 //              twoDTableUS aTable;
00516                 errorID = validateTwoDTable((twoDTableUS*)RXBufferCurrentPosition);
00517             }// TODO add other table types here
00518             /* If the validation failed, report it */
00519             if(errorID != 0){
00520                 sendErrorInternal(errorID);
00521                 break;
00522             }
00523 
00524             /* Calculate the position of the end of the stored packet for use as a buffer */
00525             void* buffer = (void*)((unsigned short)&RXBuffer + RXPacketLengthReceived);
00526 
00527             /* Swap the RAM details such that the block gets pulled down from the buffer */
00528             unsigned char originalRAMPage = details.RAMPage;
00529             void* originalRAMAddress = details.RAMAddress;
00530             details.RAMPage = RPAGE;
00531             details.RAMAddress = RXBufferCurrentPosition;
00532 
00533             /* Copy from the RX buffer to the block of flash */
00534             errorID = writeBlock(&details, buffer);
00535             if(errorID != 0){
00536                 sendErrorInternal(errorID);
00537                 break;
00538             }
00539 
00540             /* If present in RAM, update that too */
00541             if((originalRAMPage != 0) && (originalRAMAddress != 0)){
00542                 /* Save page values for restore */
00543                 unsigned char oldRamPage = RPAGE;
00544                 /* Set the viewable ram page */
00545                 RPAGE = originalRAMPage;
00546                 /* Copy from the RX buffer to the block of ram */
00547                 memcpy(originalRAMAddress, RXBufferCurrentPosition, details.size);
00548                 /* Restore the original ram and flash pages */
00549                 RPAGE = oldRamPage;
00550             }
00551 
00552             sendAckIfRequired();
00553             // TODO document errors can always be returned and add error check in to send as response for ack and async otherwise
00554             break;
00555         }
00556         case retrieveBlockFromRAM:
00557         {
00558             if(RXCalculatedPayloadLength != 2){
00559                 sendErrorInternal(payloadLengthTypeMismatch);
00560                 break;
00561             }
00562 
00563             /* Extract the ram location ID from the received data */
00564             unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
00565             /* Store it back into the output data */
00566             *(unsigned short*)TXBufferCurrentPositionHandler = locationID;
00567             TXBufferCurrentPositionHandler += 2;
00568 
00569             /* If it's a main table we are returning, specify the limits explicitly */
00570             if(locationID < 16){
00571                 /* Store it back into the output data */
00572                 *(unsigned short*)TXBufferCurrentPositionHandler = MAINTABLE_MAX_RPM_LENGTH;
00573                 TXBufferCurrentPositionHandler += 2;
00574                 /* Store it back into the output data */
00575                 *(unsigned short*)TXBufferCurrentPositionHandler = MAINTABLE_MAX_LOAD_LENGTH;
00576                 TXBufferCurrentPositionHandler += 2;
00577                 /* Store it back into the output data */
00578                 *(unsigned short*)TXBufferCurrentPositionHandler = MAINTABLE_MAX_MAIN_LENGTH;
00579                 TXBufferCurrentPositionHandler += 2;
00580             }
00581 
00582             /* Look up the memory location details */
00583             blockDetails details;
00584             lookupBlockDetails(locationID, &details);
00585 
00586             if((details.RAMPage == 0) || (details.RAMAddress == 0)){
00587                 sendErrorInternal(invalidMemoryActionForID);
00588                 break;
00589             }
00590 
00591             /* Save page value for restore and set the visible page */
00592             unsigned char oldRamPage = RPAGE;
00593             RPAGE = details.RAMPage;
00594 
00595             /* Copy the block of ram to the TX buffer */
00596             memcpy(TXBufferCurrentPositionHandler, details.RAMAddress, details.size);
00597             TXBufferCurrentPositionHandler += details.size;
00598 
00599             /* Restore the original ram and flash pages */
00600             RPAGE = oldRamPage;
00601 
00602             checksumAndSend();
00603             break;
00604         }
00605         case retrieveBlockFromFlash:
00606         {
00607             if(RXCalculatedPayloadLength != 2){
00608                 sendErrorInternal(payloadLengthTypeMismatch);
00609                 break;
00610             }
00611 
00612             /* Extract the flash location ID from the received data */
00613             unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
00614             /* Store it back into the output data */
00615             *(unsigned short*)TXBufferCurrentPositionHandler = locationID;
00616             TXBufferCurrentPositionHandler += 2;
00617 
00618             /* If it's a main table we are returning, specify the limits explicitly */
00619             if(locationID < 16){
00620                 /* Store it back into the output data */
00621                 *(unsigned short*)TXBufferCurrentPositionHandler = MAINTABLE_MAX_RPM_LENGTH;
00622                 TXBufferCurrentPositionHandler += 2;
00623                 /* Store it back into the output data */
00624                 *(unsigned short*)TXBufferCurrentPositionHandler = MAINTABLE_MAX_LOAD_LENGTH;
00625                 TXBufferCurrentPositionHandler += 2;
00626                 /* Store it back into the output data */
00627                 *(unsigned short*)TXBufferCurrentPositionHandler = MAINTABLE_MAX_MAIN_LENGTH;
00628                 TXBufferCurrentPositionHandler += 2;
00629             }
00630 
00631             /* Look up the memory location details */
00632             blockDetails details;
00633             lookupBlockDetails(locationID, &details);
00634 
00635             if((details.FlashPage == 0) || (details.FlashAddress == 0)){
00636                 sendErrorInternal(invalidMemoryActionForID);
00637                 break;
00638             }
00639 
00640             /* Save page value for restore and set the visible page */
00641             unsigned char oldFlashPage = PPAGE;
00642             PPAGE = details.FlashPage;
00643 
00644             /* Copy the block of flash to the TX buffer */
00645             memcpy(TXBufferCurrentPositionHandler, details.FlashAddress, details.size);
00646             TXBufferCurrentPositionHandler += details.size;
00647 
00648             /* Restore the original ram and flash pages */
00649             PPAGE = oldFlashPage;
00650 
00651             checksumAndSend();
00652             break;
00653         }
00654         case burnBlockFromRamToFlash:
00655         {
00656             if(RXCalculatedPayloadLength != 2){
00657                 sendErrorInternal(payloadLengthTypeMismatch);
00658                 break;
00659             }
00660 
00661             /* Extract the flash location ID from the received data */
00662             unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
00663 
00664             /* Look up the memory location details */
00665             blockDetails details;
00666             lookupBlockDetails(locationID, &details);
00667 
00668             /* Check that all data we need is present */
00669             if((details.RAMPage == 0) || (details.RAMAddress == 0) || (details.FlashPage == 0) || (details.FlashAddress == 0)){
00670                 sendErrorInternal(invalidMemoryActionForID);
00671                 break;
00672             }
00673 
00674             /* Calculate the position of the end of the stored packet for use as a buffer */
00675             void* buffer = (void*)((unsigned short)&RXBuffer + RXPacketLengthReceived);
00676 
00677             /* Write the block down from RAM to Flash */
00678             unsigned short errorID = writeBlock(&details, buffer);
00679 
00680             if(errorID != 0){
00681                 sendErrorInternal(errorID);
00682                 break;
00683             }
00684 
00685             sendAckIfRequired();
00686             break;
00687         }
00688         case eraseAllBlocksFromFlash:
00689         {
00690             if(RXCalculatedPayloadLength != 0){
00691                 sendErrorInternal(payloadLengthTypeMismatch);
00692                 break;
00693             }
00694 
00695             // perform function TODO
00696             unsigned char page = 0xE0;
00697             unsigned short start = 0x8000;
00698             unsigned short end = 0xC000;
00699             unsigned short inc = 0x0400;
00700             for(;page < 0xF8;page++){
00701                 unsigned short addr;
00702                 for(addr = start;addr < end; addr += inc){
00703                     // TODO create selfDestruct() function for loading larger code to the device using all flash pages.
00704                     eraseSector(page, (unsigned short*)addr);
00705                 }
00706             }
00707             sendDebugInternal("Erased three 128k Flash blocks!");
00708             break;
00709         }
00710         case burnAllBlocksOfFlash:
00711         {
00712             if(RXCalculatedPayloadLength != 0){
00713                 sendErrorInternal(payloadLengthTypeMismatch);
00714                 break;
00715             }
00716 
00717             // perform function TODO
00718             unsigned char page = 0xE0;
00719             unsigned short start = 0x8000;
00720             unsigned short end = 0xC000;
00721             unsigned short inc = 0x0400;
00722             for(;page < 0xF8;page++){
00723                 unsigned short addr;
00724                 for(addr = start;addr < end; addr += inc){
00725                     writeSector(RPAGE, (unsigned short*)0xc000, page, (unsigned short*)addr);
00726                 }
00727             }
00728             sendDebugInternal("Overwrote three 128k Flash blocks!");
00729             break;
00730         }
00731         case adjustMainTableCell:
00732         {
00733             if(RXCalculatedPayloadLength != 8){
00734                 sendErrorInternal(payloadLengthTypeMismatch);
00735                 break;
00736             }
00737 
00738             /* Extract the flash location ID from the received data */
00739             unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
00740             RXBufferCurrentPosition += 2;
00741 
00742             /* Check the ID to ensure it is a main table */
00743             if(15 < locationID){
00744                 sendErrorInternal(invalidIDForMainTableAction);
00745                 break;
00746             }
00747 
00748             /* Extract the cell value and coordinates */
00749             unsigned short RPMIndex = *((unsigned short*)RXBufferCurrentPosition);
00750             RXBufferCurrentPosition += 2;
00751             unsigned short LoadIndex = *((unsigned short*)RXBufferCurrentPosition);
00752             RXBufferCurrentPosition += 2;
00753             unsigned short cellValue = *((unsigned short*)RXBufferCurrentPosition);
00754 
00755             /* Look up the memory location details */
00756             blockDetails details;
00757             lookupBlockDetails(locationID, &details);
00758 
00759             /* Attempt to set the value */
00760             unsigned short errorID = setPagedMainTableCellValue(details.RAMPage, details.RAMAddress, RPMIndex, LoadIndex, cellValue);
00761             if(errorID != 0){
00762                 sendErrorInternal(errorID);
00763             }else{
00764                 sendAckIfRequired();
00765             }
00766             break;
00767         }
00768         case adjustMainTableRPMAxis:
00769         {
00770             if(RXCalculatedPayloadLength != 6){
00771                 sendErrorInternal(payloadLengthTypeMismatch);
00772                 break;
00773             }
00774 
00775             /* Extract the flash location ID from the received data */
00776             unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
00777             RXBufferCurrentPosition -= 2;
00778 
00779             /* Check the ID to ensure it is a main table */
00780             if(15 < locationID){
00781                 sendErrorInternal(invalidIDForMainTableAction);
00782                 break;
00783             }
00784 
00785             /* Extract the cell value and coordinates */
00786             unsigned short RPMIndex = *((unsigned short*)RXBufferCurrentPosition);
00787             RXBufferCurrentPosition -= 2;
00788             unsigned short RPMValue = *((unsigned short*)RXBufferCurrentPosition);
00789 
00790             /* Look up the memory location details */
00791             blockDetails details;
00792             lookupBlockDetails(locationID, &details);
00793 
00794             /* Attempt to set the value */
00795             unsigned short errorID = setPagedMainTableRPMValue(details.RAMPage, details.RAMAddress, RPMIndex, RPMValue);
00796             if(errorID != 0){
00797                 sendErrorInternal(errorID);
00798             }else{
00799                 sendAckIfRequired();
00800             }
00801             break;
00802         }
00803         case adjustMainTableLoadAxis:
00804         {
00805             if(RXCalculatedPayloadLength != 6){
00806                 sendErrorInternal(payloadLengthTypeMismatch);
00807                 break;
00808             }
00809 
00810             /* Extract the flash location ID from the received data */
00811             unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
00812             RXBufferCurrentPosition -= 2;
00813 
00814             /* Check the ID to ensure it is a main table */
00815             if(15 < locationID){
00816                 sendErrorInternal(invalidIDForMainTableAction);
00817                 break;
00818             }
00819 
00820             /* Extract the cell value and coordinates */
00821             unsigned short LoadIndex = *((unsigned short*)RXBufferCurrentPosition);
00822             RXBufferCurrentPosition -= 2;
00823             unsigned short LoadValue = *((unsigned short*)RXBufferCurrentPosition);
00824 
00825             /* Look up the memory location details */
00826             blockDetails details;
00827             lookupBlockDetails(locationID, &details);
00828 
00829             /* Attempt to set the value */
00830             unsigned short errorID = setPagedMainTableLoadValue(details.RAMPage, details.RAMAddress, LoadIndex, LoadValue);
00831             if(errorID != 0){
00832                 sendErrorInternal(errorID);
00833             }else{
00834                 sendAckIfRequired();
00835             }
00836             break;
00837         }
00838         case adjust2dTableAxis:
00839         {
00840             if(RXCalculatedPayloadLength != 6){
00841                 sendErrorInternal(payloadLengthTypeMismatch);
00842                 break;
00843             }
00844 
00845             /* Extract the flash location ID from the received data */
00846             unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
00847             RXBufferCurrentPosition -= 2;
00848 
00849             /* Check the ID to ensure it is a 2d table */
00850             if((locationID > 899) || (locationID < 400)){
00851                 sendErrorInternal(invalidIDForTwoDTableAction);
00852                 break;
00853             }
00854 
00855             /* Extract the cell value and coordinates */
00856             unsigned short axisIndex = *((unsigned short*)RXBufferCurrentPosition);
00857             RXBufferCurrentPosition -= 2;
00858             unsigned short axisValue = *((unsigned short*)RXBufferCurrentPosition);
00859 
00860             /* Look up the memory location details */
00861             blockDetails details;
00862             lookupBlockDetails(locationID, &details);
00863 
00864             /* Attempt to set the value */
00865             unsigned short errorID = setPagedTwoDTableAxisValue(details.RAMPage, details.RAMAddress, axisIndex, axisValue);
00866             if(errorID != 0){
00867                 sendErrorInternal(errorID);
00868             }else{
00869                 sendAckIfRequired();
00870             }
00871             break;
00872         }
00873         case adjust2dTableCell:
00874         {
00875             if(RXCalculatedPayloadLength != 6){
00876                 sendErrorInternal(payloadLengthTypeMismatch);
00877                 break;
00878             }
00879 
00880             /* Extract the flash location ID from the received data */
00881             unsigned short locationID = *((unsigned short*)RXBufferCurrentPosition);
00882             RXBufferCurrentPosition -= 2;
00883 
00884             /* Check the ID to ensure it is a 2d table */
00885             if((locationID > 899) || (locationID < 400)){
00886                 sendErrorInternal(invalidIDForTwoDTableAction);
00887                 break;
00888             }
00889 
00890             /* Extract the cell value and coordinates */
00891             unsigned short cellIndex = *((unsigned short*)RXBufferCurrentPosition);
00892             RXBufferCurrentPosition -= 2;
00893             unsigned short cellValue = *((unsigned short*)RXBufferCurrentPosition);
00894 
00895             /* Look up the memory location details */
00896             blockDetails details;
00897             lookupBlockDetails(locationID, &details);
00898 
00899             /* Attempt to set the value */
00900             unsigned short errorID = setPagedTwoDTableCellValue(details.RAMPage, details.RAMAddress, cellIndex, cellValue);
00901             if(errorID != 0){
00902                 sendErrorInternal(errorID);
00903             }else{
00904                 sendAckIfRequired();
00905             }
00906             break;
00907         }
00908         case requestBasicDatalog:
00909         {
00910             if((RXCalculatedPayloadLength > 2) || (RXCalculatedPayloadLength == 1)){
00911                 sendErrorInternal(payloadLengthTypeMismatch);
00912                 break;
00913             }else if(RXCalculatedPayloadLength == 2){
00914                 unsigned short newConfiguredLength = *((unsigned short*)RXBufferCurrentPosition);
00915                 if(newConfiguredLength > maxBasicDatalogLength){
00916                     sendErrorInternal(datalogLengthExceedsMax);
00917                     break;
00918                 }else{
00919                     configuredBasicDatalogLength = newConfiguredLength;
00920                 }
00921             }
00922 
00923             /* Set the length field up */
00924             *TXHeaderFlags |= HEADER_HAS_LENGTH;
00925             *(unsigned short*)TXBufferCurrentPositionHandler = configuredBasicDatalogLength;
00926 
00927             /* Fill out the log and send */
00928             populateBasicDatalog();
00929             checksumAndSend();
00930             break;
00931         }
00932         case requestConfigurableDatalog:
00933         {
00934             // perform function TODO
00935             sendErrorInternal(unimplementedFunction);
00936             break;
00937         }
00938         case forwardPacketOverCAN:
00939         {
00940             // perform function TODO
00941             sendErrorInternal(unimplementedFunction);
00942             break;
00943         }
00944         case forwardPacketOverOtherUART:
00945         {
00946             // perform function TODO
00947             sendErrorInternal(unimplementedFunction);
00948             break;
00949         }
00950         case setAsyncDatalogType:
00951         {
00952             if(RXCalculatedPayloadLength != 1){
00953                 sendErrorInternal(payloadLengthTypeMismatch);
00954                 break;
00955             }
00956 
00957             unsigned char newDatalogType = *((unsigned char*)RXBufferCurrentPosition);
00958             if(newDatalogType > 0x03){
00959                 sendErrorInternal(noSuchAsyncDatalogType);
00960                 break;
00961             }else{
00962                 asyncDatalogType = newDatalogType;
00963             }
00964 
00965             sendAckIfRequired();
00966             break;
00967         }
00968         default:
00969             if((RXHeaderPayloadID % 2) == 1){
00970                 sendErrorInternal(invalidFirmwarePayloadID);
00971             }else{
00972                 sendErrorInternal(unrecognisedFirmwarePayloadID);
00973             }
00974         }
00975     }
00976     /* Switch reception back on now that we are done with the received data */
00977     resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS);
00978     PORTK |= BIT0;
00979 }

Here is the call graph for this function:

void populateBasicDatalog ( void   ) 

Populate a basic datalog packet.

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

Author:
Fred Cooke
Warning:
This function is only a skeleton at this time.

Definition at line 63 of file commsCore.c.

References ADCArrays, configuredBasicDatalogLength, CoreVars, DerivedVars, and TXBufferCurrentPositionHandler.

Referenced by decodePacketAndRespond(), and main().

00063                            {
00064     /* Save the current position */
00065     unsigned char* position = TXBufferCurrentPositionHandler;
00066 
00067     /* Get core vars */
00068     memcpy(TXBufferCurrentPositionHandler, CoreVars, sizeof(CoreVar));
00069     TXBufferCurrentPositionHandler += sizeof(CoreVar);
00070     /* Get derived vars */
00071     memcpy(TXBufferCurrentPositionHandler, DerivedVars, sizeof(DerivedVar));
00072     TXBufferCurrentPositionHandler += sizeof(DerivedVar);
00073     /* Get raw adc counts */
00074     memcpy(TXBufferCurrentPositionHandler, ADCArrays, sizeof(ADCArray));
00075     TXBufferCurrentPositionHandler += sizeof(ADCArray);
00076 
00077     /* Set/Truncate the log to the specified length */
00078     TXBufferCurrentPositionHandler = position + configuredBasicDatalogLength;
00079 }

void sendAckIfRequired ( void   ) 

Send an ack if required.

Currently only used to clear the TX buffer flags if we no longer need it.

Author:
Fred Cooke
Todo:
TODO when implementing, check that ppage is OK!!!

Definition at line 1256 of file commsCore.c.

References TXBufferInUseFlags.

Referenced by decodePacketAndRespond().

01256                         {
01257     TXBufferInUseFlags = 0;
01258     // check PPAGE while implementing TODO
01259 }

void sendDebugBusyWait ( unsigned char *  message  ) 

Send a debug message even if we must wait

This is a wrapper for use outside the communication handler function. This function will block until the debug message is able to be sent.

Author:
Fred Cooke
Note:
This function exists as a convenience to developers, do not publish code that calls this function.
Parameters:
message is a pointer to the null terminated debug message string.

Definition at line 1112 of file commsCore.c.

References ONES, sendDebugInternal(), and TXBufferInUseFlags.

01112                                               {
01113     while(TXBufferInUseFlags){} /* Wait till clear to send */
01114     TXBufferInUseFlags = ONES;
01115     sendDebugInternal(message);
01116 }

Here is the call graph for this function:

void sendDebugIfClear ( unsigned char *  message  ) 

Send a debug message if buffer free.

This is a wrapper for use outside the communication handler function. The debug message will only be sent if the buffer is empty and available, if not, it will be discarded.

Author:
Fred Cooke
Note:
This function exists as a convenience to developers, do not publish code that calls this function.
Parameters:
message is a pointer to the null terminated debug message string.

Definition at line 1091 of file commsCore.c.

References Counter::commsDebugMessagesNotSent, Counters, ONES, sendDebugInternal(), and TXBufferInUseFlags.

01091                                              {
01092     if(!TXBufferInUseFlags){
01093         TXBufferInUseFlags = ONES;
01094         sendDebugInternal(message);
01095     }else{
01096         Counters.commsDebugMessagesNotSent++;
01097     }
01098 }

Here is the call graph for this function:

void sendDebugInternal ( unsigned char *  message  ) 

Send a debug message.

Sends a null terminated debug message out on the broadcast address of all available interfaces.

Author:
Fred Cooke
Warning:
ONLY use this function from within the communication handler.
See also:
sendDebugIfClear()

sendDebugBusyWait()

Note:
This function exists as a convenience to developers, do not publish code that calls this function.
Todo:
TODO clean up the mess of commented out crap in here!
Parameters:
message is a pointer to the null terminated debug message string.

Definition at line 1136 of file commsCore.c.

References asyncDebugInfoPacket, checksumAndSend(), stringCopy(), and TXBufferCurrentPositionHandler.

Referenced by decodePacketAndRespond(), sendDebugBusyWait(), and sendDebugIfClear().

01136                                               {
01137 
01138 //  set buffer in use, consider blocking interrupts to do this cleanly
01139 
01140 //  if(TRUE){
01141 //      Counters.serialDebugUnsentCounter++;
01142 //      return;
01143 //  }
01144     // wrong :
01145     /* No need for atomic block here as one of two conditions will always be */
01146     /* true when calling this. Either we have been flagged to receive and    */
01147     /* decode a packet, or we are in an ISR. In either case it is safe to    */
01148     /* check the flags and initiate the sequence if they are clear.          */
01149     //if(RXTXSerialStateFlags & TX_IN_PROGRESS){
01150         // wrong :
01151         /* It's OK to return without resetting as it will be done by */
01152         /* either of those processes if they are underway. The other */
01153         /* processes are not overridden because they have priority.  */
01154         //TXBufferInUseFlags = 0;
01155         //return;
01156 //  }else{ /* Turn off reception */
01157         /* It's OK to turn this off if nothing was currently being received */
01158     //  SCI0CR2 &= SCICR2_RX_ISR_DISABLE;
01159     //  SCI0CR2 &= SCICR2_RX_DISABLE;
01160 
01161         /* Build up the packet */
01162         /* Set the pointer to the start and init the length */
01163         TXBufferCurrentPositionHandler = (unsigned char*)&TXBuffer;
01164 
01165         /* Load a protocol with length header into the TX buffer ready for masking */
01166         *TXBufferCurrentPositionHandler = 0x11;
01167         TXBufferCurrentPositionHandler++;
01168 
01169         /* Set the payload ID */
01170         *((unsigned short*)TXBufferCurrentPositionHandler) = asyncDebugInfoPacket;
01171         TXBufferCurrentPositionHandler += 2;
01172 
01173         /* Store the length location */
01174         unsigned short* TXLength = (unsigned short*)TXBufferCurrentPositionHandler;
01175         TXBufferCurrentPositionHandler += 2;
01176 
01177         /* Copy the string into place and record the length copied */
01178         unsigned short messageLength = stringCopy(TXBufferCurrentPositionHandler, message);
01179         *TXLength = messageLength;
01180         TXBufferCurrentPositionHandler += messageLength;
01181 
01182         checksumAndSend();
01183     //}
01184 }

Here is the call graph for this function:

void sendErrorBusyWait ( unsigned short  errorID  ) 

Send an error even if we must wait.

This is a wrapper for use outside the communication handler function. This function will block until the error is able to be sent. This behaviour is not recommended as it will interfere with engine operation somewhat.

Author:
Fred Cooke
Warning:
Use of this function signifies that the error you are trying to propagate is extremely urgent and can not be forgotten.
Note:
Using this function blocks other main loop code from execution. Consider handling the error in another way if it seems appropriate to use this.
Parameters:
errorID is the error ID to be passed out to listening devices.

Definition at line 1018 of file commsCore.c.

References ONES, sendErrorInternal(), and TXBufferInUseFlags.

01018                                               {
01019     while(TXBufferInUseFlags){} /* Wait till clear to send */
01020     TXBufferInUseFlags = ONES;
01021     sendErrorInternal(errorID);
01022 }

Here is the call graph for this function:

void sendErrorIfClear ( unsigned short  errorID  ) 

Send an error if buffer free.

This is a wrapper for use outside the communication handler function. The error will only be sent if the buffer is empty and available, if not, it will be discarded.

Author:
Fred Cooke
Warning:
Use of this function signifies that the error you are trying to propagate is not urgent and can be forgotten.
Note:
Consider not throwing an error if it seems appropriate to use this.
Parameters:
errorID is the error ID to be passed out to listening devices.

Definition at line 994 of file commsCore.c.

References Counter::commsErrorMessagesNotSent, Counters, ONES, sendErrorInternal(), and TXBufferInUseFlags.

Referenced by generateCoreVars(), and generateDerivedVars().

00994                                              {
00995     if(!TXBufferInUseFlags){
00996         TXBufferInUseFlags = ONES;
00997         sendErrorInternal(errorID);
00998     }else{
00999         Counters.commsErrorMessagesNotSent++;
01000     }
01001 }

Here is the call graph for this function:

void sendErrorInternal ( unsigned short  errorCode  ) 

Send an error.

This function is only for use inside the communication handling function. Use of it outside this environment is not supported and behaviour when used as such is undefined.

Author:
Fred Cooke
Warning:
ONLY use this function from within the communication handler.
See also:
sendErrorIfClear()

sendErrorBusyWait()

Todo:
TODO clean up the mess of commented out crap in here!

TODO decide on errorCode or errorID and consistencise it everywhere.

Parameters:
errorCode is the error ID to be passed out to listening devices.

Definition at line 1043 of file commsCore.c.

References asyncErrorCodePacket, checksumAndSend(), and TXBufferCurrentPositionHandler.

Referenced by decodePacketAndRespond(), sendErrorBusyWait(), and sendErrorIfClear().

01043                                                 {
01044 //  set buffer in use, consider blocking interrupts to do this cleanly
01045 
01046 
01047     //  TXBufferInUseFlags = 0;
01048     /* No need for atomic block here as one of two conditions will always be */
01049     /* true when calling this. Either we have been flagged to receive and    */
01050     /* decode a packet, or we are in an ISR. In either case it is safe to    */
01051     /* check the flags and initiate the sequence if they are clear.          */
01052 //  if(RXTXSerialStateFlags & TX_IN_PROGRESS){
01053         /* It's OK to return without resetting as it will be done by */
01054         /* either of those processes if they are underway. The other */
01055         /* processes are not overridden because they have priority.  */
01056 //      return;
01057 //  }else{ /* Turn off reception */
01058         /* It's OK to turn this off if nothing was currently being received */
01059 //      SCI0CR2 &= SCICR2_RX_ISR_DISABLE;
01060 //      SCI0CR2 &= SCICR2_RX_DISABLE;
01061 
01062         /* Build up the packet */
01063         /* Set the pointer to the start */
01064         TXBufferCurrentPositionHandler = (unsigned char*)&TXBuffer;
01065         /* Set the length */
01066 //      TXPacketLengthToSend = 5; /* Flags + Payload ID + Error Code */
01067         /* Flags = protocol with no extra fields */
01068         *TXBufferCurrentPositionHandler = 0x01;
01069         TXBufferCurrentPositionHandler++;
01070         /* Set the payload ID */
01071         *((unsigned short*)TXBufferCurrentPositionHandler) = asyncErrorCodePacket;
01072         TXBufferCurrentPositionHandler += 2;
01073         /* Set the error code */
01074         *((unsigned short*)TXBufferCurrentPositionHandler) = errorCode;
01075         TXBufferCurrentPositionHandler += 2;
01076         checksumAndSend();
01077 //  }
01078 }

Here is the call graph for this function:


Generated on Mon Jan 26 00:16:21 2009 for FreeEMS by  doxygen 1.5.8