commsCore.c File Reference

Core communications functions. More...

#include "inc/freeEMS.h"
#include "inc/flashWrite.h"
#include "inc/interrupts.h"
#include "inc/blockDetailsLookup.h"
#include <string.h>
Include dependency graph for commsCore.c:
This graph shows which files directly or indirectly include this file:

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 sendErrorInternal (unsigned short errorCode)
 Send an error.
void sendDebugIfClear (unsigned char *message)
 Send a debug message if buffer free.
void sendDebugInternal (unsigned char *message)
 Send a debug message.

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 44 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 149 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().

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

Here is the call graph for this function:

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.

Author:
Fred Cooke

Todo:
TODO implement default return of empty packet.
Todo:
TODO implement default return of empty packet.
Todo:
TODO implement default return of empty packet.
Todo:
TODO implement default return of empty packet.
Todo:
TODO implement default return of empty packet.
Todo:
TODO implement default return of empty packet.
Todo:
TODO implement default return of empty packet.
Todo:
TODO implement default return of empty packet.
Todo:
TODO implement default return of empty packet.

Definition at line 225 of file commsCore.c.

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

Referenced by main().

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

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 64 of file commsCore.c.

References ADCArrays, configuredBasicDatalogLength, CoreVars, DerivedVars, DerivedVar::sp5, and TXBufferCurrentPositionHandler.

Referenced by decodePacketAndRespond(), and main().

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

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 1130 of file commsCore.c.

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

01130                                              {
01131     if(!TXBufferInUseFlags){
01132         TXBufferInUseFlags = ONES;
01133         sendDebugInternal(message);
01134     }else{
01135         Counters.commsDebugMessagesNotSent++;
01136     }
01137 }

Here is the call graph for this function:

void sendDebugInternal ( unsigned char *  message  ) 

Send a debug 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. 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 1175 of file commsCore.c.

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

Referenced by decodePacketAndRespond(), and sendDebugIfClear().

01175                                               {
01176 
01177 //  set buffer in use, consider blocking interrupts to do this cleanly
01178 
01179 //  if(TRUE){
01180 //      Counters.serialDebugUnsentCounter++;
01181 //      return;
01182 //  }
01183     // wrong :
01184     /* No need for atomic block here as one of two conditions will always be */
01185     /* true when calling this. Either we have been flagged to receive and    */
01186     /* decode a packet, or we are in an ISR. In either case it is safe to    */
01187     /* check the flags and initiate the sequence if they are clear.          */
01188     //if(RXTXSerialStateFlags & TX_IN_PROGRESS){
01189         // wrong :
01190         /* It's OK to return without resetting as it will be done by */
01191         /* either of those processes if they are underway. The other */
01192         /* processes are not overridden because they have priority.  */
01193         //TXBufferInUseFlags = 0;
01194         //return;
01195 //  }else{ /* Turn off reception */
01196         /* It's OK to turn this off if nothing was currently being received */
01197     //  SCI0CR2 &= SCICR2_RX_ISR_DISABLE;
01198     //  SCI0CR2 &= SCICR2_RX_DISABLE;
01199 
01200         /* Build up the packet */
01201         /* Set the pointer to the start and init the length */
01202         TXBufferCurrentPositionHandler = (unsigned char*)&TXBuffer;
01203 
01204         /* Load a protocol with length header into the TX buffer ready for masking */
01205         *TXBufferCurrentPositionHandler = 0x11;
01206         TXBufferCurrentPositionHandler++;
01207 
01208         /* Set the payload ID */
01209         *((unsigned short*)TXBufferCurrentPositionHandler) = asyncDebugInfoPacket;
01210         TXBufferCurrentPositionHandler += 2;
01211 
01212         /* Store the length location */
01213         unsigned short* TXLength = (unsigned short*)TXBufferCurrentPositionHandler;
01214         TXBufferCurrentPositionHandler += 2;
01215 
01216         /* Copy the string into place and record the length copied */
01217         unsigned short messageLength = stringCopy(TXBufferCurrentPositionHandler, message);
01218         *TXLength = messageLength;
01219         TXBufferCurrentPositionHandler += messageLength;
01220 
01221         checksumAndSend();
01222     //}
01223 }

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 1032 of file commsCore.c.

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

Referenced by generateCoreVars(), and generateDerivedVars().

01032                                              {
01033     if(!TXBufferInUseFlags){
01034         TXBufferInUseFlags = ONES;
01035         sendErrorInternal(errorID);
01036     }else{
01037         Counters.commsErrorMessagesNotSent++;
01038     }
01039 }

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 1082 of file commsCore.c.

References asyncErrorCodePacket, checksumAndSend(), and TXBufferCurrentPositionHandler.

Referenced by decodePacketAndRespond(), and sendErrorIfClear().

01082                                                 {
01083 //  set buffer in use, consider blocking interrupts to do this cleanly
01084 
01085 
01086     //  TXBufferInUseFlags = 0;
01087     /* No need for atomic block here as one of two conditions will always be */
01088     /* true when calling this. Either we have been flagged to receive and    */
01089     /* decode a packet, or we are in an ISR. In either case it is safe to    */
01090     /* check the flags and initiate the sequence if they are clear.          */
01091 //  if(RXTXSerialStateFlags & TX_IN_PROGRESS){
01092         /* It's OK to return without resetting as it will be done by */
01093         /* either of those processes if they are underway. The other */
01094         /* processes are not overridden because they have priority.  */
01095 //      return;
01096 //  }else{ /* Turn off reception */
01097         /* It's OK to turn this off if nothing was currently being received */
01098 //      SCI0CR2 &= SCICR2_RX_ISR_DISABLE;
01099 //      SCI0CR2 &= SCICR2_RX_DISABLE;
01100 
01101         /* Build up the packet */
01102         /* Set the pointer to the start */
01103         TXBufferCurrentPositionHandler = (unsigned char*)&TXBuffer;
01104         /* Set the length */
01105 //      TXPacketLengthToSend = 5; /* Flags + Payload ID + Error Code */
01106         /* Flags = protocol with no extra fields */
01107         *TXBufferCurrentPositionHandler = 0x01;
01108         TXBufferCurrentPositionHandler++;
01109         /* Set the payload ID */
01110         *((unsigned short*)TXBufferCurrentPositionHandler) = asyncErrorCodePacket;
01111         TXBufferCurrentPositionHandler += 2;
01112         /* Set the error code */
01113         *((unsigned short*)TXBufferCurrentPositionHandler) = errorCode;
01114         TXBufferCurrentPositionHandler += 2;
01115         checksumAndSend();
01116 //  }
01117 }

Here is the call graph for this function:

Generated on Sat Oct 16 21:29:03 2010 for FreeEMS by  doxygen 1.6.3