Library set up as dummy module on mbed to mimic Nordic.
Embed:
(wiki syntax)
Show/hide line numbers
rs485.cpp
00001 #include <string.h> 00002 #include <stdio.h> 00003 00004 #include "rs485.h" 00005 00006 #define DEBUG 00007 00008 static list_t functionList = { .index = 0 }; 00009 00010 Packet buildPacket; 00011 static unsigned int buffPtr; 00012 static unsigned char buffer[128+1]; 00013 int checksum; 00014 int pState = START; 00015 int returnState; 00016 unsigned int plength; 00017 unsigned char command; 00018 int message; 00019 static unsigned char packetBuffer[128]; 00020 static unsigned int packetBufferSize; 00021 00022 /************************** External Functions******************************** 00023 * These functions need to be externall defined to be able to process packets 00024 * and to send out chars over the bus. 00025 /************************** External Functions********************************/ 00026 extern int Bluetooth_ReceivePacket( Packet *_packet ); 00027 extern int Bluetooth_SendChar( unsigned char ); 00028 extern const unsigned char DEVADDRESS; 00029 00030 /****************************************************************************** 00031 * Function void RegisterCommand( command , function ) 00032 * 00033 * When a command is registered with this function it will be added to the function 00034 * list. Once on the list, when a packet is received on the bus containing that 00035 * command the associated function will get called and it will be passed the data 00036 * within the packet as a parameter. 00037 * 00038 * PreCondition: None 00039 * 00040 * Input: 'command' - command byte 00041 * 'function' - pointer to function to be called 00042 * 00043 * Output: None 00044 * 00045 * Side Effects: None 00046 * 00047 *****************************************************************************/ 00048 unsigned char RegisterCommand( unsigned char _command , void (*_function)( unsigned char *) ){ 00049 functionList.list[ functionList.index ].function = _function; 00050 functionList.list[ functionList.index ].command = _command; 00051 functionList.index++; 00052 return 0; 00053 } 00054 00055 /****************************************************************************** 00056 * Function void CheckFunction( Packet * ) 00057 * 00058 * This passes in a packet and compares the command byte with a list of registered 00059 * commands. If it finds a match it will call that function along with the data 00060 * in the packet. 00061 * 00062 * PreCondition: None 00063 * 00064 * Input: '_packet' - packet containing command byte and data 00065 * 00066 * Output: '1' - command matched and function called 00067 * '2' - no command found 00068 * 00069 * Side Effects: None 00070 * 00071 *****************************************************************************/ 00072 int CheckFunction( Packet *_packet ){ 00073 int i = 0; 00074 void (*Caller)(unsigned char *); 00075 for( i = 0 ; i < functionList.index ; i++ ){ 00076 if( _packet->command == functionList.list[i].command ){ 00077 Caller = (void (*)(unsigned char *))functionList.list[i].function; 00078 Caller( (unsigned char *)_packet->packetData ); 00079 return 1; 00080 } 00081 } 00082 return 0; 00083 } 00084 00085 void RS495_Init( void ){ 00086 00087 } 00088 00089 /****************************************************************************** 00090 * Function void SendAck( void ) 00091 * 00092 * Sends an acknowledge byte over the bus. It calls an external function to 00093 * handle the actual hardware communication. 00094 * 00095 * PreCondition: None 00096 * 00097 * Input: '_packet' - prebuilt packet to send 00098 * 00099 * Output: None 00100 * 00101 * Side Effects: None 00102 * 00103 *****************************************************************************/ 00104 static void SendAck( void ){ 00105 #ifdef DEBUG 00106 pc.printf( "\n\rAck Sent.\n\r" ); 00107 #endif // DEBUG 00108 unsigned char ack = ACKCHAR; 00109 Bluetooth_SendChar( ack ); 00110 } 00111 00112 /****************************************************************************** 00113 * Function void SendNack( void ) 00114 * 00115 * Sends a non acknowledge byte over the bus. It calls an external function to 00116 * handle the actual hardware communication. 00117 * 00118 * PreCondition: None 00119 * 00120 * Input: '_packet' - prebuilt packet to send 00121 * 00122 * Output: None 00123 * 00124 * Side Effects: None 00125 * 00126 *****************************************************************************/ 00127 static void SendNack( void ){ 00128 #ifdef DEBUG 00129 pc.printf( "\n\rNack Sent.\n\r" ); 00130 #endif // DEBUG 00131 unsigned char nack = NAKCHAR; 00132 Bluetooth_SendChar( nack ); 00133 } 00134 00135 /****************************************************************************** 00136 * Function void ProcessPacket( Packet *) 00137 * 00138 * Gets automatically called once an entire packet is successfully received. 00139 * May modify what is done, but it should just pass the packet over to 00140 * an external function where it can be correctly handled. 00141 * 00142 * PreCondition: None 00143 * 00144 * Input: '_packet' - packet received on bus 00145 * 00146 * Output: None 00147 * 00148 * Side Effects: None 00149 * 00150 *****************************************************************************/ 00151 static int ProcessPacket( Packet *_packet ){ 00152 return Bluetooth_ReceivePacket( _packet ); 00153 } 00154 00155 /****************************************************************************** 00156 * Function void setResponse(int, int, int) 00157 * 00158 * This function sets the feedback information to be send in the master device. 00159 * 00160 * PreCondition: None 00161 * 00162 * Input: '_packet' - prebuilt packet to send 00163 * 00164 * Output: None 00165 * 00166 * Side Effects: None 00167 * 00168 *****************************************************************************/ 00169 void SendMessage( void ){ 00170 int j = 0; 00171 Bluetooth_SendChar( packetBuffer[ j++ ] ); 00172 while( j < packetBufferSize ){ 00173 if( packetBuffer[ j ] == STARTPACK ){ 00174 Bluetooth_SendChar( ESCAPE ); // #SCD Added this line, I think it should be here 00175 Bluetooth_SendChar( 0x01 ); 00176 j++; 00177 } 00178 else if( packetBuffer[ j ] == ESCAPE ){ 00179 Bluetooth_SendChar( ESCAPE ); 00180 Bluetooth_SendChar( ESCAPE ); 00181 j++; 00182 } 00183 else if( packetBuffer[ j ] == STARTPOLL ){ 00184 Bluetooth_SendChar( ESCAPE ); 00185 Bluetooth_SendChar( 0x02 ); 00186 j++; 00187 } 00188 else{ 00189 Bluetooth_SendChar( packetBuffer[ j++ ] ); 00190 } 00191 } 00192 } 00193 00194 /****************************************************************************** 00195 * Function void SetResponse( Packet *_packet ) 00196 * 00197 * This function sets the feedback information to be send in the master device. 00198 * 00199 * PreCondition: None 00200 * 00201 * Input: '_packet' - prebuilt packet to send 00202 * 00203 * Output: None 00204 * 00205 * Side Effects: None 00206 * 00207 *****************************************************************************/ 00208 void SetResponsePacket( Packet *_packet ){ 00209 packetBufferSize = getFormattedPacket(_packet, packetBuffer); 00210 message = 1; 00211 } 00212 00213 /****************************************************************************** 00214 * Function void SetResponseWithData( unsigned char deviceID, unsigned char 00215 command, unsigned char * data, unsigned short dataLength) 00216 * 00217 * This function sets the feedback information to be send in the master device. 00218 * 00219 * PreCondition: None 00220 * 00221 * Input: 'deviceID' - address where the packet is going 00222 'command' - command to be sent 00223 '*data' - point to unsiged char array packet with data 00224 'dataLength' - length of 'data' 00225 * 00226 * Output: None 00227 * 00228 * Side Effects: None 00229 * 00230 *****************************************************************************/ 00231 void SetResponseWithData( unsigned char deviceID, unsigned char command, unsigned char * data, unsigned short dataLength){ 00232 00233 // build packet to be sent 00234 Packet packet; 00235 packet.deviceID = deviceID; 00236 packet.sourceID = DEVADDRESS; 00237 packet.command = command; 00238 packet.packetLength = dataLength; 00239 memcpy( packet.packetData , data , dataLength ); 00240 packetBufferSize = getFormattedPacket(&packet, packetBuffer); 00241 00242 // print message to be sent 00243 #ifdef DEBUG 00244 pc.printf( "Message to send: "); 00245 unsigned short length = 0; 00246 for( length = 1 ; length < ( dataLength + sizeof( packet.deviceID ) + sizeof( packet.sourceID ) + sizeof( packet.command ) + sizeof( packet.packetLength ) + 1 ) ; length++ ){ 00247 pc.printf( "%x " , packetBuffer[ length ] ); 00248 } 00249 pc.printf( "\n\r" ); 00250 #endif 00251 00252 message = 1; 00253 } 00254 00255 /****************************************************************************** 00256 * Function void SerialHandler(unsigned char ) 00257 * 00258 * This function handles the received data from the Serial Communication. 00259 * 00260 * PreCondition: None 00261 * 00262 * Input: 'RXByte' - the received data from Serial Communication 00263 * 00264 * 00265 * Output: None 00266 * 00267 * Side Effects: Will call functions to send ACK, NACK and process a packet 00268 * once an entire packet is received. 00269 * 00270 *****************************************************************************/ 00271 void SerialHandler(unsigned char RXByte){ 00272 00273 #ifdef DEBUG 00274 pc.printf( "RXByte: %x" , RXByte ); 00275 #endif 00276 00277 00278 // check the incoming byte for special characters 00279 if( RXByte == STARTPACK ){ // start of packet byte 00280 #ifdef DEBUG 00281 pc.printf( " - STARTBYTE\n\r" ); 00282 #endif 00283 pState = DEVICEADDRESS; // move on to check the destination address 00284 buffPtr = 0; // reset buffer pointer 00285 buffer[buffPtr++] = STARTPACK; // load RXByte into buffer 00286 checksum = STARTPACK; // add to checksum 00287 return; // exit function, will be called again in next state 00288 } 00289 else if( RXByte == STARTPOLL ){ // poll byte 00290 #ifdef DEBUG 00291 pc.printf( " - STARTPOLL\n\r" ); 00292 #endif 00293 pState = POLL; // move on to check the distination address 00294 return; // exit function, will be called again in next state 00295 } 00296 else if( RXByte == ESCAPE ){ // escape byte 00297 if( pState == HANDLEESCAPE ){ // if this is the second escape byte in a row 00298 } 00299 else{ 00300 #ifdef DEBUG 00301 pc.printf( " - ESCAPE TO " ); 00302 #endif 00303 returnState = pState; // if this is the first escape byte, record the current state 00304 pState = HANDLEESCAPE; // change state 00305 return; // exit function, will be called again in next state 00306 } 00307 } 00308 00309 if( pState == HANDLEESCAPE ){ // if entering here RXByte needs to be unescaped 00310 switch( RXByte ){ 00311 case 1: // unescape a 0x7F/Start of packet byte 00312 RXByte = 0x7F; 00313 #ifdef DEBUG 00314 pc.printf( " -> %x" , RXByte ); 00315 #endif 00316 break; 00317 00318 case 2: // unescape a 0x8F/Poll byte 00319 RXByte = 0x8F; 00320 #ifdef DEBUG 00321 pc.printf( " -> %x" , RXByte ); 00322 #endif 00323 break; 00324 00325 case ESCAPE: // unescape a 0x8E/Escape byte 00326 RXByte = 0x8E; 00327 #ifdef DEBUG 00328 pc.printf( " -> %x" , RXByte ); 00329 #endif 00330 break; 00331 } 00332 pState = returnState; // change back to state before escape byte received 00333 } 00334 00335 switch( pState ){ 00336 00337 case POLL: // of switch( pState ) // poll state checks RXByte to see if there is an address match 00338 00339 00340 if( RXByte == DEVADDRESS ){ // if the device is being polled... 00341 #ifdef DEBUG 00342 pc.printf( " - Address Match: %x" , DEVADDRESS ); 00343 #endif 00344 00345 if( message ){ // if a message is available send it 00346 #ifdef DEBUG 00347 pc.printf( " - Message to Send\n\r" ); 00348 #endif 00349 SendMessage(); // #SCD haven't tested this 00350 pState = RESPONSE; // change state to wait for ACK or NACK 00351 } 00352 else{ // device is pulled but no message to be sent 00353 #ifdef DEBUG 00354 pc.printf( " - No message to Send\n\r" ); 00355 #endif 00356 SendAck(); // just send an ACK 00357 pState = START; 00358 } 00359 } 00360 else{ 00361 pState = START; // device not addressed, do nothing 00362 } 00363 break; 00364 00365 case START: // of switch( pState ) // this state really does nothing and just waits for 00366 pState = START; // if the device is not addressed in a packet 00367 break; 00368 00369 case RESPONSE: // of switch( pState ) // a message was sent it last state and now this state is 00370 00371 switch( RXByte ){ 00372 00373 case ACKCHAR: // ACK is received - message successful, clear message to be sent 00374 #ifdef DEBUG 00375 pc.printf( " - ACK RECEIVED\n\r" ); 00376 #endif 00377 message = 0; 00378 pState = START; 00379 break; 00380 00381 case NAKCHAR: // NACK is received - message not successful 00382 #ifdef DEBUG 00383 pc.printf( " - NACK RECEIVED\n\r" ); 00384 #endif 00385 if( message ){ // if a message still needs to be sent, send again 00386 SendMessage(); 00387 message = 0; // clear message after this seconda attempt to prevent too many tries 00388 pState = RESPONSE; // set state to come by here next time around 00389 } 00390 else{ // if a NACK is received for the second time in a row 00391 //#error #SCD // throw an error and do not resend 00392 pc.printf( "Received two NACKs from master. Message failed.\n\r" ); 00393 } 00394 break; 00395 00396 default: 00397 #ifdef DEBUG 00398 pc.printf( " - EXPECTED ACK or NACK\n\r" ); 00399 #endif 00400 pState = START; // if neither an ACK nor NACK is received, reset state 00401 break; 00402 00403 } 00404 break; 00405 00406 case DEVICEADDRESS: // of switch( pState ) // checks to see if device is addressed in current packet 00407 #ifdef DEBUG 00408 pc.printf( " - DEVICEADDRESS\n\r" ); 00409 #endif 00410 00411 if( RXByte == DEVADDRESS ){ 00412 #ifdef PRINT_ADDRESS_MATCH 00413 pc.printf( "Address Match: %d\n\r" , DEVADDRESS ); 00414 #endif 00415 00416 pState = SOURCEADD; // next state is grabbing the source device ID 00417 buffer[buffPtr++] = RXByte; // add RXByte to buffer 00418 buildPacket.deviceID = RXByte; // build packet 00419 checksum += RXByte; // add RXByte to checksum 00420 } 00421 else{ 00422 pState = START; // if device is not addressed reset state 00423 } 00424 00425 break; 00426 00427 case SOURCEADD: // of switch( pState ) // records the source address of the packet 00428 #ifdef DEBUG 00429 pc.printf( " - SOURCEADD\n\r" ); 00430 #endif 00431 00432 pState = COLLECTCOMMAND; // state advances to get the command byte 00433 buffer[buffPtr++] = RXByte; // add RXByte to buffer 00434 buildPacket.sourceID = RXByte; // build packet 00435 checksum += RXByte; // add RXByte to checksum 00436 break; 00437 00438 case COLLECTCOMMAND: // of switch( pState )// records the command byte of the packet 00439 #ifdef DEBUG 00440 pc.printf( " - COMMAND\n\r" ); 00441 #endif 00442 00443 command = RXByte; // record command byte 00444 buildPacket.command = RXByte; // build packet 00445 pState = COLLECTCOUNT1; // advance to get packetLength 00446 buffer[buffPtr++] = RXByte; // add RXByte to buffer 00447 checksum += RXByte; // add RXByte to checksum 00448 break; 00449 00450 case COLLECTCOUNT1: // of switch( pState ) // records first byte of packetLength 00451 #ifdef DEBUG 00452 pc.printf( " - COUNT MSB \n\r" ); 00453 #endif 00454 00455 pState = COLLECTCOUNT2; // advance state to get next byte of packetLength 00456 plength = RXByte; 00457 plength <<= 8; // store byte in packetLength #SCD is this storing correctly? 00458 buffer[buffPtr++] = RXByte; // add RXByte to buffer 00459 checksum += RXByte; // add RXByte to checksum 00460 break; 00461 00462 case COLLECTCOUNT2: // of switch( pState ) // records second byte of packetLength 00463 #ifdef DEBUG 00464 pc.printf( " - COUNT LSB\n\r" ); 00465 #endif 00466 00467 plength += RXByte; // add RXByte to packetLength total 00468 buildPacket.packetLength = plength; // build packet 00469 buffer[buffPtr++] = RXByte; // add RXByte to buffer 00470 checksum += RXByte; // add RXByte to checksum 00471 if( plength == 0 ) // if packetLength is 0, advance to checksum state 00472 pState = COLLECTCHECKSUM; 00473 else // otherwise move on to collect packet payload 00474 pState = COLLECTPACKET; 00475 break; 00476 00477 case COLLECTPACKET: // of switch( pState ) // collects packetData, enters this state multiple times 00478 #ifdef DEBUG 00479 pc.printf( " - PACKETDATA \n\r" ); 00480 #endif 00481 00482 plength--; // decrement length 00483 buffer[buffPtr++] = RXByte; // add RXByte to buffer 00484 checksum += RXByte; // add RXByte to checksum 00485 00486 if( plength == 0 ){ // if collected all packetData advance state 00487 pState = COLLECTCHECKSUM; 00488 } 00489 break; 00490 00491 case COLLECTCHECKSUM:// of switch( pState ) // collects checksum of packet and checks for validity 00492 #ifdef DEBUG 00493 pc.printf( " - CHECKSUM\n\r" ); 00494 #endif 00495 memcpy( &buildPacket.packetData , &buffer[6] , buildPacket.packetLength ); 00496 00497 if( RXByte == ( ( checksum* - 1 ) & 0xFF ) ){ // compares RXByte with LSB of checksum 00498 message = 0; // if checksum is correct clear message #SCD could a message be waiting? 00499 memset(packetBuffer, '\0', 128); // clear packetBuffer 00500 00501 buffer[buffPtr++] = RXByte; // add RXByte to buffer 00502 00503 #ifdef DEBUG 00504 pc.printf( "Receive Buffer: " ); // debug print received packet 00505 unsigned int i = 0; 00506 for( i = 0 ; i < buffPtr ; i++ ){ 00507 pc.printf( "%x " , buffer[ i ] ); 00508 } 00509 pc.printf( "\n\r" ); 00510 #endif 00511 00512 int errorResult = ProcessPacket( &buildPacket ); 00513 00514 if( errorResult == -1 ){ // check to make sure function performed properly 00515 //#SCD setResponse(RPIADDRESS, command, ERRORCOMMAND); 00516 } 00517 SendAck(); // send an ACK 00518 } 00519 else{ 00520 SendNack(); // if checksum is not corret, send a NACK 00521 } 00522 00523 pState = START; 00524 break; 00525 00526 } // end switch( pState ) 00527 00528 } // end serial2Handler function 00529 00530
Generated on Tue Jul 12 2022 22:58:49 by
1.7.2