diff options
Diffstat (limited to 'host/lib')
-rw-r--r-- | host/lib/usrp/common/fw_comm_protocol.h | 102 | ||||
-rw-r--r-- | host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp | 2 | ||||
-rw-r--r-- | host/lib/usrp/n230/n230_cores.cpp | 2 | ||||
-rw-r--r-- | host/lib/usrp/n230/n230_eeprom_manager.cpp | 27 | ||||
-rw-r--r-- | host/lib/usrp/n230/n230_eeprom_manager.hpp | 2 | ||||
-rw-r--r-- | host/lib/usrp/n230/n230_fw_defs.h | 137 | ||||
-rw-r--r-- | host/lib/usrp/n230/n230_fw_host_iface.h | 128 | ||||
-rw-r--r-- | host/lib/usrp/n230/n230_image_loader.cpp | 3 | ||||
-rw-r--r-- | host/lib/usrp/n230/n230_impl.cpp | 76 | ||||
-rw-r--r-- | host/lib/usrp/n230/n230_resource_manager.cpp | 21 | ||||
-rw-r--r-- | host/lib/usrp/n230/n230_resource_manager.hpp | 7 |
11 files changed, 459 insertions, 48 deletions
diff --git a/host/lib/usrp/common/fw_comm_protocol.h b/host/lib/usrp/common/fw_comm_protocol.h new file mode 100644 index 000000000..14adb33a9 --- /dev/null +++ b/host/lib/usrp/common/fw_comm_protocol.h @@ -0,0 +1,102 @@ +// +// Copyright 2014 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_FW_COMM_PROTOCOL +#define INCLUDED_FW_COMM_PROTOCOL + +#include <stdint.h> +#ifndef __cplusplus +#include <stdbool.h> +#endif + +/*! + * Structs and constants for communication between firmware and host. + * This header is shared by the firmware and host code. + * Therefore, this header may only contain valid C code. + */ +#ifdef __cplusplus +extern "C" { +#endif + +#define FW_COMM_PROTOCOL_SIGNATURE 0xACE3 +#define FW_COMM_PROTOCOL_VERSION 0 +#define FW_COMM_MAX_DATA_WORDS 16 +#define FW_COMM_PROTOCOL_MTU 256 + +#define FW_COMM_FLAGS_ACK 0x00000001 +#define FW_COMM_FLAGS_CMD_MASK 0x00000FF0 +#define FW_COMM_FLAGS_ERROR_MASK 0xFF000000 + +#define FW_COMM_CMD_ECHO 0x00000000 +#define FW_COMM_CMD_POKE32 0x00000010 +#define FW_COMM_CMD_PEEK32 0x00000020 +#define FW_COMM_CMD_BLOCK_POKE32 0x00000030 +#define FW_COMM_CMD_BLOCK_PEEK32 0x00000040 + +#define FW_COMM_ERR_PKT_ERROR 0x80000000 +#define FW_COMM_ERR_CMD_ERROR 0x40000000 +#define FW_COMM_ERR_SIZE_ERROR 0x20000000 + +#define FW_COMM_GENERATE_ID(prod) ((((uint32_t) FW_COMM_PROTOCOL_SIGNATURE) << 0) | \ + (((uint32_t) prod) << 16) | \ + (((uint32_t) FW_COMM_PROTOCOL_VERSION) << 24)) + +#define FW_COMM_GET_PROTOCOL_SIG(id) ((uint16_t)(id & 0xFFFF)) +#define FW_COMM_GET_PRODUCT_ID(id) ((uint8_t)(id >> 16)) +#define FW_COMM_GET_PROTOCOL_VER(id) ((uint8_t)(id >> 24)) + +typedef struct +{ + uint32_t id; //Protocol and device identifier + uint32_t flags; //Holds commands and ack messages + uint32_t sequence; //Sequence number (specific to FW communication transactions) + uint32_t data_words; //Number of data words in payload + uint32_t addr; //Address field for the command in flags + uint32_t data[FW_COMM_MAX_DATA_WORDS]; //Data field for the command in flags +} fw_comm_pkt_t; + +#ifdef __cplusplus +} //extern "C" +#endif + +// The following definitions are only useful in firmware. Exclude in host code. +#ifndef __cplusplus + +typedef void (*poke32_func)(const uint32_t addr, const uint32_t data); +typedef uint32_t (*peek32_func)(const uint32_t addr); + +/*! + * Process a firmware communication packet and compute a response. + * Args: + * - (in) request: Pointer to the request struct + * - (out) response: Pointer to the response struct + * - (in) product_id: The 8-bit usrp3 specific product ID (for request filtering) + * - (func) poke_callback, peek_callback: Callback functions for a single peek/poke + * - return value: Send a response packet + */ +bool process_fw_comm_protocol_pkt( + const fw_comm_pkt_t* request, + fw_comm_pkt_t* response, + uint8_t product_id, + uint32_t iface_id, + poke32_func poke_callback, + peek32_func peek_callback +); + +#endif //ifdef __cplusplus + +#endif /* INCLUDED_FW_COMM_PROTOCOL */ diff --git a/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp b/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp index d3f11b9ee..aefd84882 100644 --- a/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp +++ b/host/lib/usrp/common/usrp3_fw_ctrl_iface.cpp @@ -17,13 +17,13 @@ #include "usrp3_fw_ctrl_iface.hpp" -#include "../../../firmware/usrp3/include/fw_comm_protocol.h" #include <uhd/utils/byteswap.hpp> #include <uhd/utils/msg.hpp> #include <uhd/exception.hpp> #include <boost/format.hpp> #include <boost/asio.hpp> //used for htonl and ntohl #include <boost/foreach.hpp> +#include "fw_comm_protocol.h" namespace uhd { namespace usrp { namespace usrp3 { diff --git a/host/lib/usrp/n230/n230_cores.cpp b/host/lib/usrp/n230/n230_cores.cpp index 14e99b692..58c702ec1 100644 --- a/host/lib/usrp/n230/n230_cores.cpp +++ b/host/lib/usrp/n230/n230_cores.cpp @@ -15,9 +15,9 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include "../../../firmware/usrp3/n230/n230_fw_defs.h" #include "n230_cores.hpp" #include "n230_fpga_defs.h" +#include "n230_fw_defs.h" namespace uhd { namespace usrp { namespace n230 { diff --git a/host/lib/usrp/n230/n230_eeprom_manager.cpp b/host/lib/usrp/n230/n230_eeprom_manager.cpp index ed40b47be..40f501ef9 100644 --- a/host/lib/usrp/n230/n230_eeprom_manager.cpp +++ b/host/lib/usrp/n230/n230_eeprom_manager.cpp @@ -65,10 +65,22 @@ const mboard_eeprom_t& n230_eeprom_manager::read_mb_eeprom() const n230_eeprom_map_t* map_ptr = reinterpret_cast<const n230_eeprom_map_t*>(_response.data); const n230_eeprom_map_t& map = *map_ptr; + uint16_t ver_major = uhd::htonx<boost::uint16_t>(map.data_version_major); + uint16_t ver_minor = uhd::htonx<boost::uint16_t>(map.data_version_minor); + _mb_eeprom["product"] = boost::lexical_cast<std::string>( uhd::htonx<boost::uint16_t>(map.hw_product)); _mb_eeprom["revision"] = boost::lexical_cast<std::string>( uhd::htonx<boost::uint16_t>(map.hw_revision)); + //The revision_compat field does not exist in version 1.0 + //EEPROM version 1.0 will only exist on HW revision 1 so it is safe to set + //revision_compat = revision + if (ver_major == 1 and ver_minor == 0) { + _mb_eeprom["revision_compat"] = _mb_eeprom["revision"]; + } else { + _mb_eeprom["revision_compat"] = boost::lexical_cast<std::string>( + uhd::htonx<boost::uint16_t>(map.hw_revision_compat)); + } _mb_eeprom["serial"] = _bytes_to_string( map.serial, N230_EEPROM_SERIAL_LEN); @@ -104,6 +116,15 @@ void n230_eeprom_manager::write_mb_eeprom(const mboard_eeprom_t& eeprom) memcpy(map_ptr, _response.data, sizeof(n230_eeprom_map_t)); n230_eeprom_map_t& map = *map_ptr; + // Automatic version upgrade handling + uint16_t old_ver_major = uhd::htonx<boost::uint16_t>(map.data_version_major); + uint16_t old_ver_minor = uhd::htonx<boost::uint16_t>(map.data_version_minor); + + //The revision_compat field does not exist for version 1.0 so force write it + //EEPROM version 1.0 will only exist on HW revision 1 so it is safe to set + //revision_compat = revision for the upgrade + bool force_write_version_compat = (old_ver_major == 1 and old_ver_minor == 0); + map.data_version_major = uhd::htonx<boost::uint16_t>(N230_EEPROM_VER_MAJOR); map.data_version_minor = uhd::htonx<boost::uint16_t>(N230_EEPROM_VER_MINOR); @@ -115,6 +136,12 @@ void n230_eeprom_manager::write_mb_eeprom(const mboard_eeprom_t& eeprom) map.hw_revision = uhd::htonx<boost::uint16_t>( boost::lexical_cast<boost::uint16_t>(_mb_eeprom["revision"])); } + if (_mb_eeprom.has_key("revision_compat")) { + map.hw_revision_compat = uhd::htonx<boost::uint16_t>( + boost::lexical_cast<boost::uint16_t>(_mb_eeprom["revision_compat"])); + } else if (force_write_version_compat) { + map.hw_revision_compat = map.hw_revision; + } if (_mb_eeprom.has_key("serial")) { _string_to_bytes(_mb_eeprom["serial"], N230_EEPROM_SERIAL_LEN, map.serial); } diff --git a/host/lib/usrp/n230/n230_eeprom_manager.hpp b/host/lib/usrp/n230/n230_eeprom_manager.hpp index 612124d89..cc5aee9f3 100644 --- a/host/lib/usrp/n230/n230_eeprom_manager.hpp +++ b/host/lib/usrp/n230/n230_eeprom_manager.hpp @@ -18,11 +18,11 @@ #ifndef INCLUDED_N230_EEPROM_MANAGER_HPP #define INCLUDED_N230_EEPROM_MANAGER_HPP -#include "../../../firmware/usrp3/n230/n230_fw_host_iface.h" #include <boost/thread/mutex.hpp> #include <uhd/transport/udp_simple.hpp> #include <uhd/types/dict.hpp> #include <uhd/usrp/mboard_eeprom.hpp> +#include "n230_fw_host_iface.h" namespace uhd { namespace usrp { namespace n230 { diff --git a/host/lib/usrp/n230/n230_fw_defs.h b/host/lib/usrp/n230/n230_fw_defs.h new file mode 100644 index 000000000..fbdc67ebb --- /dev/null +++ b/host/lib/usrp/n230/n230_fw_defs.h @@ -0,0 +1,137 @@ +// +// Copyright 2014 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_N230_FW_DEFS_H +#define INCLUDED_N230_FW_DEFS_H + +#include <stdint.h> + +/*! + * Constants specific to N230 firmware. + * This header is shared by the firmware and host code. + * Therefore, this header may only contain valid C code. + * However, if it is included from within the host code, + * it will be namespaced appropriately + */ +#ifdef __cplusplus +namespace uhd { +namespace usrp { +namespace n230 { +namespace fw { +#endif + +static inline uint32_t reg_addr(uint32_t base, uint32_t offset) { + return ((base) + (offset)*4); +} + +/******************************************************************* + * Global + *******************************************************************/ +static const uint32_t CPU_CLOCK_FREQ = 80000000; +static const uint32_t PER_MILLISEC_CRON_JOBID = 0; +static const uint32_t PER_SECOND_CRON_JOBID = 1; + +/******************************************************************* + * Wishbone slave addresses + *******************************************************************/ +static const uint32_t WB_MAIN_RAM_BASE = 0x0000; +static const uint32_t WB_PKT_RAM_BASE = 0x8000; +static const uint32_t WB_SBRB_BASE = 0xa000; +static const uint32_t WB_SPI_FLASH_BASE = 0xb000; +static const uint32_t WB_ETH0_MAC_BASE = 0xc000; +static const uint32_t WB_ETH1_MAC_BASE = 0xd000; +static const uint32_t WB_XB_SBRB_BASE = 0xe000; +static const uint32_t WB_ETH0_I2C_BASE = 0xf600; +static const uint32_t WB_ETH1_I2C_BASE = 0xf700; +static const uint32_t WB_DBG_UART_BASE = 0xf900; + +/******************************************************************* + * Seting Register Base addresses + *******************************************************************/ +static const uint32_t SR_ZPU_SW_RST = 0; +static const uint32_t SR_ZPU_BOOT_DONE = 1; +static const uint32_t SR_ZPU_LEDS = 2; +static const uint32_t SR_ZPU_XB_LOCAL = 4; +static const uint32_t SR_ZPU_SFP_CTRL0 = 16; +static const uint32_t SR_ZPU_SFP_CTRL1 = 17; +static const uint32_t SR_ZPU_ETHINT0 = 64; +static const uint32_t SR_ZPU_ETHINT1 = 80; + +static const uint32_t SR_ZPU_SW_RST_NONE = 0x0; +static const uint32_t SR_ZPU_SW_RST_PHY = 0x1; +static const uint32_t SR_ZPU_SW_RST_RADIO = 0x2; + +/******************************************************************* + * Readback addresses + *******************************************************************/ +static const uint32_t RB_ZPU_COMPAT = 0; +static const uint32_t RB_ZPU_COUNTER = 1; +static const uint32_t RB_ZPU_SFP_STATUS0 = 2; +static const uint32_t RB_ZPU_SFP_STATUS1 = 3; +static const uint32_t RB_ZPU_ETH0_PKT_CNT = 6; +static const uint32_t RB_ZPU_ETH1_PKT_CNT = 7; + +/******************************************************************* + * Ethernet + *******************************************************************/ +static const uint32_t WB_PKT_RAM_CTRL_OFFSET = 0x1FFC; + +static const uint32_t SR_ZPU_ETHINT_FRAMER_BASE = 0; +static const uint32_t SR_ZPU_ETHINT_DISPATCHER_BASE = 8; + +//Eth framer constants +static const uint32_t ETH_FRAMER_SRC_MAC_HI = 0; +static const uint32_t ETH_FRAMER_SRC_MAC_LO = 1; +static const uint32_t ETH_FRAMER_SRC_IP_ADDR = 2; +static const uint32_t ETH_FRAMER_SRC_UDP_PORT = 3; +static const uint32_t ETH_FRAMER_DST_RAM_ADDR = 4; +static const uint32_t ETH_FRAMER_DST_IP_ADDR = 5; +static const uint32_t ETH_FRAMER_DST_UDP_MAC = 6; +static const uint32_t ETH_FRAMER_DST_MAC_LO = 7; + +/******************************************************************* + * CODEC + *******************************************************************/ +static const uint32_t CODEC_SPI_CLOCK_FREQ = 4000000; //4MHz +static const uint32_t ADF4001_SPI_CLOCK_FREQ = 200000; //200kHz + +/******************************************************************* + * UART + *******************************************************************/ +static const uint32_t DBG_UART_BAUD = 115200; + +/******************************************************************* + * Build Compatability Numbers + *******************************************************************/ +static const uint8_t PRODUCT_NUM = 0x01; +static const uint8_t COMPAT_MAJOR = 0x00; +static const uint16_t COMPAT_MINOR = 0x0000; + +static inline uint8_t get_prod_num(uint32_t compat_reg) { + return (compat_reg >> 24) & 0xFF; +} +static inline uint8_t get_compat_major(uint32_t compat_reg) { + return (compat_reg >> 16) & 0xFF; +} +static inline uint8_t get_compat_minor(uint32_t compat_reg) { + return compat_reg & 0xFFFF; +} + +#ifdef __cplusplus +}}}} //namespace +#endif +#endif /* INCLUDED_N230_FW_DEFS_H */ diff --git a/host/lib/usrp/n230/n230_fw_host_iface.h b/host/lib/usrp/n230/n230_fw_host_iface.h new file mode 100644 index 000000000..dc82df2fc --- /dev/null +++ b/host/lib/usrp/n230/n230_fw_host_iface.h @@ -0,0 +1,128 @@ +// +// Copyright 2014 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_N230_FW_HOST_IFACE_H +#define INCLUDED_N230_FW_HOST_IFACE_H + +#include <stdint.h> + +/*! + * Structs and constants for N230 communication between firmware and host. + * This header is shared by the firmware and host code. + * Therefore, this header may only contain valid C code. + */ +#ifdef __cplusplus +extern "C" { +#endif + +//-------------------------------------------------- +// Ethernet related +// +#define N230_DEFAULT_ETH0_MAC {0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff} +#define N230_DEFAULT_ETH1_MAC {0x00, 0x50, 0xC2, 0x85, 0x3f, 0x33} +#define N230_DEFAULT_ETH0_IP (192 << 24 | 168 << 16 | 10 << 8 | 2 << 0) +#define N230_DEFAULT_ETH1_IP (192 << 24 | 168 << 16 | 20 << 8 | 2 << 0) +#define N230_DEFAULT_ETH0_MASK (255 << 24 | 255 << 16 | 255 << 8 | 0 << 0) +#define N230_DEFAULT_ETH1_MASK (255 << 24 | 255 << 16 | 255 << 8 | 0 << 0) +#define N230_DEFAULT_GATEWAY (192 << 24 | 168 << 16 | 10 << 8 | 1 << 0) + +#define N230_FW_COMMS_UDP_PORT 49152 +#define N230_FW_COMMS_CVITA_PORT 49153 +#define N230_FW_COMMS_FLASH_PROG_PORT 49154 +// +//-------------------------------------------------- + +//-------------------------------------------------- +// Memory shared with host +// +#define N230_FW_HOST_SHMEM_BASE_ADDR 0x10000 +#define N230_FW_HOST_SHMEM_RW_BASE_ADDR 0x1000C +#define N230_FW_HOST_SHMEM_NUM_WORDS (sizeof(n230_host_shared_mem_data_t)/sizeof(uint32_t)) + +#define N230_FW_HOST_SHMEM_MAX_ADDR \ + (N230_FW_HOST_SHMEM_BASE_ADDR + ((N230_FW_HOST_SHMEM_NUM_WORDS - 1) * sizeof(uint32_t))) + +#define N230_FW_HOST_SHMEM_OFFSET(member) \ + (N230_FW_HOST_SHMEM_BASE_ADDR + ((uint32_t)offsetof(n230_host_shared_mem_data_t, member))) + +//The shared memory block can only be accessed on 32-bit boundaries +typedef struct { //All fields must be 32-bit wide to avoid packing directives + //Read-Only fields (N230_FW_HOST_SHMEM_BASE_ADDR) + uint32_t fw_compat_num; //Compat number must be at offset 0 + uint32_t fw_version_hash; + uint32_t claim_status; + + //Read-Write fields (N230_FW_HOST_SHMEM_RW_BASE_ADDR) + uint32_t scratch; + uint32_t claim_time; + uint32_t claim_src; +} n230_host_shared_mem_data_t; + +typedef union +{ + uint32_t buff[N230_FW_HOST_SHMEM_NUM_WORDS]; + n230_host_shared_mem_data_t data; +} n230_host_shared_mem_t; + +#define N230_FW_PRODUCT_ID 1 +#define N230_FW_COMPAT_NUM_MAJOR 3 +#define N230_FW_COMPAT_NUM_MINOR 0 +#define N230_FW_COMPAT_NUM (((N230_FW_COMPAT_NUM_MAJOR & 0xFF) << 16) | (N230_FW_COMPAT_NUM_MINOR & 0xFFFF)) +// +//-------------------------------------------------- + +//-------------------------------------------------- +// Flash read-write interface for host +// +#define N230_FLASH_COMM_FLAGS_ACK 0x00000001 +#define N230_FLASH_COMM_FLAGS_CMD_MASK 0x00000FF0 +#define N230_FLASH_COMM_FLAGS_ERROR_MASK 0xFF000000 + +#define N230_FLASH_COMM_CMD_READ_NV_DATA 0x00000010 +#define N230_FLASH_COMM_CMD_WRITE_NV_DATA 0x00000020 +#define N230_FLASH_COMM_CMD_READ_FPGA 0x00000030 +#define N230_FLASH_COMM_CMD_WRITE_FPGA 0x00000040 +#define N230_FLASH_COMM_CMD_ERASE_FPGA 0x00000050 + +#define N230_FLASH_COMM_ERR_PKT_ERROR 0x80000000 +#define N230_FLASH_COMM_ERR_CMD_ERROR 0x40000000 +#define N230_FLASH_COMM_ERR_SIZE_ERROR 0x20000000 + +#define N230_FLASH_COMM_MAX_PAYLOAD_SIZE 128 + +typedef struct +{ + uint32_t flags; + uint32_t seq; + uint32_t offset; + uint32_t size; + uint8_t data[N230_FLASH_COMM_MAX_PAYLOAD_SIZE]; +} n230_flash_prog_t; +// +//-------------------------------------------------- + +#define N230_HW_REVISION_COMPAT 1 +#define N230_HW_REVISION_MIN 1 + + +#define N230_CLAIMER_TIMEOUT_IN_MS 2000 + +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDED_N230_FW_HOST_IFACE_H */ diff --git a/host/lib/usrp/n230/n230_image_loader.cpp b/host/lib/usrp/n230/n230_image_loader.cpp index 48b41c7a9..f8a6ba092 100644 --- a/host/lib/usrp/n230/n230_image_loader.cpp +++ b/host/lib/usrp/n230/n230_image_loader.cpp @@ -24,8 +24,9 @@ #include <uhd/transport/udp_simple.hpp> #include <boost/algorithm/string.hpp> #include <boost/filesystem.hpp> + +#include "n230_fw_host_iface.h" #include "n230_impl.hpp" -#include "../../../firmware/usrp3/n230/n230_fw_host_iface.h" using namespace uhd; using namespace uhd::usrp; diff --git a/host/lib/usrp/n230/n230_impl.cpp b/host/lib/usrp/n230/n230_impl.cpp index b3cc4ab59..ab7fa6fe6 100644 --- a/host/lib/usrp/n230/n230_impl.cpp +++ b/host/lib/usrp/n230/n230_impl.cpp @@ -17,9 +17,6 @@ #include "n230_impl.hpp" -#include "../../../firmware/usrp3/n230/n230_fw_host_iface.h" -#include "../../../firmware/usrp3/n230/n230_fw_defs.h" -#include "../../../firmware/usrp3/include/fw_comm_protocol.h" #include "usrp3_fw_ctrl_iface.hpp" #include "validate_subdev_spec.hpp" #include <uhd/utils/static.hpp> @@ -31,6 +28,7 @@ #include <uhd/utils/msg.hpp> #include <uhd/types/sensors.hpp> #include <uhd/types/ranges.hpp> +#include <uhd/types/direction.hpp> #include <uhd/usrp/mboard_eeprom.hpp> #include <uhd/usrp/dboard_eeprom.hpp> #include <uhd/usrp/gps_ctrl.hpp> @@ -43,8 +41,12 @@ #include <boost/asio/ip/address_v4.hpp> #include <boost/asio.hpp> //used for htonl and ntohl #include <boost/make_shared.hpp> + +#include "../common/fw_comm_protocol.h" #include "n230_defaults.h" #include "n230_fpga_defs.h" +#include "n230_fw_defs.h" +#include "n230_fw_host_iface.h" namespace uhd { namespace usrp { namespace n230 { @@ -180,13 +182,37 @@ n230_impl::n230_impl(const uhd::device_addr_t& dev_addr) //TODO: Only supports one motherboard per device class. const fs_path mb_path = "/mboards/0"; - //Initialize subsystems + //Initialize addresses std::vector<std::string> ip_addrs(1, dev_addr["addr"]); if (dev_addr.has_key("secondary-addr")) { ip_addrs.push_back(dev_addr["secondary-addr"]); } - _resource_mgr = boost::make_shared<n230_resource_manager>(ip_addrs, _dev_args.get_safe_mode()); + + //Read EEPROM and perform version checks before talking to HW _eeprom_mgr = boost::make_shared<n230_eeprom_manager>(ip_addrs[0]); + const mboard_eeprom_t& mb_eeprom = _eeprom_mgr->get_mb_eeprom(); + bool recover_mb_eeprom = dev_addr.has_key("recover_mb_eeprom"); + if (recover_mb_eeprom) { + UHD_MSG(warning) << "UHD is operating in EEPROM Recovery Mode which disables hardware version " + "checks.\nOperating in this mode may cause hardware damage and unstable " + "radio performance!"<< std::endl; + } + boost::uint16_t hw_rev = boost::lexical_cast<boost::uint16_t>(mb_eeprom["revision"]); + boost::uint16_t hw_rev_compat = boost::lexical_cast<boost::uint16_t>(mb_eeprom["revision_compat"]); + if (not recover_mb_eeprom) { + if (hw_rev_compat > N230_HW_REVISION_COMPAT) { + throw uhd::runtime_error(str(boost::format( + "Hardware is too new for this software. Please upgrade to a driver that supports hardware revision %d.") + % hw_rev)); + } else if (hw_rev < N230_HW_REVISION_MIN) { //Compare min against the revision (and not compat) to give us more leeway for partial support for a compat + throw uhd::runtime_error(str(boost::format( + "Software is too new for this hardware. Please downgrade to a driver that supports hardware revision %d.") + % hw_rev)); + } + } + + //Initialize all subsystems + _resource_mgr = boost::make_shared<n230_resource_manager>(ip_addrs, _dev_args.get_safe_mode()); _stream_mgr = boost::make_shared<n230_stream_manager>(_dev_args, _resource_mgr, _tree); //Build property tree @@ -459,38 +485,14 @@ void n230_impl::_initialize_radio_properties(const fs_path& mb_path, size_t inst .publish(boost::bind(&tx_dsp_core_3000::get_freq_range, perif.duc)); //RF Frontend Interfacing - static const std::vector<std::string> data_directions = boost::assign::list_of("tx")("rx"); - BOOST_FOREACH(const std::string& direction, data_directions) { - const std::string key = boost::to_upper_copy(direction) + str(boost::format("%u") % (instance + 1)); - const fs_path rf_fe_path = mb_path / "dboards" / "A" / (direction + "_frontends") / ((instance==0)?"A":"B"); - - _tree->create<std::string>(rf_fe_path / "name") - .set("FE-" + key); - _tree->create<int>(rf_fe_path / "sensors"); //empty TODO - BOOST_FOREACH(const std::string &name, ad9361_ctrl::get_gain_names(key)) { - _tree->create<meta_range_t>(rf_fe_path / "gains" / name / "range") - .set(ad9361_ctrl::get_gain_range(key)); - _tree->create<double>(rf_fe_path / "gains" / name / "value") - .coerce(boost::bind(&ad9361_ctrl::set_gain, _resource_mgr->get_codec_ctrl_sptr(), key, _1)) - .set(n230::DEFAULT_FE_GAIN); - } - _tree->create<std::string>(rf_fe_path / "connection") - .set("IQ"); - _tree->create<bool>(rf_fe_path / "enabled") - .set(true); - _tree->create<bool>(rf_fe_path / "use_lo_offset") - .set(false); - _tree->create<double>(rf_fe_path / "bandwidth" / "value") - .coerce(boost::bind(&ad9361_ctrl::set_bw_filter, _resource_mgr->get_codec_ctrl_sptr(), key, _1)) - .set(n230::DEFAULT_FE_BW); - _tree->create<meta_range_t>(rf_fe_path / "bandwidth" / "range") - .publish(boost::bind(&ad9361_ctrl::get_bw_filter_range, key)); - _tree->create<double>(rf_fe_path / "freq" / "value") - .set(n230::DEFAULT_FE_FREQ) - .coerce(boost::bind(&ad9361_ctrl::tune, _resource_mgr->get_codec_ctrl_sptr(), key, _1)) - .subscribe(boost::bind(&n230_frontend_ctrl::set_bandsel, _resource_mgr->get_frontend_ctrl_sptr(), key, _1)); - _tree->create<meta_range_t>(rf_fe_path / "freq" / "range") - .publish(boost::bind(&ad9361_ctrl::get_rf_freq_range)); + static const std::vector<direction_t> data_directions = boost::assign::list_of(RX_DIRECTION)(TX_DIRECTION); + BOOST_FOREACH(direction_t direction, data_directions) { + const std::string dir_str = (direction == RX_DIRECTION) ? "rx" : "tx"; + const std::string key = boost::to_upper_copy(dir_str) + str(boost::format("%u") % (instance + 1)); + const fs_path rf_fe_path = mb_path / "dboards" / "A" / (dir_str + "_frontends") / ((instance==0)?"A":"B"); + + //CODEC subtree + _resource_mgr->get_codec_mgr().populate_frontend_subtree(_tree->subtree(rf_fe_path), key, direction); //User settings _tree->create<uhd::wb_iface::sptr>(rf_fe_path / "user_settings" / "iface") diff --git a/host/lib/usrp/n230/n230_resource_manager.cpp b/host/lib/usrp/n230/n230_resource_manager.cpp index 38e689533..4db494302 100644 --- a/host/lib/usrp/n230/n230_resource_manager.cpp +++ b/host/lib/usrp/n230/n230_resource_manager.cpp @@ -17,8 +17,6 @@ #include "n230_resource_manager.hpp" -#include "../../../firmware/usrp3/n230/n230_fw_host_iface.h" -#include "../../../firmware/usrp3/n230/n230_fw_defs.h" #include "usrp3_fw_ctrl_iface.hpp" #include <uhd/transport/if_addrs.hpp> #include <uhd/transport/udp_zero_copy.hpp> @@ -32,6 +30,8 @@ #include <boost/functional/hash.hpp> #include <boost/lexical_cast.hpp> #include <boost/make_shared.hpp> +#include "n230_fw_defs.h" +#include "n230_fw_host_iface.h" #define IF_DATA_I_MASK 0xFFF00000 #define IF_DATA_Q_MASK 0x0000FFF0 @@ -88,12 +88,19 @@ n230_resource_manager::n230_resource_manager( n230_eth_conn_t conn_iface; conn_iface.ip_addr = addr; - boost::uint32_t iface_id = usrp3::usrp3_fw_ctrl_iface::get_iface_id( - conn_iface.ip_addr, BOOST_STRINGIZE(N230_FW_COMMS_UDP_PORT), N230_FW_PRODUCT_ID); + boost::uint32_t iface_id = 0xFFFFFFFF; + try { + iface_id = usrp3::usrp3_fw_ctrl_iface::get_iface_id( + conn_iface.ip_addr, BOOST_STRINGIZE(N230_FW_COMMS_UDP_PORT), N230_FW_PRODUCT_ID); + } catch (uhd::io_error&) { + throw uhd::io_error(str(boost::format( + "Could not communicate with the device over address %s") % + conn_iface.ip_addr)); + } switch (iface_id) { case N230_ETH0_IFACE_ID: conn_iface.type = ETH0; break; case N230_ETH1_IFACE_ID: conn_iface.type = ETH1; break; - default: throw uhd::runtime_error("N230 Initialization Error: Could not detect iface.)"); + default: throw uhd::runtime_error("N230 Initialization Error: Could not detect ethernet port number.)"); } _eth_conns.push_back(conn_iface); } @@ -143,7 +150,7 @@ n230_resource_manager::n230_resource_manager( throw uhd::runtime_error("N230 Initialization Error: Could not create SPI ctrl.)"); } - //Create Catalina interface + //Create AD9361 interface UHD_MSG(status) << "Initializing CODEC...\n"; _codec_ctrl = ad9361_ctrl::make_spi( boost::make_shared<n230_ad9361_client_t>(), _core_spi_ctrl, fpga::AD9361_SPI_SLAVE_NUM); @@ -151,6 +158,8 @@ n230_resource_manager::n230_resource_manager( throw uhd::runtime_error("N230 Initialization Error: Could not create Catalina ctrl.)"); } _codec_ctrl->set_clock_rate(fpga::CODEC_DEFAULT_CLK_RATE); + _codec_mgr = ad936x_manager::make(_codec_ctrl, fpga::NUM_RADIOS); + _codec_mgr->init_codec(); //Create AD4001 interface _ref_pll_ctrl = boost::make_shared<n230_ref_pll_ctrl>(_core_spi_ctrl); diff --git a/host/lib/usrp/n230/n230_resource_manager.hpp b/host/lib/usrp/n230/n230_resource_manager.hpp index c98140141..3a0b13329 100644 --- a/host/lib/usrp/n230/n230_resource_manager.hpp +++ b/host/lib/usrp/n230/n230_resource_manager.hpp @@ -28,6 +28,7 @@ #include "tx_dsp_core_3000.hpp" #include "user_settings_core_3000.hpp" #include "ad9361_ctrl.hpp" +#include "ad936x_manager.hpp" #include <uhd/utils/tasks.hpp> #include <uhd/types/sid.hpp> #include <uhd/types/device_addr.hpp> @@ -139,13 +140,16 @@ public: //Methods return _core_ctrl; } - //Catalina control interface + //AD931 control interface inline ad9361_ctrl& get_codec_ctrl() const { return *_codec_ctrl; } inline ad9361_ctrl::sptr get_codec_ctrl_sptr() { return _codec_ctrl; } + inline uhd::usrp::ad936x_manager& get_codec_mgr() const { + return *_codec_mgr; + } //Clock PPS controls inline n230_ref_pll_ctrl& get_ref_pll_ctrl() const { @@ -282,6 +286,7 @@ private: radio_ctrl_core_3000::sptr _core_ctrl; n230_core_spi_core::sptr _core_spi_ctrl; ad9361_ctrl::sptr _codec_ctrl; + uhd::usrp::ad936x_manager::sptr _codec_mgr; //Core Registers fpga::core_radio_ctrl_reg_t _core_radio_ctrl_reg; |