From ff1546f8137f7f92bb250f685561b0c34cc0e053 Mon Sep 17 00:00:00 2001 From: Ben Hilburn Date: Fri, 14 Feb 2014 12:05:07 -0800 Subject: Pushing the bulk of UHD-3.7.0 code. --- firmware/x300/lib/chinch.c | 19 ++-- firmware/x300/lib/ethernet.c | 5 +- firmware/x300/x300/x300_init.c | 8 +- firmware/x300/x300/x300_main.c | 9 +- firmware/x300/x300_debug.py | 167 ------------------------------- firmware/x300/x300_fpga_downloader.py | 179 ---------------------------------- 6 files changed, 23 insertions(+), 364 deletions(-) delete mode 100755 firmware/x300/x300_debug.py delete mode 100755 firmware/x300/x300_fpga_downloader.py (limited to 'firmware/x300') diff --git a/firmware/x300/lib/chinch.c b/firmware/x300/lib/chinch.c index 054845754..e33378851 100644 --- a/firmware/x300/lib/chinch.c +++ b/firmware/x300/lib/chinch.c @@ -210,15 +210,18 @@ bool chinch_flash_write_buf(uint32_t offset, uint16_t* buf, uint32_t size) STATUS_CHAIN(chinch_poke16(base_addr + (i * 2), buf[i]), status); } - //Commit write and poll until data is written + //Commit write STATUS_CHAIN(chinch_poke16(CHINCH_FLASH_WINDOW_BASE, 0x0029), status); - if (status) { - uint16_t read_data; - while (true) { - STATUS_MERGE(chinch_flash_read(base_addr, &read_data), status); //Wait for write to finish - if ((read_data == buf[0]) || !status) break; - } - } + + //Poll for completion + //Bit 7 of the data at the final address is the status bit. + //It is set to the inverse of bit 7 of the final data to be + //written until the final write is completed. + uint32_t read_data; + do { + STATUS_MERGE(chinch_peek16(base_addr + ((size - 1) * 2), &read_data), status); + } while (status && (((uint16_t)read_data ^ buf[size - 1]) & (1 << 7))); + return status; } diff --git a/firmware/x300/lib/ethernet.c b/firmware/x300/lib/ethernet.c index 806a3840d..fdde9e41b 100644 --- a/firmware/x300/lib/ethernet.c +++ b/firmware/x300/lib/ethernet.c @@ -336,9 +336,8 @@ xge_phy_init(const uint8_t eth, const uint32_t mdio_port) x = read_mdio(eth, 0x0, XGE_MDIO_DEVICE_PMA,mdio_port); x = x | (1 << 15); write_mdio(eth, 0x0,XGE_MDIO_DEVICE_PMA,mdio_port,x); - //FIXME uncomment lines below when 1gigE MDIO works - //while(x&(1<<15)) - // x = read_mdio(eth, 0x0,XGE_MDIO_DEVICE_PMA,mdio_port); + while(x&(1<<15)) + x = read_mdio(eth, 0x0,XGE_MDIO_DEVICE_PMA,mdio_port); } void diff --git a/firmware/x300/x300/x300_init.c b/firmware/x300/x300/x300_init.c index 2a3ee472e..2ddfef86b 100644 --- a/firmware/x300/x300/x300_init.c +++ b/firmware/x300/x300/x300_init.c @@ -149,8 +149,12 @@ void x300_init(void) // For eth interfaces, initialize the PHY's mdelay(100); - xge_ethernet_init(0); - xge_ethernet_init(1); + if (wb_peek32(SR_ADDR(RB0_BASE, RB_ETH_TYPE0)) == 1) { + xge_ethernet_init(0); + } + if (wb_peek32(SR_ADDR(RB0_BASE, RB_ETH_TYPE1)) == 1) { + xge_ethernet_init(1); + } //print network summary for (uint8_t e = 0; e < ethernet_ninterfaces(); e++) diff --git a/firmware/x300/x300/x300_main.c b/firmware/x300/x300/x300_main.c index 7d6771bc7..4e3f2d585 100644 --- a/firmware/x300/x300/x300_main.c +++ b/firmware/x300/x300/x300_main.c @@ -330,11 +330,10 @@ static void handle_uarts(void) shmem[X300_FW_SHMEM_UART_WORDS32] = NUM_POOL_WORDS32; //////////////////////////////////////////////////////////////////// - // RX UART - try to get a character and post it to the shmem buffer + // RX UART - get available characters and post to the shmem buffer //////////////////////////////////////////////////////////////////// static uint32_t rxoffset = 0; - const int rxch = wb_uart_getc(UART0_BASE); - if (rxch != -1) + for (int rxch = wb_uart_getc(UART0_BASE); rxch != -1; rxch = wb_uart_getc(UART0_BASE)) { rxoffset = (rxoffset+1) % (NUM_POOL_WORDS32*4); const int shift = ((rxoffset%4) * 8); @@ -346,10 +345,10 @@ static void handle_uarts(void) } //////////////////////////////////////////////////////////////////// - // TX UART - check for a character in the shmem buffer and send it + // TX UART - check for characters in the shmem buffer and send them //////////////////////////////////////////////////////////////////// static uint32_t txoffset = 0; - if (txoffset != shmem[X300_FW_SHMEM_UART_TX_INDEX]) + while (txoffset != shmem[X300_FW_SHMEM_UART_TX_INDEX]) { const int shift = ((txoffset%4) * 8); const int txch = txpool[txoffset/4] >> shift; diff --git a/firmware/x300/x300_debug.py b/firmware/x300/x300_debug.py deleted file mode 100755 index c9bcbb138..000000000 --- a/firmware/x300/x300_debug.py +++ /dev/null @@ -1,167 +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 . -# - -import optparse -import math -import socket -import struct - - -######################################################################## -# constants -######################################################################## -B250_FW_COMMS_UDP_PORT = 49152 - -B250_FW_COMMS_FLAGS_ACK = 1 -B250_FW_COMMS_FLAGS_ERROR = 2 -B250_FW_COMMS_FLAGS_POKE32 = 4 -B250_FW_COMMS_FLAGS_PEEK32 = 8 - -#UDP_CTRL_PORT = 49183 -UDP_MAX_XFER_BYTES = 1024 -UDP_TIMEOUT = 3 -#USRP2_FW_PROTO_VERSION = 11 #should be unused after r6 - -#REG_ARGS_FMT = '!LLLLLB15x' -#REG_IP_FMT = '!LLLL20x' -REG_PEEK_POKE_FMT = '!LLLL' - - -_seq = -1 -def seq(): - global _seq - _seq = _seq+1 - return _seq - - -######################################################################## -# helper functions -######################################################################## - -def unpack_reg_peek_poke_fmt(s): - return struct.unpack(REG_PEEK_POKE_FMT,s) #(flags, seq, addr, data) - -def pack_reg_peek_poke_fmt(flags, seq, addr, data): - return struct.pack(REG_PEEK_POKE_FMT, flags, seq, addr, data); - -######################################################################## -# Burner class, holds a socket and send/recv routines -######################################################################## -class ctrl_socket(object): - def __init__(self, addr): - self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self._sock.settimeout(UDP_TIMEOUT) - self._sock.connect((addr, B250_FW_COMMS_UDP_PORT)) - self.set_callbacks(lambda *a: None, lambda *a: None) - #self.init_update() #check that the device is there - - 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 read_router_stats(self): - print - print(" "), - ports = [' eth0',' eth1',' radio0',' radio1',' compute0',' compute1',' compute2',' pcie'] - for in_prt in ports: - print("%s" % in_prt), - print(" Egress Port") - print(" "), - for in_prt in range (0, 8): - print("____________"), - print - for in_prt in range (0, 8): - print("%s |" % ports[in_prt]), - for out_prt in range (0, 8): - out_pkt = pack_reg_peek_poke_fmt(B250_FW_COMMS_FLAGS_PEEK32|B250_FW_COMMS_FLAGS_ACK, seq(), 0xA000+256+((in_prt*8+out_prt)*4), 0) - in_pkt = self.send_and_recv(out_pkt) - (flags, rxseq, addr, data) = unpack_reg_peek_poke_fmt(in_pkt) - if flags & B250_FW_COMMS_FLAGS_ERROR == B250_FW_COMMS_FLAGS_ERROR: - raise Exception("B250 peek returns error code") - print("%10d " % (data)), - print - print - print("Ingress Port") - print - - - def peek(self,peek_addr): - out_pkt = pack_reg_peek_poke_fmt(B250_FW_COMMS_FLAGS_PEEK32|B250_FW_COMMS_FLAGS_ACK, seq(), peek_addr, 0) - in_pkt = self.send_and_recv(out_pkt) - (flags, rxseq, addr, data) = unpack_reg_peek_poke_fmt(in_pkt) - if flags & B250_FW_COMMS_FLAGS_ERROR == B250_FW_COMMS_FLAGS_ERROR: - raise Exception("B250 peek of address %d returns error code" % (addr)) - print("PEEK of address %d(0x%x) reads %d(0x%x)" % (addr,addr,data,data)) - - def poke(self,poke_addr,poke_data): - out_pkt = pack_reg_peek_poke_fmt(B250_FW_COMMS_FLAGS_POKE32|B250_FW_COMMS_FLAGS_ACK, seq(), poke_addr, poke_data) - in_pkt = self.send_and_recv(out_pkt) - (flags, rxseq, addr, data) = unpack_reg_peek_poke_fmt(in_pkt) - if flags & B250_FW_COMMS_FLAGS_ERROR == B250_FW_COMMS_FLAGS_ERROR: - raise Exception("B250 peek of address %d returns error code" % (addr)) - print("POKE of address %d(0x%x) with %d(0x%x)" % (poke_addr,poke_addr,poke_data,poke_data) ) - - -######################################################################## -# command line options -######################################################################## -def get_options(): - parser = optparse.OptionParser() - parser.add_option("--addr", type="string", help="USRP-N2XX device address", default='') - parser.add_option("--list", action="store_true", help="list possible network devices", default=False) - 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("--stats", action="store_true", help="Display SuperMIMO Network Stats", default=False) - (options, args) = parser.parse_args() - - return options - - -######################################################################## -# main -######################################################################## -if __name__=='__main__': - options = get_options() - - - if options.list: - print('Possible network devices:') - print(' ' + '\n '.join(enumerate_devices())) - exit() - - if not options.addr: raise Exception('no address specified') - - status = ctrl_socket(addr=options.addr) - - if options.stats: - status.read_router_stats() - - - if options.peek is not None: - addr = options.peek - status.peek(addr) - - if options.poke is not None and options.data is not None: - addr = options.poke - data = options.data - status.poke(addr,data) diff --git a/firmware/x300/x300_fpga_downloader.py b/firmware/x300/x300_fpga_downloader.py deleted file mode 100755 index 5529afcb7..000000000 --- a/firmware/x300/x300_fpga_downloader.py +++ /dev/null @@ -1,179 +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 . -# - -import optparse -import math -import socket -import struct -import time -import sys - -######################################################################## -# constants -######################################################################## -B250_FPGA_IMAGE_SIZE_BYTES = 15877916 -B250_FPGA_PROG_UDP_PORT = 49157 - -B250_FPGA_PROG_FLAGS_ACK = 1 -B250_FPGA_PROG_FLAGS_ERROR = 2 -B250_FPGA_PROG_FLAGS_INIT = 4 -B250_FPGA_PROG_FLAGS_CLEANUP = 8 -B250_FPGA_PROG_FLAGS_ERASE = 16 -B250_FPGA_PROG_FLAGS_VERIFY = 32 -B250_FPGA_PROG_CONFIGURE = 64 -B250_FPGA_PROG_CONFIG_STATUS = 128 - -B250_FLASH_SECTOR_SIZE = 131072 -B250_PACKET_SIZE = 256 -B250_FPGA_SECTOR_START = 16 - -B250_MAX_RESPONSE_BYTES = 128 -UDP_TIMEOUT = 3 -FPGA_LOAD_TIMEOUT = 15 - -######################################################################## -# helper functions -######################################################################## -def get_options(): - parser = optparse.OptionParser() - parser.add_option("--addr", type="string", help="USRP-B250 device address", default='') - parser.add_option("--download", type="string", help="Path to the FPGA image to download.", default=None) - parser.add_option("--posc", type="string", help="Path to the POSC image to download.", default=None) - parser.add_option("--program", action="store_true", help="Program the FPGA from flash.", default=False) - parser.add_option("--verify", action="store_true", help="Verify data downloaded to flash.", default=False) - (options, args) = parser.parse_args() - return options - -def draw_progress_bar(percent, bar_len = 28): - 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() - -def unpack_x300_fpga_flags_fmt(s): - return struct.unpack('!L', s)[0] #(flags) - -def pack_x300_fpga_prog_fmt(flags, sector, offset, size, data): - return struct.pack("!LLLL%dH" % (len(data),), flags, sector, offset, size, *data) - -def bit_reverse(byte): - b = ord(byte) - b = (b & 0xF0) >> 4 | (b & 0x0F) << 4 - b = (b & 0xCC) >> 2 | (b & 0x33) << 2 - b = (b & 0xAA) >> 1 | (b & 0x55) << 1 - return chr(b) - -def chunkify(stuff, n): - return [stuff[i:i+n] for i in range(0, len(stuff), n)] - -######################################################################## -# Burner class, holds a socket and send/recv routines -######################################################################## -class ctrl_socket(object): - def __init__(self, addr): - self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self._sock.settimeout(UDP_TIMEOUT) - self._sock.connect((addr, B250_FPGA_PROG_UDP_PORT)) - self.set_callbacks(lambda *a: None, lambda *a: None) - - def set_callbacks(self, progress_cb, status_cb): - self._progress_cb = progress_cb - self._status_cb = status_cb - - def send_without_ack(self, pkt): - self._sock.send(pkt) - - def send_with_ack(self, out_pkt, message): - self.send_without_ack(out_pkt) - in_pkt = self._sock.recv(B250_MAX_RESPONSE_BYTES) - flags = unpack_x300_fpga_flags_fmt(in_pkt) - if flags & B250_FPGA_PROG_FLAGS_ERROR == B250_FPGA_PROG_FLAGS_ERROR: - raise Exception(message) - - def download_fpga(self, image, verify): - print("Reading FPGA image file...") - fpga_file = open(image, 'rb') - print("Processing FPGA image...") - fpga_image = ''.join([ bit_reverse(b) for b in fpga_file.read() ]) - - print("Writing FPGA image to flash...") - out_pkt = pack_x300_fpga_prog_fmt(B250_FPGA_PROG_FLAGS_ACK|B250_FPGA_PROG_FLAGS_INIT, - 0, 0, 0, [0]*(B250_PACKET_SIZE/2)) - self.send_with_ack(out_pkt, "Flash initialization failed!!!") - - sector_chunks = chunkify(fpga_image, B250_FLASH_SECTOR_SIZE) - for sector_idx in range(len(sector_chunks)): - packet_chunks = chunkify(sector_chunks[sector_idx], B250_PACKET_SIZE) - offset = 0 - for packet_data in packet_chunks: - data = struct.unpack("%dH" % (len(packet_data) / 2), packet_data) - flags = B250_FPGA_PROG_FLAGS_ACK - if offset == 0: flags |= B250_FPGA_PROG_FLAGS_ERASE - if verify: flags |= B250_FPGA_PROG_FLAGS_VERIFY - out_pkt = pack_x300_fpga_prog_fmt(flags, B250_FPGA_SECTOR_START+sector_idx, offset, len(data), data) - self.send_with_ack(out_pkt, "Transfer failed or data verification failed!!!") - offset += len(data) - draw_progress_bar(((sector_idx+1)*100)/len(sector_chunks)) - - print(' ') - out_pkt = pack_x300_fpga_prog_fmt(B250_FPGA_PROG_FLAGS_ACK|B250_FPGA_PROG_FLAGS_CLEANUP, - 0, 0, 0, [0]*(B250_PACKET_SIZE/2)) - self.send_with_ack(out_pkt, "Flash cleanup failed!!!") - - def program(self): - print("Programming FPGA from flash...") - out_pkt = pack_x300_fpga_prog_fmt(B250_FPGA_PROG_CONFIGURE, 0, 0, 0, [0]*(B250_PACKET_SIZE/2)) - self.send_without_ack(out_pkt) - print("Waiting for FPGA to load...") - self._sock.settimeout(1) - out_pkt = pack_x300_fpga_prog_fmt(B250_FPGA_PROG_FLAGS_ACK|B250_FPGA_PROG_CONFIG_STATUS, 0, 0, 0, [0]*(B250_PACKET_SIZE/2)) - for i in range(FPGA_LOAD_TIMEOUT): - try: - self.send_without_ack(out_pkt) - in_pkt = self._sock.recv(B250_MAX_RESPONSE_BYTES) - flags = unpack_x300_fpga_flags_fmt(in_pkt) - if not(flags & B250_FPGA_PROG_FLAGS_ERROR == B250_FPGA_PROG_FLAGS_ERROR): - break - except socket.error: - pass - - -######################################################################## -# main -######################################################################## -if __name__=='__main__': - options = get_options() - - if not options.addr: - raise Exception('No address specified') - - status = ctrl_socket(addr=options.addr) - - start_time = time.time() - if options.download is not None: - status.download_fpga(options.download, options.verify) - - if options.program: - status.program() - - print("(Elapsed time: %.1fs)" % (time.time() - start_time)) -- cgit v1.2.3