diff options
author | Nick Foster <nick@nerdnetworks.org> | 2010-07-26 15:33:30 -0700 |
---|---|---|
committer | Nick Foster <nick@nerdnetworks.org> | 2010-07-26 15:33:30 -0700 |
commit | f72ad02f5ec370f45995ecd2b3e8b322e9a7e4dc (patch) | |
tree | 069b728b6e44a5db8607a8c5815e3a2d50a114ac /firmware/microblaze/lib/xilinx_s3_icap.c | |
parent | f86c25317b457b280c697fc47905c79bdbbc0c93 (diff) | |
download | uhd-f72ad02f5ec370f45995ecd2b3e8b322e9a7e4dc.tar.gz uhd-f72ad02f5ec370f45995ecd2b3e8b322e9a7e4dc.tar.bz2 uhd-f72ad02f5ec370f45995ecd2b3e8b322e9a7e4dc.zip |
New branch with firmware dir from USRP2P branch.
Diffstat (limited to 'firmware/microblaze/lib/xilinx_s3_icap.c')
-rw-r--r-- | firmware/microblaze/lib/xilinx_s3_icap.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/firmware/microblaze/lib/xilinx_s3_icap.c b/firmware/microblaze/lib/xilinx_s3_icap.c new file mode 100644 index 000000000..8aa7fd297 --- /dev/null +++ b/firmware/microblaze/lib/xilinx_s3_icap.c @@ -0,0 +1,101 @@ +/* -*- c -*- */ +/* + * Copyright 2009 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/>. + */ + + +/* Changes required to work for the Spartan-3A series: + * The ICAP interface on the 3A is 8 bits wide, instead of 32. + * Everything is Xilinx standard LSB-first. + * The operations are all different. + * Commands are 16 bits long, presented to the ICAP interface 8 bits at a time. +*/ + +#include <xilinx_s3_icap.h> +#include <memory_map.h> +#include <spi_flash_private.h> //for READ_CMD + + +/* bit swap end-for-end */ +static unsigned char +swap8(unsigned char x) +{ + unsigned char r = 0; + r |= (x >> 7) & 0x01; + r |= (x >> 5) & 0x02; + r |= (x >> 3) & 0x04; + r |= (x >> 1) & 0x08; + + r |= (x << 1) & 0x10; + r |= (x << 3) & 0x20; + r |= (x << 5) & 0x40; + r |= (x << 7) & 0x80; + + return r; +} + +void +wr_icap(uint8_t x) +{ + uint8_t t = swap8(x); + + icap_regs->icap = t; //DEBUG: does not swap bits +} + +uint8_t +rd_icap(void) +{ + return swap8(icap_regs->icap); +} + + +void +icap_reload_fpga(uint32_t flash_address) +//this DOES NOT WORK right now. reboot is not getting executed correctly. +{ + union { + uint32_t i; + uint8_t c[4]; + } t; + t.i = flash_address; + + //note! t.c[0] MUST contain the byte-wide read command for the flash device used. + //for the 25P64, and most other flash devices, this is 0x03. + t.c[0] = READ_CMD; //legacy command, use FAST_READ_CMD 0x0B after testing + + //TODO: look up the watchdog timer, ensure it won't fire too soon + + //UG332 p279 +// wr_icap(0xff); +// wr_icap(0xff); //dummy word, probably unnecessary + wr_icap(0xAA); + wr_icap(0x99); //sync word + wr_icap(0x32); + wr_icap(0x61); //Type 1 write General 1 (1 word) + wr_icap(t.c[2]); //bits 15-8 + wr_icap(t.c[3]); //bits 7-0 + wr_icap(0x32); + wr_icap(0x81); //Type 1 write General 2 (1 word) + wr_icap(t.c[0]); //C0-C8, the byte-wide read command + wr_icap(t.c[1]); //Upper 8 bits of 24-bit address + wr_icap(0x30); + wr_icap(0xA1); //Type 1 write CMD (1 word) + wr_icap(0x00); + wr_icap(0x0E); //REBOOT command + wr_icap(0x20); + wr_icap(0x00); //Type 1 NOP + +} |