diff options
-rw-r--r-- | firmware/usrp3/CMakeLists.txt | 1 | ||||
-rw-r--r-- | firmware/usrp3/n230/CMakeLists.txt | 40 | ||||
-rwxr-xr-x | firmware/usrp3/n230/n230_burner.py | 359 | ||||
-rwxr-xr-x | firmware/usrp3/n230/n230_debug.py | 387 | ||||
-rw-r--r-- | firmware/usrp3/n230/n230_eeprom.c | 196 | ||||
-rw-r--r-- | firmware/usrp3/n230/n230_eth_handlers.c | 340 | ||||
-rw-r--r-- | firmware/usrp3/n230/n230_eth_handlers.h | 48 | ||||
-rw-r--r-- | firmware/usrp3/n230/n230_fw_comm_protocol.c | 105 | ||||
-rw-r--r-- | firmware/usrp3/n230/n230_init.c | 125 | ||||
-rw-r--r-- | firmware/usrp3/n230/n230_init.h | 28 | ||||
-rw-r--r-- | firmware/usrp3/n230/n230_main.c | 113 |
11 files changed, 0 insertions, 1742 deletions
diff --git a/firmware/usrp3/CMakeLists.txt b/firmware/usrp3/CMakeLists.txt index abf1d46cb..9cfbe9987 100644 --- a/firmware/usrp3/CMakeLists.txt +++ b/firmware/usrp3/CMakeLists.txt @@ -134,4 +134,3 @@ endmacro(GEN_OUTPUTS) ######################################################################## add_subdirectory(lib) add_subdirectory(x300) -add_subdirectory(n230) diff --git a/firmware/usrp3/n230/CMakeLists.txt b/firmware/usrp3/n230/CMakeLists.txt deleted file mode 100644 index 185704276..000000000 --- a/firmware/usrp3/n230/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -# -# Copyright 2010-2014,2016 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/>. -# - -######################################################################## -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_SOURCE_DIR}/../../host/lib/usrp/n230) - -list(APPEND n230_sources - n230_eeprom.c - n230_fw_comm_protocol.c - n230_eth_handlers.c - n230_init.c - n230_main.c) - -######################################################################## -set(GEN_OUTPUTS_BIN_SIZE 0x7fff) - -add_executable(n230_main.elf ${n230_sources}) -target_link_libraries(n230_main.elf usrp3fw) -GEN_OUTPUTS(n230_main.elf n230) - -#install( -# FILES ${CMAKE_CURRENT_BINARY_DIR}/n230_main.bin -# DESTINATION share/uhd/images -# RENAME usrp_n230_fw.bin -#) diff --git a/firmware/usrp3/n230/n230_burner.py b/firmware/usrp3/n230/n230_burner.py deleted file mode 100755 index 7b9920de7..000000000 --- a/firmware/usrp3/n230/n230_burner.py +++ /dev/null @@ -1,359 +0,0 @@ -#!/usr/bin/env python -# -# 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/>. -# - -import optparse -import math -import socket -import struct -import os.path -import sys -from array import array - -######################################################################## -# constants -######################################################################## -N230_FLASH_COMM_UDP_PORT = 49154 -N230_FLASH_COMM_PAYLOAD_SIZE = 128 -N230_FLASH_COMM_SECTOR_SIZE = 65536 - -N230_FLASH_COMM_FLAGS_ACK = 0x00000001 -N230_FLASH_COMM_FLAGS_CMD_MASK = 0x00000FF0 -N230_FLASH_COMM_FLAGS_ERROR_MASK = 0xFF000000 - -N230_FLASH_COMM_CMD_READ_NV_DATA = 0x00000010 -N230_FLASH_COMM_CMD_WRITE_NV_DATA = 0x00000020 -N230_FLASH_COMM_CMD_READ_FPGA = 0x00000030 -N230_FLASH_COMM_CMD_WRITE_FPGA = 0x00000040 -N230_FLASH_COMM_CMD_ERASE_FPGA = 0x00000050 - -N230_FLASH_COMM_ERR_PKT_ERROR = 0x80000000 -N230_FLASH_COMM_ERR_CMD_ERROR = 0x40000000 -N230_FLASH_COMM_ERR_SIZE_ERROR = 0x20000000 - -N230_FLASH_COMM_SAFE_IMG_BASE = 0x000000 -N230_FLASH_COMM_PROD_IMG_BASE = 0x400000 -N230_FLASH_COMM_FPGA_IMG_MAX_SIZE = 0x400000 - -UDP_MAX_XFER_BYTES = 256 -UDP_TIMEOUT = 3 - -_seq = -1 -def next_seq(): - global _seq - _seq = _seq+1 - return _seq - -def seq(): - return _seq - -######################################################################## -# helper functions -######################################################################## - -short = struct.Struct('>H') -ulong = struct.Struct('>I') - -def unpack_flash_transaction(buf): - (flags, seqno, offset, size) = struct.unpack_from('!LLLL', buf) - check_error(flags) - if (seqno != seq()): - raise Exception("The flash transaction operation returned an incorrect sequence number") - data = bytes() - for i in xrange(16, len(buf), 1): - data += buf[i] - return (flags, offset, size, data) - -def pack_flash_transaction(flags, offset, size, data): - buf = bytes() - buf = struct.pack('!LLLL', flags, next_seq(), offset, size) - for i in range(N230_FLASH_COMM_PAYLOAD_SIZE): - if (i < size): - buf += struct.pack('!B', data[i]) - else: - buf += struct.pack('!B', 0) - return buf - -def check_error(flags): - if flags & N230_FLASH_COMM_ERR_PKT_ERROR == N230_FLASH_COMM_ERR_PKT_ERROR: - raise Exception("The flash transaction operation returned a packet error") - if flags & N230_FLASH_COMM_ERR_CMD_ERROR == N230_FLASH_COMM_ERR_CMD_ERROR: - raise Exception("The flash transaction operation returned a command error") - if flags & N230_FLASH_COMM_ERR_SIZE_ERROR == N230_FLASH_COMM_ERR_SIZE_ERROR: - raise Exception("The flash transaction operation returned a size error") - -def chunkify(stuff, n): - return [stuff[i:i+n] for i in range(0, len(stuff), n)] - -def draw_progress_bar(percent, bar_len = 32): - sys.stdout.write("\r") - progress = "" - for i in range(bar_len): - if i < int((bar_len * percent) / 100): - progress += "=" - else: - progress += "-" - sys.stdout.write("[%s] %d%%" % (progress, percent)) - sys.stdout.flush() - -######################################################################## -# Burner class, holds a socket and send/recv routines -######################################################################## -class ctrl_socket(object): - def __init__(self, addr): - self._safe_image = False - self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self._sock.settimeout(UDP_TIMEOUT) - self._sock.connect((addr, N230_FLASH_COMM_UDP_PORT)) - self.set_callbacks(lambda *a: None, lambda *a: None) - - def set_safe_image(self, noprompt): - confirm_msg = ('----------------------------------------------------------------------\n' - 'WARNING!!! You are about to access the safe-image stored in the flash \n' - '----------------------------------------------------------------------\n' - 'Writing a non-functional image will brick the device.\n' - 'Are you sure you want to proceed?') - if not noprompt: - if raw_input("%s (y/N) " % confirm_msg).lower() == 'y': - self._safe_image = True - else: - print 'Aborted by user' - sys.exit(1) - else: - print '[WARNING] Operating on safe image without a prompt as requested' - self._safe_image = True - - def set_callbacks(self, progress_cb, status_cb): - self._progress_cb = progress_cb - self._status_cb = status_cb - - def send_and_recv(self, pkt): - self._sock.send(pkt) - return self._sock.recv(UDP_MAX_XFER_BYTES) - - def compute_offset(self, offset): - base = N230_FLASH_COMM_SAFE_IMG_BASE if (self._safe_image) else N230_FLASH_COMM_PROD_IMG_BASE - return base + offset - - def burn_fpga_to_flash(self, bitfile_path, noprompt): - print '[BURN] Reading ' + bitfile_path + '...' - with open(bitfile_path, 'rb') as bitfile: - header = file_bytes = bitfile.read() - if (self._safe_image != self.parse_bitfile_header(file_bytes)['safe-image']): - confirm_msg = ('----------------------------------------------------------------------\n' - 'WARNING!!! You are about to burn a safe image into a production slot \n' - ' or a production image into a safe slot. \n' - '----------------------------------------------------------------------\n' - 'This is dangerous and can cause the device to boot incorrectly.\n' - 'Are you sure you want to proceed?') - if not noprompt: - if raw_input("%s (y/N) " % confirm_msg).lower() != 'y': - print '[BURN] Aborted by user' - return - else: - print '[WARNING] Burning image to the wrong slot without a prompt as requested' - - print '[BURN] Writing to flash...' - pkt_chunks = chunkify(file_bytes, N230_FLASH_COMM_PAYLOAD_SIZE) - offset = 0 - for pkt_data in pkt_chunks: - pkt_data = array("B", pkt_data) - size = N230_FLASH_COMM_PAYLOAD_SIZE if (len(pkt_data) >= N230_FLASH_COMM_PAYLOAD_SIZE) else len(pkt_data) - #Erase sector - if (offset % N230_FLASH_COMM_SECTOR_SIZE == 0): - flags = N230_FLASH_COMM_FLAGS_ACK|N230_FLASH_COMM_CMD_ERASE_FPGA - out_pkt = pack_flash_transaction(flags, self.compute_offset(offset), size, pkt_data) - (flags, real_offset, size, data) = unpack_flash_transaction(self.send_and_recv(out_pkt)) - #Write data - flags = N230_FLASH_COMM_FLAGS_ACK|N230_FLASH_COMM_CMD_WRITE_FPGA - out_pkt = pack_flash_transaction(flags, self.compute_offset(offset), size, pkt_data) - (flags, real_offset, size, data) = unpack_flash_transaction(self.send_and_recv(out_pkt)) - #Increment - offset += N230_FLASH_COMM_PAYLOAD_SIZE - draw_progress_bar((((offset/N230_FLASH_COMM_PAYLOAD_SIZE)+1)*100)/len(pkt_chunks)) - print('\n[BURN] DONE') - - def parse_bitfile_header(self, header_bytes): - xil_header = dict() - n230_header = dict() - n230_header['valid'] = False - ptr = 0 - #Field 1 - if short.unpack(header_bytes[ptr:ptr+2])[0] == 9 and ulong.unpack(header_bytes[ptr+2:ptr+6])[0] == 0x0ff00ff0: - #Headers - ptr += short.unpack(header_bytes[ptr:ptr+2])[0] + 2 - ptr += short.unpack(header_bytes[ptr:ptr+2])[0] + 1 - #Fields a-d - for keynum in range(0, 4): - key = header_bytes[ptr] - ptr += 1 - val_len = short.unpack(header_bytes[ptr:ptr+2])[0] - ptr += 2 - val = header_bytes[ptr:ptr+val_len] - ptr += val_len - xil_header[key] = val - #Field e - ptr += 1 - length = ulong.unpack(header_bytes[ptr:ptr+4])[0] - xil_header['bl'] = length #Bitstream length - ptr += 4 - xil_header['hl'] = ptr #Header lengt - - #Map Xilinx header field to N230 specific ones - if xil_header and xil_header['a'].split(';')[0] == 'n230': - n230_header['valid'] = True - n230_header['user-id'] = int(xil_header['a'].split(';')[1].split('=')[1], 16) - n230_header['safe-image'] = (n230_header['user-id'] >> 16 == 0x5AFE) - n230_header['product'] = xil_header['b'] - n230_header['timestamp'] = xil_header['c'] + ' ' + xil_header['d'] - n230_header['filesize'] = xil_header['hl'] + xil_header['bl'] - return n230_header - - def read_bitfile_header_from_flash(self): - max_header_size = 1024 #Should be enough - header_bytes = bytes() - for offset in range(0, max_header_size, N230_FLASH_COMM_PAYLOAD_SIZE): - #Read data - flags = N230_FLASH_COMM_FLAGS_ACK|N230_FLASH_COMM_CMD_READ_FPGA - out_pkt = pack_flash_transaction(flags, self.compute_offset(offset), N230_FLASH_COMM_PAYLOAD_SIZE, [0]*N230_FLASH_COMM_PAYLOAD_SIZE) - (flags, real_offset, size, data) = unpack_flash_transaction(self.send_and_recv(out_pkt)) - header_bytes += data - return self.parse_bitfile_header(header_bytes) - - def extract_fpga_from_flash(self, bitfile_path): - header = self.read_bitfile_header_from_flash(); - if not header['valid']: - raise Exception("Could not detect a vaild Xilinx .bit burned into the flash") - max_offset = header['filesize'] - print '[EXTRACT] Writing ' + bitfile_path + '...' - with open(bitfile_path, 'wb') as bitfile: - for i in range(0, int(math.ceil(float(max_offset)/N230_FLASH_COMM_PAYLOAD_SIZE))): - offset = i * N230_FLASH_COMM_PAYLOAD_SIZE - size = N230_FLASH_COMM_PAYLOAD_SIZE if (max_offset - offset >= N230_FLASH_COMM_PAYLOAD_SIZE) else (max_offset - offset) - #Read data - flags = N230_FLASH_COMM_FLAGS_ACK|N230_FLASH_COMM_CMD_READ_FPGA - out_pkt = pack_flash_transaction(flags, self.compute_offset(offset), size, [0]*N230_FLASH_COMM_PAYLOAD_SIZE) - (flags, real_offset, size, data) = unpack_flash_transaction(self.send_and_recv(out_pkt)) - bitfile.write(data[:size]) - draw_progress_bar(((offset*100)/max_offset) + 1) - print('\n[EXTRACT] DONE') - - def erase_fpga_from_flash(self): - print '[ERASE] Erasing image from flash...' - for offset in range(0, N230_FLASH_COMM_FPGA_IMG_MAX_SIZE, N230_FLASH_COMM_SECTOR_SIZE): - flags = N230_FLASH_COMM_FLAGS_ACK|N230_FLASH_COMM_CMD_ERASE_FPGA - out_pkt = pack_flash_transaction(flags, self.compute_offset(offset), N230_FLASH_COMM_PAYLOAD_SIZE, [0]*N230_FLASH_COMM_PAYLOAD_SIZE) - (flags, real_offset, size, data) = unpack_flash_transaction(self.send_and_recv(out_pkt)) - draw_progress_bar(((offset+N230_FLASH_COMM_SECTOR_SIZE)*100)/N230_FLASH_COMM_FPGA_IMG_MAX_SIZE) - print('\n[ERASE] DONE') - - def wipe_user_data(self, noprompt): - confirm_msg = ('-------------------------------------------------------------------\n' - 'WARNING!!! You are about to erase all the user data from the flash \n' - '-------------------------------------------------------------------\n' - 'This will cause the device to lose the following:\n' - ' * IP Address (Will default to 192.168.10.2)\n' - ' * Subnet Mask (Will default to 255.255.255.2)\n' - ' * MAC Address\n' - ' * Serial Number\n' - ' * Hardware Revision\n' - ' * ...and other identification info\n' - 'Are you sure you want to proceed?') - if not noprompt: - if raw_input("%s (y/N) " % confirm_msg).lower() == 'y': - wipe_ok = True - else: - print '[WIPE] Aborted by user' - wipe_ok = False - else: - print '[WARNING] Wiping user data without prompt a as requested' - wipe_ok = True - - if wipe_ok: - print '[WIPE] Erasing all user data from flash...' - flags = N230_FLASH_COMM_FLAGS_ACK|N230_FLASH_COMM_CMD_WRITE_NV_DATA - out_pkt = pack_flash_transaction(flags, 0, N230_FLASH_COMM_PAYLOAD_SIZE, [0xFF]*N230_FLASH_COMM_PAYLOAD_SIZE) - (flags, real_offset, size, data) = unpack_flash_transaction(self.send_and_recv(out_pkt)) - print('[WIPE] DONE. Please power-cycle the device.') - - def print_status(self): - header = self.read_bitfile_header_from_flash(); - if header['valid']: - print('[STATUS] Detected a valid .bit header in the flash (Product = %s, Datestamp = %s%s)' % \ - (header['product'], header['timestamp'], ', Safe-Image' if header['safe-image'] else '')) - else: - print('[STATUS] No .bit header detected. Either the flash is uninitialized or the image is corrupt.') - - -######################################################################## -# command line options -######################################################################## -def get_options(): - parser = optparse.OptionParser() - parser.add_option("--addr", type="string", help="N230 device address", default='') - parser.add_option("--status", action="store_true", help="Print out the status of the burned image", default=False) - parser.add_option("--erase", action="store_true", help="Erase FPGA bitstream from flash", default=False) - parser.add_option("--burn", type="string", help="Path to FPGA bitstream (.bit) to burn to flash", default=None) - parser.add_option("--extract", type="string", help="Destination bitfile to dump contents of the extracted image", default=None) - parser.add_option("--safe_image", action="store_true", help="Operate on the safe image. WARNING: This could be dangerous", default=False) - parser.add_option("--wipe_user_data", action="store_true", help="Erase all user data like IP, MAC, S/N, etc from flash", default=False) - parser.add_option("--no_prompt", action="store_true", help="Suppress all warning prompts", default=False) - (options, args) = parser.parse_args() - return options - -######################################################################## -# main -######################################################################## -if __name__=='__main__': - options = get_options() - - if not options.addr: raise Exception('No address specified') - - ctrl_sock = ctrl_socket(addr=options.addr) - - # Initialize safe image selector first - if options.safe_image: - ctrl_sock.set_safe_image(options.no_prompt) - - if options.status: - ctrl_sock.print_status() - - # Order of operations: - # 1. Extract (if specified) - # 2. Erase (if specified) - # 3. Burn (if specified) - - if options.extract is not None: - file_path = options.extract - ctrl_sock.print_status() - ctrl_sock.extract_fpga_from_flash(file_path) - - if options.erase: - ctrl_sock.erase_fpga_from_flash() - ctrl_sock.print_status() - - if options.burn is not None: - file_path = options.burn - extension = os.path.splitext(file_path)[1] - if (extension.lower() == '.bit'): - ctrl_sock.burn_fpga_to_flash(file_path, options.no_prompt) - ctrl_sock.print_status() - else: - raise Exception("Unsupported FPGA bitfile format. You must use a .bit file.") - - if options.wipe_user_data: - ctrl_sock.wipe_user_data(options.no_prompt) diff --git a/firmware/usrp3/n230/n230_debug.py b/firmware/usrp3/n230/n230_debug.py deleted file mode 100755 index f9ff64ab7..000000000 --- a/firmware/usrp3/n230/n230_debug.py +++ /dev/null @@ -1,387 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2010-2011 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/>. -# - -import optparse -import math -import socket -import struct -import array -import os.path -import sys -import time -try: - import fcntl - N230_DEVICE_DISCOVERY_AVAILABLE = True -except: - N230_DEVICE_DISCOVERY_AVAILABLE = False - -######################################################################## -# constants -######################################################################## -N230_FW_COMMS_UDP_PORT = 49152 -N230_FW_COMMS_MAX_DATA_WORDS = 16 - -N230_FW_COMMS_FLAGS_ACK = 0x00000001 -N230_FW_COMMS_FLAGS_ERROR_MASK = 0xF0000000 -N230_FW_COMMS_FLAGS_CMD_MASK = 0x000000F0 - -N230_FW_COMMS_CMD_ECHO = 0x00000000 -N230_FW_COMMS_CMD_POKE32 = 0x00000010 -N230_FW_COMMS_CMD_PEEK32 = 0x00000020 -N230_FW_COMMS_CMD_BLOCK_POKE32 = 0x00000030 -N230_FW_COMMS_CMD_BLOCK_PEEK32 = 0x00000040 - -N230_FW_COMMS_ERR_PKT_ERROR = 0x80000000 -N230_FW_COMMS_ERR_CMD_ERROR = 0x40000000 -N230_FW_COMMS_ERR_SIZE_ERROR = 0x20000000 - -N230_FW_COMMS_ID = 0x0001ACE3 - -N230_FW_LOADER_ADDR = 0xfa00 -N230_FW_LOADER_DATA = 0xfa04 -N230_FW_LOADER_NUM_WORDS = 8192 -N230_FW_LOADER_BOOT_DONE_ADDR = 0xA004 -N230_FW_LOADER_BOOT_TIMEOUT = 5 - -N230_JESD204_TEST = 0xA014 -N230_FPGA_HASH_ADDR = 0xA010 -N230_FW_HASH_ADDR = 0x10004 -N230_ICAP_ADDR = 0xF800 -#ICAP_DUMMY_WORD = 0xFFFFFFFF -#ICAP_SYNC_WORD = 0xAA995566 -#ICAP_TYPE1_NOP = 0x20000000 -#ICAP_WRITE_WBSTAR = 0x30020001 -#ICAP_WBSTAR_ADDR = 0x00000000 -#ICAP_WRITE_CMD = 0x30008001 -#ICAP_IPROG_CMD = 0x0000000F -# Bit reversed values per Xilinx UG470 - Bits reversed within bytes. -ICAP_DUMMY_WORD = 0xFFFFFFFF -ICAP_SYNC_WORD = 0x5599AA66 -ICAP_TYPE1_NOP = 0x04000000 -ICAP_WRITE_WBSTAR = 0x0C400080 -ICAP_WBSTAR_ADDR = 0x00000000 -ICAP_WRITE_CMD = 0x0C000180 -ICAP_IPROG_CMD = 0x000000F0 - - -UDP_MAX_XFER_BYTES = 256 -UDP_TIMEOUT = 3 -FPGA_LOAD_TIMEOUT = 10 - -_seq = -1 -def seq(): - global _seq - _seq = _seq+1 - return _seq - -######################################################################## -# helper functions -######################################################################## - -def pack_fw_command(flags, seq, num_words, addr, data_arr): - if (num_words > N230_FW_COMMS_MAX_DATA_WORDS): - raise Exception("Data size too large. Firmware supports a max 16 words per block." % (addr)) - buf = bytes() - buf = struct.pack('!IIIII', N230_FW_COMMS_ID, flags, seq, num_words, addr) - for i in range(N230_FW_COMMS_MAX_DATA_WORDS): - if (i < num_words): - buf += struct.pack('!I', data_arr[i]) - else: - buf += struct.pack('!I', 0) - return buf - -def unpack_fw_command(buf, fmt=None): - (id, flags, seq, num_words, addr) = struct.unpack_from('!IIIII', buf) - fw_check_error(flags) - data = [] - if fmt is None: - fmt = 'I' - for i in xrange(20, len(buf), 4): - data.append(struct.unpack('!'+fmt, buf[i:i+4])[0]) - return (flags, seq, num_words, addr, data) - -def fw_check_error(flags): - if flags & N230_FW_COMMS_ERR_PKT_ERROR == N230_FW_COMMS_ERR_PKT_ERROR: - raise Exception("The fiwmware operation returned a packet error") - if flags & N230_FW_COMMS_ERR_CMD_ERROR == N230_FW_COMMS_ERR_CMD_ERROR: - raise Exception("The fiwmware operation returned a command error") - if flags & N230_FW_COMMS_ERR_SIZE_ERROR == N230_FW_COMMS_ERR_SIZE_ERROR: - raise Exception("The fiwmware operation returned a size error") - -def chunkify(stuff, n): - return [stuff[i:i+n] for i in range(0, len(stuff), n)] - -def draw_progress_bar(percent, bar_len = 32): - sys.stdout.write("\r") - progress = "" - for i in range(bar_len): - if i < int((bar_len * percent) / 100): - progress += "=" - else: - progress += "-" - sys.stdout.write("[%s] %d%%" % (progress, percent)) - sys.stdout.flush() - -######################################################################## -# Discovery class -######################################################################## -class discovery_socket(object): - def __init__(self): - self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - self._sock.settimeout(0.250) - - def get_bcast_addrs(self): - max_possible = 128 # arbitrary. raise if needed. - num_bytes = max_possible * 32 - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - names = array.array('B', '\0' * num_bytes) - outbytes = struct.unpack('iL', fcntl.ioctl( - s.fileno(), - 0x8912, # SIOCGIFCONF - struct.pack('iL', num_bytes, names.buffer_info()[0]) - ))[0] - namestr = names.tostring() - lst = [] - for i in range(0, outbytes, 40): - name = namestr[i:i+16].split('\0', 1)[0] - ip = map(ord, namestr[i+20:i+24]) - mask = map(ord, fcntl.ioctl(s.fileno(), 0x891B, struct.pack('256s', name))[20:24]) - bcast = [] - for i in range(len(ip)): - bcast.append((ip[i] | (~mask[i])) & 0xFF) - if (name != 'lo'): - lst.append(str(bcast[0]) + '.' + str(bcast[1]) + '.' + str(bcast[2]) + '.' + str(bcast[3])) - return lst - - def discover(self): - addrs = [] - for bcast_addr in self.get_bcast_addrs(): - out_pkt = pack_fw_command(N230_FW_COMMS_CMD_ECHO|N230_FW_COMMS_FLAGS_ACK, seq(), 0, 0, [0]) - self._sock.sendto(out_pkt, (bcast_addr, N230_FW_COMMS_UDP_PORT)) - while 1: - try: - (in_pkt, addr_pair) = self._sock.recvfrom(UDP_MAX_XFER_BYTES) - if len(in_pkt) < 20: - continue - (flags, ack_seq, block_size, addr, data) = unpack_fw_command(in_pkt) - addrs.append(addr_pair[0]) - except socket.error: - break - return addrs - - -######################################################################## -# Communications class, holds a socket and send/recv routine -######################################################################## -class ctrl_socket(object): - def __init__(self, addr, port): - self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self._sock.settimeout(UDP_TIMEOUT) - self._sock.connect((addr, port)) - self.set_callbacks(lambda *a: None, lambda *a: None) - self.peek(0) #Dummy read - - def set_callbacks(self, progress_cb, status_cb): - self._progress_cb = progress_cb - self._status_cb = status_cb - - def send(self, pkt): - self._sock.send(pkt) - - def recv(self): - return self._sock.recv(UDP_MAX_XFER_BYTES) - - def send_and_recv(self, pkt): - self.send(pkt) - return self.recv() - - def peek(self, peek_addr, fmt=None): - out_pkt = pack_fw_command(N230_FW_COMMS_CMD_PEEK32|N230_FW_COMMS_FLAGS_ACK, seq(), 1, peek_addr, [0]) - in_pkt = self.send_and_recv(out_pkt) - (flags, ack_seq, block_size, addr, data) = unpack_fw_command(in_pkt, fmt) - return data[0] - - def peek64(self, peek_addr, fmt=None): - out_pkt = pack_fw_command(N230_FW_COMMS_CMD_BLOCK_PEEK32|N230_FW_COMMS_FLAGS_ACK, seq(), 2, peek_addr, [0,0]) - in_pkt = self.send_and_recv(out_pkt) - (flags, ack_seq, block_size, addr, data) = unpack_fw_command(in_pkt, fmt) - return (data[0] | (data[1] << 32)) - - def poke(self, poke_addr, poke_data, ack=True): - ack_flag = N230_FW_COMMS_FLAGS_ACK if ack else 0 - out_pkt = pack_fw_command(N230_FW_COMMS_CMD_POKE32|ack_flag, seq(), 1, poke_addr, [poke_data]) - self.send(out_pkt) - if ack: - in_pkt = self.recv() - (flags, ack_seq, block_size, addr, data) = unpack_fw_command(in_pkt) - - def live_load_firmware_bin(self, bin_path): - raise Exception("live_load_firmware_bin not implemented yet!") - - def live_load_firmware_coe(self, coe_path): - with open(coe_path, 'r') as coe_file: - print("Loading %s..." % coe_path) - coe_lines = [line.strip(',;\n ') for line in coe_file] - start_index = coe_lines.index("memory_initialization_vector=") + 1 - coe_words = coe_lines[start_index:] - if len(coe_words) != N230_FW_LOADER_NUM_WORDS: - raise Exception("invalid COE file. Must contain 8192 words!") - self.poke(N230_FW_LOADER_ADDR, 0) #Load start address - for i in range(0, len(coe_words)): - self.poke(N230_FW_LOADER_DATA, int(coe_words[i],16), (i%10==0) and (i<len(coe_words)-1)) - draw_progress_bar(((i+1)*100)/len(coe_words)) - print("\nRebooting...") - out_pkt = pack_fw_command(N230_FW_COMMS_CMD_POKE32, seq(), 1, N230_FW_LOADER_BOOT_DONE_ADDR, [1]) - self._sock.send(out_pkt) - self._sock.settimeout(1) - out_pkt = pack_fw_command(N230_FW_COMMS_CMD_PEEK32|N230_FW_COMMS_FLAGS_ACK, seq(), 1, 0, [0]) - for i in range(N230_FW_LOADER_BOOT_TIMEOUT): - try: - self._sock.send(out_pkt) - in_pkt = self._sock.recv(UDP_MAX_XFER_BYTES) - print("Firmware is alive!") - self._sock.settimeout(UDP_TIMEOUT) - return - except socket.error: - pass - print("Firmware boot FAILED!!!") - self._sock.settimeout(UDP_TIMEOUT) - - def read_hash(self): - fpga_hash = self.peek(N230_FPGA_HASH_ADDR) - fpga_status = "clean" if (fpga_hash & 0xf0000000 == 0x0) else "modified" - fw_hash = self.peek(N230_FW_HASH_ADDR) - fw_status = "clean" if (fw_hash & 0xf0000000 == 0x0) else "modified" - print("FPGA Version : %x (%s)" % (fpga_hash & 0xfffffff, fpga_status)) - print("Firmware Version : %x (%s)" % (fw_hash & 0xfffffff, fw_status)) - - def is_claimed(self): - claimed = self.peek(0x10008) - print("Claimed : %s") % ('YES' if claimed else 'NO') - - def reset_fpga(self): - print("Reseting USRP...") - ctrl_sock.poke(N230_ICAP_ADDR,ICAP_DUMMY_WORD) - ctrl_sock.poke(N230_ICAP_ADDR,ICAP_TYPE1_NOP) - ctrl_sock.poke(N230_ICAP_ADDR,ICAP_SYNC_WORD) - ctrl_sock.poke(N230_ICAP_ADDR,ICAP_TYPE1_NOP) - ctrl_sock.poke(N230_ICAP_ADDR,ICAP_WRITE_WBSTAR) - ctrl_sock.poke(N230_ICAP_ADDR,ICAP_WBSTAR_ADDR) - ctrl_sock.poke(N230_ICAP_ADDR,ICAP_TYPE1_NOP) - ctrl_sock.poke(N230_ICAP_ADDR,ICAP_WRITE_CMD) - ctrl_sock.poke(N230_ICAP_ADDR,ICAP_IPROG_CMD, False) - print("Waiting for FPGA to load...") - self._sock.settimeout(1) - out_pkt = pack_fw_command(N230_FW_COMMS_CMD_ECHO|N230_FW_COMMS_FLAGS_ACK, seq(), 1, 0, [0]) - for i in range(FPGA_LOAD_TIMEOUT): - try: - in_pkt = self.send_and_recv(out_pkt) - (flags, ack_seq, block_size, addr, data) = unpack_fw_command(in_pkt) - print("FPGA loaded successfully.") - self._sock.settimeout(UDP_TIMEOUT) - return - except socket.error: - pass - print("FPGA load FAILED!!!") - self._sock.settimeout(UDP_TIMEOUT) - - def jesd204_test_connector(self): - print("Testing JESD204 connectors. Molex cable #79576-2102 must be connected") - ctrl_sock.poke(N230_JESD204_TEST,0x1) - while True: - jesd204_test_status = ctrl_sock.peek(N230_JESD204_TEST) - if (jesd204_test_status & 0x10000 == 0x10000): - break - ctrl_sock.poke(N230_JESD204_TEST,0x0) - if (jesd204_test_status & 0xFFFF != 0x0): - print("JESD204 loopback test Failed!: Returned status is %4x" % (jesd204_test_status & 0xFFFF)) - else: - print("JESD204 loopback test Passed.") - -######################################################################## -# command line options -######################################################################## -def get_options(): - parser = optparse.OptionParser() - parser.add_option("--discover", action="store_true",help="Find all devices connected N230 devices", default=False) - parser.add_option("--addr", type="string", help="N230 device address", default='') - parser.add_option("--peek", type="int", help="Read from memory map", default=None) - parser.add_option("--poke", type="int", help="Write to memory map", default=None) - parser.add_option("--data", type="int", help="Data for poke", default=None) - parser.add_option("--fw", type="string", help="Path to FW image to load", default=None) - parser.add_option("--hash", action="store_true",help="Display FPGA git hash", default=False) - parser.add_option("--reset", action="store_true",help="Reset and Reload USRP FPGA.", default=False) - parser.add_option("--jesd204test", action="store_true",help="Test mini-SAS connectors with loopback cable..", default=False) - - (options, args) = parser.parse_args() - return options - -######################################################################## -# main -######################################################################## -if __name__=='__main__': - options = get_options() - - if options.discover: - if N230_DEVICE_DISCOVERY_AVAILABLE: - disc_sock = discovery_socket() - for addr in disc_sock.discover(): - print '==== FOUND ' + addr + ' ====' - ctrl_sock = ctrl_socket(addr, N230_FW_COMMS_UDP_PORT) - ctrl_sock.read_hash() - ctrl_sock.is_claimed() - sys.exit() - else: - raise Exception('Discovery is only supported on Linux.') - - if not options.addr: - raise Exception('No address specified') - - ctrl_sock = ctrl_socket(options.addr, N230_FW_COMMS_UDP_PORT) - - if options.fw is not None: - file_path = options.fw - extension = os.path.splitext(file_path)[1] - if (extension.lower() == '.coe'): - ctrl_sock.live_load_firmware_coe(file_path) - elif (extension.lower() == '.bin'): - ctrl_sock.live_load_firmware_bin(file_path) - else: - raise Exception("Unsupported firmware file format") - - if options.hash: - ctrl_sock.read_hash() - - if options.peek is not None: - addr = options.peek - data = ctrl_sock.peek(addr) - print("PEEK[0x%x (%d)] => 0x%x (%d)" % (addr,addr,data,data)) - - if options.poke is not None and options.data is not None: - addr = options.poke - data = options.data - ctrl_sock.poke(addr,data) - print("POKE[0x%x (%d)] <= 0x%x (%d)" % (addr,addr,data,data)) - - if options.reset: - ctrl_sock.reset_fpga() - - if options.jesd204test: - ctrl_sock.jesd204_test_connector() diff --git a/firmware/usrp3/n230/n230_eeprom.c b/firmware/usrp3/n230/n230_eeprom.c deleted file mode 100644 index 8f756d41f..000000000 --- a/firmware/usrp3/n230/n230_eeprom.c +++ /dev/null @@ -1,196 +0,0 @@ -// -// 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/>. -// - -#include "../../../host/lib/usrp/n230/n230_eeprom.h" - -#include <trace.h> -#include <stddef.h> -#include <flash/spi_flash.h> -#include <flash/spif_spsn_s25flxx.h> -#include <string.h> //memcpy - -#include "../../../host/lib/usrp/n230/n230_fw_defs.h" -#include "../../../host/lib/usrp/n230/n230_fw_host_iface.h" - -static const wb_spi_slave_t flash_spi_slave = { - .base = (void*) 0xB000, - .slave_sel = 0x0001, - .clk_div = 4, //80MHz/4 = 20MHz - .mosi_edge = RISING, - .miso_edge = FALLING, - .lsb_first = false -}; - -static const spi_flash_dev_t spi_flash_device = { - .page_size = 256, - .sector_size = 65536, - .num_sectors = 254, - .bus = &flash_spi_slave -}; - -/*********************************************************************** - * Non-volatile device data - **********************************************************************/ -#define N230_FLASH_NV_DATA_OFFSET 0x800000 - -//Default values in case the EEPROM is not read, corrupt -const n230_eeprom_map_t default_eeprom = { - .data_version_major = N230_EEPROM_VER_MAJOR, - .data_version_minor = N230_EEPROM_VER_MINOR, - .hw_revision = 0, - .hw_product = 0x01, - .gateway = N230_DEFAULT_GATEWAY, - .eth_info = { - { //eth0 - .mac_addr = N230_DEFAULT_ETH0_MAC, - .subnet = N230_DEFAULT_ETH0_MASK, - .ip_addr = N230_DEFAULT_ETH0_IP - }, - { //eth1 - .mac_addr = N230_DEFAULT_ETH1_MAC, - .subnet = N230_DEFAULT_ETH1_MASK, - .ip_addr = N230_DEFAULT_ETH1_IP - } - } -}; - -//EEPROM cache -static spi_flash_session_t flash_session = {.device = NULL}; -static n230_eeprom_map_t eeprom_cache; -static bool cache_dirty = true; - -bool read_n230_eeprom() -{ - bool status = false; - if (flash_session.device == NULL) { //Initialize flash session structure for the first time - wb_spi_init(spi_flash_device.bus); - spif_init(&flash_session, &spi_flash_device, spif_spsn_s25flxx_operations()); - } - spif_read_sync(&flash_session, N230_FLASH_NV_DATA_OFFSET, &eeprom_cache, sizeof(n230_eeprom_map_t)); - - //Verify data format - status = (eeprom_cache.data_version_major == default_eeprom.data_version_major); - //Sanity communication info - if (eeprom_cache.eth_info[0].ip_addr == 0xFFFFFFFF) - eeprom_cache.eth_info[0].ip_addr = default_eeprom.eth_info[0].ip_addr; - if (eeprom_cache.eth_info[1].ip_addr == 0xFFFFFFFF) - eeprom_cache.eth_info[1].ip_addr = default_eeprom.eth_info[1].ip_addr; - if (eeprom_cache.eth_info[0].subnet == 0xFFFFFFFF) - eeprom_cache.eth_info[0].subnet = default_eeprom.eth_info[0].subnet; - if (eeprom_cache.eth_info[1].subnet == 0xFFFFFFFF) - eeprom_cache.eth_info[1].subnet = default_eeprom.eth_info[1].subnet; - - if (!status) { - UHD_FW_TRACE(WARN, "read_n230_eeprom: Initialized cache to the default map."); - memcpy(&eeprom_cache, &default_eeprom, sizeof(n230_eeprom_map_t)); - } - cache_dirty = !status; - return status; -} - -bool write_n230_eeprom() -{ - //Assumption: sizeof(n230_eeprom_map_t) <= flash_page_size - //This function would need to be reimplemented if this assumption is no longer true - if (sizeof(n230_eeprom_map_t) > flash_session.device->page_size) { - UHD_FW_TRACE(ERROR, "write_n230_eeprom: sizeof(n230_eeprom_map_t) > flash_page_size"); - return false; - } - - bool status = true; - if (cache_dirty) { - n230_eeprom_map_t device_eeprom; - spif_read_sync(&flash_session, N230_FLASH_NV_DATA_OFFSET, &device_eeprom, sizeof(n230_eeprom_map_t)); - if (memcmp(&eeprom_cache, &device_eeprom, sizeof(n230_eeprom_map_t)) != 0) { - //Cache does not match read state. Write. - UHD_FW_TRACE(DEBUG, "write_n230_eeprom: Writing data to flash..."); - status = spif_erase_sector_sync(&flash_session, N230_FLASH_NV_DATA_OFFSET); - if (status) { - status = spif_write_page_sync( - &flash_session, N230_FLASH_NV_DATA_OFFSET, &eeprom_cache, sizeof(n230_eeprom_map_t)); - } - if (!status) { - UHD_FW_TRACE(ERROR, "write_n230_eeprom: Operation failed!"); - } - cache_dirty = !status; - } else { - UHD_FW_TRACE(DEBUG, "write_n230_eeprom: No new data. Write skipped."); - //Cache matches read state. So mark as clean - cache_dirty = false; - } - } - return status; -} - -bool is_n230_eeprom_cache_dirty() -{ - return cache_dirty; -} - -n230_eeprom_map_t* get_n230_eeprom_map() -{ - cache_dirty = true; - return &eeprom_cache; -} - -const n230_eeprom_map_t* get_n230_const_eeprom_map() -{ - return &eeprom_cache; -} - -const n230_eth_eeprom_map_t* get_n230_ethernet_info(uint32_t iface) { - if (iface >= N230_NUM_ETH_PORTS) { - UHD_FW_TRACE_FSTR(ERROR, - "get_n230_ethernet_info called with iface=%d when there are only %d ports!!!", - iface, N230_NUM_ETH_PORTS); - } - return &(get_n230_const_eeprom_map()->eth_info[iface]); -} - - -/*********************************************************************** - * Storage for bootstrap FPGA Image - **********************************************************************/ -#define N230_FLASH_FPGA_IMAGE_OFFSET 0x000000 -#define N230_FLASH_FPGA_IMAGE_SIZE 0x400000 -#define N230_FLASH_NUM_FPGA_IMAGES 2 - -void read_n230_fpga_image_page(uint32_t offset, void *buf, uint32_t num_bytes) -{ - if (offset >= (N230_FLASH_NUM_FPGA_IMAGES * N230_FLASH_FPGA_IMAGE_SIZE)) { - UHD_FW_TRACE_FSTR(ERROR, "read_n230_fpga_image_page: Offset 0x%x out of bounds", offset); - } - spif_read_sync(&flash_session, N230_FLASH_FPGA_IMAGE_OFFSET + offset, buf, num_bytes); -} - -bool write_n230_fpga_image_page(uint32_t offset, const void *buf, uint32_t num_bytes) -{ - if (offset >= (N230_FLASH_NUM_FPGA_IMAGES * N230_FLASH_FPGA_IMAGE_SIZE)) { - UHD_FW_TRACE_FSTR(ERROR, "write_n230_fpga_image_page: Offset 0x%x out of bounds", offset); - return false; - } - return spif_write_page_sync(&flash_session, N230_FLASH_FPGA_IMAGE_OFFSET + offset, buf, num_bytes); -} - -bool erase_n230_fpga_image_sector(uint32_t offset) -{ - if (offset >= (N230_FLASH_NUM_FPGA_IMAGES * N230_FLASH_FPGA_IMAGE_SIZE)) { - UHD_FW_TRACE_FSTR(ERROR, "erase_n230_fpga_image_sector: Offset 0x%x out of bounds", offset); - return false; - } - return spif_erase_sector_sync(&flash_session, N230_FLASH_FPGA_IMAGE_OFFSET + offset); -} diff --git a/firmware/usrp3/n230/n230_eth_handlers.c b/firmware/usrp3/n230/n230_eth_handlers.c deleted file mode 100644 index f5c319681..000000000 --- a/firmware/usrp3/n230/n230_eth_handlers.c +++ /dev/null @@ -1,340 +0,0 @@ -// -// 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/>. -// - -#include "n230_eth_handlers.h" - -#include <wb_utils.h> -#include <string.h> //memcmp -#include <u3_net_stack.h> -#include <print_addrs.h> -#include <trace.h> -#include "../../../host/lib/usrp/n230/n230_fw_comm_protocol.h" -#include "../../../host/lib/usrp/n230/n230_fw_defs.h" -#include "../n230/n230_fw_host_iface.h" -#include "../../../host/lib/usrp/n230/n230_eeprom.h" - -static n230_host_shared_mem_t* host_shared_mem_ptr; - -static const soft_reg_field_t LED_REG_FIELD_ETH_LINK2 = {.num_bits=1, .shift=0}; -static const soft_reg_field_t LED_REG_FIELD_ETH_LINK1 = {.num_bits=1, .shift=1}; -static const soft_reg_field_t LED_REG_FIELD_ETH_ACT2 = {.num_bits=1, .shift=2}; -static const soft_reg_field_t LED_REG_FIELD_ETH_ACT1 = {.num_bits=1, .shift=3}; - -/*********************************************************************** - * Handler for host <-> firmware communication - **********************************************************************/ - -static inline void n230_poke32(const uint32_t addr, const uint32_t data) -{ - if (addr >= N230_FW_HOST_SHMEM_RW_BASE_ADDR && addr <= N230_FW_HOST_SHMEM_MAX_ADDR) { - host_shared_mem_ptr->buff[(addr - N230_FW_HOST_SHMEM_BASE_ADDR)/sizeof(uint32_t)] = data; - } else if (addr < N230_FW_HOST_SHMEM_BASE_ADDR) { - wb_poke32(addr, data); - } -} - -static inline uint32_t n230_peek32(const uint32_t addr) -{ - if (addr >= N230_FW_HOST_SHMEM_BASE_ADDR && addr <= N230_FW_HOST_SHMEM_MAX_ADDR) { - return host_shared_mem_ptr->buff[(addr - N230_FW_HOST_SHMEM_BASE_ADDR)/sizeof(uint32_t)]; - } else if (addr < N230_FW_HOST_SHMEM_BASE_ADDR) { - return wb_peek32(addr); - } else { - return 0; - } -} - -void n230_handle_udp_fw_comms( - const uint8_t ethno, - const struct ip_addr *src, const struct ip_addr *dst, - const uint16_t src_port, const uint16_t dst_port, - const void *buff, const size_t num_bytes) -{ - if (buff == NULL) { - UHD_FW_TRACE(WARN, "n230_handle_udp_fw_comms got an ICMP_DUR"); - /* We got here from ICMP_DUR undeliverable packet */ - /* Future space for hooks to tear down streaming radios etc */ - } else if (num_bytes != sizeof(fw_comm_pkt_t)) { - UHD_FW_TRACE(WARN, "n230_handle_udp_fw_comms got an unknown request (bad size)."); - } else { - const fw_comm_pkt_t *request = (const fw_comm_pkt_t *)buff; - fw_comm_pkt_t response; - bool send_response = process_fw_comm_protocol_pkt( - request, &response, - N230_FW_PRODUCT_ID, - (uint32_t)ethno, - n230_poke32, n230_peek32); - - if (send_response) { - u3_net_stack_send_udp_pkt(ethno, src, dst_port, src_port, &response, sizeof(response)); - } - } -} - -void n230_register_udp_fw_comms_handler(n230_host_shared_mem_t* shared_mem_ptr) -{ - host_shared_mem_ptr = shared_mem_ptr; - u3_net_stack_register_udp_handler(N230_FW_COMMS_UDP_PORT, &n230_handle_udp_fw_comms); -} - - -/*********************************************************************** - * Handler for UDP framer program packets - **********************************************************************/ -void program_udp_framer( - const uint8_t ethno, - const uint32_t sid, - const struct ip_addr *dst_ip, - const uint16_t dst_port, - const uint16_t src_port) -{ - const eth_mac_addr_t *dst_mac = u3_net_stack_arp_cache_lookup(dst_ip); - const size_t vdest = (sid >> 16) & 0xff; - - uint32_t framer_base = - ((ethno == 1) ? SR_ZPU_ETHINT1 : SR_ZPU_ETHINT0) + SR_ZPU_ETHINT_FRAMER_BASE; - - //setup source framer - const eth_mac_addr_t *src_mac = u3_net_stack_get_mac_addr(ethno); - wb_poke32(SR_ADDR(WB_SBRB_BASE, framer_base + ETH_FRAMER_SRC_MAC_HI), - (((uint32_t)src_mac->addr[0]) << 8) | (((uint32_t)src_mac->addr[1]) << 0)); - wb_poke32(SR_ADDR(WB_SBRB_BASE, framer_base + ETH_FRAMER_SRC_MAC_LO), - (((uint32_t)src_mac->addr[2]) << 24) | (((uint32_t)src_mac->addr[3]) << 16) | - (((uint32_t)src_mac->addr[4]) << 8) | (((uint32_t)src_mac->addr[5]) << 0)); - wb_poke32(SR_ADDR(WB_SBRB_BASE, framer_base + ETH_FRAMER_SRC_IP_ADDR), u3_net_stack_get_ip_addr(ethno)->addr); - wb_poke32(SR_ADDR(WB_SBRB_BASE, framer_base + ETH_FRAMER_SRC_UDP_PORT), src_port); - - //setup destination framer - wb_poke32(SR_ADDR(WB_SBRB_BASE, framer_base + ETH_FRAMER_DST_RAM_ADDR), vdest); - wb_poke32(SR_ADDR(WB_SBRB_BASE, framer_base + ETH_FRAMER_DST_IP_ADDR), dst_ip->addr); - wb_poke32(SR_ADDR(WB_SBRB_BASE, framer_base + ETH_FRAMER_DST_UDP_MAC), - (((uint32_t)dst_port) << 16) | - (((uint32_t)dst_mac->addr[0]) << 8) | (((uint32_t)dst_mac->addr[1]) << 0)); - wb_poke32(SR_ADDR(WB_SBRB_BASE, framer_base + ETH_FRAMER_DST_MAC_LO), - (((uint32_t)dst_mac->addr[2]) << 24) | (((uint32_t)dst_mac->addr[3]) << 16) | - (((uint32_t)dst_mac->addr[4]) << 8) | (((uint32_t)dst_mac->addr[5]) << 0)); -} - -void handle_udp_prog_framer( - const uint8_t ethno, - const struct ip_addr *src, const struct ip_addr *dst, - const uint16_t src_port, const uint16_t dst_port, - const void *buff, const size_t num_bytes) -{ - if (buff == NULL) { - /* We got here from ICMP_DUR undeliverable packet */ - /* Future space for hooks to tear down streaming radios etc */ - } else { - const uint32_t sid = ((const uint32_t *)buff)[1]; - program_udp_framer(ethno, sid, src, src_port, dst_port); - UHD_FW_TRACE_FSTR(INFO, "Reprogrammed eth%d framer. Src=%s:%d, Dest=%s:%d", - ethno,ip_addr_to_str(src),src_port,ip_addr_to_str(dst),dst_port); - } -} - -void n230_register_udp_prog_framer() -{ - u3_net_stack_register_udp_handler(N230_FW_COMMS_CVITA_PORT, &handle_udp_prog_framer); -} - - -/*********************************************************************** - * Handler for flash programming interface over UDP - **********************************************************************/ - -void n230_handle_flash_prog_comms( - const uint8_t ethno, - const struct ip_addr *src, const struct ip_addr *dst, - const uint16_t src_port, const uint16_t dst_port, - const void *buff, const size_t num_bytes) -{ - if (buff == NULL) { - UHD_FW_TRACE(WARN, "n230_handle_flash_prog_comms got an ICMP_DUR"); - /* We got here from ICMP_DUR undeliverable packet */ - /* Future space for hooks to tear down streaming radios etc */ - } else if (num_bytes != sizeof(n230_flash_prog_t)) { - UHD_FW_TRACE(WARN, "n230_handle_flash_prog_comms got an unknown request (bad size)."); - } else { - const n230_flash_prog_t *request = (const n230_flash_prog_t *)buff; - n230_flash_prog_t response; - bool ack_requested = request->flags & N230_FLASH_COMM_FLAGS_ACK; - - //Request is valid. Copy it into the reply. - memcpy(&response, request, sizeof(n230_flash_prog_t)); - - switch (request->flags & N230_FLASH_COMM_FLAGS_CMD_MASK) { - case N230_FLASH_COMM_CMD_READ_NV_DATA: { - UHD_FW_TRACE(DEBUG, "n230_handle_flash_prog_comms::read_nv_data()"); - //Offset ignored because all non-volatile data fits in a packet. - if (is_n230_eeprom_cache_dirty()) { - read_n230_eeprom(); - } - //EEPROM cache is up-to-date. Copy it into the packet. - //Assumption: Cache size < 256. If this is no longer true, the offset field - //will have to be used. - memcpy(response.data, get_n230_const_eeprom_map(), sizeof(n230_eeprom_map_t)); - ack_requested = true; - } break; - - case N230_FLASH_COMM_CMD_WRITE_NV_DATA: { - UHD_FW_TRACE(DEBUG, "n230_handle_flash_prog_comms::write_nv_data()"); - //Offset ignored because all non-volatile data fits in a packet. - memcpy(get_n230_eeprom_map(), request->data, sizeof(n230_eeprom_map_t)); - if (!write_n230_eeprom()) { - response.flags |= N230_FLASH_COMM_ERR_CMD_ERROR; - } - } break; - - case N230_FLASH_COMM_CMD_READ_FPGA: { - UHD_FW_TRACE_FSTR(DEBUG, "n230_handle_flash_prog_comms::read_fpga_page(offset=0x%x, size=%d)", - request->offset, request->size); - read_n230_fpga_image_page(request->offset, response.data, request->size); - ack_requested = true; - } break; - - case N230_FLASH_COMM_CMD_WRITE_FPGA: { - UHD_FW_TRACE_FSTR(DEBUG, "n230_handle_flash_prog_comms::write_fpga_page(offset=0x%x, size=%d)", - request->offset, request->size); - if (!write_n230_fpga_image_page(request->offset, request->data, request->size)) { - response.flags |= N230_FLASH_COMM_ERR_CMD_ERROR; - } - } break; - - case N230_FLASH_COMM_CMD_ERASE_FPGA: { - UHD_FW_TRACE_FSTR(DEBUG, "n230_handle_flash_prog_comms::erase_fpga_sector(offset=0x%x)", - request->offset); - if (!erase_n230_fpga_image_sector(request->offset)) { - response.flags |= N230_FLASH_COMM_ERR_CMD_ERROR; - } - } break; - - default :{ - UHD_FW_TRACE(ERROR, "n230_handle_flash_prog_comms got an invalid command."); - response.flags |= FW_COMM_ERR_CMD_ERROR; - } - } - //Send a reply if ack requested - if (ack_requested) { - u3_net_stack_send_udp_pkt(ethno, src, dst_port, src_port, &response, sizeof(response)); - } - } -} - -void n230_register_flash_comms_handler() -{ - u3_net_stack_register_udp_handler(N230_FW_COMMS_FLASH_PROG_PORT, &n230_handle_flash_prog_comms); -} - -/*********************************************************************** - * Handler for SFP state changes - **********************************************************************/ -#define SFPP_STATUS_MODABS_CHG (1 << 5) // Has MODABS changed since last read? -#define SFPP_STATUS_TXFAULT_CHG (1 << 4) // Has TXFAULT changed since last read? -#define SFPP_STATUS_RXLOS_CHG (1 << 3) // Has RXLOS changed since last read? -#define SFPP_STATUS_MODABS (1 << 2) // MODABS state -#define SFPP_STATUS_TXFAULT (1 << 1) // TXFAULT state -#define SFPP_STATUS_RXLOS (1 << 0) // RXLOS state - -static bool links_up[N230_MAX_NUM_ETH_PORTS] = {}; -static uint32_t packet_count[N230_MAX_NUM_ETH_PORTS] = {}; - -void n230_poll_sfp_status(const uint32_t eth, bool force, bool* state_updated) -{ - // Has MODDET/MODAbS changed since we last looked? - uint32_t rb = wb_peek32(SR_ADDR(WB_SBRB_BASE, (eth==0) ? RB_ZPU_SFP_STATUS0 : RB_ZPU_SFP_STATUS1)); - - if (rb & SFPP_STATUS_RXLOS_CHG) - UHD_FW_TRACE_FSTR(DEBUG, "eth%1d RXLOS changed state: %d", eth, (rb & SFPP_STATUS_RXLOS)); - if (rb & SFPP_STATUS_TXFAULT_CHG) - UHD_FW_TRACE_FSTR(DEBUG, "eth%1d TXFAULT changed state: %d", eth, ((rb & SFPP_STATUS_TXFAULT) >> 1)); - if (rb & SFPP_STATUS_MODABS_CHG) - UHD_FW_TRACE_FSTR(DEBUG, "eth%1d MODABS changed state: %d", eth, ((rb & SFPP_STATUS_MODABS) >> 2)); - - //update the link up status - if ((rb & SFPP_STATUS_RXLOS_CHG) || (rb & SFPP_STATUS_TXFAULT_CHG) || (rb & SFPP_STATUS_MODABS_CHG) || force) - { - const bool old_link_up = links_up[eth]; - const uint32_t status_reg_addr = (eth==0) ? RB_ZPU_SFP_STATUS0 : RB_ZPU_SFP_STATUS1; - - uint32_t sfpp_status = wb_peek32(SR_ADDR(WB_SBRB_BASE, status_reg_addr)) & 0xFFFF; - if ((sfpp_status & (SFPP_STATUS_RXLOS|SFPP_STATUS_TXFAULT|SFPP_STATUS_MODABS)) == 0) { - int8_t timeout = 100; - bool link_up = false; - do { - link_up = ((wb_peek32(SR_ADDR(WB_SBRB_BASE, status_reg_addr)) >> 16) & 0x1) != 0; - } while (!link_up && timeout-- > 0); - - links_up[eth] = link_up; - } else { - links_up[eth] = false; - } - - if (!old_link_up && links_up[eth]) u3_net_stack_send_arp_request(eth, u3_net_stack_get_ip_addr(eth)); - UHD_FW_TRACE_FSTR(INFO, "The link on eth port %u is %s", eth, links_up[eth]?"up":"down"); - if (rb & SFPP_STATUS_MODABS_CHG) { - // MODDET has changed state since last checked - if (rb & SFPP_STATUS_MODABS) { - // MODDET is high, module currently removed. - UHD_FW_TRACE_FSTR(INFO, "An SFP+ module has been removed from eth port %d.", eth); - } else { - // MODDET is low, module currently inserted. - // Return status. - UHD_FW_TRACE_FSTR(INFO, "A new SFP+ module has been inserted into eth port %d.", eth); - } - } - *state_updated = true; - } else { - *state_updated = false; - } -} - -void n230_update_link_act_state(soft_reg_t* led_reg) -{ - static bool first_poll = 1; - static uint32_t poll_cnt; - - bool activity[N230_MAX_NUM_ETH_PORTS] = {}; - for (uint32_t i = 0; i < N230_NUM_ETH_PORTS; i++) { - if (first_poll) { - links_up[i] = 0; - packet_count[i] = 0; - poll_cnt = 0; - } - - //Check SFP status and update links_up - bool link_state_from_sfp = false; - n230_poll_sfp_status(i, first_poll, &link_state_from_sfp); - - //Check packet counters less frequently to keep the LED on for a visible duration - uint32_t cnt = wb_peek32(SR_ADDR(WB_SBRB_BASE, (i==0)?RB_ZPU_ETH0_PKT_CNT:RB_ZPU_ETH1_PKT_CNT)); - activity[i] = (cnt != packet_count[i]); - packet_count[i] = cnt; - - //Update links_up if there is activity only if the SFP - //handler has not updated it - if (activity[i] && !link_state_from_sfp) links_up[i] = true; - } - - //TODO: Swap this when Ethernet port swap issues is fixed - soft_reg_write(led_reg, LED_REG_FIELD_ETH_LINK2, links_up[0]?1:0); - soft_reg_write(led_reg, LED_REG_FIELD_ETH_LINK1, links_up[1]?1:0); - soft_reg_write(led_reg, LED_REG_FIELD_ETH_ACT2, activity[0]?1:0); - soft_reg_write(led_reg, LED_REG_FIELD_ETH_ACT1, activity[1]?1:0); - - first_poll = 0; -} - diff --git a/firmware/usrp3/n230/n230_eth_handlers.h b/firmware/usrp3/n230/n230_eth_handlers.h deleted file mode 100644 index 67afbb246..000000000 --- a/firmware/usrp3/n230/n230_eth_handlers.h +++ /dev/null @@ -1,48 +0,0 @@ -// -// 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_ETH_HANDLERS_H -#define INCLUDED_N230_ETH_HANDLERS_H - -#include <stdint.h> -#include <stddef.h> -#include <stdbool.h> -#include <lwip/ip_addr.h> -#include <wb_soft_reg.h> -#include "../../../host/lib/usrp/n230/n230_fw_host_iface.h" - -/*! - * Registrar for host firmware communications handler. - */ -void n230_register_udp_fw_comms_handler(n230_host_shared_mem_t* shared_mem_ptr); - -/*! - * Registrar for framer programmer handler. - */ -void n230_register_udp_prog_framer(); - -/*! - * Registrar for host firmware communications handler. - */ -void n230_register_flash_comms_handler(); - -/*! - * Handle SFP updates. - */ -void n230_update_link_act_state(soft_reg_t* led_reg); - -#endif /* INCLUDED_N230_ETH_HANDLERS_H */ diff --git a/firmware/usrp3/n230/n230_fw_comm_protocol.c b/firmware/usrp3/n230/n230_fw_comm_protocol.c deleted file mode 100644 index d6f6dff5a..000000000 --- a/firmware/usrp3/n230/n230_fw_comm_protocol.c +++ /dev/null @@ -1,105 +0,0 @@ -// -// 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/>. -// - -#include "../../../host/lib/usrp/n230/n230_fw_comm_protocol.h" - -#include <trace.h> -#include <string.h> //memcmp - -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) -{ - bool send_response = false; - - uint16_t signature = request->id; - uint8_t version = FW_COMM_GET_PROTOCOL_VER(request->id); - uint8_t product = FW_COMM_GET_PRODUCT_ID(request->id); - if (signature == FW_COMM_PROTOCOL_SIGNATURE && //Verify protocol - version <= FW_COMM_PROTOCOL_VERSION && //Verify protocol version (older versions supported) - product == product_id) //Verify device - { - //Request is valid. Copy it into the reply. - memcpy(response, request, sizeof(fw_comm_pkt_t)); - - //Start assuming no error - response->flags &= ~FW_COMM_FLAGS_ERROR_MASK; - - //Otherwise, run the command set by the flags - switch (request->flags & FW_COMM_FLAGS_CMD_MASK) { - case FW_COMM_CMD_ECHO: { - UHD_FW_TRACE(DEBUG, "fw_comm_protocol::echo()"); - response->data_words = 1; - response->data[0] = iface_id; - } break; - - case FW_COMM_CMD_POKE32: { - UHD_FW_TRACE_FSTR(DEBUG, "fw_comm_protocol::poke32(0x%x)=0x%x", - request->addr,*(request->data)); - poke_callback(request->addr, *(request->data)); - } break; - - case FW_COMM_CMD_PEEK32: { - *(response->data) = peek_callback(request->addr); - UHD_FW_TRACE_FSTR(DEBUG, "fw_comm_protocol::peek32(0x%x)=0x%x", - request->addr,*(response->data)); - } break; - - case FW_COMM_CMD_BLOCK_POKE32: { - if (request->data_words > FW_COMM_MAX_DATA_WORDS) { - response->flags |= FW_COMM_ERR_SIZE_ERROR; - response->data_words = FW_COMM_MAX_DATA_WORDS; - } else { - response->data_words = request->data_words; - } - UHD_FW_TRACE_FSTR(DEBUG, "fw_comm_protocol::block_poke32(0x%x,%d)",request->addr,response->data_words); - for (uint32_t i = 0; i < response->data_words; i++) { - poke_callback(request->addr + (i * sizeof(uint32_t)), request->data[i]); - } - } break; - - case FW_COMM_CMD_BLOCK_PEEK32: { - if (request->data_words > FW_COMM_MAX_DATA_WORDS) { - response->flags |= FW_COMM_ERR_SIZE_ERROR; - response->data_words = FW_COMM_MAX_DATA_WORDS; - } else { - response->data_words = request->data_words; - } - for (uint32_t i = 0; i < response->data_words; i++) { - response->data[i] = peek_callback(request->addr + (i * sizeof(uint32_t))); - } - UHD_FW_TRACE_FSTR(DEBUG, "fw_comm_protocol::block_peek32(0x%x,%d)",request->addr,response->data_words); - } break; - - default: { - UHD_FW_TRACE(ERROR, "fw_comm_protocol got an invalid command."); - response->flags |= FW_COMM_ERR_CMD_ERROR; - } - } - - //Send a reply if ack requested - send_response = (request->flags & FW_COMM_FLAGS_ACK); - } else { //Size, protocol, product check failed - UHD_FW_TRACE(WARN, "fw_comm_protocol ignored an unknown request."); - send_response = false; - } - return send_response; -} diff --git a/firmware/usrp3/n230/n230_init.c b/firmware/usrp3/n230/n230_init.c deleted file mode 100644 index 14f5ebd77..000000000 --- a/firmware/usrp3/n230/n230_init.c +++ /dev/null @@ -1,125 +0,0 @@ -// -// 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/>. -// - -#include <cron.h> -#include <printf.h> -#include <wb_utils.h> -#include <wb_uart.h> -#include <wb_i2c.h> -#include <wb_pkt_iface64.h> -#include <u3_net_stack.h> -#include <print_addrs.h> -#include <trace.h> -#include "../../../host/lib/usrp/n230/n230_eeprom.h" -#include "n230_init.h" -#include "../../../host/lib/usrp/n230/n230_fw_defs.h" - -static wb_pkt_iface64_config_t pkt_config; - -static void putc(void *p, char c) -{ -//If FW_TRACE_LEVEL is defined, then the trace level is set -//to a non-zero number. Turn on the debug UART to enable tracing -#ifdef UHD_FW_TRACE_LEVEL - wb_uart_putc(WB_DBG_UART_BASE, c); -#endif -} - -static uint32_t get_counter_val() -{ - return wb_peek32(SR_ADDR(WB_SBRB_BASE, RB_ZPU_COUNTER)); -} - -void n230_init(void) -{ - //TODO: We may need to remove the debug UART before we release. - //Initialize the debug UART first. - wb_uart_init(WB_DBG_UART_BASE, CPU_CLOCK_FREQ/DBG_UART_BAUD); - init_printf(NULL, putc); - - //Now we can init the rest with prints - UHD_FW_TRACE_FSTR(INFO, "[ZPU Init Begin -- CPU CLOCK is %d MHz]", (CPU_CLOCK_FREQ/1000000)); - - //Initialize cron and the per millisecond cron job - UHD_FW_TRACE(INFO, "Initializing cron..."); - cron_init(get_counter_val, CPU_CLOCK_FREQ); - cron_job_init(PER_MILLISEC_CRON_JOBID, 1); - cron_job_init(PER_SECOND_CRON_JOBID, 1000); - - //Initialize rate for I2C cores - UHD_FW_TRACE(INFO, "Initializing I2C..."); - for (uint32_t i = 0; i < N230_NUM_ETH_PORTS; i++) { - wb_i2c_init((i==1)?WB_ETH1_I2C_BASE:WB_ETH0_I2C_BASE, CPU_CLOCK_FREQ); - } - - //Initialize eeprom - read_n230_eeprom(); - - UHD_FW_TRACE(INFO, "Initializing network stack..."); - init_network_stack(); -} - -void init_network_stack(void) -{ - //Hold Ethernet PHYs in reset - wb_poke32(SR_ADDR(WB_SBRB_BASE, SR_ZPU_SW_RST), SR_ZPU_SW_RST_PHY); - - //Initialize ethernet packet interface - pkt_config = wb_pkt_iface64_init(WB_PKT_RAM_BASE, WB_PKT_RAM_CTRL_OFFSET); - u3_net_stack_init(&pkt_config); - - //Initialize MACs - for (uint32_t i = 0; i < N230_NUM_ETH_PORTS; i++) { - init_ethernet_mac(i); - } - - //Pull Ethernet PHYs out of reset - wb_poke32(SR_ADDR(WB_SBRB_BASE, SR_ZPU_SW_RST), SR_ZPU_SW_RST_NONE); -} - -void init_ethernet_mac(uint32_t iface_num) -{ - UHD_FW_TRACE_FSTR(INFO, "Initializing eth%d...", iface_num); - - //Get interface info from the EEPROM (or defaults otherwise) - const n230_eth_eeprom_map_t* eth_eeprom_map = get_n230_ethernet_info(iface_num); - const eth_mac_addr_t *my_mac = (const eth_mac_addr_t *) &(eth_eeprom_map->mac_addr); - const struct ip_addr *my_ip = (const struct ip_addr *) &(eth_eeprom_map->ip_addr); - const struct ip_addr *subnet = (const struct ip_addr *) &(eth_eeprom_map->subnet); - - //Init software fields related to ethernet - u3_net_stack_init_eth(iface_num, my_mac, my_ip, subnet); - - uint32_t dispatcher_base = - ((iface_num == 1) ? SR_ZPU_ETHINT1 : SR_ZPU_ETHINT0) + SR_ZPU_ETHINT_DISPATCHER_BASE; - - //Program dispatcher - wb_poke32(SR_ADDR(WB_SBRB_BASE, dispatcher_base + 0), - (my_mac->addr[5] << 0) | (my_mac->addr[4] << 8) | (my_mac->addr[3] << 16) | (my_mac->addr[2] << 24)); - wb_poke32(SR_ADDR(WB_SBRB_BASE, dispatcher_base + 1), (my_mac->addr[1] << 0) | (my_mac->addr[0] << 8)); - wb_poke32(SR_ADDR(WB_SBRB_BASE, dispatcher_base + 2), my_ip->addr); - wb_poke32(SR_ADDR(WB_SBRB_BASE, dispatcher_base + 4), 0/*nofwd*/); - wb_poke32(SR_ADDR(WB_SBRB_BASE, dispatcher_base + 5), (ICMP_IRQ << 8) | 0); //no fwd: type, code - - //DEBUG: Print initialized info - UHD_FW_TRACE_FSTR(INFO, "-- MAC%u: %s", iface_num, mac_addr_to_str(u3_net_stack_get_mac_addr(iface_num))); - UHD_FW_TRACE_FSTR(INFO, "-- IP%u: %s", iface_num, ip_addr_to_str(u3_net_stack_get_ip_addr(iface_num))); - UHD_FW_TRACE_FSTR(INFO, "-- SUBNET%u: %s", iface_num, ip_addr_to_str(u3_net_stack_get_subnet(iface_num))); - UHD_FW_TRACE_FSTR(INFO, "-- BCAST%u: %s", iface_num, ip_addr_to_str(u3_net_stack_get_bcast(iface_num))); -} - - diff --git a/firmware/usrp3/n230/n230_init.h b/firmware/usrp3/n230/n230_init.h deleted file mode 100644 index e2231909e..000000000 --- a/firmware/usrp3/n230/n230_init.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// 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_INIT_H -#define INCLUDED_N230_INIT_H - -#include <stdint.h> -#include <stdbool.h> - -void n230_init(void); -void init_network_stack(void); -void init_ethernet_mac(uint32_t iface_num); - -#endif /* INCLUDED_B250_INIT_H */ diff --git a/firmware/usrp3/n230/n230_main.c b/firmware/usrp3/n230/n230_main.c deleted file mode 100644 index a6c12e56d..000000000 --- a/firmware/usrp3/n230/n230_main.c +++ /dev/null @@ -1,113 +0,0 @@ -// -// 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/>. -// - -#include <cron.h> -#include <wb_soft_reg.h> -#include <u3_net_stack.h> -#include <trace.h> -#include "../../../host/lib/usrp/n230/n230_fw_defs.h" -#include "../../../host/lib/usrp/n230/n230_fw_host_iface.h" -#include "n230_eth_handlers.h" -#include "n230_init.h" - -//The version hash should come from a cmake build variable -//If it doesn't then the build system does not support the feature -//so just default to 0xFFFFFFFF -#ifndef UHD_VERSION_HASH -#define UHD_VERSION_HASH 0xFFFFFFFF -#endif - -//TODO: This is just for initial debugging. -static soft_reg_t g_led_register; - -//Shared memory -static n230_host_shared_mem_t g_host_shared_mem; - -//Functions -static void n230_handle_claim(); - -/*********************************************************************** - * Main loop runs all the handlers - **********************************************************************/ -int main(void) -{ - //Initialize host shared mem - g_host_shared_mem.data.fw_compat_num = N230_FW_COMPAT_NUM; - g_host_shared_mem.data.fw_version_hash = UHD_VERSION_HASH; - - //Main initialization function - n230_init(); - - //Initialize UDP Handlers - n230_register_udp_fw_comms_handler(&g_host_shared_mem); - n230_register_udp_prog_framer(); - n230_register_flash_comms_handler(); - - initialize_writeonly_soft_reg(&g_led_register, SR_ADDR(WB_SBRB_BASE, SR_ZPU_LEDS)); - - uint32_t heart_beat = 0; - while(true) - { - //TODO: This is just for initial debugging. Once the firmware - //is somewhat stable we should delete this cron job - if (cron_job_run_due(PER_SECOND_CRON_JOBID)) { - //Everything in this block runs approx once per second - if (heart_beat % 10 == 0) { - UHD_FW_TRACE_FSTR(INFO, "0.1Hz Heartbeat (%u)", heart_beat); - } - heart_beat++; - } - - if (cron_job_run_due(PER_MILLISEC_CRON_JOBID)) { - //Everything in this block runs approx once per millisecond - n230_handle_claim(); - n230_update_link_act_state(&g_led_register); - } - - //run the network stack - poll and handle - u3_net_stack_handle_one(); - } - return 0; -} - -// Watchdog timer for claimer -static void n230_handle_claim() -{ - static uint32_t last_time = 0; - static size_t timeout = 0; - - if (g_host_shared_mem.data.claim_time == 0) { - //If time is 0 if the claim was forfeit - g_host_shared_mem.data.claim_status = 0; - } else if (last_time != g_host_shared_mem.data.claim_time) { - //If the time changes, reset timeout - g_host_shared_mem.data.claim_status = 1; - timeout = 0; - } else { - //Otherwise increment for timeout - timeout++; - } - - //Always stash the last seen time - last_time = g_host_shared_mem.data.claim_time; - - //Timeout logic - if (timeout > N230_CLAIMER_TIMEOUT_IN_MS) { - g_host_shared_mem.data.claim_time = 0; - } -} - |