/* * 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); }