161 lines
5.6 KiB
C++
161 lines
5.6 KiB
C++
/*
|
||
* HiperfaceNetworkDriver.cpp
|
||
*
|
||
* Created on: 4 февр. 2020 г.
|
||
* Author: user
|
||
*/
|
||
|
||
#include "HiperfaceNetworkDriver.hh"
|
||
|
||
void driver::HiperfaceNetworkDriver::process() {
|
||
|
||
switch( state ) {
|
||
case not_processing: {
|
||
if( process_message and message.pack_message(process_message) ) {
|
||
connection.reset();
|
||
flow_control.on();
|
||
if( connection.send(data_buff.getDataToRead(), Message::getSendMessageLen(process_message)) ) {
|
||
state = waiting_transfer_completion;
|
||
timer.start( data_send_timeout_ms );
|
||
} else {
|
||
flow_control.off();
|
||
setResult(process_message, driver::transmition_error);
|
||
process_message = nullptr;
|
||
}
|
||
}
|
||
} break;
|
||
case waiting_transfer_completion: {
|
||
if( connection.isDataSent() ) {
|
||
timer.start( getMessageTimeout(baudrate, process_message) );
|
||
flow_control.off();
|
||
state = waiting_timeout;
|
||
} else if( timer.delayFinished() ) {
|
||
flow_control.off();
|
||
connection.reset();
|
||
setResult(process_message, driver::send_timeout_error);
|
||
process_message = nullptr;
|
||
state = not_processing;
|
||
}
|
||
} break;
|
||
case waiting_timeout: {
|
||
char * rec = data_buff.getBuff( Message::getRecMessageLen(process_message) );
|
||
if( rec and connection.receive(rec, data_buff.size()) ) {
|
||
warning = Header(message).error_bit;
|
||
setResult(process_message, message.unpack_message( process_message ));
|
||
timer.start(getAfterMessageTimeout(baudrate) );
|
||
state = waiting_after_response;
|
||
} else if( timer.delayFinished() ) {
|
||
if( connection_error = connection.isRecieptionError() ) {
|
||
connection.reset();
|
||
setResult(process_message, driver::connection_error);
|
||
process_message = nullptr;
|
||
state = not_processing;
|
||
} else {
|
||
const unsigned short error_message_len = 4;
|
||
char * rec = data_buff.getBuff( error_message_len );
|
||
if( rec and connection.receive(rec, data_buff.size()) ) {
|
||
message.unpack_message( &status_request.message_control );
|
||
setResult(process_message, driver::hip_error);
|
||
process_message = nullptr;
|
||
state = not_processing;
|
||
} else
|
||
state = read_error_code;
|
||
}
|
||
}
|
||
} break;
|
||
case read_error_code: {
|
||
const unsigned short error_message_len = 4;
|
||
char * rec = data_buff.getBuff( error_message_len );
|
||
if( rec and connection.receive(rec, data_buff.size()) ) {
|
||
message.unpack_message( &status_request.message_control );
|
||
setResult(process_message, driver::hip_error);
|
||
} else
|
||
setResult(process_message, driver::timeout_error);
|
||
|
||
process_message = nullptr;
|
||
state = not_processing;
|
||
} break;
|
||
case waiting_after_response: {
|
||
if( timer.delayFinished() ) {
|
||
process_message = nullptr;
|
||
state = not_processing;
|
||
}
|
||
} break;
|
||
}
|
||
|
||
}
|
||
|
||
driver::HiperfaceNetworkDriver::HiperfaceNetworkDriver(
|
||
driver::IDiscreteOutput & flow_control,
|
||
peripheral::IUartPort & connection )
|
||
: flow_control(flow_control), connection(connection), message(data_buff.getBuff(0), data_buff.capacity()) {}
|
||
|
||
bool driver::HiperfaceNetworkDriver::send( MessageControl * message ) {
|
||
|
||
if( Message::getRecMessageLen( message ) > data_buff.capacity()
|
||
or Message::getSendMessageLen( message ) > data_buff.capacity() )
|
||
return false;
|
||
|
||
if( not process_message and ( process_message = message ) )
|
||
return status_request.message_control.address = process_message->address, process_message->ans_ready_flag = false, true; else return false;
|
||
|
||
}
|
||
|
||
void driver::HiperfaceNetworkDriver::reset() {
|
||
|
||
baudrate = default_baudrate;
|
||
process_message = nullptr;
|
||
state = not_processing;
|
||
connection_error = false;
|
||
warning = false;
|
||
connection.reset();
|
||
|
||
}
|
||
|
||
void driver::HiperfaceNetworkDriver::setResult(
|
||
MessageControl* process_message, const HipResult result ) {
|
||
|
||
process_message->result = result;
|
||
process_message->ans_ready_flag = true;
|
||
|
||
error_code = result;
|
||
|
||
}
|
||
|
||
unsigned long driver::HiperfaceNetworkDriver::getAfterMessageTimeout(
|
||
BaudRate baudrate ) {
|
||
|
||
static unsigned long timeout_ms[] = {
|
||
[HiperfaceNetworkDriver::br600] = 96,
|
||
[HiperfaceNetworkDriver::br1200] = 48,
|
||
[HiperfaceNetworkDriver::br2400] = 24,
|
||
[HiperfaceNetworkDriver::br4800] = 12,
|
||
[HiperfaceNetworkDriver::br9600] = 6,
|
||
[HiperfaceNetworkDriver::br19200] = 3,
|
||
[HiperfaceNetworkDriver::br38400] = 2
|
||
};
|
||
|
||
return timeout_ms[baudrate];
|
||
|
||
}
|
||
|
||
unsigned long driver::HiperfaceNetworkDriver::getMessageTimeout(
|
||
BaudRate baudrate, const MessageControl* message_control ) {
|
||
|
||
//передача одного байта (11 бит согласно формату передачи)
|
||
static unsigned long frame_times_us[] = {
|
||
[HiperfaceNetworkDriver::br600] = 18400,
|
||
[HiperfaceNetworkDriver::br1200] = 9200,
|
||
[HiperfaceNetworkDriver::br2400] = 4600,
|
||
[HiperfaceNetworkDriver::br4800] = 2300,
|
||
[HiperfaceNetworkDriver::br9600] = 1200,
|
||
[HiperfaceNetworkDriver::br19200] = 600,
|
||
[HiperfaceNetworkDriver::br38400] = 300
|
||
};
|
||
|
||
return 0.001f * ( frame_times_us[baudrate] * ( Message::getSendMessageLen(message_control) + Message::getRecMessageLen(message_control) ) )
|
||
+ message_control->timeout_ms + getAfterMessageTimeout(baudrate);
|
||
|
||
}
|
||
|