aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/x300
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/x300')
-rw-r--r--firmware/x300/lib/chinch.c19
-rw-r--r--firmware/x300/lib/ethernet.c5
-rw-r--r--firmware/x300/x300/x300_init.c8
-rw-r--r--firmware/x300/x300/x300_main.c9
-rwxr-xr-xfirmware/x300/x300_debug.py167
-rwxr-xr-xfirmware/x300/x300_fpga_downloader.py179
6 files changed, 23 insertions, 364 deletions
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 <http://www.gnu.org/licenses/>.
-#
-
-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 <http://www.gnu.org/licenses/>.
-#
-
-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))