diff options
author | Josh Blum <josh@joshknows.com> | 2010-07-08 19:51:59 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2010-07-08 19:51:59 -0700 |
commit | 8867df0d7e0948c2091aff1a5c4adbcdd083fe4a (patch) | |
tree | 43dde1f9fe8fa68a2b5dd0c2dae363d7c29f0da0 | |
parent | da9d47011e02f2b18fccda00dbea0b9d9c0dc704 (diff) | |
download | uhd-8867df0d7e0948c2091aff1a5c4adbcdd083fe4a.tar.gz uhd-8867df0d7e0948c2091aff1a5c4adbcdd083fe4a.tar.bz2 uhd-8867df0d7e0948c2091aff1a5c4adbcdd083fe4a.zip |
uhd: added packet type to vrt if info struct, added burst flags to rx metadata, fixed vrt if packet parsing bugs
-rw-r--r-- | host/include/uhd/transport/vrt_if_packet.hpp | 7 | ||||
-rw-r--r-- | host/include/uhd/types/metadata.hpp | 5 | ||||
-rwxr-xr-x | host/lib/transport/gen_vrt_if_packet.py | 48 | ||||
-rw-r--r-- | host/lib/transport/vrt_packet_handler.hpp | 25 | ||||
-rw-r--r-- | host/lib/types.cpp | 4 |
5 files changed, 52 insertions, 37 deletions
diff --git a/host/include/uhd/transport/vrt_if_packet.hpp b/host/include/uhd/transport/vrt_if_packet.hpp index ccefe14ea..51bd81bb1 100644 --- a/host/include/uhd/transport/vrt_if_packet.hpp +++ b/host/include/uhd/transport/vrt_if_packet.hpp @@ -35,6 +35,13 @@ namespace vrt{ * the operation used (ie the pack or unpack function call). */ struct UHD_API if_packet_info_t{ + //packet type (pack only supports data) + enum packet_type_t { + PACKET_TYPE_DATA = 0x0, + PACKET_TYPE_EXTENSION = 0x1, + PACKET_TYPE_CONTEXT = 0x2 + } packet_type; + //size fields size_t num_payload_words32; //required in pack, derived in unpack size_t num_header_words32; //derived in pack, derived in unpack diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp index f4c962ff7..6712e2594 100644 --- a/host/include/uhd/types/metadata.hpp +++ b/host/include/uhd/types/metadata.hpp @@ -52,10 +52,9 @@ namespace uhd{ * Burst flags: * Start of burst will be true for the first packet in the chain. * End of burst will be true for the last packet in the chain. - * --Not currently used in any known device implementation.-- */ - //bool start_of_burst; - //bool end_of_burst; + bool start_of_burst; + bool end_of_burst; /*! * Error conditions (TODO): diff --git a/host/lib/transport/gen_vrt_if_packet.py b/host/lib/transport/gen_vrt_if_packet.py index 9b5bfca02..07ce391ee 100755 --- a/host/lib/transport/gen_vrt_if_packet.py +++ b/host/lib/transport/gen_vrt_if_packet.py @@ -61,13 +61,6 @@ using namespace uhd::transport; #set $tsf_p = 0b01000 #set $tlr_p = 0b10000 -static UHD_INLINE void pack_uint64_$(suffix)(boost::uint64_t num, boost::uint32_t *mem){ - //*(reinterpret_cast<boost::uint64_t *>(mem)) = $(XE_MACRO)(num); - //second word is lower 32 bits due to fpga implementation - mem[1] = $(XE_MACRO)(boost::uint32_t(num >> 0)); - mem[0] = $(XE_MACRO)(boost::uint32_t(num >> 32)); -} - void vrt::if_hdr_pack_$(suffix)( boost::uint32_t *packet_buff, if_packet_info_t &if_packet_info @@ -94,8 +87,10 @@ void vrt::if_hdr_pack_$(suffix)( #end if ########## Class ID ########## #if $pred & $cid_p - pack_uint64_$(suffix)(if_packet_info.cid, packet_buff+$num_header_words); - #set $num_header_words += 2 + packet_buff[$num_header_words] = 0; //not implemented + #set $num_header_words += 1 + packet_buff[$num_header_words] = 0; //not implemented + #set $num_header_words += 1 #set $flags |= (0x1 << 27); #end if ########## Integer Time ########## @@ -106,8 +101,10 @@ void vrt::if_hdr_pack_$(suffix)( #end if ########## Fractional Time ########## #if $pred & $tsf_p - pack_uint64_$(suffix)(if_packet_info.tsf, packet_buff+$num_header_words); - #set $num_header_words += 2 + packet_buff[$num_header_words] = $(XE_MACRO)(boost::uint32_t(if_packet_info.tsf >> 32)); + #set $num_header_words += 1 + packet_buff[$num_header_words] = $(XE_MACRO)(boost::uint32_t(if_packet_info.tsf >> 0)); + #set $num_header_words += 1 #set $flags |= (0x1 << 20); #end if ########## Trailer ########## @@ -116,7 +113,6 @@ void vrt::if_hdr_pack_$(suffix)( #set $flags |= (0x1 << 26); #set $num_trailer_words = 1; #else - //packet_buff[$num_header_words+if_packet_info.num_payload_words32] = 0; #set $num_trailer_words = 0; #end if ########## Variables ########## @@ -139,13 +135,6 @@ void vrt::if_hdr_pack_$(suffix)( )); } -static UHD_INLINE void unpack_uint64_$(suffix)(boost::uint64_t &num, const boost::uint32_t *mem){ - //num = $(XE_MACRO)(*reinterpret_cast<const boost::uint64_t *>(mem)); - //second word is lower 32 bits due to fpga implementation - num = boost::uint64_t($(XE_MACRO)(mem[1])) << 0; - num |= boost::uint64_t($(XE_MACRO)(mem[0])) << 32; -} - void vrt::if_hdr_unpack_$(suffix)( const boost::uint32_t *packet_buff, if_packet_info_t &if_packet_info @@ -153,13 +142,16 @@ void vrt::if_hdr_unpack_$(suffix)( //extract vrt header boost::uint32_t vrt_hdr_word = $(XE_MACRO)(packet_buff[0]); size_t packet_words32 = vrt_hdr_word & 0xffff; - if_packet_info.packet_count = (vrt_hdr_word >> 16) & 0xf; - //failure cases + //failure case if (if_packet_info.num_packet_words32 < packet_words32) throw std::runtime_error("bad vrt header or packet fragment"); - if (vrt_hdr_word & (0x7 << 29)) - throw std::runtime_error("bad vrt header or unsupported packet type"); + + //extract fields from the header + if_packet_info.packet_type = if_packet_info_t::packet_type_t(vrt_hdr_word >> 29); + if_packet_info.packet_count = (vrt_hdr_word >> 16) & 0xf; + if_packet_info.sob = bool(vrt_hdr_word & $hex(0x1 << 25)); + if_packet_info.eob = bool(vrt_hdr_word & $hex(0x1 << 24)); boost::uint8_t pred = 0; if(vrt_hdr_word & $hex(0x1 << 28)) pred |= $hex($sid_p); @@ -184,7 +176,7 @@ void vrt::if_hdr_unpack_$(suffix)( ########## Class ID ########## #if $pred & $cid_p if_packet_info.has_cid = true; - unpack_uint64_$(suffix)(if_packet_info.cid, packet_buff+$num_header_words); + if_packet_info.cid = 0; //not implemented #set $num_header_words += 2 #else if_packet_info.has_cid = false; @@ -200,15 +192,17 @@ void vrt::if_hdr_unpack_$(suffix)( ########## Fractional Time ########## #if $pred & $tsf_p if_packet_info.has_tsf = true; - unpack_uint64_$(suffix)(if_packet_info.tsf, packet_buff+$num_header_words); - #set $num_header_words += 2 + if_packet_info.tsf = boost::uint64_t($(XE_MACRO)(packet_buff[$num_header_words])) << 32; + #set $num_header_words += 1 + if_packet_info.tsf |= boost::uint64_t($(XE_MACRO)(packet_buff[$num_header_words])) << 0; + #set $num_header_words += 1 #else if_packet_info.has_tsf = false; #end if ########## Trailer ########## #if $pred & $tlr_p if_packet_info.has_tlr = true; - if_packet_info.tlr = $(XE_MACRO)(packet_buff[$num_header_words+packet_words32]); + if_packet_info.tlr = $(XE_MACRO)(packet_buff[packet_words32-1]); #set $num_trailer_words = 1; #else if_packet_info.has_tlr = false; diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp index 68edeb1e1..f06fe94c0 100644 --- a/host/lib/transport/vrt_packet_handler.hpp +++ b/host/lib/transport/vrt_packet_handler.hpp @@ -77,15 +77,18 @@ namespace vrt_packet_handler{ vrt_unpacker_type vrt_unpacker, size_t vrt_header_offset_words32 ){ - size_t num_packet_words32 = state.managed_buffs[0]->size()/sizeof(boost::uint32_t); - if (num_packet_words32 <= vrt_header_offset_words32){ - state.size_of_copy_buffs = 0; - return; //must exit here after setting the buffer - } - //vrt unpack each managed buffer uhd::transport::vrt::if_packet_info_t if_packet_info; for (size_t i = 0; i < state.width; i++){ + + //extract packet words and check thats its enough to move on + size_t num_packet_words32 = state.managed_buffs[i]->size()/sizeof(boost::uint32_t); + if (num_packet_words32 <= vrt_header_offset_words32){ + state.size_of_copy_buffs = 0; + return; //must exit here after setting the buffer + } + + //unpack the vrt header into the info struct const boost::uint32_t *vrt_hdr = state.managed_buffs[i]->cast<const boost::uint32_t *>() + vrt_header_offset_words32; if_packet_info.num_packet_words32 = num_packet_words32 - vrt_header_offset_words32; vrt_unpacker(vrt_hdr, if_packet_info); @@ -96,6 +99,13 @@ namespace vrt_packet_handler{ } state.next_packet_seq[i] = (if_packet_info.packet_count+1)%16; + //make sure that its a data packet (TODO handle non-data packets) + if (if_packet_info.packet_type != uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA){ + std::cout << "vrt packet handler _recv1_helper got non data packet" << std::endl; + state.size_of_copy_buffs = 0; + return; //must exit here after setting the buffer + } + //setup the buffer to point to the data state.copy_buffs[i] = reinterpret_cast<const boost::uint8_t *>(vrt_hdr + if_packet_info.num_header_words32); @@ -111,6 +121,9 @@ namespace vrt_packet_handler{ metadata.time_spec = uhd::time_spec_t( time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), tick_rate ); + metadata.start_of_burst = if_packet_info.sob; + static const int tlr_eob_flags = (1 << 20) | (1 << 8); //enable and indicator bits + metadata.end_of_burst = if_packet_info.has_tlr and (int(if_packet_info.tlr & tlr_eob_flags) == tlr_eob_flags); } /******************************************************************* diff --git a/host/lib/types.cpp b/host/lib/types.cpp index 9cf2a2220..1e7917ad7 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -99,7 +99,9 @@ rx_metadata_t::rx_metadata_t(void): has_time_spec(false), time_spec(time_spec_t()), more_fragments(false), - fragment_offset(0) + fragment_offset(0), + start_of_burst(false), + end_of_burst(false) { /* NOP */ } |