Library set up as dummy module on mbed to mimic Nordic.
rs485.cpp
- Committer:
- Stephen_NewVistas
- Date:
- 2016-12-12
- Revision:
- 1:d6b18299a715
- Parent:
- 0:226550611f0d
- Child:
- 2:9ab591cf81b8
File content as of revision 1:d6b18299a715:
#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