1 // 2 // Copyright 2013-2014 Ettus Research LLC 3 // Copyright 2018 Ettus Research, a National Instruments Company 4 // 5 // SPDX-License-Identifier: GPL-3.0-or-later 6 // 7 8 #pragma once 9 10 #include <uhd/transport/nirio/nirio_driver_iface.h> 11 #include <uhd/transport/nirio/nirio_quirks.h> 12 #include <uhd/utils/noncopyable.hpp> 13 #include <stdint.h> 14 #include <boost/thread/locks.hpp> 15 #include <boost/thread/shared_mutex.hpp> 16 17 #define NI_VENDOR_NUM 0x1093 18 19 #define VERSION_BUILD_SHIFT 0 20 #define VERSION_PHASE_SHIFT 14 21 #define VERSION_MAINT_SHIFT 16 22 #define VERSION_UPGRD_SHIFT 20 23 #define VERSION_MAJOR_SHIFT 24 24 #define VERSION_BUILD_MASK 0x00003FFF 25 #define VERSION_PHASE_MASK 0x0000C000 26 #define VERSION_MAINT_MASK 0x000F0000 27 #define VERSION_UPGRD_MASK 0x00F00000 28 #define VERSION_MAJOR_MASK 0xFF000000 29 30 #define GET_FIFO_MEMORY_TYPE(fifo_inst) (static_cast<uint16_t>(0x0100 | static_cast<uint16_t>(fifo_inst))) 31 32 #define READER_LOCK \ 33 boost::shared_lock<boost::shared_mutex> reader_lock(_synchronization); 34 35 #define WRITER_LOCK \ 36 boost::upgrade_lock<boost::shared_mutex> write_upgrade_lock(_synchronization);\ 37 boost::upgrade_to_unique_lock<boost::shared_mutex> write_unique_lock(write_upgrade_lock); 38 39 40 namespace uhd { namespace niusrprio 41 { 42 enum nirio_version_t { CURRENT, OLDEST_COMPATIBLE }; 43 44 enum nirio_addr_space_t { 45 INVALID = 0, 46 BUS_INTERFACE = 1, 47 FPGA = 2, 48 BAR_WINDOW = 3, 49 }; 50 51 typedef uint64_t nirio_u64_t; 52 typedef uint32_t nirio_u32_t; 53 typedef uint16_t nirio_u16_t; 54 typedef uint8_t nirio_u8_t; 55 typedef int32_t nirio_i32_t; 56 57 typedef enum { 58 RIO_PRODUCT_NUMBER = 2UL, // 200 59 RIO_CURRENT_VERSION = 14UL, // 220 60 RIO_OLDEST_COMPATIBLE_VERSION = 15UL, // 220 61 RIO_ADDRESS_SPACE = 25UL, // 230 62 RIO_IS_FPGA_PROGRAMMED = 48UL, // 300 63 RIO_FPGA_DEFAULT_SIGNATURE_OFFSET = 53UL, // 300 Default Offsets for FPGA 64 // registers. Supplied by 65 // the board driver on device 66 // start. 67 } nirio_device_attribute32_t; 68 69 typedef enum { 70 RIO_SCALAR_TYPE_IB = 1UL, 71 RIO_SCALAR_TYPE_IW = 2UL, 72 RIO_SCALAR_TYPE_IL = 3UL, 73 RIO_SCALAR_TYPE_IQ = 4UL, 74 RIO_SCALAR_TYPE_UB = 5UL, 75 RIO_SCALAR_TYPE_UW = 6UL, 76 RIO_SCALAR_TYPE_UL = 7UL, 77 RIO_SCALAR_TYPE_UQ = 8UL, 78 } nirio_scalar_type_t; 79 map_int_to_scalar_type(uint32_t scalar_type_as_int)80 static inline nirio_scalar_type_t map_int_to_scalar_type(uint32_t scalar_type_as_int) 81 { 82 switch (scalar_type_as_int) 83 { 84 case 1: return RIO_SCALAR_TYPE_IB; 85 case 2: return RIO_SCALAR_TYPE_IW; 86 case 3: return RIO_SCALAR_TYPE_IL; 87 case 4: return RIO_SCALAR_TYPE_IQ; 88 case 5: return RIO_SCALAR_TYPE_UB; 89 case 6: return RIO_SCALAR_TYPE_UW; 90 case 7: return RIO_SCALAR_TYPE_UL; 91 case 8: return RIO_SCALAR_TYPE_UQ; 92 default: UHD_ASSERT_THROW(false); return RIO_SCALAR_TYPE_UL; 93 } 94 } 95 96 enum fifo_direction_t { 97 INPUT_FIFO, 98 OUTPUT_FIFO 99 }; 100 101 struct nirio_fifo_info_t { nirio_fifo_info_tnirio_fifo_info_t102 nirio_fifo_info_t( 103 uint32_t arg_channel, 104 const char* arg_name, 105 fifo_direction_t arg_direction, 106 uint32_t arg_base_addr, 107 uint32_t arg_depth, 108 nirio_scalar_type_t arg_scalar_type, 109 uint32_t arg_bitWidth, 110 int32_t arg_integerWordLength, 111 uint32_t arg_version) : 112 channel(arg_channel), 113 name(arg_name), 114 direction(arg_direction), 115 base_addr(arg_base_addr), 116 depth(arg_depth), 117 scalar_type(arg_scalar_type), 118 bitWidth(arg_bitWidth), 119 integerWordLength(arg_integerWordLength), 120 version(arg_version) 121 {} 122 123 uint32_t channel; 124 std::string name; 125 fifo_direction_t direction; 126 uint32_t base_addr; 127 uint32_t depth; 128 nirio_scalar_type_t scalar_type; 129 uint32_t bitWidth; 130 int32_t integerWordLength; 131 uint32_t version; 132 }; 133 134 class UHD_API niriok_proxy : public uhd::noncopyable { 135 public: 136 typedef std::shared_ptr<niriok_proxy> sptr; 137 138 static sptr make_and_open(const std::string& interface_path); 139 140 niriok_proxy(); 141 virtual ~niriok_proxy(); 142 143 //File operations 144 virtual nirio_status open(const std::string& interface_path) = 0; 145 virtual void close(void) = 0; 146 147 virtual nirio_status reset() = 0; 148 get_interface_num()149 uint32_t get_interface_num() { return _interface_num; } 150 151 virtual nirio_status get_version( 152 nirio_version_t type, 153 uint32_t& major, 154 uint32_t& upgrade, 155 uint32_t& maintenance, 156 char& phase, 157 uint32_t& build) = 0; 158 159 virtual nirio_status get_attribute( 160 const nirio_device_attribute32_t attribute, 161 uint32_t& attrValue) = 0; 162 163 virtual nirio_status set_attribute( 164 const nirio_device_attribute32_t attribute, 165 const uint32_t value) = 0; 166 167 virtual nirio_status peek(uint32_t offset, uint32_t& value) = 0; 168 169 virtual nirio_status peek(uint32_t offset, uint64_t& value) = 0; 170 171 virtual nirio_status poke(uint32_t offset, const uint32_t& value) = 0; 172 173 virtual nirio_status poke(uint32_t offset, const uint64_t& value) = 0; 174 175 virtual nirio_status map_fifo_memory( 176 uint32_t fifo_instance, 177 size_t size, 178 nirio_driver_iface::rio_mmap_t& map) = 0; 179 180 virtual nirio_status unmap_fifo_memory( 181 nirio_driver_iface::rio_mmap_t& map) = 0; 182 183 virtual nirio_status stop_all_fifos() = 0; 184 get_rio_quirks()185 nirio_quirks& get_rio_quirks() { 186 return _rio_quirks; 187 } 188 189 virtual nirio_status add_fifo_resource(const nirio_fifo_info_t& fifo_info) = 0; 190 191 virtual nirio_status set_device_config() = 0; 192 193 virtual nirio_status start_fifo( 194 uint32_t channel) = 0; 195 196 virtual nirio_status stop_fifo( 197 uint32_t channel) = 0; 198 199 virtual nirio_status configure_fifo( 200 uint32_t channel, 201 uint32_t requested_depth, 202 uint8_t requires_actuals, 203 uint32_t& actual_depth, 204 uint32_t& actual_size) = 0; 205 206 virtual nirio_status wait_on_fifo( 207 uint32_t channel, 208 uint32_t elements_requested, 209 uint32_t scalar_type, 210 uint32_t bit_width, 211 uint32_t timeout, 212 uint8_t output, 213 void*& data_pointer, 214 uint32_t& elements_acquired, 215 uint32_t& elements_remaining) = 0; 216 217 virtual nirio_status grant_fifo( 218 uint32_t channel, 219 uint32_t elements_to_grant) = 0; 220 221 virtual nirio_status read_fifo( 222 uint32_t channel, 223 uint32_t elements_to_read, 224 void* buffer, 225 uint32_t buffer_datatype_width, 226 uint32_t scalar_type, 227 uint32_t bit_width, 228 uint32_t timeout, 229 uint32_t& number_read, 230 uint32_t& number_remaining) = 0; 231 232 virtual nirio_status write_fifo( 233 uint32_t channel, 234 uint32_t elements_to_write, 235 void* buffer, 236 uint32_t buffer_datatype_width, 237 uint32_t scalar_type, 238 uint32_t bit_width, 239 uint32_t timeout, 240 uint32_t& number_remaining) = 0; 241 242 protected: //Members 243 nirio_driver_iface::rio_dev_handle_t _device_handle; 244 uint32_t _interface_num; 245 nirio_quirks _rio_quirks; 246 247 static boost::shared_mutex _synchronization; 248 249 // protected close function that doesn't acquire synchronization lock 250 virtual void _close() = 0; 251 }; 252 253 class niriok_scoped_addr_space : public uhd::noncopyable { 254 public: niriok_scoped_addr_space(niriok_proxy::sptr proxy,nirio_addr_space_t addr_space,nirio_status & status)255 explicit niriok_scoped_addr_space(niriok_proxy::sptr proxy, nirio_addr_space_t addr_space, nirio_status& status) : 256 driver_proxy(proxy) 257 { 258 cache_status = driver_proxy->get_attribute(RIO_ADDRESS_SPACE, cached_addr_space); 259 nirio_status_chain(driver_proxy->set_attribute(RIO_ADDRESS_SPACE, addr_space), status); 260 } 261 ~niriok_scoped_addr_space()262 ~niriok_scoped_addr_space() { 263 if (nirio_status_not_fatal(cache_status)) 264 driver_proxy->set_attribute(RIO_ADDRESS_SPACE, cached_addr_space); 265 } 266 267 private: 268 niriok_proxy::sptr driver_proxy; 269 uint32_t cached_addr_space; 270 nirio_status cache_status; 271 }; 272 }} 273