173 lines
6.6 KiB
C++
173 lines
6.6 KiB
C++
/*
|
||
* BiSSCAdapterLogic.cpp
|
||
*
|
||
* Created on: 6 сент. 2021 г.
|
||
* Author: sozonov
|
||
*/
|
||
#include <cstring>
|
||
#include <cmath>
|
||
#include "BiSSCAdaperLogic.hh"
|
||
|
||
driver::BiSSCAdapterLogic::BiSSCAdapterLogic(peripheral::ISerialPort * _isp_source, uint16_t _ACK_bits , uint16_t _line_delay, uint16_t _inv ) : isp_source ( _isp_source ),
|
||
master_bits_count( 48 ), line_delay( _line_delay ), ACK_bits( _ACK_bits ),
|
||
start_bits( 1 ), cbs_bits ( 1 ), two_bits_wait( 2 ), fE( 0 ),
|
||
tech_bits_size ( line_delay + two_bits_wait + ACK_bits + start_bits + cbs_bits ),
|
||
size_of_array( 0 ), num_of_cpy_byte( 0 ), f_inversion( _inv ) {}
|
||
|
||
|
||
driver::BiSSCAdapterLogic::BiSSCAdapterLogic(peripheral::ISerialPort * _isp_source, uint16_t _ACK_bits, uint16_t _line_delay, uint16_t _master_bit_count, uint16_t _two_bits_wait,
|
||
uint16_t _start_bits, uint16_t _cbs_bits ): isp_source ( _isp_source ),
|
||
line_delay ( _line_delay ),
|
||
ACK_bits ( _ACK_bits ),
|
||
master_bits_count ( _master_bit_count ),
|
||
start_bits ( _start_bits ),
|
||
cbs_bits ( _cbs_bits ),
|
||
two_bits_wait ( _two_bits_wait ),
|
||
fE ( 0 ),
|
||
tech_bits_size ( line_delay + two_bits_wait + ACK_bits + start_bits + cbs_bits ),
|
||
size_of_array ( 0 ),
|
||
num_of_cpy_byte ( 0 ),
|
||
f_inversion( 0 ){ }
|
||
|
||
|
||
bool driver::BiSSCAdapterLogic::transmite( const void * bit_stream, int bit_count ) {
|
||
|
||
master_bits_count = bit_count;
|
||
|
||
return isp_source->transmite( bit_stream, master_bits_count + tech_bits_size + ( 16 - ( ( master_bits_count + tech_bits_size ) %16 ) ) );
|
||
|
||
}
|
||
|
||
bool driver::BiSSCAdapterLogic::receive( void * data ) {
|
||
|
||
size_of_array = ( ( master_bits_count + tech_bits_size + ( ( master_bits_count + tech_bits_size ) % 16u ) ) / 16u ) ;
|
||
|
||
isp_source->receive( buf_data_array );
|
||
|
||
fE = parceMessage( buf_data_array );
|
||
|
||
if (!fE) {
|
||
std::memcpy( data, buf_data_array, size_of_array );
|
||
}
|
||
|
||
return !fE;
|
||
|
||
}
|
||
|
||
bool driver::BiSSCAdapterLogic::isDataReady() {
|
||
|
||
return isp_source->isDataReady();
|
||
|
||
}
|
||
|
||
bool driver::BiSSCAdapterLogic::parceMessage( uint16_t *data ) {
|
||
|
||
bool tmp_fE = 0; //<!Флаг ошибки входящего фрейма.
|
||
bool tmp_fE_tbw = 0; //<!Флаг, признак ошибки в части фрейма двух бит ожидания.
|
||
bool tmp_fE_ack = 0; //<!Флаг, признак ошибки в части фрейма нулевых бит ожидания.
|
||
bool tmp_fE_sb = 0; //<!Флаг, признак ошибки стартового бита.
|
||
bool tmp_fE_cbs = 0; //<!Флаг, признак ошибки ответа от слейва.
|
||
size_of_array = ( ( master_bits_count + tech_bits_size + ( ( master_bits_count + tech_bits_size ) % 16u ) ) / 16u ) ;
|
||
|
||
|
||
uint16_t bits_counter = line_delay; //<! Счетчик прохода по фрейму сообщения. Фрейм начинается после компенсированых битов.
|
||
uint16_t part_of_frame = 0; //<! Счётчик, отвечающий за то, в какой части фрейма находится проверка.
|
||
|
||
//todo: алгоритм необходимо проверять на реальных данных, что бы правильно учесть упаковку посылок в массив и по номерам бит!
|
||
//Проверка правильности фрейма данных.
|
||
//Проверка двух стартовых бит.
|
||
part_of_frame = two_bits_wait;
|
||
while ( part_of_frame ) {
|
||
|
||
uint16_t data_part = f_inversion ? data[static_cast<uint16_t>( bits_counter / 16 )] : ~data[static_cast<uint16_t>( bits_counter / 16 )];
|
||
|
||
if ( !( ( data_part >> static_cast<uint16_t>( 15 - bits_counter % 16 ) ) & 0x1 ) ) {
|
||
|
||
tmp_fE_tbw = 1;
|
||
|
||
}
|
||
|
||
part_of_frame--;
|
||
bits_counter++;
|
||
|
||
}
|
||
|
||
//Проверка количества "нулевых" бит ожидания.
|
||
part_of_frame = ACK_bits;
|
||
while ( part_of_frame ) {
|
||
|
||
uint16_t data_part = f_inversion ? data[static_cast<uint16_t>( bits_counter / 16 )] : ~data[static_cast<uint16_t>( bits_counter / 16 )];
|
||
|
||
if ( ( data_part >> static_cast<uint16_t>( 15 - bits_counter % 16 ) ) & 0x1 ) {
|
||
|
||
tmp_fE_ack = 1;
|
||
|
||
}
|
||
|
||
part_of_frame--;
|
||
bits_counter++;
|
||
|
||
}
|
||
|
||
//Проверка стартового бита.
|
||
part_of_frame = start_bits;
|
||
while ( part_of_frame ) {
|
||
|
||
uint16_t data_part = f_inversion ? data[static_cast<uint16_t>( bits_counter / 16 )] : ~data[static_cast<uint16_t>( bits_counter / 16 )];
|
||
|
||
if ( !( ( data_part >> static_cast<uint16_t>( 15 - bits_counter % 16 ) ) & 0x1 ) ) {
|
||
|
||
tmp_fE_sb = 1;
|
||
|
||
}
|
||
|
||
part_of_frame--;
|
||
bits_counter++;
|
||
|
||
}
|
||
|
||
//Проверка бита ответа от слейва.
|
||
part_of_frame = cbs_bits;
|
||
while ( part_of_frame ) {
|
||
|
||
uint16_t data_part = f_inversion ? data[static_cast<uint16_t>( bits_counter / 16 )] : ~data[static_cast<uint16_t>( bits_counter / 16 )];
|
||
|
||
if ( ( data_part >> static_cast<uint16_t>( 15 - bits_counter % 16 ) ) & 0x1 ) {
|
||
|
||
tmp_fE_cbs = 1;
|
||
|
||
}
|
||
|
||
part_of_frame--;
|
||
bits_counter++;
|
||
|
||
}
|
||
|
||
tmp_fE = tmp_fE_tbw || tmp_fE_ack || tmp_fE_sb;
|
||
|
||
uint16_t tmp_data_array[32] = {};
|
||
|
||
if ( !tmp_fE ) {
|
||
|
||
uint16_t size_tmp_array = ( ( master_bits_count + ( ( master_bits_count ) % 16u ) ) / 16u );
|
||
|
||
uint16_t word_offset = bits_counter / 16;
|
||
uint16_t bit_offset = bits_counter % 16;
|
||
|
||
for( int i = 0; i < size_tmp_array ; i++ ) {
|
||
uint16_t data_first_word = f_inversion ? data[ i + word_offset ] : ~data[ i + word_offset ] ;
|
||
uint16_t data_second_word = f_inversion ? data[ i + word_offset + 1 ] : ~data[ i + word_offset + 1 ] ;
|
||
|
||
tmp_data_array[i] = data_first_word << bit_offset;
|
||
tmp_data_array[i] |= data_second_word >> (16u - bit_offset) ;
|
||
|
||
}
|
||
|
||
std::memcpy( data, tmp_data_array, size_of_array );
|
||
}
|
||
|
||
return tmp_fE;
|
||
}
|
||
|
||
|