commsCore.c File Reference

#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 sendErrorInternal (unsigned short) FPAGE_FE
void sendDebugInternal (unsigned char *)
void checksumAndSend ()
 * Just dump the ADC channels as fast as possible */
void decodePacketAndRespond ()
void sendErrorIfClear (unsigned short errorID)
void sendErrorBusyWait (unsigned short errorID)
void sendDebugIfClear (unsigned char *message)
void sendDebugBusyWait (unsigned char *message)
void sendAckIfRequired ()


Define Documentation

#define COMMSCORE_C

Definition at line 24 of file commsCore.c.


Function Documentation

void checksumAndSend ( void   ) 

* Just dump the ADC channels as fast as possible */

Definition at line 122 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(), and sendErrorInternal().

00122                       {
00123         /* Get the length from the pointer */
00124         unsigned short TXPacketLengthToSend = (unsigned short)TXBufferCurrentPositionHandler - (unsigned short)&TXBuffer;
00125 
00126         /* Tag the checksum on the end */
00127         *TXBufferCurrentPositionHandler = checksum((unsigned char*)&TXBuffer, TXPacketLengthToSend);
00128         TXPacketLengthToSend++;
00129 
00130         /* Send it out on all the channels required. */
00131 
00132         /* SCI0 - Main serial interface */
00133         if(TXBufferInUseFlags & COM_SET_SCI0_INTERFACE_ID){
00134                 /* Copy numbers to interface specific vars */
00135                 TXPacketLengthToSendSCI0 = TXPacketLengthToSend;
00136                 TXPacketLengthToSendCAN0 = TXPacketLengthToSend;
00137 
00138                 /* Queue preamble by clearing and then setting transmit enable  */
00139                 /* See section 11.4.5.2 of the xdp512 specification document    */
00140                 //SCI0CR2 &= SCICR2_TX_DISABLE;
00141                 //SCI0CR2 |= SCICR2_TX_ENABLE;
00142 
00143                 /* Initiate transmission */
00144                 SCI0DRL = START_BYTE;
00145                 while(!(SCI0SR1 & 0x80)){/* Wait for ever until able to send then move on */}
00146                 SCI0DRL = START_BYTE; // TODO nasty hack that works... means at least one and most 2 starts are sent so stuff works, but is messy... must be a better way.
00147 
00148                 // TODO http://freeems.aaronb.info/tracker/view.php?id=81
00149 
00150                 /* Note : Order Is Important! */
00151                 /* TX empty flag is already set, so we must clear it by writing out before enabling the interrupt */
00152                 SCI0CR2 |= SCICR2_TX_ISR_ENABLE;
00153         }
00154         /* CAN0 - Main CAN interface */
00155         if(TXBufferInUseFlags & COM_SET_CAN0_INTERFACE_ID){
00156                 // just clear up front for now
00157                 TXBufferInUseFlags &= COM_CLEAR_CAN0_INTERFACE_ID;
00158         }
00159         /* spare2 */
00160         if(TXBufferInUseFlags & COM_SET_SPARE2_INTERFACE_ID){
00161                 // just clear up front for now
00162                 TXBufferInUseFlags &= COM_CLEAR_SPARE2_INTERFACE_ID;
00163         }
00164         /* spare3 */
00165         if(TXBufferInUseFlags & COM_SET_SPARE3_INTERFACE_ID){
00166                 // just clear up front for now
00167                 TXBufferInUseFlags &= COM_CLEAR_SPARE3_INTERFACE_ID;
00168         }
00169         /* spare4 */
00170         if(TXBufferInUseFlags & COM_SET_SPARE4_INTERFACE_ID){
00171                 // just clear up front for now
00172                 TXBufferInUseFlags &= COM_CLEAR_SPARE4_INTERFACE_ID;
00173         }
00174         /* spare5 */
00175         if(TXBufferInUseFlags & COM_SET_SPARE5_INTERFACE_ID){
00176                 // just clear up front for now
00177                 TXBufferInUseFlags &= COM_CLEAR_SPARE5_INTERFACE_ID;
00178         }
00179         /* spare6 */
00180         if(TXBufferInUseFlags & COM_SET_SPARE6_INTERFACE_ID){
00181                 // just clear up front for now
00182                 TXBufferInUseFlags &= COM_CLEAR_SPARE6_INTERFACE_ID;
00183         }
00184         /* spare7 */
00185         if(TXBufferInUseFlags & COM_SET_SPARE7_INTERFACE_ID){
00186                 // just clear up front for now
00187                 TXBufferInUseFlags &= COM_CLEAR_SPARE7_INTERFACE_ID;
00188         }
00189 }

Here is the call graph for this function:

void decodePacketAndRespond ( void   ) 

Definition at line 196 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, fixedConfigs2, 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, fixedConfig2::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(), 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().

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

Here is the call graph for this function:

void sendAckIfRequired ( void   ) 

Definition at line 1134 of file commsCore.c.

References TXBufferInUseFlags.

Referenced by decodePacketAndRespond().

01134                         {
01135         TXBufferInUseFlags = 0;
01136         // check PPAGE while implementing TODO
01137 }

void sendDebugBusyWait ( unsigned char *  message  ) 

Definition at line 1013 of file commsCore.c.

References ONES, sendDebugInternal(), and TXBufferInUseFlags.

01013                                               {
01014         while(TXBufferInUseFlags){} /* Wait till clear to send */
01015         TXBufferInUseFlags = ONES;
01016         sendDebugInternal(message);
01017 }

Here is the call graph for this function:

void sendDebugIfClear ( unsigned char *  message  ) 

Definition at line 1002 of file commsCore.c.

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

01002                                              {
01003         if(!TXBufferInUseFlags){
01004                 TXBufferInUseFlags = ONES;
01005                 sendDebugInternal(message);
01006         }else{
01007                 Counters.commsDebugMessagesNotSent++;
01008         }
01009 }

Here is the call graph for this function:

void sendDebugInternal ( unsigned char *  message  ) 

Definition at line 37 of file commsCore.c.

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

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

00041                            {
00042         /* Save the current position */
00043         unsigned char* position = TXBufferCurrentPositionHandler;
00044 
00045         /* Get core vars */
00046         memcpy(TXBufferCurrentPositionHandler, CoreVars, sizeof(CoreVar));
00047         TXBufferCurrentPositionHandler += sizeof(CoreVar);
00048         /* Get derived vars */
00049         memcpy(TXBufferCurrentPositionHandler, DerivedVars, sizeof(DerivedVar));
00050         TXBufferCurrentPositionHandler += sizeof(DerivedVar);
00051         /* Get raw adc counts */
00052         memcpy(TXBufferCurrentPositionHandler, ADCArrays, sizeof(ADCArray));
00053         TXBufferCurrentPositionHandler += sizeof(ADCArray);
00054 
00055         /* Set/Truncate the log to the specified length */
00056         TXBufferCurrentPositionHandler = position + configuredBasicDatalogLength;
00057 }

void sendErrorBusyWait ( unsigned short  errorID  ) 

Definition at line 954 of file commsCore.c.

References ONES, sendErrorInternal(), and TXBufferInUseFlags.

00954                                               {
00955         while(TXBufferInUseFlags){} /* Wait till clear to send */
00956         TXBufferInUseFlags = ONES;
00957         sendErrorInternal(errorID);
00958 }

Here is the call graph for this function:

void sendErrorIfClear ( unsigned short  errorID  ) 

Definition at line 943 of file commsCore.c.

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

Referenced by generateCoreVars(), and generateDerivedVars().

00943                                              {
00944         if(!TXBufferInUseFlags){
00945                 TXBufferInUseFlags = ONES;
00946                 sendErrorInternal(errorID);
00947         }else{
00948                 Counters.commsErrorMessagesNotSent++;
00949         }
00950 }

Here is the call graph for this function:

void sendErrorInternal ( unsigned  short  ) 

Definition at line 962 of file commsCore.c.

References asyncErrorCodePacket, checksumAndSend(), and TXBufferCurrentPositionHandler.

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

00962                                                 { // TODO build wrapper to check for use inside handler or not and not send if busy and not in handler ditto for debug
00963 
00964 //      set buffer in use, consider blocking interrupts to do this cleanly
00965 
00966 
00967         //      TXBufferInUseFlags = 0;
00968         /* No need for atomic block here as one of two conditions will always be */
00969         /* true when calling this. Either we have been flagged to receive and    */
00970         /* decode a packet, or we are in an ISR. In either case it is safe to    */
00971         /* check the flags and initiate the sequence if they are clear.          */
00972 //      if(RXTXSerialStateFlags & TX_IN_PROGRESS){
00973                 /* It's OK to return without resetting as it will be done by */
00974                 /* either of those processes if they are underway. The other */
00975                 /* processes are not overridden because they have priority.  */
00976 //              return;
00977 //      }else{ /* Turn off reception */
00978                 /* It's OK to turn this off if nothing was currently being received */
00979 //              SCI0CR2 &= SCICR2_RX_ISR_DISABLE;
00980 //              SCI0CR2 &= SCICR2_RX_DISABLE;
00981 
00982                 /* Build up the packet */
00983                 /* Set the pointer to the start */
00984                 TXBufferCurrentPositionHandler = (unsigned char*)&TXBuffer;
00985                 /* Set the length */
00986 //              TXPacketLengthToSend = 5; /* Flags + Payload ID + Error Code */
00987                 /* Flags = protocol with no extra fields */
00988                 *TXBufferCurrentPositionHandler = 0x01;
00989                 TXBufferCurrentPositionHandler++;
00990                 /* Set the payload ID */
00991                 *((unsigned short*)TXBufferCurrentPositionHandler) = asyncErrorCodePacket;
00992                 TXBufferCurrentPositionHandler += 2;
00993                 /* Set the error code */
00994                 *((unsigned short*)TXBufferCurrentPositionHandler) = errorCode;
00995                 TXBufferCurrentPositionHandler += 2;
00996                 checksumAndSend();
00997 //      }
00998 }

Here is the call graph for this function:


Generated on Mon Dec 22 21:29:28 2008 for freeems by  doxygen 1.5.2