Core communications functions. More...
#include "inc/freeEMS.h"
#include "inc/flashWrite.h"
#include "inc/interrupts.h"
#include "inc/blockDetailsLookup.h"
#include <string.h>
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. |
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 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
Definition in file commsCore.c.
#define COMMSCORE_C |
Definition at line 44 of file commsCore.c.
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.
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 }
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.
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 }
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.
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.
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 }
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.
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. |
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 }
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.
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 }
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.
TODO clean up the mess of commented out crap in here!
TODO decide on errorCode or errorID and consistencise it everywhere.
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 }