Stephen Davis
/
BT_Hub
Library set up as dummy module on mbed to mimic Nordic.
Diff: rs485.cpp
- Revision:
- 0:226550611f0d
- Child:
- 1:d6b18299a715
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rs485.cpp Mon Dec 12 23:06:58 2016 +0000 @@ -0,0 +1,404 @@ +#include <string.h> +#include <stdio.h> + +#include "rs485.h" + + +#define PRINTPACKETDEBUG +#define DEVADDRESS 0xF0 +#define DEBUG + +static list_t functionList = { .index = 0 }; + + +Packet buildPacket; +static unsigned int buffPtr; +static unsigned char buffer[128+1]; +int checksum; +int pState = START; +int returnState; +unsigned int plength; +unsigned char command; +int message; +// extern int message; + +// extern unsigned char packetBuffer[128]; +// extern unsigned int packetBufferSize; +static unsigned char packetBuffer[128]; +static unsigned int packetBufferSize; + +extern int Bluetooth_ReceivePacket( Packet *_packet ); +extern int Bluetooth_SendChar( unsigned char ); + +#ifdef __cplusplus +extern "C" { +#endif + + +unsigned char RegisterCommand( unsigned char _command , void (*_function)( unsigned char *) ){ + functionList.list[ functionList.index ].function = _function; + functionList.list[ functionList.index ].command = _command; + functionList.index++; + return 0; +} + +int CheckFunction( Packet *_packet ){ + int i = 0; + void (*Caller)(unsigned char *); + for( i = 0 ; i < functionList.index ; i++ ){ + if( _packet->command == functionList.list[i].command ){ + Caller = (void (*)(unsigned char *))functionList.list[i].function; + Caller( (unsigned char *)_packet->packetData ); + return 1; + } + } + return 0; +} + +void RS495_Init( void ){ + +} + +static void SendAck( void ){ + #ifdef DEBUG + pc.printf( "\n\rAck Sent.\n\r" ); + #endif // DEBUG + unsigned char ack = ACKCHAR; + Bluetooth_SendChar( ack ); +} + +static void SendNack( void ){ + #ifdef DEBUG + pc.printf( "\n\rNack Sent.\n\r" ); + #endif // DEBUG + unsigned char nack = NAKCHAR; + Bluetooth_SendChar( nack ); +} + +static int ProcessPacket( Packet *_packet ){ + return Bluetooth_ReceivePacket( _packet ); +} + +void SendMessage( void ){ + int j = 0; + Bluetooth_SendChar( packetBuffer[ j++ ] ); + while( j < packetBufferSize ){ + if( packetBuffer[ j ] == STARTPACK ){ + Bluetooth_SendChar( ESCAPE ); // #SCD Added this line, I think it should be here + Bluetooth_SendChar( 0x01 ); + j++; + } + else if( packetBuffer[ j ] == ESCAPE ){ + Bluetooth_SendChar( ESCAPE ); + Bluetooth_SendChar( ESCAPE ); + j++; + } + else if( packetBuffer[ j ] == STARTPOLL ){ + Bluetooth_SendChar( ESCAPE ); + Bluetooth_SendChar( 0x02 ); + j++; + } + else{ + Bluetooth_SendChar( packetBuffer[ j++ ] ); + } + } +} + +/****************************************************************************** + * Function void setResponse(int, int, int) + * + * This function sets the feedback information to be send in the master device. + * + * PreCondition: None + * + * Input: '_packet' - prebuilt packet to send + * + * Output: None + * + * Side Effects: None + * + *****************************************************************************/ + void SetResponse( Packet *_packet ){ + packetBufferSize = getFormattedPacket(&_packet, packetBuffer); + message = 1; +} + +/****************************************************************************** + * Function void SerialHandler(unsigned char ) + * + * This function handles the received data from the Serial Communication. + * + * PreCondition: None + * + * Input: 'RXByte' - the received data from Serial Communication + * + * + * Output: None + * + * Side Effects: None + * + *****************************************************************************/ +void SerialHandler(unsigned char RXByte){ + + #ifdef DEBUG + pc.printf( "RXByte: %x" , RXByte ); + #endif + + + // check the incoming byte for special characters + if( RXByte == STARTPACK ){ // start of packet byte + #ifdef DEBUG + pc.printf( " - STARTBYTE\n\r" ); + #endif + pState = DEVICEADDRESS; // move on to check the destination address + buffPtr = 0; // reset buffer pointer + buffer[buffPtr++] = STARTPACK; // load RXByte into buffer + checksum = STARTPACK; // add to checksum + return; // exit function, will be called again in next state + } + else if( RXByte == STARTPOLL ){ // poll byte + #ifdef DEBUG + pc.printf( " - STARTPOLL\n\r" ); + #endif + pState = POLL; // move on to check the distination address + return; // exit function, will be called again in next state + } + else if( RXByte == ESCAPE ){ // escape byte + if( pState == HANDLEESCAPE ){ // if this is the second escape byte in a row + } + else{ + #ifdef DEBUG + pc.printf( " - ESCAPE TO " ); + #endif + returnState = pState; // if this is the first escape byte, record the current state + pState = HANDLEESCAPE; // change state + return; // exit function, will be called again in next state + } + } + + if( pState == HANDLEESCAPE ){ // if entering here RXByte needs to be unescaped + switch( RXByte ){ + case 1: // unescape a 0x7F/Start of packet byte + RXByte = 0x7F; + #ifdef DEBUG + pc.printf( " -> %x" , RXByte ); + #endif + break; + + case 2: // unescape a 0x8F/Poll byte + RXByte = 0x8F; + #ifdef DEBUG + pc.printf( " -> %x" , RXByte ); + #endif + break; + + case ESCAPE: // unescape a 0x8E/Escape byte + RXByte = 0x8E; + #ifdef DEBUG + pc.printf( " -> %x" , RXByte ); + #endif + break; + } + pState = returnState; // change back to state before escape byte received + } + + switch( pState ){ + + case POLL: // of switch( pState ) // poll state checks RXByte to see if there is an address match + + + if( RXByte == DEVADDRESS ){ // if the device is being polled... + #ifdef DEBUG + pc.printf( " - Address Match: %x" , DEVADDRESS ); + #endif + + if( message ){ // if a message is available send it + #ifdef DEBUG + pc.printf( " - Message to Send\n\r" ); + #endif + SendMessage(); // #SCD haven't tested this + pState = RESPONSE; // change state to wait for ACK or NACK + } + else{ // device is pulled but no message to be sent + #ifdef DEBUG + pc.printf( " - No message to Send\n\r" ); + #endif + SendAck(); // just send an ACK + pState = START; + } + } + else{ + pState = START; // device not addressed, do nothing + } + break; + + case START: // of switch( pState ) // this state really does nothing and just waits for + pState = START; // if the device is not addressed in a packet + break; + + case RESPONSE: // of switch( pState ) // a message was sent it last state and now this state is + + switch( RXByte ){ + + case ACKCHAR: // ACK is received - message successful, clear message to be sent + #ifdef DEBUG + pc.printf( " - ACK RECEIVED\n\r" ); + #endif + message = 0; + pState = START; + break; + + case NAKCHAR: // NACK is received - message not successful + #ifdef DEBUG + pc.printf( " - NACK RECEIVED\n\r" ); + #endif + if( message ){ // if a message still needs to be sent, send again + SendMessage(); + message = 0; // clear message after this seconda attempt to prevent too many tries + pState = RESPONSE; // set state to come by here next time around + } + else{ // if a NACK is received for the second time in a row + //#error #SCD // throw an error and do not resend + pc.printf( "Received two NACKs from master. Message failed.\n\r" ); + } + break; + + default: + #ifdef DEBUG + pc.printf( " - EXPECTED ACK or NACK\n\r" ); + #endif + pState = START; // if neither an ACK nor NACK is received, reset state + break; + + } + break; + + case DEVICEADDRESS: // of switch( pState ) // checks to see if device is addressed in current packet + #ifdef DEBUG + pc.printf( " - DEVICEADDRESS\n\r" ); + #endif + + if( RXByte == DEVADDRESS ){ + #ifdef PRINT_ADDRESS_MATCH + pc.printf( "Address Match: %d\n\r" , DEVADDRESS ); + #endif + + pState = SOURCEADD; // next state is grabbing the source device ID + buffer[buffPtr++] = RXByte; // add RXByte to buffer + buildPacket.deviceID = RXByte; // build packet + checksum += RXByte; // add RXByte to checksum + } + else{ + pState = START; // if device is not addressed reset state + } + + break; + + case SOURCEADD: // of switch( pState ) // records the source address of the packet + #ifdef DEBUG + pc.printf( " - SOURCEADD\n\r" ); + #endif + + pState = COLLECTCOMMAND; // state advances to get the command byte + buffer[buffPtr++] = RXByte; // add RXByte to buffer + buildPacket.sourceID = RXByte; // build packet + checksum += RXByte; // add RXByte to checksum + break; + + case COLLECTCOMMAND: // of switch( pState )// records the command byte of the packet + #ifdef DEBUG + pc.printf( " - COMMAND\n\r" ); + #endif + + command = RXByte; // record command byte + buildPacket.command = RXByte; // build packet + pState = COLLECTCOUNT1; // advance to get packetLength + buffer[buffPtr++] = RXByte; // add RXByte to buffer + checksum += RXByte; // add RXByte to checksum + break; + + case COLLECTCOUNT1: // of switch( pState ) // records first byte of packetLength + #ifdef DEBUG + pc.printf( " - COUNT MSB \n\r" ); + #endif + + pState = COLLECTCOUNT2; // advance state to get next byte of packetLength + plength = RXByte; + plength <<= 8; // store byte in packetLength #SCD is this storing correctly? + buffer[buffPtr++] = RXByte; // add RXByte to buffer + checksum += RXByte; // add RXByte to checksum + break; + + case COLLECTCOUNT2: // of switch( pState ) // records second byte of packetLength + #ifdef DEBUG + pc.printf( " - COUNT LSB\n\r" ); + #endif + + plength += RXByte; // add RXByte to packetLength total + buildPacket.packetLength = plength; // build packet + buffer[buffPtr++] = RXByte; // add RXByte to buffer + checksum += RXByte; // add RXByte to checksum + if( plength == 0 ) // if packetLength is 0, advance to checksum state + pState = COLLECTCHECKSUM; + else // otherwise move on to collect packet payload + pState = COLLECTPACKET; + break; + + case COLLECTPACKET: // of switch( pState ) // collects packetData, enters this state multiple times + #ifdef DEBUG + pc.printf( " - PACKETDATA \n\r" ); + #endif + + plength--; // decrement length + buffer[buffPtr++] = RXByte; // add RXByte to buffer + checksum += RXByte; // add RXByte to checksum + + if( plength == 0 ){ // if collected all packetData advance state + pState = COLLECTCHECKSUM; + } + break; + + case COLLECTCHECKSUM:// of switch( pState ) // collects checksum of packet and checks for validity + #ifdef DEBUG + pc.printf( " - CHECKSUM\n\r" ); + #endif + memcpy( &buildPacket.packetData , &buffer[6] , buildPacket.packetLength ); + + if( RXByte == ( ( checksum* - 1 ) & 0xFF ) ){ // compares RXByte with LSB of checksum + message = 0; // if checksum is correct clear message #SCD could a message be waiting? + memset(packetBuffer, '\0', 128); // clear packetBuffer + + buffer[buffPtr++] = RXByte; // add RXByte to buffer + + #ifdef PRINTPACKETDEBUG + pc.printf( "Receive Buffer: " ); // debug print received packet + unsigned int i = 0; + for( i = 0 ; i < buffPtr ; i++ ){ + pc.printf( "%x " , buffer[ i ] ); + } + pc.printf( "\n\r" ); + #endif + + int errorResult = ProcessPacket( &buildPacket ); + + if( errorResult == -1 ){ // check to make sure function performed properly + //#SCD setResponse(RPIADDRESS, command, ERRORCOMMAND); + } + SendAck(); // send an ACK + } + else{ + SendNack(); // if checksum is not corret, send a NACK + } + + pState = START; + break; + + } // end switch( pState ) + +} // end serial2Handler function + + + +#ifdef __cplusplus +} +#endif