2013-07-19 21:08:22 +00:00
|
|
|
//
|
|
|
|
|
// Copyright 2013 Ettus Research LLC
|
2018-02-19 23:30:32 +00:00
|
|
|
// Copyright 2018 Ettus Research, a National Instruments Company
|
2013-07-19 21:08:22 +00:00
|
|
|
//
|
2018-02-19 23:30:32 +00:00
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
2013-07-19 21:08:22 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#include "b200_uart.hpp"
|
2016-08-15 18:18:37 +00:00
|
|
|
#include "b200_impl.hpp"
|
2020-03-02 23:25:13 +00:00
|
|
|
#include <uhd/exception.hpp>
|
2013-07-19 21:08:22 +00:00
|
|
|
#include <uhd/transport/bounded_buffer.hpp>
|
|
|
|
|
#include <uhd/transport/vrt_if_packet.hpp>
|
2020-03-02 23:25:13 +00:00
|
|
|
#include <uhd/types/time_spec.hpp>
|
2013-07-19 21:08:22 +00:00
|
|
|
#include <uhd/utils/byteswap.hpp>
|
2017-02-08 00:37:25 +00:00
|
|
|
#include <uhd/utils/log.hpp>
|
2013-07-19 21:08:22 +00:00
|
|
|
|
|
|
|
|
using namespace uhd;
|
|
|
|
|
using namespace uhd::transport;
|
|
|
|
|
|
|
|
|
|
struct b200_uart_impl : b200_uart
|
|
|
|
|
{
|
2020-03-02 23:25:13 +00:00
|
|
|
b200_uart_impl(zero_copy_if::sptr xport, const uint32_t sid)
|
|
|
|
|
: _xport(xport)
|
|
|
|
|
, _sid(sid)
|
|
|
|
|
, _count(0)
|
|
|
|
|
, _baud_div(std::floor(B200_BUS_CLOCK_RATE / 115200 + 0.5))
|
|
|
|
|
, _line_queue(4096)
|
2013-07-19 21:08:22 +00:00
|
|
|
{
|
2016-08-15 18:18:37 +00:00
|
|
|
/*NOP*/
|
2013-07-19 21:08:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void send_char(const char ch)
|
|
|
|
|
{
|
|
|
|
|
managed_send_buffer::sptr buff = _xport->get_send_buff();
|
|
|
|
|
UHD_ASSERT_THROW(bool(buff));
|
|
|
|
|
|
|
|
|
|
vrt::if_packet_info_t packet_info;
|
2020-03-02 23:25:13 +00:00
|
|
|
packet_info.link_type = vrt::if_packet_info_t::LINK_TYPE_CHDR;
|
|
|
|
|
packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CONTEXT;
|
2013-07-19 21:08:22 +00:00
|
|
|
packet_info.num_payload_words32 = 2;
|
2020-03-02 23:25:13 +00:00
|
|
|
packet_info.num_payload_bytes =
|
|
|
|
|
packet_info.num_payload_words32 * sizeof(uint32_t);
|
2013-07-19 21:08:22 +00:00
|
|
|
packet_info.packet_count = _count++;
|
2020-03-02 23:25:13 +00:00
|
|
|
packet_info.sob = false;
|
|
|
|
|
packet_info.eob = false;
|
|
|
|
|
packet_info.sid = _sid;
|
|
|
|
|
packet_info.has_sid = true;
|
|
|
|
|
packet_info.has_cid = false;
|
|
|
|
|
packet_info.has_tsi = false;
|
|
|
|
|
packet_info.has_tsf = false;
|
|
|
|
|
packet_info.has_tlr = false;
|
2013-07-19 21:08:22 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
uint32_t* packet_buff = buff->cast<uint32_t*>();
|
2013-07-19 21:08:22 +00:00
|
|
|
vrt::if_hdr_pack_le(packet_buff, packet_info);
|
2020-03-02 23:25:13 +00:00
|
|
|
packet_buff[packet_info.num_header_words32 + 0] = uhd::htowx(uint32_t(_baud_div));
|
|
|
|
|
packet_buff[packet_info.num_header_words32 + 1] = uhd::htowx(uint32_t(ch));
|
|
|
|
|
buff->commit(packet_info.num_packet_words32 * sizeof(uint32_t));
|
2013-07-19 21:08:22 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void write_uart(const std::string& buff)
|
2013-07-19 21:08:22 +00:00
|
|
|
{
|
2020-03-02 23:25:13 +00:00
|
|
|
for (const char ch : buff) {
|
2016-08-15 18:18:37 +00:00
|
|
|
this->send_char(ch);
|
2013-07-19 21:08:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string read_uart(double timeout)
|
|
|
|
|
{
|
|
|
|
|
std::string line;
|
2016-07-18 21:34:00 +00:00
|
|
|
_line_queue.pop_with_timed_wait(line, timeout);
|
2013-07-19 21:08:22 +00:00
|
|
|
return line;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void handle_uart_packet(managed_recv_buffer::sptr buff)
|
|
|
|
|
{
|
2020-03-02 23:25:13 +00:00
|
|
|
const uint32_t* packet_buff = buff->cast<const uint32_t*>();
|
2013-07-19 21:08:22 +00:00
|
|
|
vrt::if_packet_info_t packet_info;
|
2020-03-02 23:25:13 +00:00
|
|
|
packet_info.link_type = vrt::if_packet_info_t::LINK_TYPE_CHDR;
|
|
|
|
|
packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t);
|
2013-07-19 21:08:22 +00:00
|
|
|
vrt::if_hdr_unpack_le(packet_buff, packet_info);
|
2020-03-02 23:25:13 +00:00
|
|
|
const char ch = char(uhd::wtohx(packet_buff[packet_info.num_header_words32 + 1]));
|
2016-08-15 18:18:37 +00:00
|
|
|
_line += ch;
|
2020-03-02 23:25:13 +00:00
|
|
|
if (ch == '\n') {
|
2016-08-15 18:18:37 +00:00
|
|
|
_line_queue.push_with_pop_on_full(_line);
|
2016-07-18 21:34:00 +00:00
|
|
|
_line.clear();
|
|
|
|
|
}
|
2013-07-19 21:08:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const zero_copy_if::sptr _xport;
|
2016-10-31 21:30:52 +00:00
|
|
|
const uint32_t _sid;
|
2013-07-19 21:08:22 +00:00
|
|
|
size_t _count;
|
|
|
|
|
size_t _baud_div;
|
2016-07-18 21:34:00 +00:00
|
|
|
bounded_buffer<std::string> _line_queue;
|
|
|
|
|
std::string _line;
|
2013-07-19 21:08:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2016-10-31 21:30:52 +00:00
|
|
|
b200_uart::sptr b200_uart::make(zero_copy_if::sptr xport, const uint32_t sid)
|
2013-07-19 21:08:22 +00:00
|
|
|
{
|
|
|
|
|
return b200_uart::sptr(new b200_uart_impl(xport, sid));
|
|
|
|
|
}
|