Merge remote-tracking branch 'mossmann/master' into rad1o

Just a very rough merge to get off the ground. Major parts are not yet
implemented. The mixer intergration is in a messed up state. Part which
need work have been marked with XXX

Conflicts:
	firmware/common/hackrf_core.c
	firmware/common/hackrf_core.h
	firmware/common/max2837.c
	firmware/common/max2837.h
	firmware/common/rf_path.c
	firmware/common/rffc5071.c
	firmware/common/rffc5071.h
	firmware/common/sgpio.c
	firmware/common/si5351c.c
	firmware/common/tuning.c
	firmware/common/w25q80bv.c
	firmware/common/w25q80bv.h
	firmware/common/xapp058/ports.c
	firmware/hackrf-common.cmake
	firmware/hackrf_usb/hackrf_usb.c
	firmware/hackrf_usb/usb_api_register.c
	firmware/hackrf_usb/usb_api_transceiver.c
	host/hackrf-tools/src/hackrf_transfer.c
This commit is contained in:
schneider
2017-01-25 23:07:00 +01:00
128 changed files with 103942 additions and 61941 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "firmware/libopencm3"]
path = firmware/libopencm3
url = https://github.com/mossmann/libopencm3.git
[submodule "hardware/gsg-kicad-lib"]
path = hardware/gsg-kicad-lib
url = https://github.com/greatscottgadgets/gsg-kicad-lib.git

41
.travis.yml Normal file
View File

@ -0,0 +1,41 @@
language: c
cache: apt
sudo: false
os:
- linux
- osx
compiler:
- gcc
# - clang
before_script:
# - wget https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q1-update/+download/gcc-arm-none-eabi-5_3-2016q1-20160330-linux.tar.bz2 -O /tmp/gcc-arm.tar.bz2
# - tar -xvf /tmp/gcc-arm.tar.bz2
# - export PATH=$PWD/gcc-arm-none-eabi-5_3-2016q1/bin:$PATH
- export CFLAGS="-Wall -Wextra -Werror"
before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libusb; fi
script:
- mkdir host/build
- cd host/build
- cmake ..
- make
# - cd ../../firmware/hackrf_usb
# - mkdir build
# - cd build
# - export CC="arm-none-eabi-gcc"
# - export CXX="arm-none-eabi-g++"
# - cmake ..
# - make
addons:
apt:
packages:
- libusb-1.0-0-dev

View File

@ -1,9 +1,9 @@
This repository contains hardware designs and software for HackRF, a project to
produce a low cost, open source software radio platform.
![Jawbreaker](https://raw.github.com/mossmann/hackrf/master/doc/jawbreaker-fd0-145436.jpeg)
![HackRF One](https://raw.github.com/mossmann/hackrf/master/doc/HackRF-One-fd0-0009.jpeg)
(photo by fd0 from https://github.com/fd0/jawbreaker-pictures)
(photo by fd0 from https://github.com/fd0/hackrf-one-pictures)
principal author: Michael Ossmann <mike@ossmann.com>

View File

@ -1,3 +1,3 @@
"HackRF" is a trademark of Michael Ossmann. Permission to use the trademark
with attribution to Michael Ossmann is granted to all licensees of HackRF for
the purpose of naming or describing copies or derived works. (See COPYING.)
"HackRF" is a trademark of Great Scott Gadgets. Permission to use the trademark
with attribution to Great Scott Gadgets is granted to all licensees of HackRF for
the sole purpose of naming or describing copies or derived works. (See COPYING.)

Binary file not shown.

After

Width:  |  Height:  |  Size: 679 KiB

View File

@ -1,415 +1,66 @@
ref;value;Field1;Field2;Field3;Field4;Field5;Field6;Field7;Field8
C1;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C2;10nF;Murata;GRM155R71C103KA01D;CAP CER 10000PF 16V 10% X7R 0402;;;;;
C3;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C4;10nF;Murata;GRM155R71C103KA01D;CAP CER 10000PF 16V 10% X7R 0402;;;;;
C5;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C6;10nF;Murata;GRM155R71C103KA01D;CAP CER 10000PF 16V 10% X7R 0402;;;;;
C7;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C8;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;;;;;
C9;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C10;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C11;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C12;330pF;Murata;GRM155R71H331KA01D;CAP CER 330PF 50V 10% X7R 0402;;;;;
C13;330pF;Murata;GRM155R71H331KA01D;CAP CER 330PF 50V 10% X7R 0402;;;;;
C14;8p2;Taiyo Yuden;UMK105CG8R2DV-F;CAP CER 8.2PF 50V NP0 0402;;;;;
C15;180pF;Murata;GRM1555C1H181JA01D;CAP CER 180PF 50V 5% NP0 0402;;;;;
C16;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C17;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C18;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C19;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C20;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C21;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;;;;;
C22;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C23;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C24;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C25;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C26;47pF;Murata;GRM1555C1H470JA01D;CAP CER 47PF 50V 5% NP0 0402;;;;;
C27;47pF;Murata;GRM1555C1H470JA01D;CAP CER 47PF 50V 5% NP0 0402;;;;;
C28;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C29;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C30;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C31;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C32;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;;;;;
C33;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C34;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C35;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C36;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C37;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C38;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C39;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C40;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C41;100pF;Murata;GRM1555C1H101JA01D;CAP CER 100PF 50V 5% NP0 0402;;;;;
C42;100pF;Murata;GRM1555C1H101JA01D;CAP CER 100PF 50V 5% NP0 0402;;;;;
C43;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;;;;;
C44;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C45;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C46;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C47;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C48;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;;;;;
C49;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C50;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C51;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;;;;;
C52;100pF;Murata;GRM1555C1H101JA01D;CAP CER 100PF 50V 5% NP0 0402;;;;;
C53;1uF;Taiyo Yuden;LMK105BJ105KV-F;CAP CER 1UF 10V 10% X5R 0402;;;;;
C54;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C55;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C56;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C57;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C58;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C59;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C60;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C61;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C62;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C63;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C64;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C65;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C66;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C67;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C68;100pF;Murata;GRM1555C1H101JA01D;CAP CER 100PF 50V 5% NP0 0402;DNP;;;;
C69;100pF;Murata;GRM1555C1H101JA01D;CAP CER 100PF 50V 5% NP0 0402;DNP;;;;
C70;100pF;Murata;GRM1555C1H101JA01D;CAP CER 100PF 50V 5% NP0 0402;;;;;
C71;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C72;2.2uF;Taiyo Yuden;LMK105BJ225MV-F;CAP CER 2.2UF 10V 20% X5R 0402;;;;;
C73;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C74;2.2uF;Taiyo Yuden;LMK105BJ225MV-F;CAP CER 2.2UF 10V 20% X5R 0402;;;;;
C75;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C76;2.2uF;Taiyo Yuden;LMK105BJ225MV-F;CAP CER 2.2UF 10V 20% X5R 0402;;;;;
C77;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C78;2.2uF;Taiyo Yuden;LMK105BJ225MV-F;CAP CER 2.2UF 10V 20% X5R 0402;;;;;
C79;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C80;2.2uF;Taiyo Yuden;LMK105BJ225MV-F;CAP CER 2.2UF 10V 20% X5R 0402;;;;;
C81;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C82;2.2uF;Taiyo Yuden;LMK105BJ225MV-F;CAP CER 2.2UF 10V 20% X5R 0402;;;;;
C83;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C84;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;;;;;
C85;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;;;;;
C86;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;;;;;
C87;10nF;Murata;GRM155R71C103KA01D;CAP CER 10000PF 16V 10% X7R 0402;;;;;
C88;10nF;Murata;GRM155R71C103KA01D;CAP CER 10000PF 16V 10% X7R 0402;;;;;
C89;10nF;Murata;GRM155R71C103KA01D;CAP CER 10000PF 16V 10% X7R 0402;;;;;
C90;100pF;Murata;GRM1555C1H101JA01D;CAP CER 100PF 50V 5% NP0 0402;;;;;
C91;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C92;10nF;Murata;GRM155R71C103KA01D;CAP CER 10000PF 16V 10% X7R 0402;;;;;
C93;10nF;Murata;GRM155R71C103KA01D;CAP CER 10000PF 16V 10% X7R 0402;;;;;
C94;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;;;;;
C95;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;DNP;;;;
C96;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;DNP;;;;
C97;330nF;Murata;GRM155R61A334KE15D;CAP CER 0.33UF 10V 10% X5R 0402;;;;;
C98;330nF;Murata;GRM155R61A334KE15D;CAP CER 0.33UF 10V 10% X5R 0402;;;;;
C99;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;;;;;
C100;330nF;Murata;GRM155R61A334KE15D;CAP CER 0.33UF 10V 10% X5R 0402;;;;;
C101;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;DNP;;;;
C102;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;;;;;
C103;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;DNP;;;;
C104;3pF;Murata;GRM1555C1H3R0CA01D;CAP CER 3PF 50V NP0 0402;;;;;
C105;10uF;Murata;GRM21BR61A106KE19L;CAP CER 10UF 10V 10% X5R 0805;;;;;
C106;1uF;Taiyo Yuden;LMK105BJ105KV-F;CAP CER 1UF 10V 10% X5R 0402;;;;;
C107;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;DNP;;;;
C108;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;DNP;;;;
C109;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;DNP;;;;
C110;22pF;Murata;GRM1555C1H220JA01D;CAP CER 22PF 50V 5% NP0 0402;DNP;;;;
C111;3pF;Murata;GRM1555C1H3R0CA01D;CAP CER 3PF 50V NP0 0402;;;;;
C112;180pF;Murata;GRM1555C1H181JA01D;CAP CER 180PF 50V 5% NP0 0402;;;;;
C113;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C114;3.3nF;Murata;GRM155R71H332KA01D;CAP CER 3300PF 50V 10% X7R 0402;;;;;
C115;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C116;47pF;Murata;GRM1555C1H470JA01D;CAP CER 47PF 50V 5% NP0 0402;;;;;
C118;18pF;Murata;GRM1555C1H180JA01D;CAP CER 18PF 50V 5% NP0 0402;;;;;
C119;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C120;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C121;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C122;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C123;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C124;2.2uF;Taiyo Yuden;LMK105BJ225MV-F;CAP CER 2.2UF 10V 20% X5R 0402;;;;;
C125;33pF;Murata;GRM1555C1H330JA01D;CAP CER 33PF 50V 5% NP0 0402;;;;;
C126;10uF;Murata;GRM21BR61A106KE19L;CAP CER 10UF 10V 10% X5R 0805;;;;;
C127;10uF;Murata;GRM21BR61A106KE19L;CAP CER 10UF 10V 10% X5R 0805;;;;;
C128;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C129;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C130;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C131;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C132;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C133;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C134;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C135;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C136;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C137;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C138;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C139;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C140;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C141;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C142;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C143;10uF;Murata;GRM21BR61A106KE19L;CAP CER 10UF 10V 10% X5R 0805;;;;;
C144;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C145;10uF;Murata;GRM21BR61A106KE19L;CAP CER 10UF 10V 10% X5R 0805;;;;;
C146;10uF;Murata;GRM21BR61A106KE19L;CAP CER 10UF 10V 10% X5R 0805;;;;;
C147;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C148;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C149;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C150;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C151;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C152;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C153;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C154;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C155;DNP;DNP;;;;;;;
C156;47pF;Murata;GRM1555C1H470JA01D;CAP CER 47PF 50V 5% NP0 0402;DNP;;;;
C157;18pF;Murata;GRM1555C1H180JA01D;CAP CER 18PF 50V 5% NP0 0402;;;;;
C158;18pF;Murata;GRM1555C1H180JA01D;CAP CER 18PF 50V 5% NP0 0402;;;;;
C159;100pF;Murata;GRM1555C1H101JA01D;CAP CER 100PF 50V 5% NP0 0402;DNP;;;;
C160;100pF;Murata;GRM1555C1H101JA01D;CAP CER 100PF 50V 5% NP0 0402;;;;;
C161;1uF;Taiyo Yuden;LMK105BJ105KV-F;CAP CER 1UF 10V 10% X5R 0402;;;;;
C162;10nF;Murata;GRM155R71C103KA01D;CAP CER 10000PF 16V 10% X7R 0402;;;;;
C163;10nF;Murata;GRM155R71C103KA01D;CAP CER 10000PF 16V 10% X7R 0402;;;;;
C164;18pF;Murata;GRM1555C1H180JA01D;CAP CER 18PF 50V 5% NP0 0402;;;;;
C165;100pF;Murata;GRM1555C1H101JA01D;CAP CER 100PF 50V 5% NP0 0402;DNP;;;;
C166;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C167;100nF;Murata;GRM155R61A104KA01D;CAP CER 0.1UF 10V 10% X5R 0402;;;;;
C168;100pF;Murata;GRM1555C1H101JA01D;CAP CER 100PF 50V 5% NP0 0402;DNP;;;;
C169;DNP;DNP;;;;;;;
C170;DNP;DNP;;;;;;;
C171;1uF;Taiyo Yuden;LMK105BJ105KV-F;CAP CER 1UF 10V 10% X5R 0402;;;;;
D1;GSG-DIODE-TVS-BI;Murata;LXES15AAA1-100;TVS DIODE ESD .05PF 15KV 0402;;;;;
D2;VAALED;Lite-On;LTST-S220KRKT;LED SUPR RED CLR RT ANG 0805;;;;;
D3;GSG-DIODE-TVS-BI;Murata;LXES15AAA1-100;TVS DIODE ESD .05PF 15KV 0402;;;;;
D4;USBLED;Lite-On;LTST-S220KGKT;LED GREEN CLEAR RT ANG 0805;;;;;
D5;RXLED;Lite-On;LTST-S220KSKT;LED YELLOW CLEAR RT ANG 0805;;;;;
D6;TXLED;Lite-On;LTST-S220KRKT;LED SUPR RED CLR RT ANG 0805;;;;;
D7;VCCLED;Lite-On;LTST-S220KGKT;LED GREEN CLEAR RT ANG 0805;;;;;
D8;1V8LED;Lite-On;LTST-S220KSKT;LED YELLOW CLEAR RT ANG 0805;;;;;
D9;GSG-DIODE-TVS-BI;Murata;LXES15AAA1-100;TVS DIODE ESD .05PF 15KV 0402;;;;;
FB1;FILTER;Murata;BLM21PG221SN1D;FERRITE CHIP 220 OHM 2000MA 0805;;;;;
FB2;FILTER;Murata;BLM21PG221SN1D;FERRITE CHIP 220 OHM 2000MA 0805;;;;;
FB3;FILTER;Murata;BLM21PG221SN1D;FERRITE CHIP 220 OHM 2000MA 0805;;;;;
J1;USB-MICRO-B;FCI;10103592-0001LF;CONN RCPT REV MICRO USB TYPE B;;;;;
J2;RF-SHIELD-FRAME;Laird;BMI-S-230-F-R;BOARD SHIELD 2INX1.5IN FRAME;DNP;;;;
J3;RF-SHIELD-COVER;Laird;BMI-S-230-C;BOARD SHIELD 2INX1.5IN COVER;DNP;;;;
J4;MOUNTING_HOLE;DNP;;;;;;;
J5;MOUNTING_HOLE;DNP;;;;;;;
J6;MOUNTING_HOLE;DNP;;;;;;;
J7;MOUNTING_HOLE;DNP;;;;;;;
J8;MOUNTING_HOLE;DNP;;;;;;;
J9;MOUNTING_HOLE;DNP;;;;;;;
J10;GND_CLIP;Harwin;S1751-46R;PC TEST POINT TIN SMD;DNP;;;;
L1;DNP;DNP;;;;;;;
L2;10uH;Taiyo Yuden;BRL1608T100M;INDUCTR 10UH 220MA 20% 0603 SMD;;;;;
L3;10uH;Taiyo Yuden;BRL1608T100M;INDUCTR 10UH 220MA 20% 0603 SMD;;;;;
L4;DNP;DNP;;;;;;;
L5;10uH;Taiyo Yuden;BRL1608T100M;INDUCTR 10UH 220MA 20% 0603 SMD;;;;;
L6;DNP;DNP;;;;;;;
L7;6.2nH;Taiyo Yuden;HK10056N2S-T;INDUCTOR HIFREQ 6.2+/-0.3NH 0402;;;;;
L8;DNP;DNP;;;;;;;
L9;DNP;DNP;;;;;;;
L10;4u7;Taiyo Yuden;NRG4026T4R7M;INDUCTOR 4.7UH 1.6A 20% SMD;;;;;
L11;4u7;Taiyo Yuden;NRG4026T4R7M;INDUCTOR 4.7UH 1.6A 20% SMD;;;;;
L12;10uH;Taiyo Yuden;BRL1608T100M;INDUCTR 10UH 220MA 20% 0603 SMD;;;;;
L13;10uH;Taiyo Yuden;BRL1608T100M;INDUCTR 10UH 220MA 20% 0603 SMD;;;;;
P1;1V8;DNP;;;;;;;
P2;CLKOUT;Molex;73251-2121;CONN SMA JACK 50 OHM EDGE MNT W/JAM NUT & LOCK WASHER;;;;;
P3;GND;DNP;;;;;;;
P4;ANTENNA;Molex;73251-2121;CONN SMA JACK 50 OHM EDGE MNT W/JAM NUT & LOCK WASHER;;;;;
P5;LEDS;DNP;;;;;;;
P6;GPO4;DNP;;;;;;;
P7;GPO2;DNP;;;;;;;
P8;VCC;DNP;;;;;;;
P9;BASEBAND;Sullins;PPPC082LFBN-RC;CONN HEADER FMAL 16PS.1" DL GOLD;;;;;
P13;GPO1;DNP;;;;;;;
P14;XCVR_CLKOUT;DNP;;;;;;;
P15;INTR;DNP;;;;;;;
P16;CLKIN;Molex;73251-2121;CONN SMA JACK 50 OHM EDGE MNT W/JAM NUT & LOCK WASHER;;;;;
P17;GPO6;DNP;;;;;;;
P18;OEB;DNP;;;;;;;
P19;GPO3;DNP;;;;;;;
P20;GPIO;Sullins;PPPC112LFBN-RC;CONN HEADER FMAL 22PS.1" DL GOLD;;;;;
P21;REF_IN;DNP;;;;;;;
P22;I2S;Sullins;PPPC132LFBN-RC;CONN HEADER FMAL 26PS.1" DL GOLD;;;;;
P23;DBGEN;DNP;;;;;;;
P24;TRST;DNP;;;;;;;
P25;LPC_ISP;DNP;;;;;;;
P26;LPC_JTAG;Sullins;GRPB052VWVN-RC;CONN HEADER .050" 10PS DL PCB AU;DNP;;;;
P27;MIXER_SDATA;DNP;;;;;;;
P28;SD;Sullins;PPPC112LFBN-RC;CONN HEADER FMAL 22PS.1" DL GOLD;;;;;
P29;CPLD_JTAG;DNP;;;;;;;
P30;BANK2_AUX;DNP;;;;;;;
P31;MIXER_SCLK;DNP;;;;;;;
P32;MIXER_ENX;DNP;;;;;;;
P33;MIXER_RESETX;DNP;;;;;;;
P34;MIX_BYPASS;DNP;;;;;;;
P35;!MIX_BYPASS;DNP;;;;;;;
P36;VAA;DNP;;;;;;;
P37;SCL;DNP;;;;;;;
P38;SDA;DNP;;;;;;;
P39;SSP1_SCK;DNP;;;;;;;
P40;SSP1_MOSI;DNP;;;;;;;
P41;SSP1_MISO;DNP;;;;;;;
P42;TX;DNP;;;;;;;
P43;RX;DNP;;;;;;;
P44;HP;DNP;;;;;;;
P45;LP;DNP;;;;;;;
P46;TX_MIX_BP;DNP;;;;;;;
P47;RX_MIX_BP;DNP;;;;;;;
P48;TX_AMP;DNP;;;;;;;
P49;RX_AMP;DNP;;;;;;;
P50;AMP_BYPASS;DNP;;;;;;;
P51;!TX_AMP_PWR;DNP;;;;;;;
P52;!RX_AMP_PWR;DNP;;;;;;;
P53;CS_XCVR;DNP;;;;;;;
P54;CS_AD;DNP;;;;;;;
P55;TXENABLE;DNP;;;;;;;
P56;RXENABLE;DNP;;;;;;;
P57;XTAL2;DNP;;;;;;;
P58;GCK1;DNP;;;;;;;
P59;GCK2;DNP;;;;;;;
P60;SGPIO_CLK;DNP;;;;;;;
P61;DA0;DNP;;;;;;;
P62;DA7;DNP;;;;;;;
P63;DD0;DNP;;;;;;;
P64;DD9;DNP;;;;;;;
P65;DA4;DNP;;;;;;;
P66;DD5;DNP;;;;;;;
P67;RSSI;DNP;;;;;;;
P68;SPIFI_CS;DNP;;;;;;;
P69;VREGMODE;DNP;;;;;;;
P70;EN_1V8;DNP;;;;;;;
P71;ID;DNP;;;;;;;
P72;GP_CLKIN;DNP;;;;;;;
P73;P1_2;DNP;;;;;;;
P74;P1_1;DNP;;;;;;;
P75;GP_CLKIN;DNP;;;;;;;
P76;GP_CLKIN;DNP;;;;;;;
P77;GP_CLKIN;DNP;;;;;;;
P78;GP_CLKIN;DNP;;;;;;;
P79;GP_CLKIN;DNP;;;;;;;
P80;SHIELD;DNP;;;;;;;
P81;SPIFI_SIO2;DNP;;;;;;;
P82;SPIFI_SIO3;DNP;;;;;;;
P83;GND;DNP;;;;;;;
P84;GND;DNP;;;;;;;
P85;GND;DNP;;;;;;;
P86;GND;DNP;;;;;;;
P87;GND;DNP;;;;;;;
P88;GND;DNP;;;;;;;
P89;GND;DNP;;;;;;;
P90;GND;DNP;;;;;;;
P91;GND;DNP;;;;;;;
P92;GND;DNP;;;;;;;
Q1;MOSFET_P;Fairchild;BSS84;MOSFET P-CH 50V 130MA SOT-23;;;;;
Q2;MOSFET_P;Fairchild;BSS84;MOSFET P-CH 50V 130MA SOT-23;;;;;
Q3;MOSFET_P;Diodes Inc.;DMP2305U-7;MOSFET P-CH 20V 4.2A SOT-23;;;;;
Q4;MOSFET_P;Fairchild;BSS84;MOSFET P-CH 50V 130MA SOT-23;;;;;
Q5;MOSFET_P;Alpha and Omega;AO3407A;MOSFET P-CH -30V -4.3A SOT23;;;;;
R1;470;Stackpole;RMCF0402JT470R;RES TF 1/16W 470 OHM 5% 0402;;;;;
R2;470;Stackpole;RMCF0402JT470R;RES TF 1/16W 470 OHM 5% 0402;;;;;
R3;22k;Panasonic;ERJ-2GEJ223X;RES 22K OHM 1/10W 5% 0402 SMD;;;;;
R4;51k;Stackpole;RMCF0402FT51K0;RES TF 51K OHM 1% 0.0625W 0402;;;;;
R5;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R6;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R7;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R8;1k;Stackpole;RMCF0402FT1K00;RES 1K OHM 1/16W 1% 0402;;;;;
R9;1k;Stackpole;RMCF0402FT1K00;RES 1K OHM 1/16W 1% 0402;;;;;
R10;1k;Stackpole;RMCF0402FT1K00;RES 1K OHM 1/16W 1% 0402;;;;;
R11;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R12;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R13;1k;Stackpole;RMCF0402FT1K00;RES 1K OHM 1/16W 1% 0402;;;;;
R14;4k7;Stackpole;RMCF0402FT4K70;RES 4.7K OHM 1/16W 1% 0402;;;;;
R15;4k7;Stackpole;RMCF0402FT4K70;RES 4.7K OHM 1/16W 1% 0402;;;;;
R16;4k7;Stackpole;RMCF0402FT4K70;RES 4.7K OHM 1/16W 1% 0402;;;;;
R17;4k7;Stackpole;RMCF0402FT4K70;RES 4.7K OHM 1/16W 1% 0402;;;;;
R18;1k8;Stackpole;RMCF0402JT1K80;RES TF 1.8K OHM 5% 1/16W 0402;;;;;
R19;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R20;0;Stackpole;RMCF0402ZT0R00;RES 0.0 OHM 1/16W 0402 SMD;;;;;
R21;0;Stackpole;RMCF0402ZT0R00;RES 0.0 OHM 1/16W 0402 SMD;;;;;
R22;0;Stackpole;RMCF0402ZT0R00;RES 0.0 OHM 1/16W 0402 SMD;;;;;
R23;0;Stackpole;RMCF0402ZT0R00;RES 0.0 OHM 1/16W 0402 SMD;;;;;
R24;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R25;475;Stackpole;RMCF0402JT470R;RES TF 1/16W 470 OHM 5% 0402;;;;;
R26;475;Stackpole;RMCF0402JT470R;RES TF 1/16W 470 OHM 5% 0402;;;;;
R27;1k8;Stackpole;RMCF0402JT1K80;RES TF 1.8K OHM 5% 1/16W 0402;;;;;
R28;1k8;Stackpole;RMCF0402JT1K80;RES TF 1.8K OHM 5% 1/16W 0402;;;;;
R29;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R30;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R31;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R32;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R33;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R34;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R35;DNP;DNP;;;;;;;
R36;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R37;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R41;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R46;162k;Stackpole;RMCF0402FT162K;RES TF 1/16W 162K OHM 1% 0402;;;;;
R47;330k;Stackpole;RMCF0402FT330K;RES TF 1/16W 330K OHM 1% 0402;;;;;
R48;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R49;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R51;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R52;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R54;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R55;162k;Stackpole;RMCF0402FT162K;RES TF 1/16W 162K OHM 1% 0402;;;;;
R56;715k;Stackpole;RMCF0402FT715K;RES TF 1/16W 715K OHM 1% 0402;;;;;
R57;0;Stackpole;RMCF0402ZT0R00;RES 0.0 OHM 1/16W 0402 SMD;;;;;
R58;0;Stackpole;RMCF0402ZT0R00;RES 0.0 OHM 1/16W 0402 SMD;;;;;
R59;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R62;0;Stackpole;RMCF0402ZT0R00;RES 0.0 OHM 1/16W 0402 SMD;;;;;
R63;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R64;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R65;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R66;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R67;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R68;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R69;12k;Rohm;MCR01MRTF1202;RES 12.0K OHM 1/16W 1% 0402 SMD;;;;;
R72;470;Stackpole;RMCF0402JT470R;RES TF 1/16W 470 OHM 5% 0402;;;;;
R73;1k;Stackpole;RMCF0402FT1K00;RES 1K OHM 1/16W 1% 0402;;;;;
R74;1k8;Stackpole;RMCF0402JT1K80;RES TF 1.8K OHM 5% 1/16W 0402;;;;;
R75;470;Stackpole;RMCF0402JT470R;RES TF 1/16W 470 OHM 5% 0402;;;;;
R76;1k;Stackpole;RMCF0402FT1K00;RES 1K OHM 1/16W 1% 0402;;;;;
R77;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R78;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R79;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R80;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R81;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R85;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R86;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R87;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R88;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R89;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R90;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R91;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R93;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R94;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R96;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R98;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R99;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R100;39;Stackpole;RMCF0402JT39R0;RES 39 OHM 1/16W 5% 0402 SMD;;;;;
R104;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
R105;10k;Stackpole;RMCF0402JT10K0;RES 10K OHM 1/16W 5% 0402 SMD;;;;;
SW1;DFU;TE Connectivity;FSMRA3JH;SWITCH TACTILE SPST-NO 0.05A 12V;;;;;
SW2;RESET;TE Connectivity;FSMRA3JH;SWITCH TACTILE SPST-NO 0.05A 12V;;;;;
T1;MIX_IN_BALUN;Anaren;B0310J50100AHF;Ultra Low Profile 0805 Balun 50 to 100 ohm Balanced;;;;;
T2;MIX_OUT_BALUN;Anaren;B0310J50100AHF;Ultra Low Profile 0805 Balun 50 to 100 ohm Balanced;;;;;
T3;RX_BALUN;Johanson Technology;2500BL14M100T;BALUN CERAMIC CHIP WIMAX 2.5GHZ;;;;;
T4;TX_BALUN;Johanson Technology;2500BL14M100T;BALUN CERAMIC CHIP WIMAX 2.5GHZ;;;;;
U1;SKY13350;Skyworks;SKY13350-385LF;0.01-6.0 GHz GaAs SPDT Switch;;;;;
U2;SKY13350;Skyworks;SKY13350-385LF;0.01-6.0 GHz GaAs SPDT Switch;;;;;
U3;RX_LOWPASS_FILTER;AVX;LP0603A1880ANTR;FILTER LOW PASS 1880MHZ 0603 SMD;;;;;
U4;RFFC5072;RFMD;RFFC5072TR7;WIDEBAND SYNTHESIZER/VCO WITH INTEGRATED 6GHz MIXER;;;;;
U5;SKY13350;Skyworks;SKY13350-385LF;0.01-6.0 GHz GaAs SPDT Switch;;;;;
U6;SKY13350;Skyworks;SKY13350-385LF;0.01-6.0 GHz GaAs SPDT Switch;;;;;
U7;SKY13350;Skyworks;SKY13350-385LF;0.01-6.0 GHz GaAs SPDT Switch;;;;;
U8;RX_HIGHPASS_FILTER;TDK;DEA162400HT-8004B1;FILTER HIGHPASS WLAN&BLUETOOTH;;;;;
U9;SKY13317;Skyworks;SKY13317-373LF;20 MHz-6.0 GHz pHEMT GaAs SP3T Switch;;;;;
U10;SKY13350;Skyworks;SKY13350-385LF;0.01-6.0 GHz GaAs SPDT Switch;;;;;
U11;SKY13350;Skyworks;SKY13350-385LF;0.01-6.0 GHz GaAs SPDT Switch;;;;;
U12;SKY13317;Skyworks;SKY13317-373LF;20 MHz-6.0 GHz pHEMT GaAs SP3T Switch;;;;;
U13;MGA-81563;Avago;MGA-81563-TR1G;0.1-6 GHz 3 V, 14 dBm Amplifier;;;;;
U14;SKY13317;Skyworks;SKY13317-373LF;20 MHz-6.0 GHz pHEMT GaAs SP3T Switch;;;;;
U15;LXES1TBCC2-004;Murata;LXES1TBCC2-004;ESD Suppressors 0.55pF 6V 2ch;;;;;
U17;MAX2837;Maxim;MAX2837ETM+;IC TXRX 2.3GHZ-2.7GHZ 48TQFN;;;;;
U18;MAX5864;Maxim;MAX5864ETM+;IC ANLG FRONT END 22MSPS 48-TQFN;;;;;
U19;SI5351C;Silicon Laboratories Inc;SI5351C-B-GM;IC CLK GENERATOR 160MHZ 20QFN;;;;;
U20;W25Q80BV;Winbond;W25Q80BVSSIG;IC FLASH 8MBIT 8SOIC;;;;;
U21;TPS62410;Texas Instruments;TPS62410DRCR;IC BUCK SYNC DUAL ADJ 0.8A 10SON;;;;;
U23;LPC4320FBD144;NXP;LPC4320FBD144,551;IC MCU 32BIT 144LQFP;;;;;
U24;GSG-XC2C64A-7VQG100C;Xilinx;XC2C64A-7VQG100C;IC CR-II CPLD 64MCELL 100-VQFP;;;;;
U25;MGA-81563;Avago;MGA-81563-TR1G;0.1-6 GHz 3 V, 14 dBm Amplifier;;;;;
X1;GSG-XTAL4PIN;AVX;CX3225GB25000D0HEQZ1;CRYSTAL 25.000MHZ 8PF SMD;;;;;
X2;MCU_XTAL;TXC;7V-12.000MAAE-T;CRYSTAL 12.000 MHZ 12PF SMD;;;;;
X3;RTC_XTAL;Abracon;AB26TRQ-32.768KHZ-T;CRYSTAL 32.768KHZ 12.5PF SMD;;;;;
Item,Qty,Reference(s),Value,LibPart,Footprint,Datasheet,Description,Manufacturer,Part Number
1,33,"C1, C3, C5, C7, C10, C11, C16, C19, C22, C24, C29, C30, C33, C34, C35, C36, C37, C38, C39, C40, C45, C47, C54, C55, C56, C57, C60, C63, C65, C66, C67, C115, C125",33pF,device:C,,,CAP CER 33PF 50V 5% NP0 0402,Murata,GRM1555C1H330JA01D
2,3,"C97, C98, C100",330nF,device:C,,,CAP CER 0.33UF 10V 10% X5R 0402,Murata,GRM155R61A334KE15D
3,12,"C8, C21, C32, C43, C48, C51, C84, C85, C86, C94, C99, C102",22pF,device:C,,,CAP CER 22PF 50V 5% NP0 0402,Murata,GRM1555C1H220JA01D
4,2,"C104, C111",3pF,device:C,,,CAP CER 3PF 50V NP0 0402,Murata,GRM1555C1H3R0CA01D
5,6,"C105, C126, C127, C143, C145, C146",10uF,device:C,,,CAP CER 10UF 10V 10% X5R 0805,Murata,GRM21BR61A106KE19L
6,4,"C53, C106, C161, C171",1uF,device:C,,,CAP CER 1UF 10V 10% X5R 0402,Taiyo Yuden,LMK105BJ105KV-F
7,2,"C15, C112",180pF,device:C,,,CAP CER 180PF 50V 5% NP0 0402,Murata,GRM1555C1H181JA01D
8,57,"C9, C17, C18, C20, C23, C25, C28, C31, C44, C46, C49, C50, C58, C59, C61, C62, C64, C71, C73, C75, C77, C79, C81, C83, C91, C113, C119, C120, C121, C122, C123, C128, C129, C130, C131, C132, C133, C134, C135, C136, C137, C138, C139, C140, C141, C142, C144, C147, C148, C149, C150, C151, C152, C153, C154, C166, C167",100nF,device:C,,,CAP CER 0.1UF 10V 10% X5R 0402,Murata,GRM155R61A104KA01D
9,1,C114,3.3nF,device:C,,,CAP CER 3300PF 50V 10% X7R 0402,Murata,GRM155R71H332KA01D
10,3,"C26, C27, C116",47pF,device:C,,,CAP CER 47PF 50V 5% NP0 0402,Murata,GRM1555C1H470JA01D
11,4,"C118, C157, C158, C164",18pF,device:C,,,CAP CER 18PF 50V 5% NP0 0402,Murata,GRM1555C1H180JA01D
12,2,"C12, C13",330pF,device:C,,,CAP CER 330PF 50V 10% X7R 0402,Murata,GRM155R71H331KA01D
13,7,"C72, C74, C76, C78, C80, C82, C124",2.2uF,device:C,,,CAP CER 2.2UF 10V 20% X5R 0402,Taiyo Yuden,LMK105BJ225MV-F
14,1,C14,8p2,device:C,,,CAP CER 8.2PF 50V NP0 0402,Taiyo Yuden,UMK105CG8R2DV-F
15,6,"C41, C42, C52, C70, C90, C160",100pF,device:C,,,CAP CER 100PF 50V 5% NP0 0402,Murata,GRM1555C1H101JA01D
16,10,"C2, C4, C6, C87, C88, C89, C92, C93, C162, C163",10nF,device:C,,,CAP CER 10000PF 16V 10% X7R 0402,Murata,GRM155R71C103KA01D
17,3,"D1, D3, D9",GSG-DIODE-TVS-BI,hackrf:GSG-DIODE-TVS-BI,,,TVS DIODE ESD .05PF 15KV 0402,Murata,LXES15AAA1-100
18,2,"D2, D6",TXLED,device:LED,,,LED SUPR RED CLR RT ANG 0805,Lite-On,LTST-S220KRKT
19,2,"D4, D7",VCCLED,device:LED,,,LED GREEN CLEAR RT ANG 0805,Lite-On,LTST-S220KGKT
20,2,"D5, D8",1V8LED,device:LED,,,LED YELLOW CLEAR RT ANG 0805,Lite-On,LTST-S220KSKT
21,3,"FB1, FB2, FB3",FILTER,device:FILTER,,,FERRITE CHIP 220 OHM 2000MA 0805,Murata,BLM21PG221SN1D
22,1,J1,USB-MICRO-B,hackrf:GSG-USB-MICRO-B-SHIELDED,,,CONN RCPT REV MICRO USB TYPE B,FCI,10103592-0001LF
23,2,"L10, L11",4u7,device:INDUCTOR,,,INDUCTOR 4.7UH 1.6A 20% SMD,Taiyo Yuden,NRG4026T4R7M
24,5,"L2, L3, L5, L12, L13",10uH,device:INDUCTOR,,,INDUCTR 10UH 220MA 20% 0603 SMD,Taiyo Yuden,BRL1608T100M
25,1,L7,6.2nH,device:INDUCTOR,,,INDUCTOR HIFREQ 6.2+/-0.3NH 0402,Taiyo Yuden,HK10056N2S-T
26,3,"P2, P4, P16",ANTENNA,hackrf:GSG-RF-CONN,,,CONN SMA JACK 50 OHM EDGE MNT W/JAM NUT & LOCK WASHER,Molex,73251-2121
27,2,"P20, P28",SD,hackrf:CONN_11X2,,,"CONN HEADER FMAL 22PS.1"" DL GOLD",Sullins,PPPC112LFBN-RC
28,1,P22,I2S,hackrf-one-cache:CONN_13X2,,,"CONN HEADER FMAL 26PS.1"" DL GOLD",Sullins,PPPC132LFBN-RC
29,1,P9,BASEBAND,hackrf-one-cache:CONN_8X2,,,"CONN HEADER FMAL 16PS.1"" DL GOLD",Sullins,PPPC082LFBN-RC
30,3,"Q1, Q2, Q4",MOSFET_P,hackrf-one-cache:MOSFET_P,,,MOSFET P-CH 50V 130MA SOT-23,Fairchild,BSS84
31,1,Q3,MOSFET_P,hackrf-one-cache:MOSFET_P,,,MOSFET P-CH 20V 4.2A SOT-23,Diodes Inc.,DMP2305U-7
32,1,Q5,MOSFET_P,hackrf-one-cache:MOSFET_P,,,MOSFET P-CH -30V -4.3A SOT23,Alpha and Omega,AO3407A
33,6,"R1, R2, R25, R26, R72, R75",470,device:R,,,RES TF 1/16W 470 OHM 5% 0402,Stackpole,RMCF0402JT470R
34,6,"R8, R9, R10, R13, R73, R76",1k,device:R,,,RES 1K OHM 1/16W 1% 0402,Stackpole,RMCF0402FT1K00
35,22,"R19, R30, R31, R32, R33, R34, R77, R78, R79, R80, R81, R86, R87, R88, R89, R90, R91, R94, R96, R98, R99, R100",39,device:R,,,RES 39 OHM 1/16W 5% 0402 SMD,Stackpole,RMCF0402JT39R0
36,26,"R5, R6, R7, R11, R12, R24, R29, R36, R37, R41, R48, R49, R51, R52, R54, R59, R63, R64, R65, R66, R67, R68, R85, R93, R104, R105",10k,device:R,,,RES 10K OHM 1/16W 5% 0402 SMD,Stackpole,RMCF0402JT10K0
37,4,"R14, R15, R16, R17",4k7,device:R,,,RES 4.7K OHM 1/16W 1% 0402,Stackpole,RMCF0402FT4K70
38,4,"R18, R27, R28, R74",1k8,device:R,,,RES TF 1.8K OHM 5% 1/16W 0402,Stackpole,RMCF0402JT1K80
39,7,"R20, R21, R22, R23, R57, R58, R62",0,device:R,,,RES 0.0 OHM 1/16W 0402 SMD,Stackpole,RMCF0402ZT0R00
40,1,R3,22k,device:R,,,RES 22K OHM 1/10W 5% 0402 SMD,Panasonic,ERJ-2GEJ223X
41,1,R4,51k,device:R,,,RES TF 51K OHM 1% 0.0625W 0402,Stackpole,RMCF0402FT51K0
42,2,"R46, R55",162k,device:R,,,RES TF 1/16W 162K OHM 1% 0402,Stackpole,RMCF0402FT162K
43,1,R47,330k,device:R,,,RES TF 1/16W 330K OHM 1% 0402,Stackpole,RMCF0402FT330K
44,1,R56,715k,device:R,,,RES TF 1/16W 715K OHM 1% 0402,Stackpole,RMCF0402FT715K
45,1,R69,12k,device:R,,,RES 12.0K OHM 1/16W 1% 0402 SMD,Rohm,MCR01MRTF1202
46,2,"SW1, SW2",RESET,hackrf:SW_PUSH_SHIELDED,,,SWITCH TACTILE SPST-NO 0.05A 12V,TE Connectivity,FSMRA3JH
47,2,"T1, T2",MIX_OUT_BALUN,hackrf:BALUN-B0310J50100AHF,,,Ultra Low Profile 0805 Balun 50 to 100 ohm Balanced,Anaren,B0310J50100AHF
48,2,"T3, T4",TX_BALUN,hackrf:BALUN,,,BALUN CERAMIC CHIP WIMAX 2.5GHZ,Johanson Technology,2500BL14M100T
49,7,"U1, U2, U5, U6, U7, U10, U11",SKY13350,hackrf:SKY13350,,,0.01-6.0 GHz GaAs SPDT Switch,Skyworks,SKY13350-385LF
50,3,"U9, U12, U14",SKY13317,hackrf:SKY13317,,,20 MHz-6.0 GHz pHEMT GaAs SP3T Switch,Skyworks,SKY13317-373LF
51,2,"U13, U25",MGA-81563,hackrf:MGA-81563,,,"0.1-6 GHz 3 V, 14 dBm Amplifier",Avago,MGA-81563-TR1G
52,1,U15,LXES1TBCC2-004,hackrf:LXES1TBCC2-004,,,ESD Suppressors 0.55pF 6V 2ch,Murata,LXES1TBCC2-004
53,1,U17,MAX2837,hackrf:MAX2837,,,IC TXRX 2.3GHZ-2.7GHZ 48TQFN,Maxim,MAX2837ETM+
54,1,U18,MAX5864,hackrf:MAX5864,,,IC ANLG FRONT END 22MSPS 48-TQFN,Maxim,MAX5864ETM+
55,1,U19,SI5351C,hackrf:SI5351C,,,IC CLK GENERATOR 160MHZ 20QFN,Silicon Laboratories Inc,SI5351C-B-GM
56,1,U20,W25Q80BV,hackrf:W25Q80BV,,,IC FLASH 8MBIT 8SOIC,Winbond,W25Q80BVSSIG
57,1,U21,TPS62410,hackrf:TPS62410,,,IC BUCK SYNC DUAL ADJ 0.8A 10SON,Texas Instruments,TPS62410DRCR
58,1,U23,LPC4320FBD144,hackrf:LPC43XXFBD144,,,IC MCU 32BIT 144LQFP,NXP,"LPC4320FBD144,551"
59,1,U24,GSG-XC2C64A-7VQG100C,hackrf:GSG-XC2C64A-7VQG100C,,,IC CR-II CPLD 64MCELL 100-VQFP,Xilinx,XC2C64A-7VQG100C
60,1,U3,RX_LOWPASS_FILTER,hackrf:FIL-LP0603,,,FILTER LOW PASS 1880MHZ 0603 SMD,AVX,LP0603A1880ANTR
61,1,U4,RFFC5072,hackrf:RFFC5072,,,WIDEBAND SYNTHESIZER/VCO WITH INTEGRATED 6GHz MIXER,RFMD,RFFC5072TR7
62,1,U8,RX_HIGHPASS_FILTER,hackrf:FIL-DEA,,,FILTER HIGHPASS WLAN&BLUETOOTH,TDK,DEA162400HT-8004B1
63,1,X1,GSG-XTAL4PIN,hackrf:GSG-XTAL4PIN,,,CRYSTAL 25.000MHZ 8PF SMD,AVX,CX3225GB25000D0HEQZ1
64,1,X2,MCU_XTAL,hackrf:GSG-XTAL4PIN,,,CRYSTAL 12.000 MHZ 12PF SMD,TXC,7V-12.000MAAE-T
65,1,X3,RTC_XTAL,hackrf-one-cache:CRYSTAL,,,CRYSTAL 32.768KHZ 12.5PF SMD,Abracon,AB26TRQ-32.768KHZ-T

Can't render this file because it contains an unexpected character in line 215 and column 59.

View File

@ -6,7 +6,7 @@ projects. The cpld directory contains HDL source for the CPLD.
The firmware is set up for compilation with the GCC toolchain available here:
https://code.launchpad.net/gcc-arm-embedded
https://launchpad.net/gcc-arm-embedded
Required dependency:
@ -40,15 +40,7 @@ To start up HackRF One in DFU mode, hold down the DFU button while powering it
on or while pressing and releasing the RESET button. Release the DFU button
after the 3V3 LED illuminates.
With dfu-util and dfu-suffix (from the dfu-util package) installed and with the
HackRF operating in DFU mode, you can build firmware for RAM and load it with:
$ cd hackrf_usb
$ mkdir build
$ cd build
$ cmake .. -DRUN_FROM=RAM
$ make hackrf_usb-program
Alternatively you can load a .dfu file from a release package with:
A .dfu file is built by default when building firmware. Alternatively you can
load a known good .dfu file from a release package with:
$ dfu-util --device 1fc9:000c --alt 0 --download hackrf_usb_ram.dfu

View File

@ -19,13 +19,8 @@
* Boston, MA 02110-1301, USA.
*/
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include "hackrf_core.h"
uint32_t boot0, boot1, boot2, boot3;
int main(void)
{
int i;
@ -34,18 +29,20 @@ int main(void)
/* enable all power supplies */
enable_1v8_power();
/* Blink LED1/2/3 on the board and Read BOOT0/1/2/3 pins. */
/* Blink LED1/2/3 on the board. */
while (1)
{
boot0 = BOOT0_STATE;
boot1 = BOOT1_STATE;
boot2 = BOOT2_STATE;
boot3 = BOOT3_STATE;
led_on(LED1);
led_on(LED2);
led_on(LED3);
gpio_set(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LEDs on */
for (i = 0; i < 2000000; i++) /* Wait a bit. */
__asm__("nop");
gpio_clear(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LED off */
led_off(LED1);
led_off(LED2);
led_off(LED3);
for (i = 0; i < 2000000; i++) /* Wait a bit. */
__asm__("nop");
}

View File

@ -22,7 +22,6 @@
#include "cpld_jtag.h"
#include "hackrf_core.h"
#include "xapp058/micro.h"
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include <stdint.h>
@ -30,47 +29,45 @@ static refill_buffer_cb refill_buffer;
static uint32_t xsvf_buffer_len, xsvf_pos;
static unsigned char* xsvf_buffer;
void cpld_jtag_setup(void) {
void cpld_jtag_setup(jtag_t* const jtag) {
scu_pinmux(SCU_PINMUX_CPLD_TDO, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION4);
scu_pinmux(SCU_PINMUX_CPLD_TCK, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_PINMUX_CPLD_TMS, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_PINMUX_CPLD_TDI, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
/* TDO is an input */
GPIO_DIR(PORT_CPLD_TDO) &= ~PIN_CPLD_TDO;
/* the rest are outputs */
GPIO_DIR(PORT_CPLD_TCK) |= PIN_CPLD_TCK;
GPIO_DIR(PORT_CPLD_TMS) |= PIN_CPLD_TMS;
GPIO_DIR(PORT_CPLD_TDI) |= PIN_CPLD_TDI;
gpio_input(jtag->gpio->gpio_tdo);
gpio_output(jtag->gpio->gpio_tck);
gpio_output(jtag->gpio->gpio_tms);
gpio_output(jtag->gpio->gpio_tdi);
}
/* set pins as inputs so we don't interfere with an external JTAG device */
void cpld_jtag_release(void) {
void cpld_jtag_release(jtag_t* const jtag) {
scu_pinmux(SCU_PINMUX_CPLD_TDO, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION4);
scu_pinmux(SCU_PINMUX_CPLD_TCK, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_PINMUX_CPLD_TMS, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_PINMUX_CPLD_TDI, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
GPIO_DIR(PORT_CPLD_TDO) &= ~PIN_CPLD_TDO;
GPIO_DIR(PORT_CPLD_TCK) &= ~PIN_CPLD_TCK;
GPIO_DIR(PORT_CPLD_TMS) &= ~PIN_CPLD_TMS;
GPIO_DIR(PORT_CPLD_TDI) &= ~PIN_CPLD_TDI;
gpio_input(jtag->gpio->gpio_tdo);
gpio_input(jtag->gpio->gpio_tck);
gpio_input(jtag->gpio->gpio_tms);
gpio_input(jtag->gpio->gpio_tdi);
}
/* return 0 if success else return error code see xsvfExecute() */
int cpld_jtag_program(
jtag_t* const jtag,
const uint32_t buffer_length,
unsigned char* const buffer,
refill_buffer_cb refill
) {
int error;
cpld_jtag_setup();
cpld_jtag_setup(jtag);
xsvf_buffer = buffer;
xsvf_buffer_len = buffer_length;
refill_buffer = refill;
error = xsvfExecute();
cpld_jtag_release();
error = xsvfExecute(jtag->gpio);
cpld_jtag_release(jtag);
return error;
}

View File

@ -24,9 +24,22 @@
#include <stdint.h>
#include "gpio.h"
typedef struct jtag_gpio_t {
gpio_t gpio_tms;
gpio_t gpio_tck;
gpio_t gpio_tdi;
gpio_t gpio_tdo;
} jtag_gpio_t;
typedef struct jtag_t {
jtag_gpio_t* const gpio;
} jtag_t;
typedef void (*refill_buffer_cb)(void);
void cpld_jtag_release(void);
void cpld_jtag_release(jtag_t* const jtag);
/* Return 0 if success else return error code see xsvfExecute() see micro.h.
*
@ -34,6 +47,7 @@ void cpld_jtag_release(void);
* contents of the buffer has been streamed to the CPLD the given
* refill_buffer callback will be called. */
int cpld_jtag_program(
jtag_t* const jtag,
const uint32_t buffer_length,
unsigned char* const buffer,
refill_buffer_cb refill

38
firmware/common/gpio.h Normal file
View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __GPIO_H__
#define __GPIO_H__
#include <stdbool.h>
typedef const struct gpio_t* gpio_t;
void gpio_init();
void gpio_set(gpio_t gpio);
void gpio_clear(gpio_t gpio);
void gpio_toggle(gpio_t gpio);
void gpio_output(gpio_t gpio);
void gpio_input(gpio_t gpio);
void gpio_write(gpio_t gpio, const bool value);
bool gpio_read(gpio_t gpio);
#endif/*__GPIO_H__*/

View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "gpio_lpc.h"
#include <stddef.h>
void gpio_init() {
for(size_t i=0; i<8; i++) {
GPIO_LPC_PORT(i)->dir = 0;
}
}
void gpio_set(gpio_t gpio) {
gpio->port->set = gpio->mask;
}
void gpio_clear(gpio_t gpio) {
gpio->port->clr = gpio->mask;
}
void gpio_toggle(gpio_t gpio) {
gpio->port->not = gpio->mask;
}
void gpio_output(gpio_t gpio) {
gpio->port->dir |= gpio->mask;
}
void gpio_input(gpio_t gpio) {
gpio->port->dir &= ~gpio->mask;
}
void gpio_write(gpio_t gpio, const bool value) {
*gpio->gpio_w = value;
}
bool gpio_read(gpio_t gpio) {
return *gpio->gpio_w;
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __GPIO_LPC_H__
#define __GPIO_LPC_H__
#include <stdint.h>
#include "gpio.h"
/* NOTE: libopencm3 constants and functions not used here due to naming
* conflicts. I'd recommend changes to libopencm3 design to separate
* register #defines and API declarations into separate header files.
*/
typedef struct gpio_port_t {
volatile uint32_t dir; /* +0x000 */
uint32_t _reserved0[31];
volatile uint32_t mask; /* +0x080 */
uint32_t _reserved1[31];
volatile uint32_t pin; /* +0x100 */
uint32_t _reserved2[31];
volatile uint32_t mpin; /* +0x180 */
uint32_t _reserved3[31];
volatile uint32_t set; /* +0x200 */
uint32_t _reserved4[31];
volatile uint32_t clr; /* +0x280 */
uint32_t _reserved5[31];
volatile uint32_t not; /* +0x300 */
} gpio_port_t;
struct gpio_t {
const uint32_t mask;
gpio_port_t* const port;
volatile uint32_t* const gpio_w;
};
#define GPIO_LPC_BASE (0x400f4000)
#define GPIO_LPC_B_OFFSET (0x0)
#define GPIO_LPC_W_OFFSET (0x1000)
#define GPIO_LPC_PORT_OFFSET (0x2000)
#define GPIO_LPC_PORT(_n) ((gpio_port_t*)((GPIO_LPC_BASE + GPIO_LPC_PORT_OFFSET) + (_n) * 4))
#define GPIO_LPC_W(_port_num, _pin_num) (volatile uint32_t*)((GPIO_LPC_BASE + GPIO_LPC_W_OFFSET) + ((_port_num) * 0x80) + ((_pin_num) * 4))
#define GPIO(_port_num, _pin_num) { \
.mask = (1UL << (_pin_num)), \
.port = GPIO_LPC_PORT(_port_num), \
.gpio_w = GPIO_LPC_W(_port_num, _pin_num), \
}
#endif/*__GPIO_LPC_H__*/

View File

@ -22,22 +22,311 @@
*/
#include "hackrf_core.h"
#include "si5351c.h"
#include "max2837.h"
#include "rffc5071.h"
#include "sgpio.h"
#include "rf_path.h"
#include "hackrf-ui.h"
#include <libopencm3/lpc43xx/i2c.h>
#include "si5351c.h"
#include "spi_ssp.h"
#include "max2837.h"
#include "max2837_target.h"
#include "max5864.h"
#include "max5864_target.h"
#include "rffc5071.h"
#include "rffc5071_spi.h"
#include "w25q80bv.h"
#include "w25q80bv_target.h"
#include "i2c_bus.h"
#include "i2c_lpc.h"
#include <libopencm3/lpc43xx/cgu.h>
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/ssp.h>
#include "gpio_lpc.h"
/* TODO: Consolidate ARRAY_SIZE declarations */
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define WAIT_CPU_CLOCK_INIT_DELAY (10000)
/* GPIO Output PinMux */
static struct gpio_t gpio_led[] = {
GPIO(2, 1),
GPIO(2, 2),
GPIO(2, 8),
#ifdef RAD1O
GPIO(5, 26),
#endif
};
static struct gpio_t gpio_1v8_enable = GPIO(3, 6);
/* MAX2837 GPIO (XCVR_CTL) PinMux */
static struct gpio_t gpio_max2837_select = GPIO(0, 15);
static struct gpio_t gpio_max2837_enable = GPIO(2, 6);
static struct gpio_t gpio_max2837_rx_enable = GPIO(2, 5);
static struct gpio_t gpio_max2837_tx_enable = GPIO(2, 4);
#ifdef JELLYBEAN
static struct gpio_t gpio_max2837_rxhp = GPIO(2, 0);
static struct gpio_t gpio_max2837_b1 = GPIO(2, 9);
static struct gpio_t gpio_max2837_b2 = GPIO(2, 10);
static struct gpio_t gpio_max2837_b3 = GPIO(2, 11);
static struct gpio_t gpio_max2837_b4 = GPIO(2, 12);
static struct gpio_t gpio_max2837_b5 = GPIO(2, 13);
static struct gpio_t gpio_max2837_b6 = GPIO(2, 14);
static struct gpio_t gpio_max2837_b7 = GPIO(2, 15);
#endif
/* MAX5864 SPI chip select (AD_CS) GPIO PinMux */
static struct gpio_t gpio_max5864_select = GPIO(2, 7);
/* RFFC5071 GPIO serial interface PinMux */
#ifdef JELLYBEAN
static struct gpio_t gpio_rffc5072_select = GPIO(3, 8);
static struct gpio_t gpio_rffc5072_clock = GPIO(3, 9);
static struct gpio_t gpio_rffc5072_data = GPIO(3, 10);
static struct gpio_t gpio_rffc5072_reset = GPIO(3, 11);
#endif
#if (defined JAWBREAKER || defined HACKRF_ONE)
static struct gpio_t gpio_rffc5072_select = GPIO(2, 13);
static struct gpio_t gpio_rffc5072_clock = GPIO(5, 6);
static struct gpio_t gpio_rffc5072_data = GPIO(3, 3);
static struct gpio_t gpio_rffc5072_reset = GPIO(2, 14);
#endif
/* RF LDO control */
#ifdef JAWBREAKER
static struct gpio_t gpio_rf_ldo_enable = GPIO(2, 9);
#endif
/* RF supply (VAA) control */
#if (defined HACKRF_ONE || defined RAD1O)
static struct gpio_t gpio_vaa_disable = GPIO(2, 9);
#endif
static struct gpio_t gpio_w25q80bv_hold = GPIO(1, 14);
static struct gpio_t gpio_w25q80bv_wp = GPIO(1, 15);
static struct gpio_t gpio_w25q80bv_select = GPIO(5, 11);
/* RF switch control */
#ifdef HACKRF_ONE
static struct gpio_t gpio_hp = GPIO(2, 0);
static struct gpio_t gpio_lp = GPIO(2, 10);
static struct gpio_t gpio_tx_mix_bp = GPIO(2, 11);
static struct gpio_t gpio_no_mix_bypass = GPIO(1, 0);
static struct gpio_t gpio_rx_mix_bp = GPIO(2, 12);
static struct gpio_t gpio_tx_amp = GPIO(2, 15);
static struct gpio_t gpio_tx = GPIO(5, 15);
static struct gpio_t gpio_mix_bypass = GPIO(5, 16);
static struct gpio_t gpio_rx = GPIO(5, 5);
static struct gpio_t gpio_no_tx_amp_pwr = GPIO(3, 5);
static struct gpio_t gpio_amp_bypass = GPIO(0, 14);
static struct gpio_t gpio_rx_amp = GPIO(1, 11);
static struct gpio_t gpio_no_rx_amp_pwr = GPIO(1, 12);
#endif
// XXX
#ifdef RAD1O
#endif
#if 0
/* GPIO Input */
static struct gpio_t gpio_boot[] = {
GPIO(0, 8),
GPIO(0, 9),
GPIO(5, 7),
GPIO(1, 10),
};
#endif
/* CPLD JTAG interface GPIO pins */
static struct gpio_t gpio_cpld_tdo = GPIO(5, 18);
static struct gpio_t gpio_cpld_tck = GPIO(3, 0);
#ifdef HACKRF_ONE
static struct gpio_t gpio_cpld_tms = GPIO(3, 4);
static struct gpio_t gpio_cpld_tdi = GPIO(3, 1);
#else
static struct gpio_t gpio_cpld_tms = GPIO(3, 1);
static struct gpio_t gpio_cpld_tdi = GPIO(3, 4);
#endif
static struct gpio_t gpio_rx_decimation[3] = {
GPIO(5, 12),
GPIO(5, 13),
GPIO(5, 14),
};
static struct gpio_t gpio_rx_q_invert = GPIO(0, 13);
i2c_bus_t i2c0 = {
.obj = (void*)I2C0_BASE,
.start = i2c_lpc_start,
.stop = i2c_lpc_stop,
.transfer = i2c_lpc_transfer,
};
i2c_bus_t i2c1 = {
.obj = (void*)I2C1_BASE,
.start = i2c_lpc_start,
.stop = i2c_lpc_stop,
.transfer = i2c_lpc_transfer,
};
const i2c_lpc_config_t i2c_config_si5351c_slow_clock = {
.duty_cycle_count = 15,
};
const i2c_lpc_config_t i2c_config_si5351c_fast_clock = {
.duty_cycle_count = 255,
};
si5351c_driver_t clock_gen = {
.bus = &i2c0,
.i2c_address = 0x60,
};
const ssp_config_t ssp_config_max2837 = {
/* FIXME speed up once everything is working reliably */
/*
// Freq About 0.0498MHz / 49.8KHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz
const uint8_t serial_clock_rate = 32;
const uint8_t clock_prescale_rate = 128;
*/
// Freq About 4.857MHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz
.data_bits = SSP_DATA_16BITS,
.serial_clock_rate = 21,
.clock_prescale_rate = 2,
.gpio_select = &gpio_max2837_select,
};
const ssp_config_t ssp_config_max5864 = {
/* FIXME speed up once everything is working reliably */
/*
// Freq About 0.0498MHz / 49.8KHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz
const uint8_t serial_clock_rate = 32;
const uint8_t clock_prescale_rate = 128;
*/
// Freq About 4.857MHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz
.data_bits = SSP_DATA_8BITS,
.serial_clock_rate = 21,
.clock_prescale_rate = 2,
.gpio_select = &gpio_max5864_select,
};
spi_bus_t spi_bus_ssp1 = {
.obj = (void*)SSP1_BASE,
.config = &ssp_config_max2837,
.start = spi_ssp_start,
.stop = spi_ssp_stop,
.transfer = spi_ssp_transfer,
.transfer_gather = spi_ssp_transfer_gather,
};
max2837_driver_t max2837 = {
.bus = &spi_bus_ssp1,
.gpio_enable = &gpio_max2837_enable,
.gpio_rx_enable = &gpio_max2837_rx_enable,
.gpio_tx_enable = &gpio_max2837_tx_enable,
#ifdef JELLYBEAN
.gpio_rxhp = &gpio_max2837_rxhp,
.gpio_b1 = &gpio_max2837_b1,
.gpio_b2 = &gpio_max2837_b2,
.gpio_b3 = &gpio_max2837_b3,
.gpio_b4 = &gpio_max2837_b4,
.gpio_b5 = &gpio_max2837_b5,
.gpio_b6 = &gpio_max2837_b6,
.gpio_b7 = &gpio_max2837_b7,
#endif
.target_init = max2837_target_init,
.set_mode = max2837_target_set_mode,
};
max5864_driver_t max5864 = {
.bus = &spi_bus_ssp1,
.target_init = max5864_target_init,
};
#if 0 //XXX
const rffc5071_spi_config_t rffc5071_spi_config = {
.gpio_select = &gpio_rffc5072_select,
.gpio_clock = &gpio_rffc5072_clock,
.gpio_data = &gpio_rffc5072_data,
};
spi_bus_t spi_bus_rffc5071 = {
.config = &rffc5071_spi_config,
.start = rffc5071_spi_start,
.stop = rffc5071_spi_stop,
.transfer = rffc5071_spi_transfer,
.transfer_gather = rffc5071_spi_transfer_gather,
};
rffc5071_driver_t rffc5072 = {
.bus = &spi_bus_rffc5071,
.gpio_reset = &gpio_rffc5072_reset,
};
#endif
const ssp_config_t ssp_config_w25q80bv = {
.data_bits = SSP_DATA_8BITS,
.serial_clock_rate = 2,
.clock_prescale_rate = 2,
.gpio_select = &gpio_w25q80bv_select,
};
spi_bus_t spi_bus_ssp0 = {
.obj = (void*)SSP0_BASE,
.config = &ssp_config_w25q80bv,
.start = spi_ssp_start,
.stop = spi_ssp_stop,
.transfer = spi_ssp_transfer,
.transfer_gather = spi_ssp_transfer_gather,
};
w25q80bv_driver_t spi_flash = {
.bus = &spi_bus_ssp0,
.gpio_hold = &gpio_w25q80bv_hold,
.gpio_wp = &gpio_w25q80bv_wp,
.target_init = w25q80bv_target_init,
};
sgpio_config_t sgpio_config = {
.gpio_rx_q_invert = &gpio_rx_q_invert,
.gpio_rx_decimation = {
&gpio_rx_decimation[0],
&gpio_rx_decimation[1],
&gpio_rx_decimation[2],
},
.slice_mode_multislice = true,
};
rf_path_t rf_path = {
.switchctrl = 0,
#ifdef HACKRF_ONE
.gpio_hp = &gpio_hp,
.gpio_lp = &gpio_lp,
.gpio_tx_mix_bp = &gpio_tx_mix_bp,
.gpio_no_mix_bypass = &gpio_no_mix_bypass,
.gpio_rx_mix_bp = &gpio_rx_mix_bp,
.gpio_tx_amp = &gpio_tx_amp,
.gpio_tx = &gpio_tx,
.gpio_mix_bypass = &gpio_mix_bypass,
.gpio_rx = &gpio_rx,
.gpio_no_tx_amp_pwr = &gpio_no_tx_amp_pwr,
.gpio_amp_bypass = &gpio_amp_bypass,
.gpio_rx_amp = &gpio_rx_amp,
.gpio_no_rx_amp_pwr = &gpio_no_rx_amp_pwr,
#endif
#ifdef RAD1O
#endif
};
jtag_gpio_t jtag_gpio_cpld = {
.gpio_tms = &gpio_cpld_tms,
.gpio_tck = &gpio_cpld_tck,
.gpio_tdi = &gpio_cpld_tdi,
.gpio_tdo = &gpio_cpld_tdo,
};
jtag_t jtag_cpld = {
.gpio = &jtag_gpio_cpld,
};
void delay(uint32_t duration)
{
uint32_t i;
@ -123,9 +412,9 @@ bool sample_rate_frac_set(uint32_t rate_num, uint32_t rate_denom)
/* Can we enable integer mode ? */
if (a & 0x1 || b)
si5351c_set_int_mode(0, 0);
si5351c_set_int_mode(&clock_gen, 0, 0);
else
si5351c_set_int_mode(0, 1);
si5351c_set_int_mode(&clock_gen, 0, 1);
/* Final MS values */
MSx_P1 = 128*a + (128 * b/c) - 512;
@ -133,13 +422,13 @@ bool sample_rate_frac_set(uint32_t rate_num, uint32_t rate_denom)
MSx_P3 = c;
/* MS0/CLK0 is the source for the MAX5864/CPLD (CODEC_CLK). */
si5351c_configure_multisynth(0, MSx_P1, MSx_P2, MSx_P3, 1);
si5351c_configure_multisynth(&clock_gen, 0, MSx_P1, MSx_P2, MSx_P3, 1);
/* MS0/CLK1 is the source for the CPLD (CODEC_X2_CLK). */
si5351c_configure_multisynth(1, 0, 0, 0, 0);//p1 doesn't matter
si5351c_configure_multisynth(&clock_gen, 1, 0, 0, 0, 0);//p1 doesn't matter
/* MS0/CLK2 is the source for SGPIO (CODEC_X2_CLK) */
si5351c_configure_multisynth(2, 0, 0, 0, 0);//p1 doesn't matter
si5351c_configure_multisynth(&clock_gen, 2, 0, 0, 0, 0);//p1 doesn't matter
return true;
}
@ -181,13 +470,13 @@ bool sample_rate_set(const uint32_t sample_rate_hz) {
* values are irrelevant. */
/* MS0/CLK1 is the source for the MAX5864 codec. */
si5351c_configure_multisynth(1, 4608, 0, 1, r_div_sample);
si5351c_configure_multisynth(&clock_gen, 1, 4608, 0, 1, r_div_sample);
/* MS0/CLK2 is the source for the CPLD codec clock (same as CLK1). */
si5351c_configure_multisynth(2, 4608, 0, 1, r_div_sample);
si5351c_configure_multisynth(&clock_gen, 2, 4608, 0, 1, r_div_sample);
/* MS0/CLK3 is the source for the SGPIO clock. */
si5351c_configure_multisynth(3, 4608, 0, 1, r_div_sgpio);
si5351c_configure_multisynth(&clock_gen, 3, 4608, 0, 1, r_div_sgpio);
return true;
#endif
@ -244,21 +533,20 @@ bool sample_rate_set(const uint32_t sample_rate_hz) {
}
/* MS0/CLK0 is the source for the MAX5864/CPLD (CODEC_CLK). */
si5351c_configure_multisynth(0, p1, p2, p3, 1);
si5351c_configure_multisynth(&clock_gen, 0, p1, p2, p3, 1);
/* MS0/CLK1 is the source for the CPLD (CODEC_X2_CLK). */
si5351c_configure_multisynth(1, p1, 0, 1, 0);//p1 doesn't matter
si5351c_configure_multisynth(&clock_gen, 1, p1, 0, 1, 0);//p1 doesn't matter
/* MS0/CLK2 is the source for SGPIO (CODEC_X2_CLK) */
si5351c_configure_multisynth(2, p1, 0, 1, 0);//p1 doesn't matter
si5351c_configure_multisynth(&clock_gen, 2, p1, 0, 1, 0);//p1 doesn't matter
return true;
#endif
}
bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz) {
uint32_t bandwidth_hz_real = max2837_set_lpf_bandwidth(bandwidth_hz);
uint32_t bandwidth_hz_real = max2837_set_lpf_bandwidth(&max2837, bandwidth_hz);
if(bandwidth_hz_real) hackrf_ui_setFilterBW(bandwidth_hz_real);
@ -276,15 +564,15 @@ void cpu_clock_init(void)
/* use IRC as clock source for APB3 */
CGU_BASE_APB3_CLK = CGU_BASE_APB3_CLK_CLK_SEL(CGU_SRC_IRC);
i2c0_init(15);
i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_slow_clock);
si5351c_disable_all_outputs();
si5351c_disable_oeb_pin_control();
si5351c_power_down_all_clocks();
si5351c_set_crystal_configuration();
si5351c_enable_xo_and_ms_fanout();
si5351c_configure_pll_sources();
si5351c_configure_pll_multisynth();
si5351c_disable_all_outputs(&clock_gen);
si5351c_disable_oeb_pin_control(&clock_gen);
si5351c_power_down_all_clocks(&clock_gen);
si5351c_set_crystal_configuration(&clock_gen);
si5351c_enable_xo_and_ms_fanout(&clock_gen);
si5351c_configure_pll_sources(&clock_gen);
si5351c_configure_pll_multisynth(&clock_gen);
#ifdef JELLYBEAN
/*
@ -300,13 +588,13 @@ void cpu_clock_init(void)
*/
/* MS0/CLK0 is the source for the MAX2837 clock input. */
si5351c_configure_multisynth(0, 2048, 0, 1, 0); /* 40MHz */
si5351c_configure_multisynth(&clock_gen, 0, 2048, 0, 1, 0); /* 40MHz */
/* MS4/CLK4 is the source for the LPC43xx microcontroller. */
si5351c_configure_multisynth(4, 8021, 0, 3, 0); /* 12MHz */
si5351c_configure_multisynth(&clock_gen, 4, 8021, 0, 3, 0); /* 12MHz */
/* MS5/CLK5 is the source for the RFFC5071 mixer. */
si5351c_configure_multisynth(5, 1536, 0, 1, 0); /* 50MHz */
si5351c_configure_multisynth(&clock_gen, 5, 1536, 0, 1, 0); /* 50MHz */
#endif
#if (defined JAWBREAKER || defined HACKRF_ONE)
@ -323,19 +611,18 @@ void cpu_clock_init(void)
*/
/* MS3/CLK3 is the source for the external clock output. */
si5351c_configure_multisynth(3, 80*128-512, 0, 1, 0); /* 800/80 = 10MHz */
si5351c_configure_multisynth(&clock_gen, 3, 80*128-512, 0, 1, 0); /* 800/80 = 10MHz */
/* MS4/CLK4 is the source for the RFFC5071 mixer. */
si5351c_configure_multisynth(4, 16*128-512, 0, 1, 0); /* 800/16 = 50MHz */
si5351c_configure_multisynth(&clock_gen, 4, 16*128-512, 0, 1, 0); /* 800/16 = 50MHz */
/* MS5/CLK5 is the source for the MAX2837 clock input. */
si5351c_configure_multisynth(5, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */
si5351c_configure_multisynth(&clock_gen, 5, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */
/* MS6/CLK6 is unused. */
/* MS7/CLK7 is the source for the LPC43xx microcontroller. */
uint8_t ms7data[] = { 90, 255, 20, 0 };
si5351c_write(ms7data, sizeof(ms7data));
si5351c_write(&clock_gen, ms7data, sizeof(ms7data));
#endif
#ifdef RAD1O
@ -352,34 +639,34 @@ void cpu_clock_init(void)
*/
/* MS3/CLK3 is the source for the external clock output. */
si5351c_configure_multisynth(3, 80*128-512, 0, 1, 0); /* 800/80 = 10MHz */
si5351c_configure_multisynth(&clock_gen, 3, 80*128-512, 0, 1, 0); /* 800/80 = 10MHz */
/* MS4/CLK4 is the source for the MAX2837 clock input. */
si5351c_configure_multisynth(4, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */
si5351c_configure_multisynth(&clock_gen, 4, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */
/* MS5/CLK5 is the source for the RFFC5071 mixer. */
si5351c_configure_multisynth(5, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */
si5351c_configure_multisynth(&clock_gen, 5, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */
/* MS6/CLK6 is unused. */
/* MS7/CLK7 is the source for the LPC43xx microcontroller. */
uint8_t ms7data[] = { 90, 255, 20, 0 };
si5351c_write(ms7data, sizeof(ms7data));
si5351c_write(&clock_gen, ms7data, sizeof(ms7data));
#endif
/* Set to 10 MHz, the common rate between Jellybean and Jawbreaker. */
sample_rate_set(10000000);
//sample_rate_set(8000000);
si5351c_set_clock_source(PLL_SOURCE_XTAL);
si5351c_set_clock_source(&clock_gen, PLL_SOURCE_XTAL);
// soft reset
uint8_t resetdata[] = { 177, 0xac };
si5351c_write(resetdata, sizeof(resetdata));
si5351c_enable_clock_outputs();
si5351c_write(&clock_gen, resetdata, sizeof(resetdata));
si5351c_enable_clock_outputs(&clock_gen);
//FIXME disable I2C
/* Kick I2C0 down to 400kHz when we switch over to APB1 clock = 204MHz */
i2c0_init(255);
i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_fast_clock);
/*
* 12MHz clock is entering LPC XTAL1/OSC input now. On
@ -454,6 +741,12 @@ void cpu_clock_init(void)
/* Switch APB3 clock over to use PLL1 (204MHz) */
CGU_BASE_APB3_CLK = CGU_BASE_APB3_CLK_AUTOBLOCK(1)
| CGU_BASE_APB3_CLK_CLK_SEL(CGU_SRC_PLL1);
CGU_BASE_SSP0_CLK = CGU_BASE_SSP0_CLK_AUTOBLOCK(1)
| CGU_BASE_SSP0_CLK_CLK_SEL(CGU_SRC_PLL1);
CGU_BASE_SSP1_CLK = CGU_BASE_SSP1_CLK_AUTOBLOCK(1)
| CGU_BASE_SSP1_CLK_CLK_SEL(CGU_SRC_PLL1);
}
@ -547,70 +840,14 @@ void cpu_clock_pll1_max_speed(void)
}
void ssp1_init(void)
{
/*
* Configure CS_AD pin to keep the MAX5864 SPI disabled while we use the
* SPI bus for the MAX2837. FIXME: this should probably be somewhere else.
*/
scu_pinmux(SCU_AD_CS, SCU_GPIO_FAST);
GPIO_SET(PORT_AD_CS) = PIN_AD_CS;
GPIO_DIR(PORT_AD_CS) |= PIN_AD_CS;
scu_pinmux(SCU_XCVR_CS, SCU_GPIO_FAST);
GPIO_SET(PORT_XCVR_CS) = PIN_XCVR_CS;
GPIO_DIR(PORT_XCVR_CS) |= PIN_XCVR_CS;
/* Configure SSP1 Peripheral (to be moved later in SSP driver) */
scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1));
}
void ssp1_set_mode_max2837(void)
{
/* FIXME speed up once everything is working reliably */
/*
// Freq About 0.0498MHz / 49.8KHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz
const uint8_t serial_clock_rate = 32;
const uint8_t clock_prescale_rate = 128;
*/
// Freq About 4.857MHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz
const uint8_t serial_clock_rate = 21;
const uint8_t clock_prescale_rate = 2;
ssp_init(SSP1_NUM,
SSP_DATA_16BITS,
SSP_FRAME_SPI,
SSP_CPOL_0_CPHA_0,
serial_clock_rate,
clock_prescale_rate,
SSP_MODE_NORMAL,
SSP_MASTER,
SSP_SLAVE_OUT_ENABLE);
spi_bus_start(max2837.bus, &ssp_config_max2837);
}
void ssp1_set_mode_max5864(void)
{
/* FIXME speed up once everything is working reliably */
/*
// Freq About 0.0498MHz / 49.8KHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz
const uint8_t serial_clock_rate = 32;
const uint8_t clock_prescale_rate = 128;
*/
// Freq About 4.857MHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz
const uint8_t serial_clock_rate = 21;
const uint8_t clock_prescale_rate = 2;
ssp_init(SSP1_NUM,
SSP_DATA_8BITS,
SSP_FRAME_SPI,
SSP_CPOL_0_CPHA_0,
serial_clock_rate,
clock_prescale_rate,
SSP_MODE_NORMAL,
SSP_MASTER,
SSP_SLAVE_OUT_ENABLE);
spi_bus_start(max5864.bus, &ssp_config_max5864);
}
void pin_setup(void) {
@ -620,10 +857,10 @@ void pin_setup(void) {
scu_pinmux(SCU_PINMUX_CPLD_TMS, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_PINMUX_CPLD_TDI, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0);
GPIO_DIR(PORT_CPLD_TDO) &= ~PIN_CPLD_TDO;
GPIO_DIR(PORT_CPLD_TCK) &= ~PIN_CPLD_TCK;
GPIO_DIR(PORT_CPLD_TMS) &= ~PIN_CPLD_TMS;
GPIO_DIR(PORT_CPLD_TDI) &= ~PIN_CPLD_TDI;
gpio_input(&gpio_cpld_tdo);
gpio_input(&gpio_cpld_tck);
gpio_input(&gpio_cpld_tms);
gpio_input(&gpio_cpld_tdi);
/* Configure SCU Pin Mux as GPIO */
scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_NOPULL);
@ -646,63 +883,80 @@ void pin_setup(void) {
#endif
/* Configure all GPIO as Input (safe state) */
GPIO0_DIR = 0;
GPIO1_DIR = 0;
GPIO2_DIR = 0;
GPIO3_DIR = 0;
GPIO4_DIR = 0;
GPIO5_DIR = 0;
GPIO6_DIR = 0;
GPIO7_DIR = 0;
gpio_init();
/* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */
GPIO2_DIR |= (PIN_LED1 | PIN_LED2 | PIN_LED3);
gpio_output(&gpio_led[0]);
gpio_output(&gpio_led[1]);
gpio_output(&gpio_led[2]);
#ifdef RAD1O
GPIO5_DIR |= PIN_LED4;
gpio_output(&gpio_1v8_enable);
#if (defined HACKRF_ONE || defined RAD1O)
/* Configure RF power supply (VAA) switch control signal as output */
gpio_output(&gpio_vaa_disable);
/* Safe state: start with VAA turned off: */
disable_rf_power();
#endif
/* GPIO3[6] on P6_10 as output. */
GPIO3_DIR |= PIN_EN1V8;
#ifdef RAD1O
gpio_output(&gpio_led[4]);
#endif
rf_path_pin_setup();
/* enable input on SCL and SDA pins */
SCU_SFSI2C0 = SCU_I2C0_NOMINAL;
/* Configure SSP1 Peripheral (to be moved later in SSP driver) */
scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1));
scu_pinmux(SCU_SSP1_SSEL, (SCU_SSP_IO | SCU_CONF_FUNCTION1));
spi_bus_start(&spi_bus_ssp1, &ssp_config_max2837);
#if (defined JELLYBEAN || defined JAWBREAKER || defined HACKRF_ONE)
spi_bus_start(&spi_bus_rffc5071, &rffc5071_spi_config);
#endif
// XXX
#ifdef RAD1O
#endif
rf_path_pin_setup(&rf_path);
/* Configure external clock in */
scu_pinmux(SCU_PINMUX_GP_CLKIN, SCU_CLK_IN | SCU_CONF_FUNCTION1);
sgpio_configure_pin_functions();
sgpio_configure_pin_functions(&sgpio_config);
}
void enable_1v8_power(void) {
gpio_set(PORT_EN1V8, PIN_EN1V8);
gpio_set(&gpio_1v8_enable);
}
void disable_1v8_power(void) {
gpio_clear(PORT_EN1V8, PIN_EN1V8);
gpio_clear(&gpio_1v8_enable);
}
#ifdef HACKRF_ONE
void enable_rf_power(void) {
gpio_clear(PORT_NO_VAA_ENABLE, PIN_NO_VAA_ENABLE);
gpio_clear(&gpio_vaa_disable);
}
void disable_rf_power(void) {
gpio_set(PORT_NO_VAA_ENABLE, PIN_NO_VAA_ENABLE);
gpio_set(&gpio_vaa_disable);
}
#endif
#ifdef RAD1O
void enable_rf_power(void) {
gpio_set(PORT_VAA_ENABLE, PIN_VAA_ENABLE);
gpio_set(&gpio_vaa_disable);
}
void disable_rf_power(void) {
gpio_clear(PORT_VAA_ENABLE, PIN_VAA_ENABLE);
gpio_clear(&gpio_vaa_disable);
}
#endif
void led_on(const led_t led) {
gpio_set(&gpio_led[led]);
}
void led_off(const led_t led) {
gpio_clear(&gpio_led[led]);
}
void led_toggle(const led_t led) {
gpio_toggle(&gpio_led[led]);
}

View File

@ -32,6 +32,17 @@ extern "C"
#include <stdint.h>
#include <stdbool.h>
#include "si5351c.h"
#include "spi_ssp.h"
#include "max2837.h"
#include "max5864.h"
#include "rffc5071.h"
#include "w25q80bv.h"
#include "sgpio.h"
#include "rf_path.h"
#include "cpld_jtag.h"
/* hardware identification number */
#define BOARD_ID_JELLYBEAN 0
#define BOARD_ID_JAWBREAKER 1
@ -248,43 +259,11 @@ extern "C"
#define SCU_PINMUX_GP_CLKIN (P4_7)
/*
* GPIO Pins
*/
/* GPIO Output */
#define PIN_LED1 (BIT1) /* GPIO2[1] on P4_1 */
#define PIN_LED2 (BIT2) /* GPIO2[2] on P4_2 */
#define PIN_LED3 (BIT8) /* GPIO2[8] on P6_12 */
#define PORT_LED1_3 (GPIO2) /* PORT for LED1, 2 & 3 */
#ifdef RAD1O
#define PIN_LED4 (BIT26) /* GPIO5[26] on PB_6 */
#define PORT_LED4 (GPIO5) /* PORT for LED4 */
#endif
#define PIN_EN1V8 (BIT6) /* GPIO3[6] on P6_10 */
#define PORT_EN1V8 (GPIO3)
#define PIN_XCVR_CS (BIT15) /* GPIO0[15] on P1_20 */
#define PORT_XCVR_CS (GPIO0) /* PORT for CS */
#define PIN_XCVR_ENABLE (BIT6) /* GPIO2[6] on P4_6 */
#define PIN_XCVR_RXENABLE (BIT5) /* GPIO2[5] on P4_5 */
#define PIN_XCVR_TXENABLE (BIT4) /* GPIO2[4] on P4_4 */
#define PORT_XCVR_ENABLE (GPIO2) /* PORT for ENABLE, TXENABLE, RXENABLE */
#ifdef JELLYBEAN
#define PIN_XCVR_RXHP (BIT0) /* GPIO2[0] on P4_0 */
#define PORT_XCVR_RXHP (GPIO2)
#define PIN_XCVR_B1 (BIT9) /* GPIO2[9] on P5_0 */
#define PIN_XCVR_B2 (BIT10) /* GPIO2[10] on P5_1 */
#define PIN_XCVR_B3 (BIT11) /* GPIO2[11] on P5_2 */
#define PIN_XCVR_B4 (BIT12) /* GPIO2[12] on P5_3 */
#define PIN_XCVR_B5 (BIT13) /* GPIO2[13] on P5_4 */
#define PIN_XCVR_B6 (BIT14) /* GPIO2[14] on P5_5 */
#define PIN_XCVR_B7 (BIT15) /* GPIO2[15] on P5_6 */
#define PORT_XCVR_B (GPIO2)
#endif
#ifdef RAD1O
#define PIN_XCVR_RXHP (BIT1) /* GPIO4[1] on P8_1 */
#define PORT_XCVR_RXHP (GPIO4)
@ -293,29 +272,6 @@ extern "C"
#define PORT_XCVR_B (GPIO4)
#endif
#define PIN_AD_CS (BIT7) /* GPIO2[7] on P5_7 */
#define PORT_AD_CS (GPIO2) /* PORT for AD_CS */
#ifdef JELLYBEAN
#define PIN_MIXER_ENX (BIT8) /* GPIO3[8] on P7_0 */
#define PORT_MIXER_ENX (GPIO3)
#define PIN_MIXER_SCLK (BIT9) /* GPIO3[9] on P7_1 */
#define PORT_MIXER_SCLK (GPIO3)
#define PIN_MIXER_SDATA (BIT10) /* GPIO3[10] on P7_2 */
#define PORT_MIXER_SDATA (GPIO3)
#define PIN_MIXER_RESETX (BIT11) /* GPIO3[11] on P7_3 */
#define PORT_MIXER_RESETX (GPIO3)
#endif
#if (defined JAWBREAKER || defined HACKRF_ONE)
#define PIN_MIXER_ENX (BIT13) /* GPIO2[13] on P5_4 */
#define PORT_MIXER_ENX (GPIO2)
#define PIN_MIXER_SCLK (BIT6) /* GPIO5[6] on P2_6 */
#define PORT_MIXER_SCLK (GPIO5)
#define PIN_MIXER_SDATA (BIT3) /* GPIO3[3] on P6_4 */
#define PORT_MIXER_SDATA (GPIO3)
#define PIN_MIXER_RESETX (BIT14) /* GPIO2[14] on P5_5 */
#define PORT_MIXER_RESETX (GPIO2)
#endif
#ifdef RAD1O
#define PIN_VCO_CE (BIT13) /* GPIO2[13] on P5_4 */
#define PORT_VCO_CE (GPIO2)
@ -333,57 +289,11 @@ extern "C"
#define PORT_SYNT_RFOUT_EN (GPIO3)
#endif
#ifdef JAWBREAKER
#define PIN_RF_LDO_ENABLE (BIT9) /* GPIO2[9] on P5_0 */
#define PORT_RF_LDO_ENABLE (GPIO2) /* PORT for RF_LDO_ENABLE */
#endif
#ifdef HACKRF_ONE
#define PIN_NO_VAA_ENABLE (BIT9) /* GPIO2[9] on P5_0 */
#define PORT_NO_VAA_ENABLE (GPIO2) /* PORT for NO_VAA_ENABLE */
#endif
#ifdef RAD1O
#define PIN_VAA_ENABLE (BIT9) /* GPIO2[9] on P5_0 */
#define PORT_VAA_ENABLE (GPIO2) /* PORT for VAA_ENABLE */
#endif
#define PIN_FLASH_HOLD (BIT14) /* GPIO1[14] on P3_4 */
#define PIN_FLASH_WP (BIT15) /* GPIO1[15] on P3_5 */
#define PORT_FLASH (GPIO1)
#define PIN_SSP0_SSEL (BIT11) /* GPIO5[11] on P3_8 */
#define PORT_SSP0_SSEL (GPIO5)
/* RF switch control */
#ifdef HACKRF_ONE
#define PIN_HP (GPIOPIN0) /* GPIO2[0] on P4_0 */
#define PORT_HP (GPIO2)
#define PIN_LP (GPIOPIN10) /* GPIO2[10] on P5_1 */
#define PORT_LP (GPIO2)
#define PIN_TX_MIX_BP (GPIOPIN11) /* GPIO2[11] on P5_2 */
#define PORT_TX_MIX_BP (GPIO2)
#define PIN_NO_MIX_BYPASS (GPIOPIN0) /* GPIO1[0] on P1_7 */
#define PORT_NO_MIX_BYPASS (GPIO1)
#define PIN_RX_MIX_BP (GPIOPIN12) /* GPIO2[12] on P5_3 */
#define PORT_RX_MIX_BP (GPIO2)
#define PIN_TX_AMP (GPIOPIN15) /* GPIO2[15] on P5_6 */
#define PORT_TX_AMP (GPIO2)
#define PIN_TX (GPIOPIN15) /* GPIO5[15] on P6_7 */
#define PORT_TX (GPIO5)
#define PIN_MIX_BYPASS (GPIOPIN16) /* GPIO5[16] on P6_8 */
#define PORT_MIX_BYPASS (GPIO5)
#define PIN_RX (GPIOPIN5) /* GPIO5[5] on P2_5 */
#define PORT_RX (GPIO5)
#define PIN_NO_TX_AMP_PWR (GPIOPIN5) /* GPIO3[5] on P6_9 */
#define PORT_NO_TX_AMP_PWR (GPIO3)
#define PIN_AMP_BYPASS (GPIOPIN14) /* GPIO0[14] on P2_10 */
#define PORT_AMP_BYPASS (GPIO0)
#define PIN_RX_AMP (GPIOPIN11) /* GPIO1[11] on P2_11 */
#define PORT_RX_AMP (GPIO1)
#define PIN_NO_RX_AMP_PWR (GPIOPIN12) /* GPIO1[12] on P2_12 */
#define PORT_NO_RX_AMP_PWR (GPIO1)
#endif
#ifdef RAD1O
#define PIN_BY_AMP (GPIOPIN0) /* GPIO1[0] on P1_7 */
#define PORT_BY_AMP (GPIO1)
@ -407,40 +317,13 @@ extern "C"
#define PORT_RX_LNA (GPIO5)
#endif
/* GPIO Input */
#define PIN_BOOT0 (BIT8) /* GPIO0[8] on P1_1 */
#define PIN_BOOT1 (BIT9) /* GPIO0[9] on P1_2 */
#define PIN_BOOT2 (BIT7) /* GPIO5[7] on P2_8 */
#define PIN_BOOT3 (BIT10) /* GPIO1[10] on P2_9 */
/* CPLD JTAG interface GPIO pins */
#define PIN_CPLD_TDO (GPIOPIN18)
#define PORT_CPLD_TDO (GPIO5)
#define PIN_CPLD_TCK (GPIOPIN0)
#define PORT_CPLD_TCK (GPIO3)
#if (defined HACKRF_ONE || defined RAD1O)
#define PIN_CPLD_TMS (GPIOPIN4)
#define PORT_CPLD_TMS (GPIO3)
#define PIN_CPLD_TDI (GPIOPIN1)
#define PORT_CPLD_TDI (GPIO3)
#else
#define PIN_CPLD_TMS (GPIOPIN1)
#define PORT_CPLD_TMS (GPIO3)
#define PIN_CPLD_TDI (GPIOPIN4)
#define PORT_CPLD_TDI (GPIO3)
#endif
/* Read GPIO Pin */
#define GPIO_STATE(port, pin) ((GPIO_PIN(port) & (pin)) == (pin))
#define BOOT0_STATE GPIO_STATE(GPIO0, PIN_BOOT0)
#define BOOT1_STATE GPIO_STATE(GPIO0, PIN_BOOT1)
#define BOOT2_STATE GPIO_STATE(GPIO5, PIN_BOOT2)
#define BOOT3_STATE GPIO_STATE(GPIO1, PIN_BOOT3)
#define MIXER_SDATA_STATE GPIO_STATE(PORT_MIXER_SDATA, PIN_MIXER_SDATA)
#define CPLD_TDO_STATE GPIO_STATE(PORT_CPLD_TDO, PIN_CPLD_TDO)
/* TODO add other Pins */
typedef enum {
TRANSCEIVER_MODE_OFF = 0,
TRANSCEIVER_MODE_RX = 1,
@ -451,10 +334,24 @@ typedef enum {
void delay(uint32_t duration);
/* TODO: Hide these configurations */
extern si5351c_driver_t clock_gen;
extern const ssp_config_t ssp_config_w25q80bv;
extern const ssp_config_t ssp_config_max2837;
extern const ssp_config_t ssp_config_max5864;
extern max2837_driver_t max2837;
extern max5864_driver_t max5864;
// XXX
extern rffc5071_driver_t mixer;
extern w25q80bv_driver_t spi_flash;
extern sgpio_config_t sgpio_config;
extern rf_path_t rf_path;
extern jtag_t jtag_cpld;
void cpu_clock_init(void);
void cpu_clock_pll1_low_speed(void);
void cpu_clock_pll1_max_speed(void);
void ssp1_init(void);
void ssp1_set_mode_max2837(void);
void ssp1_set_mode_max5864(void);
@ -472,6 +369,16 @@ void enable_rf_power(void);
void disable_rf_power(void);
#endif
typedef enum {
LED1 = 0,
LED2 = 1,
LED3 = 2,
} led_t;
void led_on(const led_t led);
void led_off(const led_t led);
void led_toggle(const led_t led);
#ifdef __cplusplus
}
#endif

39
firmware/common/i2c_bus.c Normal file
View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "i2c_bus.h"
void i2c_bus_start(i2c_bus_t* const bus, const void* const config) {
bus->start(bus, config);
}
void i2c_bus_stop(i2c_bus_t* const bus) {
bus->stop(bus);
}
void i2c_bus_transfer(
i2c_bus_t* const bus,
const uint_fast8_t slave_address,
const uint8_t* const tx, const size_t tx_count,
uint8_t* const rx, const size_t rx_count
) {
bus->transfer(bus, slave_address, tx, tx_count, rx, rx_count);
}

52
firmware/common/i2c_bus.h Normal file
View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __I2C_BUS_H__
#define __I2C_BUS_H__
#include <stdint.h>
#include <stddef.h>
struct i2c_bus_t;
typedef struct i2c_bus_t i2c_bus_t;
struct i2c_bus_t {
void* const obj;
void (*start)(i2c_bus_t* const bus, const void* const config);
void (*stop)(i2c_bus_t* const bus);
void (*transfer)(
i2c_bus_t* const bus,
const uint_fast8_t slave_address,
const uint8_t* const tx, const size_t tx_count,
uint8_t* const rx, const size_t rx_count
);
};
void i2c_bus_start(i2c_bus_t* const bus, const void* const config);
void i2c_bus_stop(i2c_bus_t* const bus);
void i2c_bus_transfer(
i2c_bus_t* const bus,
const uint_fast8_t slave_address,
const uint8_t* const tx, const size_t tx_count,
uint8_t* const rx, const size_t rx_count
);
#endif/*__I2C_BUS_H__*/

62
firmware/common/i2c_lpc.c Normal file
View File

@ -0,0 +1,62 @@
/*
* Copyright 2012 Michael Ossmann <mike@ossmann.com>
* Copyright 2012 Jared Boone <jared@sharebrained.com>
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "i2c_lpc.h"
#include <libopencm3/lpc43xx/i2c.h>
/* FIXME return i2c0 status from each function */
void i2c_lpc_start(i2c_bus_t* const bus, const void* const _config) {
const i2c_lpc_config_t* const config = _config;
const uint32_t port = (uint32_t)bus->obj;
i2c_init(port, config->duty_cycle_count);
}
void i2c_lpc_stop(i2c_bus_t* const bus) {
const uint32_t port = (uint32_t)bus->obj;
i2c_disable(port);
}
void i2c_lpc_transfer(i2c_bus_t* const bus,
const uint_fast8_t slave_address,
const uint8_t* const data_tx, const size_t count_tx,
uint8_t* const data_rx, const size_t count_rx
) {
const uint32_t port = (uint32_t)bus->obj;
i2c_tx_start(port);
i2c_tx_byte(port, (slave_address << 1) | I2C_WRITE);
for(size_t i=0; i<count_tx; i++) {
i2c_tx_byte(port, data_tx[i]);
}
if( data_rx ) {
i2c_tx_start(port);
i2c_tx_byte(port, (slave_address << 1) | I2C_READ);
for(size_t i=0; i<count_rx; i++) {
data_rx[i] = i2c_rx_byte(port);
}
}
i2c_stop(port);
}

42
firmware/common/i2c_lpc.h Normal file
View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __I2C_LPC_H__
#define __I2C_LPC_H__
#include <stdint.h>
#include <stddef.h>
#include "i2c_bus.h"
typedef struct i2c_lpc_config_t {
const uint16_t duty_cycle_count;
} i2c_lpc_config_t;
void i2c_lpc_start(i2c_bus_t* const bus, const void* const config);
void i2c_lpc_stop(i2c_bus_t* const bus);
void i2c_lpc_transfer(i2c_bus_t* const bus,
const uint_fast8_t slave_address,
const uint8_t* const data_tx, const size_t count_tx,
uint8_t* const data_rx, const size_t count_rx
);
#endif/*__I2C_LPC_H__*/

View File

@ -1,3 +1,25 @@
/*
* Copyright 2012 Will Code? (TODO: Proper attribution)
* Copyright 2014 Jared Boone <jared@sharebrained.com>
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
/*
* 'gcc -DTEST -DDEBUG -O2 -o test max2837.c' prints out what test
* program would do if it had a real spi library
@ -11,19 +33,8 @@
#include "max2837.h"
#include "max2837_regs.def" // private register def macros
#if (defined DEBUG || defined BUS_PIRATE)
#include <stdio.h>
#define LOG printf
#else
#define LOG(x,...)
#include <libopencm3/lpc43xx/ssp.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/gpio.h>
#include "hackrf_core.h"
#endif
/* Default register values. */
static uint16_t max2837_regs_default[MAX2837_NUM_REGS] = {
static const uint16_t max2837_regs_default[MAX2837_NUM_REGS] = {
0x150, /* 0 */
0x002, /* 1 */
0x1f4, /* 2 */
@ -62,283 +73,130 @@ static uint16_t max2837_regs_default[MAX2837_NUM_REGS] = {
0x080, /* 30 */
0x000 }; /* 31 */
uint16_t max2837_regs[MAX2837_NUM_REGS];
/* Mark all regsisters dirty so all will be written at init. */
uint32_t max2837_regs_dirty = 0xffffffff;
/* Set up all registers according to defaults specified in docs. */
void max2837_init(void)
static void max2837_init(max2837_driver_t* const drv)
{
LOG("# max2837_init\n");
memcpy(max2837_regs, max2837_regs_default, sizeof(max2837_regs));
max2837_regs_dirty = 0xffffffff;
drv->target_init(drv);
max2837_set_mode(drv, MAX2837_MODE_SHUTDOWN);
memcpy(drv->regs, max2837_regs_default, sizeof(drv->regs));
drv->regs_dirty = 0xffffffff;
/* Write default register values to chip. */
max2837_regs_commit();
max2837_regs_commit(drv);
}
/*
* Set up pins for GPIO and SPI control, configure SSP peripheral for SPI, and
* set our own default register configuration.
*/
void max2837_setup(void)
void max2837_setup(max2837_driver_t* const drv)
{
LOG("# max2837_setup\n");
#if !defined TEST
/* Configure XCVR_CTL GPIO pins. */
#ifdef JELLYBEAN
scu_pinmux(SCU_XCVR_RXHP, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B1, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B2, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B3, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B4, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B5, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B6, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B7, SCU_GPIO_FAST);
#endif
scu_pinmux(SCU_XCVR_ENABLE, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_RXENABLE, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_TXENABLE, SCU_GPIO_FAST);
/* Set GPIO pins as outputs. */
GPIO2_DIR |= (PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE);
#ifdef JELLYBEAN
GPIO_DIR(PORT_XCVR_RXHP) |= PIN_XCVR_RXHP;
GPIO_DIR(PORT_XCVR_B) |=
PIN_XCVR_B1
| PIN_XCVR_B2
| PIN_XCVR_B3
| PIN_XCVR_B4
| PIN_XCVR_B5
| PIN_XCVR_B6
| PIN_XCVR_B7
;
#endif
max2837_mode_shutdown();
#ifdef JELLYBEAN
gpio_set(PORT_XCVR_RXHP, PIN_XCVR_RXHP);
gpio_set(PORT_XCVR_B,
PIN_XCVR_B1
| PIN_XCVR_B2
| PIN_XCVR_B3
| PIN_XCVR_B4
| PIN_XCVR_B5
| PIN_XCVR_B6
| PIN_XCVR_B7
);
#endif
#endif
max2837_init();
LOG("# max2837_init done\n");
max2837_init(drv);
/* Use SPI control instead of B1-B7 pins for gain settings. */
set_MAX2837_TXVGA_GAIN_SPI_EN(1);
set_MAX2837_TXVGA_GAIN_MSB_SPI_EN(1);
set_MAX2837_TXVGA_GAIN_SPI_EN(drv, 1);
set_MAX2837_TXVGA_GAIN_MSB_SPI_EN(drv, 1);
//set_MAX2837_TXVGA_GAIN(0x3f); /* maximum attenuation */
set_MAX2837_TXVGA_GAIN(0x00); /* minimum attenuation */
set_MAX2837_VGAMUX_enable(1);
set_MAX2837_VGA_EN(1);
set_MAX2837_HPC_RXGAIN_EN(0);
set_MAX2837_HPC_STOP(MAX2837_STOP_1K);
set_MAX2837_LNAgain_SPI_EN(1);
set_MAX2837_LNAgain(MAX2837_LNAgain_MAX); /* maximum gain */
set_MAX2837_VGAgain_SPI_EN(1);
set_MAX2837_VGA(0x18); /* reasonable gain for noisy 2.4GHz environment */
set_MAX2837_TXVGA_GAIN(drv, 0x00); /* minimum attenuation */
set_MAX2837_VGAMUX_enable(drv, 1);
set_MAX2837_VGA_EN(drv, 1);
set_MAX2837_HPC_RXGAIN_EN(drv, 0);
set_MAX2837_HPC_STOP(drv, MAX2837_STOP_1K);
set_MAX2837_LNAgain_SPI_EN(drv, 1);
set_MAX2837_LNAgain(drv, MAX2837_LNAgain_MAX); /* maximum gain */
set_MAX2837_VGAgain_SPI_EN(drv, 1);
set_MAX2837_VGA(drv, 0x18); /* reasonable gain for noisy 2.4GHz environment */
/* maximum rx output common-mode voltage */
set_MAX2837_BUFF_VCM(MAX2837_BUFF_VCM_1_25);
set_MAX2837_BUFF_VCM(drv, MAX2837_BUFF_VCM_1_25);
/* configure baseband filter for 8 MHz TX */
set_MAX2837_LPF_EN(1);
set_MAX2837_ModeCtrl(MAX2837_ModeCtrl_RxLPF);
set_MAX2837_FT(MAX2837_FT_5M);
set_MAX2837_LPF_EN(drv, 1);
set_MAX2837_ModeCtrl(drv, MAX2837_ModeCtrl_RxLPF);
set_MAX2837_FT(drv, MAX2837_FT_5M);
max2837_regs_commit();
max2837_regs_commit(drv);
}
/* SPI register read. */
uint16_t max2837_spi_read(uint8_t r) {
gpio_clear(PORT_XCVR_CS, PIN_XCVR_CS);
const uint16_t value = ssp_transfer(SSP1_NUM, (uint16_t)((1 << 15) | (r << 10)));
gpio_set(PORT_XCVR_CS, PIN_XCVR_CS);
static uint16_t max2837_read(max2837_driver_t* const drv, uint8_t r) {
uint16_t value = (1 << 15) | (r << 10);
spi_bus_transfer(drv->bus, &value, 1);
return value & 0x3ff;
}
/* SPI register write */
void max2837_spi_write(uint8_t r, uint16_t v) {
#ifdef BUS_PIRATE
LOG("{0x%02x 0x%02x]\n", 0x00 | ((uint16_t)r<<2) | ((v>>8) & 0x3),
v & 0xff);
#elif DEBUG
LOG("0x%03x -> reg%d\n", v, r);
#else
gpio_clear(PORT_XCVR_CS, PIN_XCVR_CS);
ssp_transfer(SSP1_NUM, (uint16_t)((r << 10) | (v & 0x3ff)));
gpio_set(PORT_XCVR_CS, PIN_XCVR_CS);
#endif
static void max2837_write(max2837_driver_t* const drv, uint8_t r, uint16_t v) {
uint16_t value = (r << 10) | (v & 0x3ff);
spi_bus_transfer(drv->bus, &value, 1);
}
uint16_t max2837_reg_read(uint8_t r)
uint16_t max2837_reg_read(max2837_driver_t* const drv, uint8_t r)
{
if ((max2837_regs_dirty >> r) & 0x1) {
max2837_regs[r] = max2837_spi_read(r);
if ((drv->regs_dirty >> r) & 0x1) {
drv->regs[r] = max2837_read(drv, r);
};
return max2837_regs[r];
return drv->regs[r];
}
void max2837_reg_write(uint8_t r, uint16_t v)
void max2837_reg_write(max2837_driver_t* const drv, uint8_t r, uint16_t v)
{
max2837_regs[r] = v;
max2837_spi_write(r, v);
MAX2837_REG_SET_CLEAN(r);
drv->regs[r] = v;
max2837_write(drv, r, v);
MAX2837_REG_SET_CLEAN(drv, r);
}
/* This functions should not be needed, and might be confusing. DELETE. */
void max2837_regs_read(void)
static inline void max2837_reg_commit(max2837_driver_t* const drv, uint8_t r)
{
;
max2837_reg_write(drv, r, drv->regs[r]);
}
static inline void max2837_reg_commit(uint8_t r)
{
max2837_reg_write(r,max2837_regs[r]);
}
void max2837_regs_commit(void)
void max2837_regs_commit(max2837_driver_t* const drv)
{
int r;
for(r = 0; r < MAX2837_NUM_REGS; r++) {
if ((max2837_regs_dirty >> r) & 0x1) {
max2837_reg_commit(r);
if ((drv->regs_dirty >> r) & 0x1) {
max2837_reg_commit(drv, r);
}
}
}
void max2837_mode_shutdown(void) {
/* All circuit blocks are powered down, except the 4-wire serial bus
* and its internal programmable registers.
*/
gpio_clear(PORT_XCVR_ENABLE,
(PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE));
void max2837_set_mode(max2837_driver_t* const drv, const max2837_mode_t new_mode) {
drv->set_mode(drv, new_mode);
}
void max2837_mode_standby(void) {
/* Used to enable the frequency synthesizer block while the rest of the
* device is powered down. In this mode, PLL, VCO, and LO generator
* are on, so that Tx or Rx modes can be quickly enabled from this mode.
* These and other blocks can be selectively enabled in this mode.
*/
gpio_clear(PORT_XCVR_ENABLE, (PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE));
gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_ENABLE);
max2837_mode_t max2837_mode(max2837_driver_t* const drv) {
return drv->mode;
}
void max2837_mode_tx(void) {
/* All Tx circuit blocks are powered on. The external PA is powered on
* after a programmable delay using the on-chip PA bias DAC. The slow-
* charging Rx circuits are in a precharged idle-off state for fast
* Tx-to-Rx turnaround time.
*/
gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE);
gpio_set(PORT_XCVR_ENABLE,
(PIN_XCVR_ENABLE | PIN_XCVR_TXENABLE));
}
void max2837_mode_rx(void) {
/* All Rx circuit blocks are powered on and active. Antenna signal is
* applied; RF is downconverted, filtered, and buffered at Rx BB I and Q
* outputs. The slow- charging Tx circuits are in a precharged idle-off
* state for fast Rx-to-Tx turnaround time.
*/
gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE);
gpio_set(PORT_XCVR_ENABLE,
(PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE));
}
max2837_mode_t max2837_mode(void) {
if( gpio_get(PORT_XCVR_ENABLE, PIN_XCVR_ENABLE) ) {
if( gpio_get(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE) ) {
return MAX2837_MODE_TX;
} else if( gpio_get(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE) ) {
return MAX2837_MODE_RX;
} else {
return MAX2837_MODE_STANDBY;
}
} else {
return MAX2837_MODE_SHUTDOWN;
}
}
void max2837_set_mode(const max2837_mode_t new_mode) {
switch(new_mode) {
case MAX2837_MODE_SHUTDOWN:
max2837_mode_shutdown();
break;
case MAX2837_MODE_STANDBY:
max2837_mode_standby();
break;
case MAX2837_MODE_TX:
max2837_mode_tx();
break;
case MAX2837_MODE_RX:
max2837_mode_rx();
break;
default:
break;
}
}
void max2837_start(void)
void max2837_start(max2837_driver_t* const drv)
{
LOG("# max2837_start\n");
set_MAX2837_EN_SPI(1);
max2837_regs_commit();
#if !defined TEST
max2837_mode_standby();
#endif
set_MAX2837_EN_SPI(drv, 1);
max2837_regs_commit(drv);
max2837_set_mode(drv, MAX2837_MODE_STANDBY);
}
void max2837_tx(void)
void max2837_tx(max2837_driver_t* const drv)
{
LOG("# max2837_tx\n");
#if !defined TEST
set_MAX2837_ModeCtrl(MAX2837_ModeCtrl_TxLPF);
max2837_regs_commit();
max2837_mode_tx();
#endif
set_MAX2837_ModeCtrl(drv, MAX2837_ModeCtrl_TxLPF);
max2837_regs_commit(drv);
max2837_set_mode(drv, MAX2837_MODE_TX);
}
void max2837_rx(void)
void max2837_rx(max2837_driver_t* const drv)
{
LOG("# max2837_rx\n");
set_MAX2837_ModeCtrl(MAX2837_ModeCtrl_RxLPF);
max2837_regs_commit();
#if !defined TEST
max2837_mode_rx();
#endif
set_MAX2837_ModeCtrl(drv, MAX2837_ModeCtrl_RxLPF);
max2837_regs_commit(drv);
max2837_set_mode(drv, MAX2837_MODE_RX);
}
void max2837_stop(void)
void max2837_stop(max2837_driver_t* const drv)
{
LOG("# max2837_stop\n");
set_MAX2837_EN_SPI(0);
max2837_regs_commit();
#if !defined TEST
max2837_mode_shutdown();
#endif
set_MAX2837_EN_SPI(drv, 0);
max2837_regs_commit(drv);
max2837_set_mode(drv, MAX2837_MODE_SHUTDOWN);
}
void max2837_set_frequency(uint32_t freq)
void max2837_set_frequency(max2837_driver_t* const drv, uint32_t freq)
{
uint8_t band;
uint8_t lna_band;
@ -366,9 +224,6 @@ void max2837_set_frequency(uint32_t freq)
lna_band = MAX2837_LNAband_2_6;
}
LOG("# max2837_set_frequency %ld, band %d, lna band %d\n",
freq, band, lna_band);
/* ASSUME 40MHz PLL. Ratio = F*(4/3)/40,000,000 = F/30,000,000 */
div_int = freq / 30000000;
div_rem = freq % 30000000;
@ -382,22 +237,21 @@ void max2837_set_frequency(uint32_t freq)
div_rem -= div_cmp;
}
}
LOG("# int %ld, frac %ld\n", div_int, div_frac);
/* Band settings */
set_MAX2837_LOGEN_BSW(band);
set_MAX2837_LNAband(lna_band);
set_MAX2837_LOGEN_BSW(drv, band);
set_MAX2837_LNAband(drv, lna_band);
/* Write order matters here, so commit INT and FRAC_HI before
* committing FRAC_LO, which is the trigger for VCO
* auto-select. TODO - it's cleaner this way, but it would be
* faster to explicitly commit the registers explicitly so the
* dirty bits aren't scanned twice. */
set_MAX2837_SYN_INT(div_int);
set_MAX2837_SYN_FRAC_HI((div_frac >> 10) & 0x3ff);
max2837_regs_commit();
set_MAX2837_SYN_FRAC_LO(div_frac & 0x3ff);
max2837_regs_commit();
set_MAX2837_SYN_INT(drv, div_int);
set_MAX2837_SYN_FRAC_HI(drv, (div_frac >> 10) & 0x3ff);
max2837_regs_commit(drv);
set_MAX2837_SYN_FRAC_LO(drv, div_frac & 0x3ff);
max2837_regs_commit(drv);
}
typedef struct {
@ -425,7 +279,7 @@ static const max2837_ft_t max2837_ft[] = {
{ 0, 0 },
};
uint32_t max2837_set_lpf_bandwidth(const uint32_t bandwidth_hz) {
uint32_t max2837_set_lpf_bandwidth(max2837_driver_t* const drv, const uint32_t bandwidth_hz) {
const max2837_ft_t* p = max2837_ft;
while( p->bandwidth_hz != 0 ) {
if( p->bandwidth_hz >= bandwidth_hz ) {
@ -435,14 +289,14 @@ uint32_t max2837_set_lpf_bandwidth(const uint32_t bandwidth_hz) {
}
if( p->bandwidth_hz != 0 ) {
set_MAX2837_FT(p->ft);
max2837_regs_commit();
set_MAX2837_FT(drv, p->ft);
max2837_regs_commit(drv);
}
return p->bandwidth_hz;
}
bool max2837_set_lna_gain(const uint32_t gain_db) {
bool max2837_set_lna_gain(max2837_driver_t* const drv, const uint32_t gain_db) {
uint16_t val;
switch(gain_db){
case 40:
@ -466,21 +320,21 @@ bool max2837_set_lna_gain(const uint32_t gain_db) {
default:
return false;
}
set_MAX2837_LNAgain(val);
max2837_reg_commit(1);
set_MAX2837_LNAgain(drv, val);
max2837_reg_commit(drv, 1);
return true;
}
bool max2837_set_vga_gain(const uint32_t gain_db) {
bool max2837_set_vga_gain(max2837_driver_t* const drv, const uint32_t gain_db) {
if( (gain_db & 0x1) || gain_db > 62)/* 0b11111*2 */
return false;
set_MAX2837_VGA( 31-(gain_db >> 1) );
max2837_reg_commit(5);
set_MAX2837_VGA(drv, 31-(gain_db >> 1) );
max2837_reg_commit(drv, 5);
return true;
}
bool max2837_set_txvga_gain(const uint32_t gain_db) {
bool max2837_set_txvga_gain(max2837_driver_t* const drv, const uint32_t gain_db) {
uint16_t val=0;
if(gain_db <16){
val = 31-gain_db;
@ -489,18 +343,7 @@ bool max2837_set_txvga_gain(const uint32_t gain_db) {
val = 31-(gain_db-16);
}
set_MAX2837_TXVGA_GAIN(val);
max2837_reg_commit(29);
set_MAX2837_TXVGA_GAIN(drv, val);
max2837_reg_commit(drv, 29);
return true;
}
#ifdef TEST
int main(int ac, char **av)
{
max2837_setup();
max2837_set_frequency(2441000000);
max2837_start();
max2837_tx();
max2837_stop();
}
#endif //TEST

View File

@ -1,42 +1,38 @@
/*
* Copyright 2012 Will Code? (TODO: Proper attribution)
* Copyright 2014 Jared Boone <jared@sharebrained.com>
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __MAX2837_H
#define __MAX2837_H
#include <stdint.h>
#include <stdbool.h>
/* TODO - make this a private header for max2837.c only, make new max2837.h */
#include "gpio.h"
#include "spi_bus.h"
/* 32 registers, each containing 10 bits of data. */
#define MAX2837_NUM_REGS 32
#define MAX2837_DATA_REGS_MAX_VALUE 1024
/* TODO - these externs will be local to max2837.c ... don't define here? */
extern uint16_t max2837_regs[MAX2837_NUM_REGS];
extern uint32_t max2837_regs_dirty;
#define MAX2837_REG_SET_CLEAN(r) max2837_regs_dirty &= ~(1UL<<r)
#define MAX2837_REG_SET_DIRTY(r) max2837_regs_dirty |= (1UL<<r)
/* Initialize chip. */
extern void max2837_init(void);
extern void max2837_setup(void);
/* Read a register via SPI. Save a copy to memory and return
* value. Mark clean. */
extern uint16_t max2837_reg_read(uint8_t r);
/* Write value to register via SPI and save a copy to memory. Mark
* clean. */
extern void max2837_reg_write(uint8_t r, uint16_t v);
/* Read all registers from chip and copy to memory. Mark all clean. */
extern void max2837_regs_read(void);
/* Write all dirty registers via SPI from memory. Mark all clean. Some
* operations require registers to be written in a certain order. Use
* provided routines for those operations. */
extern void max2837_regs_commit(void);
typedef enum {
MAX2837_MODE_SHUTDOWN,
MAX2837_MODE_STANDBY,
@ -44,27 +40,63 @@ typedef enum {
MAX2837_MODE_RX
} max2837_mode_t;
void max2837_mode_shutdown(void);
void max2837_mode_standby(void);
void max2837_mode_tx(void);
void max2837_mode_rx(void);
struct max2837_driver_t;
typedef struct max2837_driver_t max2837_driver_t;
max2837_mode_t max2837_mode(void);
void max2837_set_mode(const max2837_mode_t new_mode);
struct max2837_driver_t {
spi_bus_t* const bus;
gpio_t gpio_enable;
gpio_t gpio_rx_enable;
gpio_t gpio_tx_enable;
#ifdef JELLYBEAN
gpio_t gpio_rxhp;
gpio_t gpio_b1;
gpio_t gpio_b2;
gpio_t gpio_b3;
gpio_t gpio_b4;
gpio_t gpio_b5;
gpio_t gpio_b6;
gpio_t gpio_b7;
#endif
void (*target_init)(max2837_driver_t* const drv);
void (*set_mode)(max2837_driver_t* const drv, const max2837_mode_t new_mode);
max2837_mode_t mode;
uint16_t regs[MAX2837_NUM_REGS];
uint32_t regs_dirty;
};
/* Initialize chip. */
extern void max2837_setup(max2837_driver_t* const drv);
/* Read a register via SPI. Save a copy to memory and return
* value. Mark clean. */
extern uint16_t max2837_reg_read(max2837_driver_t* const drv, uint8_t r);
/* Write value to register via SPI and save a copy to memory. Mark
* clean. */
extern void max2837_reg_write(max2837_driver_t* const drv, uint8_t r, uint16_t v);
/* Write all dirty registers via SPI from memory. Mark all clean. Some
* operations require registers to be written in a certain order. Use
* provided routines for those operations. */
extern void max2837_regs_commit(max2837_driver_t* const drv);
max2837_mode_t max2837_mode(max2837_driver_t* const drv);
void max2837_set_mode(max2837_driver_t* const drv, const max2837_mode_t new_mode);
/* Turn on/off all chip functions. Does not control oscillator and CLKOUT */
extern void max2837_start(void);
extern void max2837_stop(void);
extern void max2837_start(max2837_driver_t* const drv);
extern void max2837_stop(max2837_driver_t* const drv);
/* Set frequency in Hz. Frequency setting is a multi-step function
* where order of register writes matters. */
extern void max2837_set_frequency(uint32_t freq);
uint32_t max2837_set_lpf_bandwidth(const uint32_t bandwidth_hz);
bool max2837_set_lna_gain(const uint32_t gain_db);
bool max2837_set_vga_gain(const uint32_t gain_db);
bool max2837_set_txvga_gain(const uint32_t gain_db);
extern void max2837_set_frequency(max2837_driver_t* const drv, uint32_t freq);
uint32_t max2837_set_lpf_bandwidth(max2837_driver_t* const drv, const uint32_t bandwidth_hz);
bool max2837_set_lna_gain(max2837_driver_t* const drv, const uint32_t gain_db);
bool max2837_set_vga_gain(max2837_driver_t* const drv, const uint32_t gain_db);
bool max2837_set_txvga_gain(max2837_driver_t* const drv, const uint32_t gain_db);
extern void max2837_tx(void);
extern void max2837_rx(void);
extern void max2837_tx(max2837_driver_t* const drv);
extern void max2837_rx(max2837_driver_t* const drv);
#endif // __MAX2837_H

View File

@ -9,19 +9,22 @@
* (structs). This may be used in firmware, or on host predefined
* register loads. */
#define MAX2837_REG_SET_CLEAN(_d, _r) (_d->regs_dirty &= ~(1UL<<_r))
#define MAX2837_REG_SET_DIRTY(_d, _r) (_d->regs_dirty |= (1UL<<_r))
/* On set_, register is always set dirty, even if nothing
* changed. This makes sure that write that have side effects,
* e.g. frequency setting, are not skipped. */
/* n=name, r=regnum, o=offset (bits from LSB), l=length (bits) */
#define __MREG__(n,r,o,l) \
static inline uint16_t get_##n(void) { \
return (max2837_regs[r] >> (o-l+1)) & ((1<<l)-1); \
static inline uint16_t get_##n(max2837_driver_t* const _d) { \
return (_d->regs[r] >> (o-l+1)) & ((1<<l)-1); \
} \
static inline void set_##n(uint16_t v) { \
max2837_regs[r] &= ~(((1<<l)-1)<<(o-l+1)); \
max2837_regs[r] |= ((v&((1<<l)-1))<<(o-l+1)); \
MAX2837_REG_SET_DIRTY(r); \
static inline void set_##n(max2837_driver_t* const _d, uint16_t v) { \
_d->regs[r] &= ~(((1<<l)-1)<<(o-l+1)); \
_d->regs[r] |= ((v&((1<<l)-1))<<(o-l+1)); \
MAX2837_REG_SET_DIRTY(_d, r); \
}
/* REG 0 */

View File

@ -0,0 +1,105 @@
/*
* Copyright 2012 Will Code? (TODO: Proper attribution)
* Copyright 2014 Jared Boone <jared@sharebrained.com>
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "max2837_target.h"
#include <libopencm3/lpc43xx/scu.h>
#include "hackrf_core.h"
void max2837_target_init(max2837_driver_t* const drv) {
/* Configure SSP1 Peripheral (to be moved later in SSP driver) */
scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1));
scu_pinmux(SCU_XCVR_CS, SCU_GPIO_FAST);
/* Configure XCVR_CTL GPIO pins. */
#ifdef JELLYBEAN
scu_pinmux(SCU_XCVR_RXHP, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B1, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B2, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B3, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B4, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B5, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B6, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_B7, SCU_GPIO_FAST);
#endif
scu_pinmux(SCU_XCVR_ENABLE, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_RXENABLE, SCU_GPIO_FAST);
scu_pinmux(SCU_XCVR_TXENABLE, SCU_GPIO_FAST);
/* Set GPIO pins as outputs. */
gpio_output(drv->gpio_enable);
gpio_output(drv->gpio_rx_enable);
gpio_output(drv->gpio_tx_enable);
#ifdef JELLYBEAN
gpio_output(drv->gpio_rxhp);
gpio_output(drv->gpio_b1);
gpio_output(drv->gpio_b2);
gpio_output(drv->gpio_b3);
gpio_output(drv->gpio_b4);
gpio_output(drv->gpio_b5);
gpio_output(drv->gpio_b6);
gpio_output(drv->gpio_b7);
#endif
#ifdef JELLYBEAN
gpio_set(drv->gpio_rxhp);
gpio_set(drv->gpio_b1);
gpio_set(drv->gpio_b2);
gpio_set(drv->gpio_b3);
gpio_set(drv->gpio_b4);
gpio_set(drv->gpio_b5);
gpio_set(drv->gpio_b6);
gpio_set(drv->gpio_b7);
#endif
}
void max2837_target_set_mode(max2837_driver_t* const drv, const max2837_mode_t new_mode) {
/* MAX2837_MODE_SHUTDOWN:
* All circuit blocks are powered down, except the 4-wire serial bus
* and its internal programmable registers.
*
* MAX2837_MODE_STANDBY:
* Used to enable the frequency synthesizer block while the rest of the
* device is powered down. In this mode, PLL, VCO, and LO generator
* are on, so that Tx or Rx modes can be quickly enabled from this mode.
* These and other blocks can be selectively enabled in this mode.
*
* MAX2837_MODE_TX:
* All Tx circuit blocks are powered on. The external PA is powered on
* after a programmable delay using the on-chip PA bias DAC. The slow-
* charging Rx circuits are in a precharged idle-off state for fast
* Tx-to-Rx turnaround time.
*
* MAX2837_MODE_RX:
* All Rx circuit blocks are powered on and active. Antenna signal is
* applied; RF is downconverted, filtered, and buffered at Rx BB I and Q
* outputs. The slow- charging Tx circuits are in a precharged idle-off
* state for fast Rx-to-Tx turnaround time.
*/
gpio_write(drv->gpio_enable, new_mode != MAX2837_MODE_SHUTDOWN);
gpio_write(drv->gpio_rx_enable, new_mode == MAX2837_MODE_RX);
gpio_write(drv->gpio_tx_enable, new_mode == MAX2837_MODE_TX);
drv->mode = new_mode;
}

View File

@ -0,0 +1,31 @@
/*
* Copyright 2012 Will Code? (TODO: Proper attribution)
* Copyright 2014 Jared Boone <jared@sharebrained.com>
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __MAX2837_TARGET_H
#define __MAX2837_TARGET_H
#include "max2837.h"
void max2837_target_init(max2837_driver_t* const drv);
void max2837_target_set_mode(max2837_driver_t* const drv, const max2837_mode_t new_mode);
#endif // __MAX2837_TARGET_H

View File

@ -10,19 +10,22 @@
#define LOG(x,...)
#include <libopencm3/lpc43xx/ssp.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/gpio.h>
//#include <libopencm3/lpc43xx/gpio.h>
#include "hackrf_core.h"
#endif
#include <stdint.h>
#include <string.h>
rffc5071_driver_t mixer;
static void max2871_spi_write(uint8_t r, uint32_t v);
static void max2871_write_registers(void);
static void delay_ms(int ms);
void mixer_setup(void)
void mixer_setup(rffc5071_driver_t* const drv)
{
#if 0 //XXX
/* Configure GPIO pins. */
scu_pinmux(SCU_VCO_CE, SCU_GPIO_FAST);
scu_pinmux(SCU_VCO_SCLK, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
@ -106,6 +109,7 @@ void mixer_setup(void)
max2871_write_registers();
mixer_set_frequency(3500);
#endif
}
static void delay_ms(int ms)
@ -136,6 +140,7 @@ static void serial_delay(void)
*/
static void max2871_spi_write(uint8_t r, uint32_t v) {
#if 0 //XXX
#if DEBUG
LOG("0x%04x -> reg%d\n", v, r);
#else
@ -168,10 +173,12 @@ static void max2871_spi_write(uint8_t r, uint32_t v) {
gpio_set(PORT_VCO_LE, PIN_VCO_LE);
#endif
#endif
}
static uint32_t max2871_spi_read(void)
{
#if 0 //XXX
uint32_t bits = 32;
uint32_t data = 0;
@ -194,6 +201,7 @@ static uint32_t max2871_spi_read(void)
data |= GPIO_STATE(PORT_VCO_MUX, PIN_VCO_MUX) ? 1 : 0;
}
return data;
#endif
}
static void max2871_write_registers(void)
@ -205,7 +213,7 @@ static void max2871_write_registers(void)
}
/* Set frequency (MHz). */
uint64_t mixer_set_frequency(uint16_t mhz)
uint64_t mixer_set_frequency(rffc5071_driver_t* const drv, uint16_t mhz)
{
int n = mhz / 40;
int diva = 0;
@ -230,21 +238,25 @@ uint64_t mixer_set_frequency(uint16_t mhz)
return (mhz/40)*40 * 1000000;
}
void mixer_tx(void)
void mixer_tx(rffc5071_driver_t* const drv)
{}
void mixer_rx(void)
void mixer_rx(rffc5071_driver_t* const drv)
{}
void mixer_rxtx(void)
void mixer_rxtx(rffc5071_driver_t* const drv)
{}
void mixer_enable(void)
void mixer_enable(rffc5071_driver_t* const drv)
{
#if 0 //XXX
gpio_set(PORT_VCO_CE, PIN_VCO_CE); /* active high */
#endif
}
void mixer_disable(void)
void mixer_disable(rffc5071_driver_t* const drv)
{
#if 0 //XXX
gpio_clear(PORT_VCO_CE, PIN_VCO_CE); /* active high */
#endif
}
void mixer_set_gpo(uint8_t gpo)
void mixer_set_gpo(rffc5071_driver_t* const drv, uint8_t gpo)
{
(void) gpo;
}

View File

View File

@ -21,16 +21,18 @@
#include <stdint.h>
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/ssp.h>
#include "hackrf_core.h"
#include "max5864.h"
void max5864_spi_write(uint_fast8_t value) {
gpio_clear(PORT_AD_CS, PIN_AD_CS);
ssp_transfer(SSP1_NUM, value);
gpio_set(PORT_AD_CS, PIN_AD_CS);
static void max5864_write(max5864_driver_t* const drv, uint8_t value) {
spi_bus_transfer(drv->bus, &value, 1);
}
static void max5864_init(max5864_driver_t* const drv) {
drv->target_init(drv);
}
void max5864_setup(max5864_driver_t* const drv) {
max5864_init(drv);
}
/* Set MAX5864 operation mode to "Shutdown":
@ -39,9 +41,9 @@ void max5864_spi_write(uint_fast8_t value) {
* ADCs: off (bus is tri-stated)
* DACs: off (set input bus to zero or OVdd)
*/
void max5864_shutdown()
void max5864_shutdown(max5864_driver_t* const drv)
{
max5864_spi_write(0x00);
max5864_write(drv, 0x00);
}
/* Set MAX5864 operation mode to "Standby":
@ -50,9 +52,9 @@ void max5864_shutdown()
* ADCs: off (bus is tri-stated)
* DACs: off (set input bus to zero or OVdd)
*/
void max5864_standby()
void max5864_standby(max5864_driver_t* const drv)
{
max5864_spi_write(0x05);
max5864_write(drv, 0x05);
}
/* Set MAX5864 operation mode to "Idle":
@ -61,9 +63,9 @@ void max5864_standby()
* ADCs: off (bus is tri-stated)
* DACs: off (set input bus to zero or OVdd)
*/
void max5864_idle()
void max5864_idle(max5864_driver_t* const drv)
{
max5864_spi_write(0x01);
max5864_write(drv, 0x01);
}
/* Set MAX5864 operation mode to "Rx":
@ -72,9 +74,9 @@ void max5864_idle()
* ADCs: on
* DACs: off (set input bus to zero or OVdd)
*/
void max5864_rx()
void max5864_rx(max5864_driver_t* const drv)
{
max5864_spi_write(0x02);
max5864_write(drv, 0x02);
}
/* Set MAX5864 operation mode to "Tx":
@ -83,9 +85,9 @@ void max5864_rx()
* ADCs: off (bus is tri-stated)
* DACs: on
*/
void max5864_tx()
void max5864_tx(max5864_driver_t* const drv)
{
max5864_spi_write(0x03);
max5864_write(drv, 0x03);
}
/* Set MAX5864 operation mode to "Xcvr":
@ -94,7 +96,7 @@ void max5864_tx()
* ADCs: on
* DACs: on
*/
void max5864_xcvr()
void max5864_xcvr(max5864_driver_t* const drv)
{
max5864_spi_write(0x04);
max5864_write(drv, 0x04);
}

View File

@ -22,11 +22,23 @@
#ifndef __MAX5864_H
#define __MAX5864_H
void max5864_shutdown();
void max5864_standby();
void max5864_idle();
void max5864_rx();
void max5864_tx();
void max5864_xcvr();
#include "spi_bus.h"
struct max5864_driver_t;
typedef struct max5864_driver_t max5864_driver_t;
struct max5864_driver_t {
spi_bus_t* const bus;
void (*target_init)(max5864_driver_t* const drv);
};
void max5864_setup(max5864_driver_t* const drv);
void max5864_shutdown(max5864_driver_t* const drv);
void max5864_standby(max5864_driver_t* const drv);
void max5864_idle(max5864_driver_t* const drv);
void max5864_rx(max5864_driver_t* const drv);
void max5864_tx(max5864_driver_t* const drv);
void max5864_xcvr(max5864_driver_t* const drv);
#endif // __MAX5864_H

View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "max5864_target.h"
#include <libopencm3/lpc43xx/scu.h>
#include "hackrf_core.h"
void max5864_target_init(max5864_driver_t* const drv) {
(void)drv;
/* Configure SSP1 Peripheral (to be moved later in SSP driver) */
scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1));
/*
* Configure CS_AD pin to keep the MAX5864 SPI disabled while we use the
* SPI bus for the MAX2837. FIXME: this should probably be somewhere else.
*/
scu_pinmux(SCU_AD_CS, SCU_GPIO_FAST);
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __MAX5864_TARGET_H__
#define __MAX5864_TARGET_H__
#include "max5864.h"
void max5864_target_init(max5864_driver_t* const drv);
#endif/*__MAX5864_TARGET_H__*/

View File

@ -24,22 +24,22 @@
#define __MIXER_H
#include <stdint.h>
// XXX
/* Initialize chip. Call _setup() externally, as it calls _init(). */
extern void mixer_init(void);
extern void mixer_setup(void);
//extern void mixer_init(void);
//extern void mixer_setup(void);
/* Set frequency (MHz). */
extern uint64_t mixer_set_frequency(uint16_t mhz);
//extern uint64_t mixer_set_frequency(uint16_t mhz);
/* Set up rx only, tx only, or full duplex. Chip should be disabled
* before _tx, _rx, or _rxtx are called. */
extern void mixer_tx(void);
extern void mixer_rx(void);
extern void mixer_rxtx(void);
extern void mixer_enable(void);
extern void mixer_disable(void);
//extern void mixer_tx(void);
//extern void mixer_rx(void);
//extern void mixer_rxtx(void);
//extern void mixer_enable(void);
//extern void mixer_disable(void);
extern void mixer_set_gpo(uint8_t);
//extern void mixer_set_gpo(uint8_t);
#endif // __MIXER_H

View File

@ -22,7 +22,6 @@
#include "rf_path.h"
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include <hackrf_core.h>
@ -30,6 +29,9 @@
#include "hackrf-ui.h"
#include <mixer.h>
#if (defined JAWBREAKER || defined HACKRF_ONE)
#include <rffc5071.h>
#endif
#include <max2837.h>
#include <max5864.h>
#include <sgpio.h>
@ -89,7 +91,8 @@ uint8_t switchctrl = SWITCHCTRL_SAFE;
#define SWITCHCTRL_ANT_PWR (1 << 6) /* turn on antenna port power */
#ifdef RAD1O
static void switchctrl_set_rad1o(uint8_t ctrl) {
static void switchctrl_set_rad1o(rf_path_t* const rf_path, uint8_t ctrl) {
#if 0 //XXX
if (ctrl & SWITCHCTRL_TX) {
gpio_set(PORT_TX_RX_N, PIN_TX_RX_N);
gpio_clear(PORT_TX_RX, PIN_TX_RX);
@ -154,64 +157,64 @@ static void switchctrl_set_rad1o(uint8_t ctrl) {
if (ctrl & SWITCHCTRL_ANT_PWR) {
// TODO
}
#endif
}
#endif
#ifdef HACKRF_ONE
static void switchctrl_set_hackrf_one(uint8_t ctrl) {
static void switchctrl_set_hackrf_one(rf_path_t* const rf_path, uint8_t ctrl) {
if (ctrl & SWITCHCTRL_TX) {
gpio_set(PORT_TX, PIN_TX);
gpio_clear(PORT_RX, PIN_RX);
gpio_set(rf_path->gpio_tx);
gpio_clear(rf_path->gpio_rx);
} else {
gpio_clear(PORT_TX, PIN_TX);
gpio_set(PORT_RX, PIN_RX);
gpio_clear(rf_path->gpio_tx);
gpio_set(rf_path->gpio_rx);
}
if (ctrl & SWITCHCTRL_MIX_BYPASS) {
gpio_set(PORT_MIX_BYPASS, PIN_MIX_BYPASS);
gpio_clear(PORT_NO_MIX_BYPASS, PIN_NO_MIX_BYPASS);
gpio_set(rf_path->gpio_mix_bypass);
gpio_clear(rf_path->gpio_no_mix_bypass);
if (ctrl & SWITCHCTRL_TX) {
gpio_set(PORT_TX_MIX_BP, PIN_TX_MIX_BP);
gpio_clear(PORT_RX_MIX_BP, PIN_RX_MIX_BP);
gpio_set(rf_path->gpio_tx_mix_bp);
gpio_clear(rf_path->gpio_rx_mix_bp);
} else {
gpio_clear(PORT_TX_MIX_BP, PIN_TX_MIX_BP);
gpio_set(PORT_RX_MIX_BP, PIN_RX_MIX_BP);
gpio_clear(rf_path->gpio_tx_mix_bp);
gpio_set(rf_path->gpio_rx_mix_bp);
}
} else {
gpio_clear(PORT_MIX_BYPASS, PIN_MIX_BYPASS);
gpio_set(PORT_NO_MIX_BYPASS, PIN_NO_MIX_BYPASS);
gpio_clear(PORT_TX_MIX_BP, PIN_TX_MIX_BP);
gpio_clear(PORT_RX_MIX_BP, PIN_RX_MIX_BP);
gpio_clear(rf_path->gpio_mix_bypass);
gpio_set(rf_path->gpio_no_mix_bypass);
gpio_clear(rf_path->gpio_tx_mix_bp);
gpio_clear(rf_path->gpio_rx_mix_bp);
}
if (ctrl & SWITCHCTRL_HP) {
gpio_set(PORT_HP, PIN_HP);
gpio_clear(PORT_LP, PIN_LP);
gpio_set(rf_path->gpio_hp);
gpio_clear(rf_path->gpio_lp);
} else {
gpio_clear(PORT_HP, PIN_HP);
gpio_set(PORT_LP, PIN_LP);
gpio_clear(rf_path->gpio_hp);
gpio_set(rf_path->gpio_lp);
}
if (ctrl & SWITCHCTRL_AMP_BYPASS) {
gpio_set(PORT_AMP_BYPASS, PIN_AMP_BYPASS);
gpio_clear(PORT_TX_AMP, PIN_TX_AMP);
gpio_set(PORT_NO_TX_AMP_PWR, PIN_NO_TX_AMP_PWR);
gpio_clear(PORT_RX_AMP, PIN_RX_AMP);
gpio_set(PORT_NO_RX_AMP_PWR, PIN_NO_RX_AMP_PWR);
gpio_set(rf_path->gpio_amp_bypass);
gpio_clear(rf_path->gpio_tx_amp);
gpio_set(rf_path->gpio_no_tx_amp_pwr);
gpio_clear(rf_path->gpio_rx_amp);
gpio_set(rf_path->gpio_no_rx_amp_pwr);
} else if (ctrl & SWITCHCTRL_TX) {
gpio_clear(PORT_AMP_BYPASS, PIN_AMP_BYPASS);
gpio_set(PORT_TX_AMP, PIN_TX_AMP);
gpio_clear(PORT_NO_TX_AMP_PWR, PIN_NO_TX_AMP_PWR);
gpio_clear(PORT_RX_AMP, PIN_RX_AMP);
gpio_set(PORT_NO_RX_AMP_PWR, PIN_NO_RX_AMP_PWR);
gpio_clear(rf_path->gpio_amp_bypass);
gpio_set(rf_path->gpio_tx_amp);
gpio_clear(rf_path->gpio_no_tx_amp_pwr);
gpio_clear(rf_path->gpio_rx_amp);
gpio_set(rf_path->gpio_no_rx_amp_pwr);
} else {
gpio_clear(PORT_AMP_BYPASS, PIN_AMP_BYPASS);
gpio_clear(PORT_TX_AMP, PIN_TX_AMP);
gpio_set(PORT_NO_TX_AMP_PWR, PIN_NO_TX_AMP_PWR);
gpio_set(PORT_RX_AMP, PIN_RX_AMP);
gpio_clear(PORT_NO_RX_AMP_PWR, PIN_NO_RX_AMP_PWR);
gpio_clear(rf_path->gpio_amp_bypass);
gpio_clear(rf_path->gpio_tx_amp);
gpio_set(rf_path->gpio_no_tx_amp_pwr);
gpio_set(rf_path->gpio_rx_amp);
gpio_clear(rf_path->gpio_no_rx_amp_pwr);
}
/*
@ -220,31 +223,31 @@ static void switchctrl_set_hackrf_one(uint8_t ctrl) {
* is unset:
*/
if (ctrl & SWITCHCTRL_NO_TX_AMP_PWR)
gpio_set(PORT_NO_TX_AMP_PWR, PIN_NO_TX_AMP_PWR);
gpio_set(rf_path->gpio_no_tx_amp_pwr);
if (ctrl & SWITCHCTRL_NO_RX_AMP_PWR)
gpio_set(PORT_NO_RX_AMP_PWR, PIN_NO_RX_AMP_PWR);
gpio_set(rf_path->gpio_no_rx_amp_pwr);
if (ctrl & SWITCHCTRL_ANT_PWR) {
mixer_set_gpo(0x00); /* turn on antenna power by clearing GPO1 */
rffc5071_set_gpo(&rffc5072, 0x00); /* turn on antenna power by clearing GPO1 */
} else {
mixer_set_gpo(0x01); /* turn off antenna power by setting GPO1 */
rffc5071_set_gpo(&rffc5072, 0x01); /* turn off antenna power by setting GPO1 */
}
}
#endif
static void switchctrl_set(const uint8_t gpo) {
static void switchctrl_set(rf_path_t* const rf_path, const uint8_t gpo) {
#ifdef JAWBREAKER
mixer_set_gpo(gpo);
rffc5071_set_gpo(&rffc5072, gpo);
#elif HACKRF_ONE
switchctrl_set_hackrf_one(gpo);
switchctrl_set_hackrf_one(rf_path, gpo);
#elif RAD1O
switchctrl_set_rad1o(gpo);
switchctrl_set_rad1o(rf_path, gpo);
#else
(void)gpo;
#endif
}
void rf_path_pin_setup() {
void rf_path_pin_setup(rf_path_t* const rf_path) {
#ifdef HACKRF_ONE
/* Configure RF switch control signals */
scu_pinmux(SCU_HP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
@ -265,26 +268,29 @@ void rf_path_pin_setup() {
scu_pinmux(SCU_NO_VAA_ENABLE, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
/* Configure RF switch control signals as outputs */
GPIO0_DIR |= PIN_AMP_BYPASS;
GPIO1_DIR |= (PIN_NO_MIX_BYPASS | PIN_RX_AMP | PIN_NO_RX_AMP_PWR);
GPIO2_DIR |= (PIN_HP | PIN_LP | PIN_TX_MIX_BP | PIN_RX_MIX_BP | PIN_TX_AMP);
GPIO3_DIR |= PIN_NO_TX_AMP_PWR;
GPIO5_DIR |= (PIN_TX | PIN_MIX_BYPASS | PIN_RX);
gpio_output(rf_path->gpio_amp_bypass);
gpio_output(rf_path->gpio_no_mix_bypass);
gpio_output(rf_path->gpio_rx_amp);
gpio_output(rf_path->gpio_no_rx_amp_pwr);
gpio_output(rf_path->gpio_hp);
gpio_output(rf_path->gpio_lp);
gpio_output(rf_path->gpio_tx_mix_bp);
gpio_output(rf_path->gpio_rx_mix_bp);
gpio_output(rf_path->gpio_tx_amp);
gpio_output(rf_path->gpio_no_tx_amp_pwr);
gpio_output(rf_path->gpio_tx);
gpio_output(rf_path->gpio_mix_bypass);
gpio_output(rf_path->gpio_rx);
/*
* Safe (initial) switch settings turn off both amplifiers and antenna port
* power and enable both amp bypass and mixer bypass.
*/
switchctrl_set(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_MIX_BYPASS);
/* Configure RF power supply (VAA) switch control signal as output */
GPIO_DIR(PORT_NO_VAA_ENABLE) |= PIN_NO_VAA_ENABLE;
/* Safe state: start with VAA turned off: */
disable_rf_power();
switchctrl_set(rf_path, SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_MIX_BYPASS);
#endif
#ifdef RAD1O
#if 0 //XXX
/* Configure RF switch control signals */
scu_pinmux(SCU_BY_AMP, SCU_GPIO_FAST | SCU_CONF_FUNCTION0);
scu_pinmux(SCU_BY_AMP_N, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
@ -320,136 +326,138 @@ void rf_path_pin_setup() {
/* Safe state: start with VAA turned off: */
disable_rf_power();
#endif
#endif
}
void rf_path_init(void) {
void rf_path_init(rf_path_t* const rf_path) {
ssp1_set_mode_max5864();
max5864_shutdown();
max5864_setup(&max5864);
max5864_shutdown(&max5864);
ssp1_set_mode_max2837();
max2837_setup();
max2837_start();
max2837_setup(&max2837);
max2837_start(&max2837);
mixer_setup();
switchctrl_set(switchctrl);
//XXX
mixer_setup(&mixer);
switchctrl_set(rf_path, switchctrl);
}
void rf_path_set_direction(const rf_path_direction_t direction) {
void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t direction) {
/* Turn off TX and RX amplifiers, then enable based on direction and bypass state. */
switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR;
rf_path->switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR;
switch(direction) {
case RF_PATH_DIRECTION_TX:
switchctrl |= SWITCHCTRL_TX;
if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) {
rf_path->switchctrl |= SWITCHCTRL_TX;
if( (rf_path->switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) {
/* TX amplifier is in path, be sure to enable TX amplifier. */
switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR;
rf_path->switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR;
}
mixer_tx();
if( switchctrl & SWITCHCTRL_MIX_BYPASS ) {
mixer_disable();
mixer_tx(&mixer);
if( rf_path->switchctrl & SWITCHCTRL_MIX_BYPASS ) {
mixer_disable(&mixer);
} else {
mixer_enable();
mixer_enable(&mixer);
}
ssp1_set_mode_max5864();
max5864_tx();
max5864_tx(&max5864);
ssp1_set_mode_max2837();
max2837_tx();
sgpio_configure(SGPIO_DIRECTION_TX);
max2837_tx(&max2837);
sgpio_configure(&sgpio_config, SGPIO_DIRECTION_TX);
break;
case RF_PATH_DIRECTION_RX:
switchctrl &= ~SWITCHCTRL_TX;
if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) {
rf_path->switchctrl &= ~SWITCHCTRL_TX;
if( (rf_path->switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) {
/* RX amplifier is in path, be sure to enable RX amplifier. */
switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR;
rf_path->switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR;
}
mixer_rx();
if( switchctrl & SWITCHCTRL_MIX_BYPASS ) {
mixer_disable();
mixer_rx(&mixer);
if( rf_path->switchctrl & SWITCHCTRL_MIX_BYPASS ) {
mixer_disable(&mixer);
} else {
mixer_enable();
mixer_enable(&mixer);
}
ssp1_set_mode_max5864();
max5864_rx();
max5864_rx(&max5864);
ssp1_set_mode_max2837();
max2837_rx();
sgpio_configure(SGPIO_DIRECTION_RX);
max2837_rx(&max2837);
sgpio_configure(&sgpio_config, SGPIO_DIRECTION_RX);
break;
case RF_PATH_DIRECTION_OFF:
default:
#ifdef HACKRF_ONE
rf_path_set_antenna(0);
rf_path_set_antenna(rf_path, 0);
#endif
rf_path_set_lna(0);
rf_path_set_lna(rf_path, 0);
/* Set RF path to receive direction when "off" */
switchctrl &= ~SWITCHCTRL_TX;
mixer_disable();
rf_path->switchctrl &= ~SWITCHCTRL_TX;
mixer_disable(&mixer);
ssp1_set_mode_max5864();
max5864_standby();
max5864_standby(&max5864);
ssp1_set_mode_max2837();
max2837_set_mode(MAX2837_MODE_STANDBY);
sgpio_configure(SGPIO_DIRECTION_RX);
max2837_set_mode(&max2837, MAX2837_MODE_STANDBY);
sgpio_configure(&sgpio_config, SGPIO_DIRECTION_RX);
break;
}
switchctrl_set(switchctrl);
switchctrl_set(rf_path, rf_path->switchctrl);
hackrf_ui_setDirection(direction);
}
void rf_path_set_filter(const rf_path_filter_t filter) {
void rf_path_set_filter(rf_path_t* const rf_path, const rf_path_filter_t filter) {
switch(filter) {
default:
case RF_PATH_FILTER_BYPASS:
switchctrl |= SWITCHCTRL_MIX_BYPASS;
mixer_disable();
rf_path->switchctrl |= SWITCHCTRL_MIX_BYPASS;
mixer_disable(&mixer);
break;
case RF_PATH_FILTER_LOW_PASS:
switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS);
mixer_enable();
rf_path->switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS);
mixer_enable(&mixer);
break;
case RF_PATH_FILTER_HIGH_PASS:
switchctrl &= ~SWITCHCTRL_MIX_BYPASS;
switchctrl |= SWITCHCTRL_HP;
mixer_enable();
rf_path->switchctrl &= ~SWITCHCTRL_MIX_BYPASS;
rf_path->switchctrl |= SWITCHCTRL_HP;
mixer_enable(&mixer);
break;
}
switchctrl_set(switchctrl);
switchctrl_set(rf_path, rf_path->switchctrl);
}
void rf_path_set_lna(const uint_fast8_t enable) {
void rf_path_set_lna(rf_path_t* const rf_path, const uint_fast8_t enable) {
if( enable ) {
if( switchctrl & SWITCHCTRL_TX ) {
if( rf_path->switchctrl & SWITCHCTRL_TX ) {
/* AMP_BYPASS=0, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=0 */
switchctrl |= SWITCHCTRL_NO_RX_AMP_PWR;
switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR);
rf_path->switchctrl |= SWITCHCTRL_NO_RX_AMP_PWR;
rf_path->switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR);
} else {
/* AMP_BYPASS=0, NO_RX_AMP_PWR=0, NO_TX_AMP_PWR=1 */
switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR;
switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_RX_AMP_PWR);
rf_path->switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR;
rf_path->switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_RX_AMP_PWR);
}
} else {
/* AMP_BYPASS=1, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=1 */
switchctrl |= SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR;
rf_path->switchctrl |= SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR;
}
switchctrl_set(switchctrl);
switchctrl_set(rf_path, rf_path->switchctrl);
hackrf_ui_setLNAPower(enable);
}
/* antenna port power control */
void rf_path_set_antenna(const uint_fast8_t enable) {
void rf_path_set_antenna(rf_path_t* const rf_path, const uint_fast8_t enable) {
if (enable) {
switchctrl |= SWITCHCTRL_ANT_PWR;
rf_path->switchctrl |= SWITCHCTRL_ANT_PWR;
} else {
switchctrl &= ~(SWITCHCTRL_ANT_PWR);
rf_path->switchctrl &= ~(SWITCHCTRL_ANT_PWR);
}
switchctrl_set(switchctrl);
switchctrl_set(rf_path, rf_path->switchctrl);
}

View File

@ -25,8 +25,7 @@
#include <stdint.h>
void rf_path_pin_setup(void);
void rf_path_init(void);
#include "gpio.h"
typedef enum {
RF_PATH_DIRECTION_OFF,
@ -34,17 +33,42 @@ typedef enum {
RF_PATH_DIRECTION_TX,
} rf_path_direction_t;
void rf_path_set_direction(const rf_path_direction_t direction);
typedef enum {
RF_PATH_FILTER_BYPASS = 0,
RF_PATH_FILTER_LOW_PASS = 1,
RF_PATH_FILTER_HIGH_PASS = 2,
} rf_path_filter_t;
void rf_path_set_filter(const rf_path_filter_t filter);
typedef struct rf_path_t {
uint8_t switchctrl;
#ifdef HACKRF_ONE
gpio_t gpio_hp;
gpio_t gpio_lp;
gpio_t gpio_tx_mix_bp;
gpio_t gpio_no_mix_bypass;
gpio_t gpio_rx_mix_bp;
gpio_t gpio_tx_amp;
gpio_t gpio_tx;
gpio_t gpio_mix_bypass;
gpio_t gpio_rx;
gpio_t gpio_no_tx_amp_pwr;
gpio_t gpio_amp_bypass;
gpio_t gpio_rx_amp;
gpio_t gpio_no_rx_amp_pwr;
#endif
/// XXX
#ifdef RAD1O
#endif
} rf_path_t;
void rf_path_set_lna(const uint_fast8_t enable);
void rf_path_set_antenna(const uint_fast8_t enable);
void rf_path_pin_setup(rf_path_t* const rf_path);
void rf_path_init(rf_path_t* const rf_path);
void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t direction);
void rf_path_set_filter(rf_path_t* const rf_path, const rf_path_filter_t filter);
void rf_path_set_lna(rf_path_t* const rf_path, const uint_fast8_t enable);
void rf_path_set_antenna(rf_path_t* const rf_path, const uint_fast8_t enable);
#endif/*__RFPATH_H__*/

View File

@ -33,23 +33,13 @@
#include <stdint.h>
#include <string.h>
#include "mixer.h"
#include "rffc5071.h"
#include "rffc5071_regs.def" // private register def macros
#if (defined DEBUG)
#include <stdio.h>
#define LOG printf
#else
#define LOG(x,...)
#include <libopencm3/lpc43xx/ssp.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/gpio.h>
#include "hackrf_core.h"
#endif
/* Default register values. */
static uint16_t rffc5071_regs_default[RFFC5071_NUM_REGS] = {
static const uint16_t rffc5071_regs_default[RFFC5071_NUM_REGS] = {
0xbefa, /* 00 */
0x4064, /* 01 */
0x9055, /* 02 */
@ -82,327 +72,139 @@ static uint16_t rffc5071_regs_default[RFFC5071_NUM_REGS] = {
0x1000, /* 1D */
0x0005, /* 1E */ };
uint16_t rffc5071_regs[RFFC5071_NUM_REGS];
/* Mark all regsisters dirty so all will be written at init. */
uint32_t rffc5071_regs_dirty = 0x7fffffff;
/* Set up all registers according to defaults specified in docs. */
void mixer_init(void)
void rffc5071_init(rffc5071_driver_t* const drv)
{
LOG("# mixer_init\n");
memcpy(rffc5071_regs, rffc5071_regs_default, sizeof(rffc5071_regs));
rffc5071_regs_dirty = 0x7fffffff;
memcpy(drv->regs, rffc5071_regs_default, sizeof(drv->regs));
drv->regs_dirty = 0x7fffffff;
/* Write default register values to chip. */
rffc5071_regs_commit();
rffc5071_regs_commit(drv);
}
/*
* Set up pins for GPIO and SPI control, configure SSP peripheral for SPI, and
* set our own default register configuration.
*/
void mixer_setup(void)
void rffc5071_setup(rffc5071_driver_t* const drv)
{
mixer_init();
LOG("# mixer_setup\n");
#if !defined TEST
/* Configure GPIO pins. */
scu_pinmux(SCU_MIXER_ENX, SCU_GPIO_FAST);
scu_pinmux(SCU_MIXER_SCLK, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(SCU_MIXER_SDATA, SCU_GPIO_FAST);
scu_pinmux(SCU_MIXER_RESETX, SCU_GPIO_FAST);
gpio_set(drv->gpio_reset);
gpio_output(drv->gpio_reset);
/* Set GPIO pins as outputs. */
GPIO_DIR(PORT_MIXER_ENX) |= PIN_MIXER_ENX;
GPIO_DIR(PORT_MIXER_SCLK) |= PIN_MIXER_SCLK;
GPIO_DIR(PORT_MIXER_SDATA) |= PIN_MIXER_SDATA;
GPIO_DIR(PORT_MIXER_RESETX) |= PIN_MIXER_RESETX;
/* set to known state */
gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX); /* active low */
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
gpio_clear(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
gpio_set(PORT_MIXER_RESETX, PIN_MIXER_RESETX); /* active low */
#endif
rffc5071_init(drv);
/* initial setup */
/* put zeros in freq contol registers */
set_RFFC5071_P2N(0);
set_RFFC5071_P2LODIV(0);
set_RFFC5071_P2PRESC(0);
set_RFFC5071_P2VCOSEL(0);
set_RFFC5071_P2N(drv, 0);
set_RFFC5071_P2LODIV(drv, 0);
set_RFFC5071_P2PRESC(drv, 0);
set_RFFC5071_P2VCOSEL(drv, 0);
set_RFFC5071_P2N(0);
set_RFFC5071_P2LODIV(0);
set_RFFC5071_P2PRESC(0);
set_RFFC5071_P2VCOSEL(0);
set_RFFC5071_P2N(drv, 0);
set_RFFC5071_P2LODIV(drv, 0);
set_RFFC5071_P2PRESC(drv, 0);
set_RFFC5071_P2VCOSEL(drv, 0);
set_RFFC5071_P2N(0);
set_RFFC5071_P2LODIV(0);
set_RFFC5071_P2PRESC(0);
set_RFFC5071_P2VCOSEL(0);
set_RFFC5071_P2N(drv, 0);
set_RFFC5071_P2LODIV(drv, 0);
set_RFFC5071_P2PRESC(drv, 0);
set_RFFC5071_P2VCOSEL(drv, 0);
/* set ENBL and MODE to be configured via 3-wire interface,
* not control pins. */
set_RFFC5071_SIPIN(1);
set_RFFC5071_SIPIN(drv, 1);
/* GPOs are active at all times */
set_RFFC5071_GATE(1);
set_RFFC5071_GATE(drv, 1);
rffc5071_regs_commit();
rffc5071_regs_commit(drv);
}
void serial_delay(void)
{
uint32_t i;
static uint16_t rffc5071_spi_read(rffc5071_driver_t* const drv, uint8_t r) {
(void)drv;
for (i = 0; i < 2; i++)
__asm__("nop");
uint16_t data[] = { 0x80 | (r & 0x7f), 0xffff };
spi_bus_transfer(drv->bus, data, 2);
return data[1];
}
/* SPI register read.
*
* Send 9 bits:
* first bit is ignored,
* second bit is one for read operation,
* next 7 bits are register address.
* Then receive 16 bits (register value).
*/
uint16_t rffc5071_spi_read(uint8_t r) {
static void rffc5071_spi_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t v) {
(void)drv;
int bits = 9;
int msb = 1 << (bits -1);
uint32_t data = 0x80 | (r & 0x7f);
#if DEBUG
LOG("reg%d = 0\n", r);
return 0;
#else
/* make sure everything is starting in the correct state */
gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX);
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
gpio_clear(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
/*
* The device requires two clocks while ENX is high before a serial
* transaction. This is not clearly documented.
*/
serial_delay();
gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
/* start transaction by bringing ENX low */
gpio_clear(PORT_MIXER_ENX, PIN_MIXER_ENX);
while (bits--) {
if (data & msb)
gpio_set(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
else
gpio_clear(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
data <<= 1;
serial_delay();
gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
}
serial_delay();
gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
bits = 16;
data = 0;
/* set SDATA line as input */
GPIO_DIR(PORT_MIXER_SDATA) &= ~PIN_MIXER_SDATA;
while (bits--) {
data <<= 1;
serial_delay();
gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
if (MIXER_SDATA_STATE)
data |= 1;
}
/* set SDATA line as output */
GPIO_DIR(PORT_MIXER_SDATA) |= PIN_MIXER_SDATA;
serial_delay();
gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX);
/*
* The device requires a clock while ENX is high after a serial
* transaction. This is not clearly documented.
*/
gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
return data;
#endif /* DEBUG */
uint16_t data[] = { 0x00 | (r & 0x7f), v };
spi_bus_transfer(drv->bus, data, 2);
}
/* SPI register write
*
* Send 25 bits:
* first bit is ignored,
* second bit is zero for write operation,
* next 7 bits are register address,
* next 16 bits are register value.
*/
void rffc5071_spi_write(uint8_t r, uint16_t v) {
#if DEBUG
LOG("0x%04x -> reg%d\n", v, r);
#else
int bits = 25;
int msb = 1 << (bits -1);
uint32_t data = ((r & 0x7f) << 16) | v;
/* make sure everything is starting in the correct state */
gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX);
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
gpio_clear(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
/*
* The device requires two clocks while ENX is high before a serial
* transaction. This is not clearly documented.
*/
serial_delay();
gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
/* start transaction by bringing ENX low */
gpio_clear(PORT_MIXER_ENX, PIN_MIXER_ENX);
while (bits--) {
if (data & msb)
gpio_set(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
else
gpio_clear(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
data <<= 1;
serial_delay();
gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
}
gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX);
/*
* The device requires a clock while ENX is high after a serial
* transaction. This is not clearly documented.
*/
serial_delay();
gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
#endif
}
uint16_t rffc5071_reg_read(uint8_t r)
uint16_t rffc5071_reg_read(rffc5071_driver_t* const drv, uint8_t r)
{
/* Readback register is not cached. */
if (r == RFFC5071_READBACK_REG)
return rffc5071_spi_read(r);
return rffc5071_spi_read(drv, r);
/* Discard uncommited write when reading. This shouldn't
* happen, and probably has not been tested. */
if ((rffc5071_regs_dirty >> r) & 0x1) {
rffc5071_regs[r] = rffc5071_spi_read(r);
if ((drv->regs_dirty >> r) & 0x1) {
drv->regs[r] = rffc5071_spi_read(drv, r);
};
return rffc5071_regs[r];
return drv->regs[r];
}
void rffc5071_reg_write(uint8_t r, uint16_t v)
void rffc5071_reg_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t v)
{
rffc5071_regs[r] = v;
rffc5071_spi_write(r, v);
RFFC5071_REG_SET_CLEAN(r);
drv->regs[r] = v;
rffc5071_spi_write(drv, r, v);
RFFC5071_REG_SET_CLEAN(drv, r);
}
static inline void rffc5071_reg_commit(uint8_t r)
static inline void rffc5071_reg_commit(rffc5071_driver_t* const drv, uint8_t r)
{
rffc5071_reg_write(r,rffc5071_regs[r]);
rffc5071_reg_write(drv, r, drv->regs[r]);
}
void rffc5071_regs_commit(void)
void rffc5071_regs_commit(rffc5071_driver_t* const drv)
{
int r;
for(r = 0; r < RFFC5071_NUM_REGS; r++) {
if ((rffc5071_regs_dirty >> r) & 0x1) {
rffc5071_reg_commit(r);
if ((drv->regs_dirty >> r) & 0x1) {
rffc5071_reg_commit(drv, r);
}
}
}
void mixer_tx(void) {
LOG("# rffc5071_tx\n");
set_RFFC5071_ENBL(0);
set_RFFC5071_FULLD(0);
set_RFFC5071_MODE(1); /* mixer 2 used for both RX and TX */
rffc5071_regs_commit();
void rffc5071_tx(rffc5071_driver_t* const drv) {
set_RFFC5071_ENBL(drv, 0);
set_RFFC5071_FULLD(drv, 0);
set_RFFC5071_MODE(drv, 1); /* mixer 2 used for both RX and TX */
rffc5071_regs_commit(drv);
}
void mixer_rx(void) {
LOG("# rfc5071_rx\n");
set_RFFC5071_ENBL(0);
set_RFFC5071_FULLD(0);
set_RFFC5071_MODE(1); /* mixer 2 used for both RX and TX */
rffc5071_regs_commit();
void rffc5071_rx(rffc5071_driver_t* const drv) {
set_RFFC5071_ENBL(drv, 0);
set_RFFC5071_FULLD(drv, 0);
set_RFFC5071_MODE(drv, 1); /* mixer 2 used for both RX and TX */
rffc5071_regs_commit(drv);
}
/*
* This function turns on both mixer (full-duplex) on the RFFC5071, but our
* current hardware designs do not support full-duplex operation.
*/
void mixer_rxtx(void) {
LOG("# rfc5071_rxtx\n");
set_RFFC5071_ENBL(0);
set_RFFC5071_FULLD(1); /* mixer 1 and mixer 2 (RXTX) */
rffc5071_regs_commit();
void rffc5071_rxtx(rffc5071_driver_t* const drv) {
set_RFFC5071_ENBL(drv, 0);
set_RFFC5071_FULLD(drv, 1); /* mixer 1 and mixer 2 (RXTX) */
rffc5071_regs_commit(drv);
mixer_enable();
rffc5071_enable(drv);
}
void mixer_disable(void) {
LOG("# rfc5071_disable\n");
set_RFFC5071_ENBL(0);
rffc5071_regs_commit();
void rffc5071_disable(rffc5071_driver_t* const drv) {
set_RFFC5071_ENBL(drv, 0);
rffc5071_regs_commit(drv);
}
void mixer_enable(void) {
LOG("# rfc5071_enable\n");
set_RFFC5071_ENBL(1);
rffc5071_regs_commit();
void rffc5071_enable(rffc5071_driver_t* const drv) {
set_RFFC5071_ENBL(drv, 1);
rffc5071_regs_commit(drv);
}
#define LO_MAX 5400
@ -410,7 +212,7 @@ void mixer_enable(void) {
#define FREQ_ONE_MHZ (1000*1000)
/* configure frequency synthesizer in integer mode (lo in MHz) */
uint64_t rffc5071_config_synth_int(uint16_t lo) {
uint64_t rffc5071_config_synth_int(rffc5071_driver_t* const drv, uint16_t lo) {
uint8_t lodiv;
uint16_t fvco;
uint8_t fbkdiv;
@ -419,8 +221,6 @@ uint64_t rffc5071_config_synth_int(uint16_t lo) {
uint16_t p1nmsb;
uint8_t p1nlsb;
LOG("# config_synth_int\n");
/* Calculate n_lo */
uint8_t n_lo = 0;
uint16_t x = LO_MAX / lo;
@ -439,10 +239,10 @@ uint64_t rffc5071_config_synth_int(uint16_t lo) {
* and will be unaffected. */
if (fvco > 3200) {
fbkdiv = 4;
set_RFFC5071_PLLCPL(3);
set_RFFC5071_PLLCPL(drv, 3);
} else {
fbkdiv = 2;
set_RFFC5071_PLLCPL(2);
set_RFFC5071_PLLCPL(drv, 2);
}
uint64_t tmp_n = ((uint64_t)fvco << 29ULL) / (fbkdiv*REF_FREQ) ;
@ -453,63 +253,42 @@ uint64_t rffc5071_config_synth_int(uint16_t lo) {
tune_freq_hz = (REF_FREQ * (tmp_n >> 5ULL) * fbkdiv * FREQ_ONE_MHZ)
/ (lodiv * (1 << 24ULL));
LOG("# lo=%d n_lo=%d lodiv=%d fvco=%d fbkdiv=%d n=%d tune_freq_hz=%d\n",
lo, n_lo, lodiv, fvco, fbkdiv, n, tune_freq);
/* Path 1 */
set_RFFC5071_P1LODIV(n_lo);
set_RFFC5071_P1N(n);
set_RFFC5071_P1PRESC(fbkdiv >> 1);
set_RFFC5071_P1NMSB(p1nmsb);
set_RFFC5071_P1NLSB(p1nlsb);
set_RFFC5071_P1LODIV(drv, n_lo);
set_RFFC5071_P1N(drv, n);
set_RFFC5071_P1PRESC(drv, fbkdiv >> 1);
set_RFFC5071_P1NMSB(drv, p1nmsb);
set_RFFC5071_P1NLSB(drv, p1nlsb);
/* Path 2 */
set_RFFC5071_P2LODIV(n_lo);
set_RFFC5071_P2N(n);
set_RFFC5071_P2PRESC(fbkdiv >> 1);
set_RFFC5071_P2NMSB(p1nmsb);
set_RFFC5071_P2NLSB(p1nlsb);
set_RFFC5071_P2LODIV(drv, n_lo);
set_RFFC5071_P2N(drv, n);
set_RFFC5071_P2PRESC(drv, fbkdiv >> 1);
set_RFFC5071_P2NMSB(drv, p1nmsb);
set_RFFC5071_P2NLSB(drv, p1nlsb);
rffc5071_regs_commit();
rffc5071_regs_commit(drv);
return tune_freq_hz;
}
/* !!!!!!!!!!! hz is currently ignored !!!!!!!!!!! */
uint64_t mixer_set_frequency(uint16_t mhz) {
uint64_t rffc5071_set_frequency(rffc5071_driver_t* const drv, uint16_t mhz) {
uint32_t tune_freq;
mixer_disable();
tune_freq = rffc5071_config_synth_int(mhz);
mixer_enable();
rffc5071_disable(drv);
tune_freq = rffc5071_config_synth_int(drv, mhz);
rffc5071_enable(drv);
return tune_freq;
}
void mixer_set_gpo(uint8_t gpo)
void rffc5071_set_gpo(rffc5071_driver_t* const drv, uint8_t gpo)
{
/* We set GPO for both paths just in case. */
set_RFFC5071_P1GPO(gpo);
set_RFFC5071_P2GPO(gpo);
set_RFFC5071_P1GPO(drv, gpo);
set_RFFC5071_P2GPO(drv, gpo);
rffc5071_regs_commit();
rffc5071_regs_commit(drv);
}
#ifdef TEST
int main(int ac, char **av)
{
mixer_setup();
rffc5071_tx(0);
mixer_set_frequency(500, 0);
mixer_set_frequency(525, 0);
mixer_set_frequency(550, 0);
mixer_set_frequency(1500, 0);
mixer_set_frequency(1525, 0);
mixer_set_frequency(1550, 0);
mixer_disable();
mixer_rx(0);
mixer_disable();
mixer_rxtx();
mixer_disable();
}
#endif //TEST

View File

@ -23,26 +23,49 @@
#ifndef __RFFC5071_H
#define __RFFC5071_H
#include <stdint.h>
#include "spi_bus.h"
#include "gpio.h"
/* 31 registers, each containing 16 bits of data. */
#define RFFC5071_NUM_REGS 31
extern uint16_t rffc5071_regs[RFFC5071_NUM_REGS];
extern uint32_t rffc5071_regs_dirty;
typedef struct {
spi_bus_t* const bus;
gpio_t gpio_reset;
uint16_t regs[RFFC5071_NUM_REGS];
uint32_t regs_dirty;
} rffc5071_driver_t;
#define RFFC5071_REG_SET_CLEAN(r) rffc5071_regs_dirty &= ~(1UL<<r)
#define RFFC5071_REG_SET_DIRTY(r) rffc5071_regs_dirty |= (1UL<<r)
/* Initialize chip. Call _setup() externally, as it calls _init(). */
extern void rffc5071_init(rffc5071_driver_t* const drv);
extern void rffc5071_setup(rffc5071_driver_t* const drv);
/* Read a register via SPI. Save a copy to memory and return
* value. Discard any uncommited changes and mark CLEAN. */
extern uint16_t rffc5071_reg_read(uint8_t r);
extern uint16_t rffc5071_reg_read(rffc5071_driver_t* const drv, uint8_t r);
/* Write value to register via SPI and save a copy to memory. Mark
* CLEAN. */
extern void rffc5071_reg_write(uint8_t r, uint16_t v);
extern void rffc5071_reg_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t v);
/* Write all dirty registers via SPI from memory. Mark all clean. Some
* operations require registers to be written in a certain order. Use
* provided routines for those operations. */
extern void rffc5071_regs_commit(void);
extern void rffc5071_regs_commit(rffc5071_driver_t* const drv);
/* Set frequency (MHz). */
extern uint64_t rffc5071_set_frequency(rffc5071_driver_t* const drv, uint16_t mhz);
/* Set up rx only, tx only, or full duplex. Chip should be disabled
* before _tx, _rx, or _rxtx are called. */
extern void rffc5071_tx(rffc5071_driver_t* const drv);
extern void rffc5071_rx(rffc5071_driver_t* const drv);
extern void rffc5071_rxtx(rffc5071_driver_t* const drv);
extern void rffc5071_enable(rffc5071_driver_t* const drv);
extern void rffc5071_disable(rffc5071_driver_t* const drv);
extern void rffc5071_set_gpo(rffc5071_driver_t* const drv, uint8_t);
#endif // __RFFC5071_H

View File

@ -23,6 +23,9 @@
#ifndef __RFFC5071_REGS_DEF
#define __RFFC5071_REGS_DEF
#define RFFC5071_REG_SET_CLEAN(_d, _r) (_d->regs_dirty &= ~(1UL<<_r))
#define RFFC5071_REG_SET_DIRTY(_d, _r) (_d->regs_dirty |= (1UL<<_r))
#define RFFC5071_READBACK_REG 31
/* Generate static inline accessors that operate on the global
@ -38,13 +41,13 @@
/* n=name, r=regnum, o=offset (bits from LSB) of LSB of field,
* l=length (bits) */
#define __MREG__(n,r,o,l) \
static inline uint16_t get_##n(void) { \
return (rffc5071_regs[r] >> o) & ((1L<<l)-1); \
static inline uint16_t get_##n(rffc5071_driver_t* const _d) { \
return (_d->regs[r] >> o) & ((1L<<l)-1); \
} \
static inline void set_##n(uint16_t v) { \
rffc5071_regs[r] &= (uint16_t)(~(((1L<<l)-1)<<o)); \
rffc5071_regs[r] |= (uint16_t)(((v&((1L<<l)-1))<<o)); \
RFFC5071_REG_SET_DIRTY(r); \
static inline void set_##n(rffc5071_driver_t* const _d, uint16_t v) { \
_d->regs[r] &= (uint16_t)(~(((1L<<l)-1)<<o)); \
_d->regs[r] |= (uint16_t)(((v&((1L<<l)-1))<<o)); \
RFFC5071_REG_SET_DIRTY(_d, r); \
}
/* REG 00 (0): LF */

View File

@ -0,0 +1,187 @@
/*
* Copyright 2012 Michael Ossmann
* Copyright 2014 Jared Boone <jared@sharebrained.com>
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <libopencm3/lpc43xx/scu.h>
#include "hackrf_core.h"
#include "rffc5071_spi.h"
static void rffc5071_spi_target_select(spi_bus_t* const bus) {
const rffc5071_spi_config_t* const config = bus->config;
gpio_clear(config->gpio_select);
}
static void rffc5071_spi_target_unselect(spi_bus_t* const bus) {
const rffc5071_spi_config_t* const config = bus->config;
gpio_set(config->gpio_select);
}
static void rffc5071_spi_direction_out(spi_bus_t* const bus) {
const rffc5071_spi_config_t* const config = bus->config;
gpio_output(config->gpio_data);
}
static void rffc5071_spi_direction_in(spi_bus_t* const bus) {
const rffc5071_spi_config_t* const config = bus->config;
gpio_input(config->gpio_data);
}
static void rffc5071_spi_data_out(spi_bus_t* const bus, const bool bit) {
const rffc5071_spi_config_t* const config = bus->config;
gpio_write(config->gpio_data, bit);
}
static bool rffc5071_spi_data_in(spi_bus_t* const bus) {
const rffc5071_spi_config_t* const config = bus->config;
return gpio_read(config->gpio_data);
}
static void rffc5071_spi_bus_init(spi_bus_t* const bus) {
const rffc5071_spi_config_t* const config = bus->config;
scu_pinmux(SCU_MIXER_SCLK, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
scu_pinmux(SCU_MIXER_SDATA, SCU_GPIO_FAST);
gpio_output(config->gpio_clock);
rffc5071_spi_direction_out(bus);
gpio_clear(config->gpio_clock);
gpio_clear(config->gpio_data);
}
static void rffc5071_spi_target_init(spi_bus_t* const bus) {
const rffc5071_spi_config_t* const config = bus->config;
/* Configure GPIO pins. */
scu_pinmux(SCU_MIXER_ENX, SCU_GPIO_FAST);
scu_pinmux(SCU_MIXER_RESETX, SCU_GPIO_FAST);
/* Set GPIO pins as outputs. */
gpio_output(config->gpio_select);
/* set to known state */
rffc5071_spi_target_unselect(bus);
}
void rffc5071_spi_start(spi_bus_t* const bus, const void* const config) {
bus->config = config;
rffc5071_spi_bus_init(bus);
rffc5071_spi_target_init(bus);
}
void rffc5071_spi_stop(spi_bus_t* const bus) {
(void)bus;
}
static void rffc5071_spi_serial_delay(spi_bus_t* const bus) {
(void)bus;
volatile uint32_t i;
for (i = 0; i < 2; i++)
__asm__("nop");
}
static void rffc5071_spi_sck(spi_bus_t* const bus) {
const rffc5071_spi_config_t* const config = bus->config;
rffc5071_spi_serial_delay(bus);
gpio_set(config->gpio_clock);
rffc5071_spi_serial_delay(bus);
gpio_clear(config->gpio_clock);
}
static uint32_t rffc5071_spi_exchange_bit(spi_bus_t* const bus, const uint32_t bit) {
rffc5071_spi_data_out(bus, bit);
rffc5071_spi_sck(bus);
return rffc5071_spi_data_in(bus) ? 1 : 0;
}
static uint32_t rffc5071_spi_exchange_word(spi_bus_t* const bus, const uint32_t data, const size_t count) {
size_t bits = count;
const uint32_t msb = 1UL << (count - 1);
uint32_t t = data;
while (bits--) {
t = (t << 1) | rffc5071_spi_exchange_bit(bus, t & msb);
}
return t & ((1UL << count) - 1);
}
/* SPI register read.
*
* Send 9 bits:
* first bit is ignored,
* second bit is one for read operation,
* next 7 bits are register address.
* Then receive 16 bits (register value).
*/
/* SPI register write
*
* Send 25 bits:
* first bit is ignored,
* second bit is zero for write operation,
* next 7 bits are register address,
* next 16 bits are register value.
*/
void rffc5071_spi_transfer(spi_bus_t* const bus, void* const _data, const size_t count) {
if( count != 2 ) {
return;
}
uint16_t* const data = _data;
const bool direction_read = (data[0] >> 7) & 1;
/*
* The device requires two clocks while ENX is high before a serial
* transaction. This is not clearly documented.
*/
rffc5071_spi_sck(bus);
rffc5071_spi_sck(bus);
rffc5071_spi_target_select(bus);
data[0] = rffc5071_spi_exchange_word(bus, data[0], 9);
if( direction_read ) {
rffc5071_spi_direction_in(bus);
rffc5071_spi_sck(bus);
}
data[1] = rffc5071_spi_exchange_word(bus, data[1], 16);
rffc5071_spi_serial_delay(bus);
rffc5071_spi_target_unselect(bus);
rffc5071_spi_direction_out(bus);
/*
* The device requires a clock while ENX is high after a serial
* transaction. This is not clearly documented.
*/
rffc5071_spi_sck(bus);
}
void rffc5071_spi_transfer_gather(spi_bus_t* const bus, const spi_transfer_t* const transfer, const size_t count) {
if( count == 1 ) {
rffc5071_spi_transfer(bus, transfer[0].data, transfer[0].count);
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright 2012 Michael Ossmann
* Copyright 2014 Jared Boone <jared@sharebrained.com>
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __RFFC5071_SPI_H
#define __RFFC5071_SPI_H
#include "spi_bus.h"
#include "gpio.h"
typedef struct rffc5071_spi_config_t {
gpio_t gpio_select;
gpio_t gpio_clock;
gpio_t gpio_data;
} rffc5071_spi_config_t;
void rffc5071_spi_start(spi_bus_t* const bus, const void* const config);
void rffc5071_spi_stop(spi_bus_t* const bus);
void rffc5071_spi_transfer(spi_bus_t* const bus, void* const data, const size_t count);
void rffc5071_spi_transfer_gather(spi_bus_t* const bus, const spi_transfer_t* const transfer, const size_t count);
#endif // __RFFC5071_SPI_H

View File

@ -77,7 +77,8 @@ isp_iap_ret_code_t iap_cmd_call(iap_cmd_res_t* iap_cmd_res)
Alternative way to retrieve Part Id on MCU with no IAP
Read Serial No => Read Unique ID in SPIFI (only compatible with W25Q80BV
*/
w25q80bv_setup();
spi_bus_start(spi_flash.bus, &ssp_config_w25q80bv);
w25q80bv_setup(&spi_flash);
switch(iap_cmd_res->cmd_param.command_code)
{
@ -92,7 +93,7 @@ isp_iap_ret_code_t iap_cmd_call(iap_cmd_res_t* iap_cmd_res)
/* Only 64bits used */
iap_cmd_res->status_res.iap_result[0] = 0;
iap_cmd_res->status_res.iap_result[1] = 0;
w25q80bv_get_unique_id( (w25q80bv_unique_id_t*)&iap_cmd_res->status_res.iap_result[2] );
w25q80bv_get_unique_id(&spi_flash, (w25q80bv_unique_id_t*)&iap_cmd_res->status_res.iap_result[2] );
iap_cmd_res->status_res.status_ret = CMD_SUCCESS;
break;

View File

@ -20,7 +20,6 @@
* Boston, MA 02110-1301, USA.
*/
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/sgpio.h>
@ -28,13 +27,11 @@
#include <sgpio.h>
static bool sgpio_slice_mode_multislice = true;
#ifdef RAD1O
static void update_q_invert(void);
#endif
void sgpio_configure_pin_functions() {
void sgpio_configure_pin_functions(sgpio_config_t* const config) {
scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3);
scu_pinmux(SCU_PINMUX_SGPIO2, SCU_GPIO_FAST | SCU_CONF_FUNCTION2);
@ -52,61 +49,20 @@ void sgpio_configure_pin_functions() {
scu_pinmux(SCU_PINMUX_SGPIO14, SCU_GPIO_FAST | SCU_CONF_FUNCTION4); /* GPIO5[13] */
scu_pinmux(SCU_PINMUX_SGPIO15, SCU_GPIO_FAST | SCU_CONF_FUNCTION4); /* GPIO5[14] */
sgpio_cpld_stream_rx_set_decimation(1);
sgpio_cpld_stream_rx_set_q_invert(0);
sgpio_cpld_stream_rx_set_decimation(config, 1);
sgpio_cpld_stream_rx_set_q_invert(config, 0);
GPIO_DIR(GPIO0) |= GPIOPIN13;
GPIO_DIR(GPIO5) |= GPIOPIN14 | GPIOPIN13 | GPIOPIN12;
}
void sgpio_test_interface() {
const uint_fast8_t host_clock_sgpio_pin = 8; // Input
const uint_fast8_t host_capture_sgpio_pin = 9; // Input
const uint_fast8_t host_disable_sgpio_pin = 10; // Output
const uint_fast8_t host_direction_sgpio_pin = 11; // Output
SGPIO_GPIO_OENREG = 0; // All inputs for the moment.
// Disable all counters during configuration
SGPIO_CTRL_ENABLE = 0;
// Make all SGPIO controlled by SGPIO's "GPIO" registers
for (uint_fast8_t i = 0; i < 16; i++) {
SGPIO_OUT_MUX_CFG(i) =
SGPIO_OUT_MUX_CFG_P_OE_CFG(0)
| SGPIO_OUT_MUX_CFG_P_OUT_CFG(4);
}
// Set SGPIO output values.
SGPIO_GPIO_OUTREG =
(1L << host_direction_sgpio_pin)
| (1L << host_disable_sgpio_pin);
// Enable SGPIO pin outputs.
SGPIO_GPIO_OENREG =
(1L << host_direction_sgpio_pin)
| (1L << host_disable_sgpio_pin)
| (0L << host_capture_sgpio_pin)
| (0L << host_clock_sgpio_pin)
| (0xFF << 0);
// Configure SGPIO slices.
// Enable codec data stream.
SGPIO_GPIO_OUTREG &= ~(1L << host_disable_sgpio_pin);
while (1) {
for (uint_fast8_t i = 0; i < 8; i++) {
SGPIO_GPIO_OUTREG ^= (1L << i);
}
}
gpio_output(config->gpio_rx_q_invert);
gpio_output(config->gpio_rx_decimation[0]);
gpio_output(config->gpio_rx_decimation[1]);
gpio_output(config->gpio_rx_decimation[2]);
}
void sgpio_set_slice_mode(
sgpio_config_t* const config,
const bool multi_slice
) {
sgpio_slice_mode_multislice = multi_slice;
config->slice_mode_multislice = multi_slice;
}
/*
@ -122,6 +78,7 @@ void sgpio_set_slice_mode(
SGPIO11 Direction Output (1/High=TX mode LPC43xx=>CPLD=>DAC, 0/Low=RX mode LPC43xx<=CPLD<=ADC)
*/
void sgpio_configure(
sgpio_config_t* const config,
const sgpio_direction_t direction
) {
// Disable all counters during configuration
@ -177,7 +134,7 @@ void sgpio_configure(
;
const uint_fast8_t output_multiplexing_mode =
sgpio_slice_mode_multislice ? 11 : 9;
config->slice_mode_multislice ? 11 : 9;
/* SGPIO0 to SGPIO7 */
for(uint_fast8_t i=0; i<8; i++) {
// SGPIO pin 0 outputs slice A bit "i".
@ -199,9 +156,9 @@ void sgpio_configure(
};
const uint_fast8_t slice_gpdma = SGPIO_SLICE_H;
const uint_fast8_t pos = sgpio_slice_mode_multislice ? 0x1f : 0x03;
const bool single_slice = !sgpio_slice_mode_multislice;
const uint_fast8_t slice_count = sgpio_slice_mode_multislice ? 8 : 1;
const uint_fast8_t pos = config->slice_mode_multislice ? 0x1f : 0x03;
const bool single_slice = !config->slice_mode_multislice;
const uint_fast8_t slice_count = config->slice_mode_multislice ? 8 : 1;
const uint_fast8_t clk_capture_mode = (direction == SGPIO_DIRECTION_TX) ? 0 : 1;
uint32_t slice_enable_mask = 0;
@ -246,7 +203,7 @@ void sgpio_configure(
slice_enable_mask |= (1 << slice_index);
}
if( sgpio_slice_mode_multislice == false ) {
if( config->slice_mode_multislice == false ) {
SGPIO_MUX_CFG(slice_gpdma) =
SGPIO_MUX_CFG_CONCAT_ORDER(0) /* Self-loop */
| SGPIO_MUX_CFG_CONCAT_ENABLE(1)
@ -284,21 +241,24 @@ void sgpio_configure(
SGPIO_CTRL_ENABLE = slice_enable_mask;
}
void sgpio_cpld_stream_enable() {
void sgpio_cpld_stream_enable(sgpio_config_t* const config) {
(void)config;
// Enable codec data stream.
SGPIO_GPIO_OUTREG &= ~(1L << 10); /* SGPIO10 */
}
void sgpio_cpld_stream_disable() {
void sgpio_cpld_stream_disable(sgpio_config_t* const config) {
(void)config;
// Disable codec data stream.
SGPIO_GPIO_OUTREG |= (1L << 10); /* SGPIO10 */
}
bool sgpio_cpld_stream_is_enabled() {
bool sgpio_cpld_stream_is_enabled(sgpio_config_t* const config) {
(void)config;
return (SGPIO_GPIO_OUTREG & (1L << 10)) == 0; /* SGPIO10 */
}
bool sgpio_cpld_stream_rx_set_decimation(const uint_fast8_t n) {
bool sgpio_cpld_stream_rx_set_decimation(sgpio_config_t* const config, const uint_fast8_t n) {
/* CPLD interface is three bits, SGPIO[15:13]:
* 111: decimate by 1 (skip_n=0, skip no samples)
* 110: decimate by 2 (skip_n=1, skip every other sample)
@ -307,8 +267,9 @@ bool sgpio_cpld_stream_rx_set_decimation(const uint_fast8_t n) {
* 000: decimate by 8 (skip_n=7, skip seven of eight samples)
*/
const uint_fast8_t skip_n = n - 1;
GPIO_SET(GPIO5) = GPIOPIN14 | GPIOPIN13 | GPIOPIN12;
GPIO_CLR(GPIO5) = (skip_n & 7) << 12;
gpio_write(config->gpio_rx_decimation[0], (skip_n & 1) == 0);
gpio_write(config->gpio_rx_decimation[1], (skip_n & 2) == 0);
gpio_write(config->gpio_rx_decimation[2], (skip_n & 4) == 0);
return (skip_n < 8);
}
@ -331,6 +292,7 @@ static bool sgpio_invert = false;
* gets called.
*/
static void update_q_invert(void) {
#if 0 //XXX
/* 1=Output SGPIO11 High(TX mode), 0=Output SGPIO11 Low(RX mode)*/
bool tx_mode = (SGPIO_GPIO_OUTREG & (1 << 11)) > 0;
@ -344,9 +306,10 @@ static void update_q_invert(void) {
} else if( sgpio_invert & tx_mode) {
GPIO_SET(GPIO0) = GPIOPIN13;
}
#endif
}
void sgpio_cpld_stream_rx_set_q_invert(const uint_fast8_t invert) {
void sgpio_cpld_stream_rx_set_q_invert(sgpio_config_t* const config, const uint_fast8_t invert) {
if( invert ) {
sgpio_invert = true;
} else {
@ -357,13 +320,7 @@ void sgpio_cpld_stream_rx_set_q_invert(const uint_fast8_t invert) {
}
#else
void sgpio_cpld_stream_rx_set_q_invert(const uint_fast8_t invert) {
// 0.13: P1_18
if( invert ) {
GPIO_SET(GPIO0) = GPIOPIN13;
} else {
GPIO_CLR(GPIO0) = GPIOPIN13;
}
void sgpio_cpld_stream_rx_set_q_invert(sgpio_config_t* const config, const uint_fast8_t invert) {
gpio_write(config->gpio_rx_q_invert, invert);
}
#endif

View File

@ -22,26 +22,39 @@
#ifndef __SGPIO_H__
#define __SGPIO_H__
#include <hackrf_core.h>
#include <stdint.h>
#include <stdbool.h>
#include <libopencm3/lpc43xx/sgpio.h>
#include "gpio.h"
typedef enum {
SGPIO_DIRECTION_RX,
SGPIO_DIRECTION_TX,
} sgpio_direction_t;
void sgpio_configure_pin_functions();
void sgpio_test_interface();
typedef struct sgpio_config_t {
gpio_t gpio_rx_q_invert;
gpio_t gpio_rx_decimation[3];
bool slice_mode_multislice;
} sgpio_config_t;
void sgpio_configure_pin_functions(sgpio_config_t* const config);
void sgpio_test_interface(sgpio_config_t* const config);
void sgpio_set_slice_mode(
sgpio_config_t* const config,
const bool multi_slice
);
void sgpio_configure(
sgpio_config_t* const config,
const sgpio_direction_t direction
);
void sgpio_cpld_stream_enable();
void sgpio_cpld_stream_disable();
bool sgpio_cpld_stream_is_enabled();
void sgpio_cpld_stream_enable(sgpio_config_t* const config);
void sgpio_cpld_stream_disable(sgpio_config_t* const config);
bool sgpio_cpld_stream_is_enabled(sgpio_config_t* const config);
bool sgpio_cpld_stream_rx_set_decimation(const uint_fast8_t n);
void sgpio_cpld_stream_rx_set_q_invert(const uint_fast8_t invert);
bool sgpio_cpld_stream_rx_set_decimation(sgpio_config_t* const config, const uint_fast8_t n);
void sgpio_cpld_stream_rx_set_q_invert(sgpio_config_t* const config, const uint_fast8_t invert);
#endif//__SGPIO_H__

View File

@ -21,73 +21,50 @@
*/
#include "si5351c.h"
#include <libopencm3/lpc43xx/i2c.h>
enum pll_sources active_clock_source;
/* FIXME return i2c0 status from each function */
/* write to single register */
void si5351c_write_single(uint8_t reg, uint8_t val)
void si5351c_write_single(si5351c_driver_t* const drv, uint8_t reg, uint8_t val)
{
i2c0_tx_start();
i2c0_tx_byte(SI5351C_I2C_ADDR | I2C_WRITE);
i2c0_tx_byte(reg);
i2c0_tx_byte(val);
i2c0_stop();
const uint8_t data_tx[] = { reg, val };
si5351c_write(drv, data_tx, 2);
}
/* read single register */
uint8_t si5351c_read_single(uint8_t reg)
uint8_t si5351c_read_single(si5351c_driver_t* const drv, uint8_t reg)
{
uint8_t val;
/* set register address with write */
i2c0_tx_start();
i2c0_tx_byte(SI5351C_I2C_ADDR | I2C_WRITE);
i2c0_tx_byte(reg);
/* read the value */
i2c0_tx_start();
i2c0_tx_byte(SI5351C_I2C_ADDR | I2C_READ);
val = i2c0_rx_byte();
i2c0_stop();
return val;
const uint8_t data_tx[] = { reg };
uint8_t data_rx[] = { 0x00 };
i2c_bus_transfer(drv->bus, drv->i2c_address, data_tx, 1, data_rx, 1);
return data_rx[0];
}
/*
* Write to one or more contiguous registers. data[0] should be the first
* register number, one or more values follow.
*/
void si5351c_write(uint8_t* const data, const uint_fast8_t data_count)
void si5351c_write(si5351c_driver_t* const drv, const uint8_t* const data, const size_t data_count)
{
uint_fast8_t i;
i2c0_tx_start();
i2c0_tx_byte(SI5351C_I2C_ADDR | I2C_WRITE);
for (i = 0; i < data_count; i++)
i2c0_tx_byte(data[i]);
i2c0_stop();
i2c_bus_transfer(drv->bus, drv->i2c_address, data, data_count, NULL, 0);
}
/* Disable all CLKx outputs. */
void si5351c_disable_all_outputs()
void si5351c_disable_all_outputs(si5351c_driver_t* const drv)
{
uint8_t data[] = { 3, 0xFF };
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
}
/* Turn off OEB pin control for all CLKx */
void si5351c_disable_oeb_pin_control()
void si5351c_disable_oeb_pin_control(si5351c_driver_t* const drv)
{
uint8_t data[] = { 9, 0xFF };
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
}
/* Power down all CLKx */
void si5351c_power_down_all_clocks()
void si5351c_power_down_all_clocks(si5351c_driver_t* const drv)
{
uint8_t data[] = { 16
, SI5351C_CLK_POWERDOWN
@ -99,7 +76,7 @@ void si5351c_power_down_all_clocks()
, SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE
, SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE
};
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
}
/*
@ -107,20 +84,20 @@ void si5351c_power_down_all_clocks()
* Reads as 0xE4 on power-up
* Set to 8pF based on crystal specs and HackRF One testing
*/
void si5351c_set_crystal_configuration()
void si5351c_set_crystal_configuration(si5351c_driver_t* const drv)
{
uint8_t data[] = { 183, 0x80 };
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
}
/*
* Register 187: Fanout Enable
* Turn on XO and MultiSynth fanout only.
*/
void si5351c_enable_xo_and_ms_fanout()
void si5351c_enable_xo_and_ms_fanout(si5351c_driver_t* const drv)
{
uint8_t data[] = { 187, 0xD0 };
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
}
/*
@ -129,34 +106,35 @@ void si5351c_enable_xo_and_ms_fanout()
* PLLA_SRC=0 (XTAL)
* PLLB_SRC=1 (CLKIN)
*/
void si5351c_configure_pll_sources(void)
void si5351c_configure_pll_sources(si5351c_driver_t* const drv)
{
uint8_t data[] = { 15, 0x08 };
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
}
/* MultiSynth NA (PLLA) and NB (PLLB) */
void si5351c_configure_pll_multisynth(void)
void si5351c_configure_pll_multisynth(si5351c_driver_t* const drv)
{
//init plla to (0x0e00+512)/128*25mhz xtal = 800mhz -> int mode
uint8_t data[] = { 26, 0x00, 0x01, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00 };
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
/* 10 MHz input on CLKIN for PLLB */
data[0] = 34;
data[4] = 0x26;
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
}
void si5351c_reset_pll(void)
void si5351c_reset_pll(si5351c_driver_t* const drv)
{
/* reset PLLA and PLLB */
uint8_t data[] = { 177, 0xA0 };
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
}
void si5351c_configure_multisynth(const uint_fast8_t ms_number,
void si5351c_configure_multisynth(si5351c_driver_t* const drv,
const uint_fast8_t ms_number,
const uint32_t p1, const uint32_t p2, const uint32_t p3,
const uint_fast8_t r_div)
{
@ -183,7 +161,7 @@ void si5351c_configure_multisynth(const uint_fast8_t ms_number,
(((p3 >> 16) & 0xF) << 4) | (((p2 >> 16) & 0xF) << 0),
(p2 >> 8) & 0xFF,
(p2 >> 0) & 0xFF };
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
}
#ifdef JELLYBEAN
@ -232,15 +210,15 @@ void si5351c_configure_multisynth(const uint_fast8_t ms_number,
* CLK5_SRC=3 (MS5 as input source)
* CLK5_IDRV=3 (8mA)
*/
void si5351c_configure_clock_control()
void si5351c_configure_clock_control(si5351c_driver_t* const drv)
{
uint8_t data[] = { 16, 0x4F, 0x4B, 0x4B, 0x4B, 0x0F, 0x4F, 0xC0, 0xC0 };
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
}
#endif
#if (defined JAWBREAKER || defined HACKRF_ONE)
void si5351c_configure_clock_control(const enum pll_sources source)
void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll_sources source)
{
uint8_t pll;
@ -261,12 +239,12 @@ void si5351c_configure_clock_control(const enum pll_sources source)
,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA)
};
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
}
#endif
#ifdef RAD1O
void si5351c_configure_clock_control(const enum pll_sources source)
void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll_sources source)
{
uint8_t pll;
@ -285,11 +263,11 @@ void si5351c_configure_clock_control(const enum pll_sources source)
,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/
,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/
};
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
}
#endif
void si5351c_enable_clock_outputs()
void si5351c_enable_clock_outputs(si5351c_driver_t* const drv)
{
#ifdef RAD1O
/* Enable CLK outputs 0, 1, 2, 4, 5 only. */
@ -300,46 +278,46 @@ void si5351c_configure_clock_control(const enum pll_sources source)
/* Enable CLK outputs 0, 1, 2, 3, 4, 5, 7 only. */
uint8_t data[] = { 3, 0x40 };
#endif
si5351c_write(data, sizeof(data));
si5351c_write(drv, data, sizeof(data));
}
void si5351c_set_int_mode(const uint_fast8_t ms_number, const uint_fast8_t on){
void si5351c_set_int_mode(si5351c_driver_t* const drv, const uint_fast8_t ms_number, const uint_fast8_t on){
uint8_t data[] = {16, 0};
if(ms_number < 8){
data[0] = 16 + ms_number;
data[1] = si5351c_read_single(data[0]);
data[1] = si5351c_read_single(drv, data[0]);
if(on)
data[1] |= SI5351C_CLK_INT_MODE;
else
data[1] &= ~(SI5351C_CLK_INT_MODE);
si5351c_write(data, 2);
si5351c_write(drv, data, 2);
}
}
void si5351c_set_clock_source(const enum pll_sources source)
void si5351c_set_clock_source(si5351c_driver_t* const drv, const enum pll_sources source)
{
si5351c_configure_clock_control(source);
si5351c_configure_clock_control(drv, source);
active_clock_source = source;
}
void si5351c_activate_best_clock_source(void)
void si5351c_activate_best_clock_source(si5351c_driver_t* const drv)
{
uint8_t device_status = si5351c_read_single(0);
uint8_t device_status = si5351c_read_single(drv, 0);
if (device_status & SI5351C_LOS) {
/* CLKIN not detected */
if (active_clock_source == PLL_SOURCE_CLKIN) {
si5351c_set_clock_source(PLL_SOURCE_XTAL);
si5351c_set_clock_source(drv, PLL_SOURCE_XTAL);
}
} else {
/* CLKIN detected */
if (active_clock_source == PLL_SOURCE_XTAL) {
si5351c_set_clock_source(PLL_SOURCE_CLKIN);
si5351c_set_clock_source(drv, PLL_SOURCE_CLKIN);
}
}
}

View File

@ -30,8 +30,9 @@ extern "C"
#include <stdint.h>
#include "i2c_bus.h"
#define SI_INTDIV(x) (x*128-512)
#define SI5351C_I2C_ADDR (0x60 << 1)
#define SI5351C_CLK_POWERDOWN (1<<7)
#define SI5351C_CLK_INT_MODE (1<<6)
@ -62,26 +63,32 @@ enum pll_sources {
PLL_SOURCE_CLKIN = 1,
};
void si5351c_disable_all_outputs();
void si5351c_disable_oeb_pin_control();
void si5351c_power_down_all_clocks();
void si5351c_set_crystal_configuration();
void si5351c_enable_xo_and_ms_fanout();
void si5351c_configure_pll_sources(void);
void si5351c_configure_pll_multisynth(void);
void si5351c_reset_pll(void);
void si5351c_configure_multisynth(const uint_fast8_t ms_number,
typedef struct {
i2c_bus_t* const bus;
uint8_t i2c_address;
} si5351c_driver_t;
void si5351c_disable_all_outputs(si5351c_driver_t* const drv);
void si5351c_disable_oeb_pin_control(si5351c_driver_t* const drv);
void si5351c_power_down_all_clocks(si5351c_driver_t* const drv);
void si5351c_set_crystal_configuration(si5351c_driver_t* const drv);
void si5351c_enable_xo_and_ms_fanout(si5351c_driver_t* const drv);
void si5351c_configure_pll_sources(si5351c_driver_t* const drv);
void si5351c_configure_pll_multisynth(si5351c_driver_t* const drv);
void si5351c_reset_pll(si5351c_driver_t* const drv);
void si5351c_configure_multisynth(si5351c_driver_t* const drv,
const uint_fast8_t ms_number,
const uint32_t p1, const uint32_t p2, const uint32_t p3,
const uint_fast8_t r_div);
void si5351c_configure_clock_control(const enum pll_sources source);
void si5351c_enable_clock_outputs();
void si5351c_set_int_mode(const uint_fast8_t ms_number, const uint_fast8_t on);
void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll_sources source);
void si5351c_enable_clock_outputs(si5351c_driver_t* const drv);
void si5351c_set_int_mode(si5351c_driver_t* const drv, const uint_fast8_t ms_number, const uint_fast8_t on);
void si5351c_set_clock_source(si5351c_driver_t* const drv, const enum pll_sources source);
void si5351c_activate_best_clock_source(si5351c_driver_t* const drv);
void si5351c_write_single(uint8_t reg, uint8_t val);
uint8_t si5351c_read_single(uint8_t reg);
void si5351c_write(uint8_t* const data, const uint_fast8_t data_count);
void si5351c_set_clock_source(const enum pll_sources source);
void si5351c_activate_best_clock_source(void);
void si5351c_write_single(si5351c_driver_t* const drv, uint8_t reg, uint8_t val);
uint8_t si5351c_read_single(si5351c_driver_t* const drv, uint8_t reg);
void si5351c_write(si5351c_driver_t* const drv, const uint8_t* const data, const size_t data_count);
#ifdef __cplusplus
}

38
firmware/common/spi_bus.c Normal file
View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "spi_bus.h"
void spi_bus_start(spi_bus_t* const bus, const void* const config) {
bus->start(bus, config);
}
void spi_bus_stop(spi_bus_t* const bus) {
bus->stop(bus);
}
void spi_bus_transfer(spi_bus_t* const bus, void* const data, const size_t count) {
bus->transfer(bus, data, count);
}
void spi_bus_transfer_gather(spi_bus_t* const bus, const spi_transfer_t* const transfers, const size_t count) {
bus->transfer_gather(bus, transfers, count);
}

49
firmware/common/spi_bus.h Normal file
View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __SPI_BUS_H__
#define __SPI_BUS_H__
#include <stddef.h>
typedef struct {
void* const data;
const size_t count;
} spi_transfer_t;
struct spi_bus_t;
typedef struct spi_bus_t spi_bus_t;
struct spi_bus_t {
void* const obj;
const void* config;
void (*start)(spi_bus_t* const bus, const void* const config);
void (*stop)(spi_bus_t* const bus);
void (*transfer)(spi_bus_t* const bus, void* const data, const size_t count);
void (*transfer_gather)(spi_bus_t* const bus, const spi_transfer_t* const transfers, const size_t count);
};
void spi_bus_start(spi_bus_t* const bus, const void* const config);
void spi_bus_stop(spi_bus_t* const bus);
void spi_bus_transfer(spi_bus_t* const bus, void* const data, const size_t count);
void spi_bus_transfer_gather(spi_bus_t* const bus, const spi_transfer_t* const transfers, const size_t count);
#endif/*__SPI_BUS_H__*/

109
firmware/common/spi_ssp.c Normal file
View File

@ -0,0 +1,109 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "spi_ssp.h"
#include <libopencm3/lpc43xx/rgu.h>
#include <libopencm3/lpc43xx/ssp.h>
void spi_ssp_start(spi_bus_t* const bus, const void* const _config) {
const ssp_config_t* const config = _config;
if( bus->obj == (void*)SSP0_BASE ) {
/* Reset SPIFI peripheral before to Erase/Write SPIFI memory through SPI */
RESET_CTRL1 = RESET_CTRL1_SPIFI_RST;
}
gpio_set(config->gpio_select);
gpio_output(config->gpio_select);
SSP_CR1(bus->obj) = 0;
SSP_CPSR(bus->obj) = config->clock_prescale_rate;
SSP_CR0(bus->obj) =
(config->serial_clock_rate << 8)
| SSP_CPOL_0_CPHA_0
| SSP_FRAME_SPI
| config->data_bits
;
SSP_CR1(bus->obj) =
SSP_SLAVE_OUT_ENABLE
| SSP_MASTER
| SSP_ENABLE
| SSP_MODE_NORMAL
;
bus->config = config;
}
void spi_ssp_stop(spi_bus_t* const bus) {
SSP_CR1(bus->obj) = 0;
}
static void spi_ssp_wait_for_tx_fifo_not_full(spi_bus_t* const bus) {
while( (SSP_SR(bus->obj) & SSP_SR_TNF) == 0 );
}
static void spi_ssp_wait_for_rx_fifo_not_empty(spi_bus_t* const bus) {
while( (SSP_SR(bus->obj) & SSP_SR_RNE) == 0 );
}
static void spi_ssp_wait_for_not_busy(spi_bus_t* const bus) {
while( SSP_SR(bus->obj) & SSP_SR_BSY );
}
static uint32_t spi_ssp_transfer_word(spi_bus_t* const bus, const uint32_t data) {
spi_ssp_wait_for_tx_fifo_not_full(bus);
SSP_DR(bus->obj) = data;
spi_ssp_wait_for_not_busy(bus);
spi_ssp_wait_for_rx_fifo_not_empty(bus);
return SSP_DR(bus->obj);
}
void spi_ssp_transfer_gather(spi_bus_t* const bus, const spi_transfer_t* const transfers, const size_t count) {
const ssp_config_t* const config = bus->config;
const bool word_size_u16 = (SSP_CR0(bus->obj) & 0xf) > SSP_DATA_8BITS;
gpio_clear(config->gpio_select);
for(size_t i=0; i<count; i++) {
const size_t data_count = transfers[i].count;
if( word_size_u16 ) {
uint16_t* const data = transfers[i].data;
for(size_t j=0; j<data_count; j++) {
data[j] = spi_ssp_transfer_word(bus, data[j]);
}
} else {
uint8_t* const data = transfers[i].data;
for(size_t j=0; j<data_count; j++) {
data[j] = spi_ssp_transfer_word(bus, data[j]);
}
}
}
gpio_set(config->gpio_select);
}
void spi_ssp_transfer(spi_bus_t* const bus, void* const data, const size_t count) {
const spi_transfer_t transfers[] = {
{ data, count },
};
spi_ssp_transfer_gather(bus, transfers, 1);
}

46
firmware/common/spi_ssp.h Normal file
View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __SPI_SSP_H__
#define __SPI_SSP_H__
#include <stdint.h>
#include <stddef.h>
#include "spi_bus.h"
#include "gpio.h"
#include <libopencm3/lpc43xx/ssp.h>
typedef struct ssp_config_t {
ssp_datasize_t data_bits;
uint8_t serial_clock_rate;
uint8_t clock_prescale_rate;
gpio_t gpio_select;
} ssp_config_t;
void spi_ssp_start(spi_bus_t* const bus, const void* const config);
void spi_ssp_stop(spi_bus_t* const bus);
void spi_ssp_transfer(spi_bus_t* const bus, void* const data, const size_t count);
void spi_ssp_transfer_gather(spi_bus_t* const bus, const spi_transfer_t* const transfers, const size_t count);
#endif/*__SPI_SSP_H__*/

View File

@ -25,18 +25,16 @@
#include <libopencm3/lpc43xx/m4/nvic.h>
#include <libopencm3/lpc43xx/sgpio.h>
#include <sgpio.h>
void baseband_streaming_enable() {
void baseband_streaming_enable(sgpio_config_t* const sgpio_config) {
nvic_set_priority(NVIC_SGPIO_IRQ, 0);
nvic_enable_irq(NVIC_SGPIO_IRQ);
SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A);
sgpio_cpld_stream_enable();
sgpio_cpld_stream_enable(sgpio_config);
}
void baseband_streaming_disable() {
sgpio_cpld_stream_disable();
void baseband_streaming_disable(sgpio_config_t* const sgpio_config) {
sgpio_cpld_stream_disable(sgpio_config);
nvic_disable_irq(NVIC_SGPIO_IRQ);
}

View File

@ -23,7 +23,9 @@
#ifndef __STREAMING_H__
#define __STREAMING_H__
void baseband_streaming_enable();
void baseband_streaming_disable();
#include <sgpio.h>
void baseband_streaming_enable(sgpio_config_t* const sgpio_config);
void baseband_streaming_disable(sgpio_config_t* const sgpio_config);
#endif/*__STREAMING_H__*/

View File

@ -24,6 +24,7 @@
#include "hackrf-ui.h"
#include <hackrf_core.h>
#include <mixer.h>
#include <max2837.h>
#include <sgpio.h>
@ -64,26 +65,26 @@ bool set_freq(const uint64_t freq)
success = true;
const max2837_mode_t prior_max2837_mode = max2837_mode();
max2837_mode_standby();
const max2837_mode_t prior_max2837_mode = max2837_mode(&max2837);
max2837_set_mode(&max2837, MAX2837_MODE_STANDBY);
if(freq_mhz < MAX_LP_FREQ_MHZ)
{
rf_path_set_filter(RF_PATH_FILTER_LOW_PASS);
rf_path_set_filter(&rf_path, RF_PATH_FILTER_LOW_PASS);
/* IF is graduated from 2650 MHz to 2343 MHz */
max2837_freq_nominal_hz = 2650000000 - (freq / 7);
max2837_freq_nominal_hz = 2300000000;
mixer_freq_mhz = (max2837_freq_nominal_hz / FREQ_ONE_MHZ) + freq_mhz;
/* Set Freq and read real freq */
real_mixer_freq_hz = mixer_set_frequency(mixer_freq_mhz);
max2837_set_frequency(real_mixer_freq_hz - freq);
sgpio_cpld_stream_rx_set_q_invert(1);
real_mixer_freq_hz = mixer_set_frequency(&mixer, mixer_freq_mhz);
max2837_set_frequency(&max2837, real_mixer_freq_hz - freq);
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 1);
}else if( (freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) )
{
rf_path_set_filter(RF_PATH_FILTER_BYPASS);
rf_path_set_filter(&rf_path, RF_PATH_FILTER_BYPASS);
MAX2837_freq_hz = (freq_mhz * FREQ_ONE_MHZ) + freq_hz;
/* mixer_freq_mhz <= not used in Bypass mode */
max2837_set_frequency(MAX2837_freq_hz);
sgpio_cpld_stream_rx_set_q_invert(0);
max2837_set_frequency(&max2837, MAX2837_freq_hz);
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 0);
}else if( (freq_mhz >= MIN_HP_FREQ_MHZ) && (freq_mhz <= MAX_HP_FREQ_MHZ) )
{
if (freq_mhz < MID1_HP_FREQ_MHZ) {
@ -96,18 +97,18 @@ bool set_freq(const uint64_t freq)
/* IF is graduated from 2500 MHz to 2738 MHz */
max2837_freq_nominal_hz = 2500000000 + ((freq - 5100000000) / 9);
}
rf_path_set_filter(RF_PATH_FILTER_HIGH_PASS);
rf_path_set_filter(&rf_path, RF_PATH_FILTER_HIGH_PASS);
mixer_freq_mhz = freq_mhz - (max2837_freq_nominal_hz / FREQ_ONE_MHZ);
/* Set Freq and read real freq */
real_mixer_freq_hz = mixer_set_frequency(mixer_freq_mhz);
max2837_set_frequency(freq - real_mixer_freq_hz);
sgpio_cpld_stream_rx_set_q_invert(0);
real_mixer_freq_hz = mixer_set_frequency(&mixer, mixer_freq_mhz);
max2837_set_frequency(&max2837, freq - real_mixer_freq_hz);
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 0);
}else
{
/* Error freq_mhz too high */
success = false;
}
max2837_set_mode(prior_max2837_mode);
max2837_set_mode(&max2837, prior_max2837_mode);
if( success ) {
freq_cache = freq;
hackrf_ui_setFrequency(freq);
@ -132,15 +133,15 @@ bool set_freq_explicit(const uint64_t if_freq_hz, const uint64_t lo_freq_hz,
return false;
}
rf_path_set_filter(path);
max2837_set_frequency(if_freq_hz);
rf_path_set_filter(&rf_path, path);
max2837_set_frequency(&max2837, if_freq_hz);
if (lo_freq_hz > if_freq_hz) {
sgpio_cpld_stream_rx_set_q_invert(1);
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 1);
} else {
sgpio_cpld_stream_rx_set_q_invert(0);
sgpio_cpld_stream_rx_set_q_invert(&sgpio_config, 0);
}
if (path != RF_PATH_FILTER_BYPASS) {
(void)mixer_set_frequency(lo_freq_hz / FREQ_ONE_MHZ);
(void)mixer_set_frequency(&mixer, lo_freq_hz / FREQ_ONE_MHZ);
}
return true;
}

View File

@ -72,7 +72,7 @@ void usb_peripheral_reset() {
while( (RESET_ACTIVE_STATUS0 & RESET_CTRL0_USB0_RST) == 0 );
}
void usb_phy_enable() {
static void usb_phy_enable() {
CREG_CREG0 &= ~CREG_CREG0_USB0PHY;
}

View File

@ -29,7 +29,6 @@
#include "usb_type.h"
void usb_peripheral_reset();
void usb_phy_enable();
void usb_device_init(
const uint_fast8_t device_ordinal,

View File

@ -130,13 +130,17 @@ static usb_request_status_t usb_send_descriptor(
static usb_request_status_t usb_send_descriptor_string(
usb_endpoint_t* const endpoint
) {
uint_fast8_t index = endpoint->setup.value_l;
for( uint_fast8_t i=0; endpoint->device->descriptor_strings[i] != 0; i++ ) {
if( i == index ) {
return usb_send_descriptor(endpoint, endpoint->device->descriptor_strings[i]);
if ((endpoint->setup.value_l == 0xee) &&
(endpoint->device->wcid_string_descriptor != NULL)) { /* MS WCID string */
return usb_send_descriptor(endpoint, endpoint->device->wcid_string_descriptor);
} else {
uint_fast8_t index = endpoint->setup.value_l;
for( uint_fast8_t i=0; endpoint->device->descriptor_strings[i] != 0; i++ ) {
if( i == index ) {
return usb_send_descriptor(endpoint, endpoint->device->descriptor_strings[i]);
}
}
}
return USB_REQUEST_STATUS_STALL;
}
@ -212,6 +216,26 @@ static usb_request_status_t usb_standard_request_get_descriptor(
}
}
usb_request_status_t usb_vendor_request_read_wcid(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage
) {
if( stage == USB_TRANSFER_STAGE_SETUP ) {
if ((endpoint->setup.index == 0x04) &&
(endpoint->device->wcid_feature_descriptor != NULL)) {
usb_send_descriptor(endpoint, endpoint->device->wcid_feature_descriptor);
return USB_REQUEST_STATUS_OK;
}
if ((endpoint->setup.index == 0x05) &&
(endpoint->device->wcid_extended_properties_descriptor != NULL)) {
usb_send_descriptor(endpoint, endpoint->device->wcid_extended_properties_descriptor);
return USB_REQUEST_STATUS_OK;
}
return USB_REQUEST_STATUS_STALL;
}
return USB_REQUEST_STATUS_OK;
}
/*********************************************************************/
static usb_request_status_t usb_standard_request_set_address_setup(

View File

@ -29,6 +29,11 @@ void usb_set_configuration_changed_cb(
void (*callback)(usb_device_t* const)
);
usb_request_status_t usb_vendor_request_read_wcid(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage
);
usb_request_status_t usb_standard_request(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage

View File

@ -127,6 +127,9 @@ typedef struct {
const uint8_t* const qualifier_descriptor;
usb_configuration_t* (*configurations)[];
const usb_configuration_t* configuration;
uint8_t* wcid_string_descriptor;
uint8_t* wcid_feature_descriptor;
uint8_t* wcid_extended_properties_descriptor;
} usb_device_t;
typedef struct usb_endpoint_t usb_endpoint_t;

View File

@ -1,6 +1,7 @@
/*
* Copyright 2013 Michael Ossmann
* Copyright 2013 Benjamin Vernoux
* Copyright 2014 Jared Boone, ShareBrained Technology
*
* This file is part of HackRF.
*
@ -27,238 +28,198 @@
*/
#include <stdint.h>
#include <stddef.h>
#include "w25q80bv.h"
#include "hackrf_core.h"
#include <libopencm3/lpc43xx/ssp.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/rgu.h>
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define W25Q80BV_READ_DATA 0x03
#define W25Q80BV_FAST_READ 0x0b
#define W25Q80BV_WRITE_ENABLE 0x06
#define W25Q80BV_CHIP_ERASE 0xC7
#define W25Q80BV_READ_STATUS1 0x05
#define W25Q80BV_PAGE_PROGRAM 0x02
#define W25Q80BV_DEVICE_ID 0xAB
#define W25Q80BV_UNIQUE_ID 0x4B
#define W25Q80BV_STATUS_BUSY 0x01
#define W25Q80BV_DEVICE_ID_RES 0x13 /* Expected device_id for W25Q80BV */
/*
* Set up pins for GPIO and SPI control, configure SSP0 peripheral for SPI.
* SSP0_SSEL is controlled by GPIO in order to handle various transfer lengths.
*/
void w25q80bv_setup(void)
void w25q80bv_setup(w25q80bv_driver_t* const drv)
{
uint8_t device_id;
const uint8_t serial_clock_rate = 2;
const uint8_t clock_prescale_rate = 2;
/* Reset SPIFI peripheral before to Erase/Write SPIFI memory through SPI */
RESET_CTRL1 = RESET_CTRL1_SPIFI_RST;
drv->page_len = 256U;
drv->num_pages = 4096U;
drv->num_bytes = 1048576U;
/* Init SPIFI GPIO to Normal GPIO */
scu_pinmux(P3_3, (SCU_SSP_IO | SCU_CONF_FUNCTION2)); // P3_3 SPIFI_SCK => SSP0_SCK
scu_pinmux(P3_4, (SCU_GPIO_FAST | SCU_CONF_FUNCTION0)); // P3_4 SPIFI SPIFI_SIO3 IO3 => GPIO1[14]
scu_pinmux(P3_5, (SCU_GPIO_FAST | SCU_CONF_FUNCTION0)); // P3_5 SPIFI SPIFI_SIO2 IO2 => GPIO1[15]
scu_pinmux(P3_6, (SCU_GPIO_FAST | SCU_CONF_FUNCTION0)); // P3_6 SPIFI SPIFI_MISO IO1 => GPIO0[6]
scu_pinmux(P3_7, (SCU_GPIO_FAST | SCU_CONF_FUNCTION4)); // P3_7 SPIFI SPIFI_MOSI IO0 => GPIO5[10]
scu_pinmux(P3_8, (SCU_GPIO_FAST | SCU_CONF_FUNCTION4)); // P3_8 SPIFI SPIFI_CS => GPIO5[11]
/* configure SSP pins */
scu_pinmux(SCU_SSP0_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
scu_pinmux(SCU_SSP0_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
scu_pinmux(SCU_SSP0_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION2));
/* configure GPIO pins */
scu_pinmux(SCU_FLASH_HOLD, SCU_GPIO_FAST);
scu_pinmux(SCU_FLASH_WP, SCU_GPIO_FAST);
scu_pinmux(SCU_SSP0_SSEL, (SCU_GPIO_FAST | SCU_CONF_FUNCTION4));
/* drive SSEL, HOLD, and WP pins high */
gpio_set(PORT_FLASH, (PIN_FLASH_HOLD | PIN_FLASH_WP));
gpio_set(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
/* Set GPIO pins as outputs. */
GPIO1_DIR |= (PIN_FLASH_HOLD | PIN_FLASH_WP);
GPIO5_DIR |= PIN_SSP0_SSEL;
/* initialize SSP0 */
ssp_init(SSP0_NUM,
SSP_DATA_8BITS,
SSP_FRAME_SPI,
SSP_CPOL_0_CPHA_0,
serial_clock_rate,
clock_prescale_rate,
SSP_MODE_NORMAL,
SSP_MASTER,
SSP_SLAVE_OUT_ENABLE);
drv->target_init(drv);
do {
device_id = w25q80bv_get_device_id();
device_id = w25q80bv_get_device_id(drv);
} while(device_id != W25Q80BV_DEVICE_ID_RES &&
device_id != W25Q16DV_DEVICE_ID_RES);
}
uint8_t w25q80bv_get_status(void)
uint8_t w25q80bv_get_status(w25q80bv_driver_t* const drv)
{
uint8_t value;
gpio_clear(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
ssp_transfer(SSP0_NUM, W25Q80BV_READ_STATUS1);
value = ssp_transfer(SSP0_NUM, 0xFF);
gpio_set(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
return value;
uint8_t data[] = { W25Q80BV_READ_STATUS1, 0xFF };
spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data));
return data[1];
}
/* Release power down / Device ID */
uint8_t w25q80bv_get_device_id(void)
uint8_t w25q80bv_get_device_id(w25q80bv_driver_t* const drv)
{
uint8_t value;
gpio_clear(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
ssp_transfer(SSP0_NUM, W25Q80BV_DEVICE_ID);
/* Read 3 dummy bytes */
value = ssp_transfer(SSP0_NUM, 0xFF);
value = ssp_transfer(SSP0_NUM, 0xFF);
value = ssp_transfer(SSP0_NUM, 0xFF);
/* Read Device ID shall return 0x13 for W25Q80BV */
value = ssp_transfer(SSP0_NUM, 0xFF);
gpio_set(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
return value;
uint8_t data[] = {
W25Q80BV_DEVICE_ID,
0xFF, 0xFF, 0xFF, 0xFF
};
spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data));
return data[4];
}
void w25q80bv_get_unique_id(w25q80bv_unique_id_t* unique_id)
void w25q80bv_get_unique_id(w25q80bv_driver_t* const drv, w25q80bv_unique_id_t* unique_id)
{
int i;
uint8_t value;
uint8_t data[] = {
W25Q80BV_UNIQUE_ID,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data));
gpio_clear(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
ssp_transfer(SSP0_NUM, W25Q80BV_UNIQUE_ID);
/* Read 4 dummy bytes */
for(i=0; i<4; i++)
value = ssp_transfer(SSP0_NUM, 0xFF);
/* Read Unique ID 64bits (8*8) */
for(i=0; i<8; i++)
{
value = ssp_transfer(SSP0_NUM, 0xFF);
unique_id->id_8b[i] = value;
for(size_t i=0; i<8; i++) {
unique_id->id_8b[i] = data[5+i];
}
gpio_set(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
}
void w25q80bv_wait_while_busy(void)
void w25q80bv_wait_while_busy(w25q80bv_driver_t* const drv)
{
while (w25q80bv_get_status() & W25Q80BV_STATUS_BUSY);
while (w25q80bv_get_status(drv) & W25Q80BV_STATUS_BUSY);
}
void w25q80bv_write_enable(void)
void w25q80bv_write_enable(w25q80bv_driver_t* const drv)
{
w25q80bv_wait_while_busy();
gpio_clear(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
ssp_transfer(SSP0_NUM, W25Q80BV_WRITE_ENABLE);
gpio_set(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
w25q80bv_wait_while_busy(drv);
uint8_t data[] = { W25Q80BV_WRITE_ENABLE };
spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data));
}
void w25q80bv_chip_erase(void)
void w25q80bv_chip_erase(w25q80bv_driver_t* const drv)
{
uint8_t device_id;
do {
device_id = w25q80bv_get_device_id();
device_id = w25q80bv_get_device_id(drv);
} while(device_id != W25Q80BV_DEVICE_ID_RES &&
device_id != W25Q16DV_DEVICE_ID_RES);
w25q80bv_write_enable();
w25q80bv_wait_while_busy();
gpio_clear(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
ssp_transfer(SSP0_NUM, W25Q80BV_CHIP_ERASE);
gpio_set(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
w25q80bv_write_enable(drv);
w25q80bv_wait_while_busy(drv);
uint8_t data[] = { W25Q80BV_CHIP_ERASE };
spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data));
}
/* write up a 256 byte page or partial page */
void w25q80bv_page_program(const uint32_t addr, const uint16_t len, const uint8_t* data)
static void w25q80bv_page_program(w25q80bv_driver_t* const drv, const uint32_t addr, const uint16_t len, uint8_t* data)
{
int i;
/* do nothing if asked to write beyond a page boundary */
if (((addr & 0xFF) + len) > W25Q80BV_PAGE_LEN)
if (((addr & 0xFF) + len) > drv->page_len)
return;
/* do nothing if we would overflow the flash */
if (addr > (W25Q80BV_NUM_BYTES - len))
if (addr > (drv->num_bytes - len))
return;
w25q80bv_write_enable();
w25q80bv_wait_while_busy();
w25q80bv_write_enable(drv);
w25q80bv_wait_while_busy(drv);
gpio_clear(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
ssp_transfer(SSP0_NUM, W25Q80BV_PAGE_PROGRAM);
ssp_transfer(SSP0_NUM, (addr & 0xFF0000) >> 16);
ssp_transfer(SSP0_NUM, (addr & 0xFF00) >> 8);
ssp_transfer(SSP0_NUM, addr & 0xFF);
for (i = 0; i < len; i++)
ssp_transfer(SSP0_NUM, data[i]);
gpio_set(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
uint8_t header[] = {
W25Q80BV_PAGE_PROGRAM,
(addr & 0xFF0000) >> 16,
(addr & 0xFF00) >> 8,
addr & 0xFF
};
const spi_transfer_t transfers[] = {
{ header, ARRAY_SIZE(header) },
{ data, len }
};
spi_bus_transfer_gather(drv->bus, transfers, ARRAY_SIZE(transfers));
}
/* write an arbitrary number of bytes */
void w25q80bv_program(uint32_t addr, uint32_t len, const uint8_t* data)
void w25q80bv_program(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, uint8_t* data)
{
uint16_t first_block_len;
uint8_t device_id;
do {
device_id = w25q80bv_get_device_id();
device_id = w25q80bv_get_device_id(drv);
} while(device_id != W25Q80BV_DEVICE_ID_RES &&
device_id != W25Q16DV_DEVICE_ID_RES);
/* do nothing if we would overflow the flash */
if ((len > W25Q80BV_NUM_BYTES) || (addr > W25Q80BV_NUM_BYTES)
|| ((addr + len) > W25Q80BV_NUM_BYTES))
if ((len > drv->num_bytes) || (addr > drv->num_bytes)
|| ((addr + len) > drv->num_bytes))
return;
/* handle start not at page boundary */
first_block_len = W25Q80BV_PAGE_LEN - (addr % W25Q80BV_PAGE_LEN);
first_block_len = drv->page_len - (addr % drv->page_len);
if (len < first_block_len)
first_block_len = len;
if (first_block_len) {
w25q80bv_page_program(addr, first_block_len, data);
w25q80bv_page_program(drv, addr, first_block_len, data);
addr += first_block_len;
data += first_block_len;
len -= first_block_len;
}
/* one page at a time on boundaries */
while (len >= W25Q80BV_PAGE_LEN) {
w25q80bv_page_program(addr, W25Q80BV_PAGE_LEN, data);
addr += W25Q80BV_PAGE_LEN;
data += W25Q80BV_PAGE_LEN;
len -= W25Q80BV_PAGE_LEN;
while (len >= drv->page_len) {
w25q80bv_page_program(drv, addr, drv->page_len, data);
addr += drv->page_len;
data += drv->page_len;
len -= drv->page_len;
}
/* handle end not at page boundary */
if (len) {
w25q80bv_page_program(addr, len, data);
w25q80bv_page_program(drv, addr, len, data);
}
}
void w25q80bv_read(uint32_t addr, uint32_t len, uint8_t* const data)
/* write an arbitrary number of bytes */
void w25q80bv_read(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, uint8_t* const data)
{
uint32_t i;
/* do nothing if we would overflow the flash */
if ((len > W25Q80BV_NUM_BYTES) || (addr > W25Q80BV_NUM_BYTES)
|| ((addr + len) > W25Q80BV_NUM_BYTES))
if ((len > drv->num_bytes) || (addr > drv->num_bytes)
|| ((addr + len) > drv->num_bytes))
return;
w25q80bv_wait_while_busy();
w25q80bv_wait_while_busy(drv);
gpio_clear(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
ssp_transfer(SSP0_NUM, W25Q80BV_FAST_READ);
ssp_transfer(SSP0_NUM, (addr >> 16) & 0xFF);
ssp_transfer(SSP0_NUM, (addr >> 8) & 0xFF);
ssp_transfer(SSP0_NUM, (addr >> 0) & 0xFF);
ssp_transfer(SSP0_NUM, 0xFF);
for (i = 0; i < len; i++)
data[i] = ssp_transfer(SSP0_NUM, 0xFF);
gpio_set(PORT_SSP0_SSEL, PIN_SSP0_SSEL);
uint8_t header[] = {
W25Q80BV_FAST_READ,
(addr & 0xFF0000) >> 16,
(addr & 0xFF00) >> 8,
addr & 0xFF,
0x00
};
const spi_transfer_t transfers[] = {
{ header, ARRAY_SIZE(header) },
{ data, len }
};
spi_bus_transfer_gather(drv->bus, transfers, ARRAY_SIZE(transfers));
}

View File

@ -1,6 +1,7 @@
/*
* Copyright 2013 Michael Ossmann
* Copyright 2013 Benjamin Vernoux
* Copyright 2014 Jared Boone, ShareBrained Technology
*
* This file is part of HackRF.
*
@ -23,24 +24,13 @@
#ifndef __W25Q80BV_H__
#define __W25Q80BV_H__
#define W25Q80BV_PAGE_LEN 256U
#define W25Q80BV_NUM_PAGES 4096U
#define W25Q80BV_NUM_BYTES 1048576U
#define W25Q80BV_READ_DATA 0x03
#define W25Q80BV_FAST_READ 0x0b
#define W25Q80BV_WRITE_ENABLE 0x06
#define W25Q80BV_CHIP_ERASE 0xC7
#define W25Q80BV_READ_STATUS1 0x05
#define W25Q80BV_PAGE_PROGRAM 0x02
#define W25Q80BV_DEVICE_ID 0xAB
#define W25Q80BV_UNIQUE_ID 0x4B
#define W25Q80BV_STATUS_BUSY 0x01
#include <stdint.h>
#include <stddef.h>
#define W25Q80BV_DEVICE_ID_RES 0x13 /* Expected device_id for W25Q80BV */
#define W25Q16DV_DEVICE_ID_RES 0x14 /* Expected device_id for W25Q16DV */
#include "spi_bus.h"
#include "gpio.h"
typedef union
{
@ -49,11 +39,24 @@ typedef union
uint8_t id_8b[8]; /* 8*8bits 64bits Unique ID */
} w25q80bv_unique_id_t;
void w25q80bv_setup(void);
void w25q80bv_chip_erase(void);
void w25q80bv_program(uint32_t addr, uint32_t len, const uint8_t* data);
uint8_t w25q80bv_get_device_id(void);
void w25q80bv_get_unique_id(w25q80bv_unique_id_t* unique_id);
void w25q80bv_read(uint32_t addr, uint32_t len, uint8_t* const data);
struct w25q80bv_driver_t;
typedef struct w25q80bv_driver_t w25q80bv_driver_t;
struct w25q80bv_driver_t {
spi_bus_t* bus;
gpio_t gpio_hold;
gpio_t gpio_wp;
void (*target_init)(w25q80bv_driver_t* const drv);
size_t page_len;
size_t num_pages;
size_t num_bytes;
};
void w25q80bv_setup(w25q80bv_driver_t* const drv);
void w25q80bv_chip_erase(w25q80bv_driver_t* const drv);
void w25q80bv_program(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, uint8_t* data);
uint8_t w25q80bv_get_device_id(w25q80bv_driver_t* const drv);
void w25q80bv_get_unique_id(w25q80bv_driver_t* const drv, w25q80bv_unique_id_t* unique_id);
void w25q80bv_read(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, uint8_t* const data);
#endif//__W25Q80BV_H__

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "w25q80bv_target.h"
#include <libopencm3/lpc43xx/scu.h>
#include "hackrf_core.h"
/* TODO: Why is SSEL being controlled manually when SSP0 could do it
* automatically?
*/
void w25q80bv_target_init(w25q80bv_driver_t* const drv) {
(void)drv;
/* Init SPIFI GPIO to Normal GPIO */
scu_pinmux(P3_3, (SCU_SSP_IO | SCU_CONF_FUNCTION2)); // P3_3 SPIFI_SCK => SSP0_SCK
scu_pinmux(P3_4, (SCU_GPIO_FAST | SCU_CONF_FUNCTION0)); // P3_4 SPIFI SPIFI_SIO3 IO3 => GPIO1[14]
scu_pinmux(P3_5, (SCU_GPIO_FAST | SCU_CONF_FUNCTION0)); // P3_5 SPIFI SPIFI_SIO2 IO2 => GPIO1[15]
scu_pinmux(P3_6, (SCU_GPIO_FAST | SCU_CONF_FUNCTION0)); // P3_6 SPIFI SPIFI_MISO IO1 => GPIO0[6]
scu_pinmux(P3_7, (SCU_GPIO_FAST | SCU_CONF_FUNCTION4)); // P3_7 SPIFI SPIFI_MOSI IO0 => GPIO5[10]
scu_pinmux(P3_8, (SCU_GPIO_FAST | SCU_CONF_FUNCTION4)); // P3_8 SPIFI SPIFI_CS => GPIO5[11]
/* configure SSP pins */
scu_pinmux(SCU_SSP0_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
scu_pinmux(SCU_SSP0_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5));
scu_pinmux(SCU_SSP0_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION2));
/* configure GPIO pins */
scu_pinmux(SCU_FLASH_HOLD, SCU_GPIO_FAST);
scu_pinmux(SCU_FLASH_WP, SCU_GPIO_FAST);
scu_pinmux(SCU_SSP0_SSEL, (SCU_GPIO_FAST | SCU_CONF_FUNCTION4));
/* drive SSEL, HOLD, and WP pins high */
gpio_set(drv->gpio_hold);
gpio_set(drv->gpio_wp);
/* Set GPIO pins as outputs. */
gpio_output(drv->gpio_hold);
gpio_output(drv->gpio_wp);
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of HackRF.
*
* 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 2, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __W25Q80BV_TARGET_H__
#define __W25Q80BV_TARGET_H__
#include "w25q80bv.h"
void w25q80bv_target_init(w25q80bv_driver_t* const drv);
#endif/*__W25Q80BV_TARGET_H__*/

View File

@ -197,7 +197,7 @@ typedef struct tagSXsvfInfo
} SXsvfInfo;
/* Declare pointer to functions that perform XSVF commands */
typedef int (*TXsvfDoCmdFuncPtr)( SXsvfInfo* );
typedef int (*TXsvfDoCmdFuncPtr)( jtag_gpio_t* const gpio, SXsvfInfo* );
/*============================================================================
@ -267,24 +267,24 @@ typedef int (*TXsvfDoCmdFuncPtr)( SXsvfInfo* );
* XSVF Function Prototypes
============================================================================*/
int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo ); /* Illegal command function */
int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo );
int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo );
int xsvfDoXSIR( SXsvfInfo* pXsvfInfo );
int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo );
int xsvfDoXSDR( SXsvfInfo* pXsvfInfo );
int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo );
int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo );
int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo );
int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo );
int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo );
int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo );
int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo );
int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo );
int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo );
int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo );
int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo );
int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo );
int xsvfDoIllegalCmd( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo ); /* Illegal command function */
int xsvfDoXCOMPLETE( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXTDOMASK( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXSIR( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXSIR2( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXSDR( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXRUNTEST( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXREPEAT( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXSDRSIZE( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXSDRTDO( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXSETSDRMASKS( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXSDRINC( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXSDRBCE( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXSDRTDOBCE( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXSTATE( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXENDXR( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXCOMMENT( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
int xsvfDoXWAIT( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo );
/* Insert new command functions here */
/*============================================================================
@ -476,11 +476,11 @@ short xsvfGetAsNumBytes( long lNumBits )
* Parameters: sTms - new TMS value.
* Returns: void.
*****************************************************************************/
void xsvfTmsTransition( short sTms )
void xsvfTmsTransition(jtag_gpio_t* const gpio, short sTms )
{
setPort( TMS, sTms );
setPort( TCK, 0 );
setPort( TCK, 1 );
setPort(gpio, TMS, sTms );
setPort(gpio, TCK, 0 );
setPort(gpio, TCK, 1 );
}
/*****************************************************************************
@ -496,7 +496,8 @@ void xsvfTmsTransition( short sTms )
* ucTargetState - New target TAP state.
* Returns: int - 0 = success; otherwise error.
*****************************************************************************/
int xsvfGotoTapState( unsigned char* pucTapState,
int xsvfGotoTapState( jtag_gpio_t* const gpio,
unsigned char* pucTapState,
unsigned char ucTargetState )
{
int i;
@ -506,11 +507,11 @@ int xsvfGotoTapState( unsigned char* pucTapState,
if ( ucTargetState == XTAPSTATE_RESET )
{
/* If RESET, always perform TMS reset sequence to reset/sync TAPs */
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
for ( i = 0; i < 5; ++i )
{
setPort( TCK, 0 );
setPort( TCK, 1 );
setPort(gpio, TCK, 0 );
setPort(gpio, TCK, 1 );
}
*pucTapState = XTAPSTATE_RESET;
XSVFDBG_PRINTF( 3, " TMS Reset Sequence -> Test-Logic-Reset\n" );
@ -532,14 +533,14 @@ int xsvfGotoTapState( unsigned char* pucTapState,
or in IRPAUSE to comply with SVF standard */
if ( ucTargetState == XTAPSTATE_PAUSEDR )
{
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_EXIT2DR;
XSVFDBG_PRINTF1( 3, " TAP State = %s\n",
xsvf_pzTapState[ *pucTapState ] );
}
else if ( ucTargetState == XTAPSTATE_PAUSEIR )
{
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_EXIT2IR;
XSVFDBG_PRINTF1( 3, " TAP State = %s\n",
xsvf_pzTapState[ *pucTapState ] );
@ -552,138 +553,138 @@ int xsvfGotoTapState( unsigned char* pucTapState,
switch ( *pucTapState )
{
case XTAPSTATE_RESET:
xsvfTmsTransition( 0 );
xsvfTmsTransition( gpio, 0 );
*pucTapState = XTAPSTATE_RUNTEST;
break;
case XTAPSTATE_RUNTEST:
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_SELECTDR;
break;
case XTAPSTATE_SELECTDR:
if ( ucTargetState >= XTAPSTATE_IRSTATES )
{
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_SELECTIR;
}
else
{
xsvfTmsTransition( 0 );
xsvfTmsTransition( gpio, 0 );
*pucTapState = XTAPSTATE_CAPTUREDR;
}
break;
case XTAPSTATE_CAPTUREDR:
if ( ucTargetState == XTAPSTATE_SHIFTDR )
{
xsvfTmsTransition( 0 );
xsvfTmsTransition( gpio, 0 );
*pucTapState = XTAPSTATE_SHIFTDR;
}
else
{
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_EXIT1DR;
}
break;
case XTAPSTATE_SHIFTDR:
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_EXIT1DR;
break;
case XTAPSTATE_EXIT1DR:
if ( ucTargetState == XTAPSTATE_PAUSEDR )
{
xsvfTmsTransition( 0 );
xsvfTmsTransition( gpio, 0 );
*pucTapState = XTAPSTATE_PAUSEDR;
}
else
{
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_UPDATEDR;
}
break;
case XTAPSTATE_PAUSEDR:
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_EXIT2DR;
break;
case XTAPSTATE_EXIT2DR:
if ( ucTargetState == XTAPSTATE_SHIFTDR )
{
xsvfTmsTransition( 0 );
xsvfTmsTransition( gpio, 0 );
*pucTapState = XTAPSTATE_SHIFTDR;
}
else
{
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_UPDATEDR;
}
break;
case XTAPSTATE_UPDATEDR:
if ( ucTargetState == XTAPSTATE_RUNTEST )
{
xsvfTmsTransition( 0 );
xsvfTmsTransition( gpio, 0 );
*pucTapState = XTAPSTATE_RUNTEST;
}
else
{
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_SELECTDR;
}
break;
case XTAPSTATE_SELECTIR:
xsvfTmsTransition( 0 );
xsvfTmsTransition( gpio, 0 );
*pucTapState = XTAPSTATE_CAPTUREIR;
break;
case XTAPSTATE_CAPTUREIR:
if ( ucTargetState == XTAPSTATE_SHIFTIR )
{
xsvfTmsTransition( 0 );
xsvfTmsTransition( gpio, 0 );
*pucTapState = XTAPSTATE_SHIFTIR;
}
else
{
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_EXIT1IR;
}
break;
case XTAPSTATE_SHIFTIR:
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_EXIT1IR;
break;
case XTAPSTATE_EXIT1IR:
if ( ucTargetState == XTAPSTATE_PAUSEIR )
{
xsvfTmsTransition( 0 );
xsvfTmsTransition( gpio, 0 );
*pucTapState = XTAPSTATE_PAUSEIR;
}
else
{
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_UPDATEIR;
}
break;
case XTAPSTATE_PAUSEIR:
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_EXIT2IR;
break;
case XTAPSTATE_EXIT2IR:
if ( ucTargetState == XTAPSTATE_SHIFTIR )
{
xsvfTmsTransition( 0 );
xsvfTmsTransition( gpio, 0 );
*pucTapState = XTAPSTATE_SHIFTIR;
}
else
{
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_UPDATEIR;
}
break;
case XTAPSTATE_UPDATEIR:
if ( ucTargetState == XTAPSTATE_RUNTEST )
{
xsvfTmsTransition( 0 );
xsvfTmsTransition( gpio, 0 );
*pucTapState = XTAPSTATE_RUNTEST;
}
else
{
xsvfTmsTransition( 1 );
xsvfTmsTransition( gpio, 1 );
*pucTapState = XTAPSTATE_SELECTDR;
}
break;
@ -714,7 +715,8 @@ int xsvfGotoTapState( unsigned char* pucTapState,
* iExitShift - 1=exit at end of shift; 0=stay in Shift-DR.
* Returns: void.
*****************************************************************************/
void xsvfShiftOnly( long lNumBits,
void xsvfShiftOnly( jtag_gpio_t* const gpio,
long lNumBits,
lenVal* plvTdi,
lenVal* plvTdoCaptured,
int iExitShift )
@ -749,25 +751,25 @@ void xsvfShiftOnly( long lNumBits,
if ( iExitShift && !lNumBits )
{
/* Exit Shift-DR state */
setPort( TMS, 1 );
setPort(gpio, TMS, 1 );
}
/* Set the new TDI value */
setPort( TDI, (short)(ucTdiByte & 1) );
setPort(gpio, TDI, (short)(ucTdiByte & 1) );
ucTdiByte >>= 1;
/* Set TCK low */
setPort( TCK, 0 );
setPort(gpio, TCK, 0 );
if ( pucTdo )
{
/* Save the TDO value */
ucTdoBit = readTDOBit();
ucTdoBit = readTDOBit(gpio);
ucTdoByte |= ( ucTdoBit << i );
}
/* Set TCK high */
setPort( TCK, 1 );
setPort(gpio, TCK, 1 );
}
/* Save the TDO byte value */
@ -802,7 +804,8 @@ void xsvfShiftOnly( long lNumBits,
* Skip the waitTime() if plvTdoMask->val[0:plvTdoMask->len-1]
* is NOT all zeros and sMatch==1.
*****************************************************************************/
int xsvfShift( unsigned char* pucTapState,
int xsvfShift( jtag_gpio_t* const gpio,
unsigned char* pucTapState,
unsigned char ucStartState,
long lNumBits,
lenVal* plvTdi,
@ -837,9 +840,9 @@ int xsvfShift( unsigned char* pucTapState,
if ( lRunTestTime )
{
/* Wait for prespecified XRUNTEST time */
xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST );
xsvfGotoTapState( gpio, pucTapState, XTAPSTATE_RUNTEST );
XSVFDBG_PRINTF1( 3, " Wait = %ld usec\n", lRunTestTime );
waitTime( lRunTestTime );
waitTime( gpio, lRunTestTime );
}
}
else
@ -847,10 +850,10 @@ int xsvfShift( unsigned char* pucTapState,
do
{
/* Goto Shift-DR or Shift-IR */
xsvfGotoTapState( pucTapState, ucStartState );
xsvfGotoTapState( gpio, pucTapState, ucStartState );
/* Shift TDI and capture TDO */
xsvfShiftOnly( lNumBits, plvTdi, plvTdoCaptured, iExitShift );
xsvfShiftOnly( gpio, lNumBits, plvTdi, plvTdoCaptured, iExitShift );
if ( plvTdoExpected )
{
@ -880,24 +883,24 @@ int xsvfShift( unsigned char* pucTapState,
XSVFDBG_PRINTF( 4, "\n");
XSVFDBG_PRINTF1( 3, " Retry #%d\n", ( ucRepeat + 1 ) );
/* Do exception handling retry - ShiftDR only */
xsvfGotoTapState( pucTapState, XTAPSTATE_PAUSEDR );
xsvfGotoTapState( gpio, pucTapState, XTAPSTATE_PAUSEDR );
/* Shift 1 extra bit */
xsvfGotoTapState( pucTapState, XTAPSTATE_SHIFTDR );
xsvfGotoTapState( gpio, pucTapState, XTAPSTATE_SHIFTDR );
/* Increment RUNTEST time by an additional 25% */
lRunTestTime += ( lRunTestTime >> 2 );
}
else
{
/* Do normal exit from Shift-XR */
xsvfGotoTapState( pucTapState, ucEndState );
xsvfGotoTapState( gpio, pucTapState, ucEndState );
}
if ( lRunTestTime )
{
/* Wait for prespecified XRUNTEST time */
xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST );
xsvfGotoTapState( gpio, pucTapState, XTAPSTATE_RUNTEST );
XSVFDBG_PRINTF1( 3, " Wait = %ld usec\n", lRunTestTime );
waitTime( lRunTestTime );
waitTime( gpio, lRunTestTime );
}
}
} while ( iMismatch && ( ucRepeat++ < ucMaxRepeat ) );
@ -941,7 +944,8 @@ int xsvfShift( unsigned char* pucTapState,
* ucMaxRepeat - maximum xc9500/xl retries.
* Returns: int - 0 = success; otherwise TDO mismatch.
*****************************************************************************/
int xsvfBasicXSDRTDO( unsigned char* pucTapState,
int xsvfBasicXSDRTDO( jtag_gpio_t* const gpio,
unsigned char* pucTapState,
long lShiftLengthBits,
short sShiftLengthBytes,
lenVal* plvTdi,
@ -957,7 +961,7 @@ int xsvfBasicXSDRTDO( unsigned char* pucTapState,
{
readVal( plvTdoExpected, sShiftLengthBytes );
}
return( xsvfShift( pucTapState, XTAPSTATE_SHIFTDR, lShiftLengthBits,
return( xsvfShift( gpio, pucTapState, XTAPSTATE_SHIFTDR, lShiftLengthBits,
plvTdi, plvTdoCaptured, plvTdoExpected, plvTdoMask,
ucEndState, lRunTestTime, ucMaxRepeat ) );
}
@ -1052,8 +1056,9 @@ void xsvfDoSDRMasking( lenVal* plvTdi,
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo )
int xsvfDoIllegalCmd( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
(void)gpio;
XSVFDBG_PRINTF2( 0, "ERROR: Encountered unsupported command #%d (%s)\n",
((unsigned int)(pXsvfInfo->ucCommand)),
((pXsvfInfo->ucCommand < XLASTCMD)
@ -1070,8 +1075,9 @@ int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo )
int xsvfDoXCOMPLETE( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
(void)gpio;
pXsvfInfo->ucComplete = 1;
return( XSVF_ERROR_NONE );
}
@ -1083,8 +1089,9 @@ int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo )
int xsvfDoXTDOMASK( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
(void)gpio;
readVal( &(pXsvfInfo->lvTdoMask), pXsvfInfo->sShiftLengthBytes );
XSVFDBG_PRINTF( 4, " TDO Mask = ");
XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvTdoMask) );
@ -1101,7 +1108,7 @@ int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXSIR( SXsvfInfo* pXsvfInfo )
int xsvfDoXSIR( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
unsigned char ucShiftIrBits;
short sShiftIrBytes;
@ -1123,7 +1130,7 @@ int xsvfDoXSIR( SXsvfInfo* pXsvfInfo )
readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( ucShiftIrBits ) );
/* Shift the data */
iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR,
iErrorCode = xsvfShift( gpio, &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR,
ucShiftIrBits, &(pXsvfInfo->lvTdi),
/*plvTdoCaptured*/0, /*plvTdoExpected*/0,
/*plvTdoMask*/0, pXsvfInfo->ucEndIR,
@ -1146,7 +1153,7 @@ int xsvfDoXSIR( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo )
int xsvfDoXSIR2( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
long lShiftIrBits;
short sShiftIrBytes;
@ -1168,7 +1175,7 @@ int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo )
readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( lShiftIrBits ) );
/* Shift the data */
iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR,
iErrorCode = xsvfShift( gpio, &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR,
lShiftIrBits, &(pXsvfInfo->lvTdi),
/*plvTdoCaptured*/0, /*plvTdoExpected*/0,
/*plvTdoMask*/0, pXsvfInfo->ucEndIR,
@ -1192,12 +1199,12 @@ int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXSDR( SXsvfInfo* pXsvfInfo )
int xsvfDoXSDR( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
int iErrorCode;
readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes );
/* use TDOExpected from last XSDRTDO instruction */
iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR,
iErrorCode = xsvfShift( gpio, &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR,
pXsvfInfo->lShiftLengthBits, &(pXsvfInfo->lvTdi),
&(pXsvfInfo->lvTdoCaptured),
&(pXsvfInfo->lvTdoExpected),
@ -1217,8 +1224,9 @@ int xsvfDoXSDR( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo )
int xsvfDoXRUNTEST( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
(void)gpio;
readVal( &(pXsvfInfo->lvTdi), 4 );
pXsvfInfo->lRunTestTime = value( &(pXsvfInfo->lvTdi) );
XSVFDBG_PRINTF1( 3, " XRUNTEST = %ld\n", pXsvfInfo->lRunTestTime );
@ -1232,8 +1240,9 @@ int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo )
int xsvfDoXREPEAT( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
(void)gpio;
readByte( &(pXsvfInfo->ucMaxRepeat) );
XSVFDBG_PRINTF1( 3, " XREPEAT = %d\n",
((unsigned int)(pXsvfInfo->ucMaxRepeat)) );
@ -1247,8 +1256,9 @@ int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo )
int xsvfDoXSDRSIZE( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
(void)gpio;
int iErrorCode;
iErrorCode = XSVF_ERROR_NONE;
readVal( &(pXsvfInfo->lvTdi), 4 );
@ -1272,10 +1282,10 @@ int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo )
int xsvfDoXSDRTDO( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
int iErrorCode;
iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
iErrorCode = xsvfBasicXSDRTDO( gpio, &(pXsvfInfo->ucTapState),
pXsvfInfo->lShiftLengthBits,
pXsvfInfo->sShiftLengthBytes,
&(pXsvfInfo->lvTdi),
@ -1303,8 +1313,9 @@ int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo )
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
#ifdef XSVF_SUPPORT_COMPRESSION
int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo )
int xsvfDoXSETSDRMASKS( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
(void)gpio;
/* read the addressMask */
readVal( &(pXsvfInfo->lvAddressMask), pXsvfInfo->sShiftLengthBytes );
/* read the dataMask */
@ -1338,7 +1349,7 @@ int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo )
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
#ifdef XSVF_SUPPORT_COMPRESSION
int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo )
int xsvfDoXSDRINC( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
int iErrorCode;
int iDataMaskLen;
@ -1347,7 +1358,7 @@ int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo )
unsigned char i;
readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes );
iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR,
iErrorCode = xsvfShift( gpio, &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR,
pXsvfInfo->lShiftLengthBits,
&(pXsvfInfo->lvTdi), &(pXsvfInfo->lvTdoCaptured),
&(pXsvfInfo->lvTdoExpected),
@ -1379,7 +1390,7 @@ int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo )
&(pXsvfInfo->lvNextData),
&(pXsvfInfo->lvAddressMask),
&(pXsvfInfo->lvDataMask) );
iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState),
iErrorCode = xsvfShift( gpio, &(pXsvfInfo->ucTapState),
XTAPSTATE_SHIFTDR,
pXsvfInfo->lShiftLengthBits,
&(pXsvfInfo->lvTdi),
@ -1410,13 +1421,13 @@ int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo )
int xsvfDoXSDRBCE( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
unsigned char ucEndDR;
int iErrorCode;
ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRE ) ?
pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR);
iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
iErrorCode = xsvfBasicXSDRTDO( gpio, &(pXsvfInfo->ucTapState),
pXsvfInfo->lShiftLengthBits,
pXsvfInfo->sShiftLengthBytes,
&(pXsvfInfo->lvTdi),
@ -1441,13 +1452,13 @@ int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo )
int xsvfDoXSDRTDOBCE( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
unsigned char ucEndDR;
int iErrorCode;
ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRTDOE ) ?
pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR);
iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
iErrorCode = xsvfBasicXSDRTDO( gpio, &(pXsvfInfo->ucTapState),
pXsvfInfo->lShiftLengthBits,
pXsvfInfo->sShiftLengthBytes,
&(pXsvfInfo->lvTdi),
@ -1470,12 +1481,12 @@ int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo )
int xsvfDoXSTATE( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
unsigned char ucNextState;
int iErrorCode;
readByte( &ucNextState );
iErrorCode = xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucNextState );
iErrorCode = xsvfGotoTapState( gpio, &(pXsvfInfo->ucTapState), ucNextState );
if ( iErrorCode != XSVF_ERROR_NONE )
{
pXsvfInfo->iErrorCode = iErrorCode;
@ -1492,8 +1503,9 @@ int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo )
int xsvfDoXENDXR( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
(void)gpio;
int iErrorCode;
unsigned char ucEndState;
@ -1549,8 +1561,10 @@ int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo )
int xsvfDoXCOMMENT( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
(void)gpio;
/* Use the comment for debugging */
/* Otherwise, read through the comment to the end '\0' and ignore */
unsigned char ucText;
@ -1587,7 +1601,7 @@ int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - XSVF information pointer.
* Returns: int - 0 = success; non-zero = error.
*****************************************************************************/
int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo )
int xsvfDoXWAIT( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
unsigned char ucWaitState;
unsigned char ucEndState;
@ -1611,16 +1625,16 @@ int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo )
/* If not already in <wait_state>, go to <wait_state> */
if ( pXsvfInfo->ucTapState != ucWaitState )
{
xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucWaitState );
xsvfGotoTapState( gpio, &(pXsvfInfo->ucTapState), ucWaitState );
}
/* Wait for <wait_time> microseconds */
waitTime( lWaitTime );
waitTime( gpio, lWaitTime );
/* If not already in <end_state>, go to <end_state> */
if ( pXsvfInfo->ucTapState != ucEndState )
{
xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucEndState );
xsvfGotoTapState( gpio, &(pXsvfInfo->ucTapState), ucEndState );
}
return( XSVF_ERROR_NONE );
@ -1641,7 +1655,7 @@ int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - ptr to the XSVF information.
* Returns: int - 0 = success; otherwise error.
*****************************************************************************/
int xsvfInitialize( SXsvfInfo* pXsvfInfo )
int xsvfInitialize( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
/* Initialize values */
pXsvfInfo->iErrorCode = xsvfInfoInit( pXsvfInfo );
@ -1649,7 +1663,7 @@ int xsvfInitialize( SXsvfInfo* pXsvfInfo )
if ( !pXsvfInfo->iErrorCode )
{
/* Initialize the TAPs */
pXsvfInfo->iErrorCode = xsvfGotoTapState( &(pXsvfInfo->ucTapState),
pXsvfInfo->iErrorCode = xsvfGotoTapState( gpio, &(pXsvfInfo->ucTapState),
XTAPSTATE_RESET );
}
@ -1666,7 +1680,7 @@ int xsvfInitialize( SXsvfInfo* pXsvfInfo )
* Parameters: pXsvfInfo - ptr to the XSVF information.
* Returns: int - 0 = success; otherwise error.
*****************************************************************************/
int xsvfRun( SXsvfInfo* pXsvfInfo )
int xsvfRun( jtag_gpio_t* const gpio, SXsvfInfo* pXsvfInfo )
{
/* Process the XSVF commands */
if ( (!pXsvfInfo->iErrorCode) && (!pXsvfInfo->ucComplete) )
@ -1682,12 +1696,12 @@ int xsvfRun( SXsvfInfo* pXsvfInfo )
xsvf_pzCommandName[pXsvfInfo->ucCommand] );
/* If your compiler cannot take this form,
then convert to a switch statement */
xsvf_pfDoCmd[ pXsvfInfo->ucCommand ]( pXsvfInfo );
xsvf_pfDoCmd[ pXsvfInfo->ucCommand ]( gpio, pXsvfInfo );
}
else
{
/* Illegal command value. Func sets error code. */
xsvfDoIllegalCmd( pXsvfInfo );
xsvfDoIllegalCmd( gpio, pXsvfInfo );
}
}
@ -1717,15 +1731,15 @@ void xsvfCleanup( SXsvfInfo* pXsvfInfo )
* Parameters: none.
* Returns: int - Legacy result values: 1 == success; 0 == failed.
*****************************************************************************/
int xsvfExecute()
int xsvfExecute(jtag_gpio_t* const gpio)
{
SXsvfInfo xsvfInfo;
xsvfInitialize( &xsvfInfo );
xsvfInitialize( gpio, &xsvfInfo );
while ( !xsvfInfo.iErrorCode && (!xsvfInfo.ucComplete) )
{
xsvfRun( &xsvfInfo );
xsvfRun( gpio, &xsvfInfo );
}
if ( xsvfInfo.iErrorCode )

View File

@ -13,6 +13,8 @@
#ifndef XSVF_MICRO_H
#define XSVF_MICRO_H
#include "cpld_jtag.h"
/* Legacy error codes for xsvfExecute from original XSVF player v2.0 */
#define XSVF_LEGACY_SUCCESS 1
#define XSVF_LEGACY_ERROR 0
@ -36,7 +38,7 @@
* Parameters: none.
* Returns: int - For error codes see above.
*****************************************************************************/
extern int xsvfExecute();
extern int xsvfExecute(jtag_gpio_t* const gpio);
#endif /* XSVF_MICRO_H */

View File

@ -11,9 +11,10 @@
/*******************************************************/
#include "ports.h"
#include "../hackrf_core.h"
#include "../cpld_jtag.h"
#include <libopencm3/lpc43xx/gpio.h>
#include "hackrf_core.h"
#include "cpld_jtag.h"
#include "gpio.h"
void delay_jtag(uint32_t duration)
{
@ -38,23 +39,23 @@ void delay_jtag(uint32_t duration)
/* setPort: Implement to set the named JTAG signal (p) to the new value (v).*/
/* if in debugging mode, then just set the variables */
void setPort(short p,short val)
void setPort(jtag_gpio_t* const gpio, short p, short val)
{
if (p==TMS) {
if (val)
gpio_set(PORT_CPLD_TMS, PIN_CPLD_TMS);
gpio_set(gpio->gpio_tms);
else
gpio_clear(PORT_CPLD_TMS, PIN_CPLD_TMS);
gpio_clear(gpio->gpio_tms);
} if (p==TDI) {
if (val)
gpio_set(PORT_CPLD_TDI, PIN_CPLD_TDI);
gpio_set(gpio->gpio_tdi);
else
gpio_clear(PORT_CPLD_TDI, PIN_CPLD_TDI);
gpio_clear(gpio->gpio_tdi);
} if (p==TCK) {
if (val)
gpio_set(PORT_CPLD_TCK, PIN_CPLD_TCK);
gpio_set(gpio->gpio_tck);
else
gpio_clear(PORT_CPLD_TCK, PIN_CPLD_TCK);
gpio_clear(gpio->gpio_tck);
}
/* conservative delay */
@ -63,11 +64,11 @@ void setPort(short p,short val)
/* toggle tck LH. No need to modify this code. It is output via setPort. */
void pulseClock()
void pulseClock(jtag_gpio_t* const gpio)
{
setPort(TCK,0); /* set the TCK port to low */
setPort(gpio, TCK,0); /* set the TCK port to low */
delay_jtag(200);
setPort(TCK,1); /* set the TCK port to high */
setPort(gpio, TCK,1); /* set the TCK port to high */
delay_jtag(200);
}
@ -81,10 +82,10 @@ void readByte(unsigned char *data)
/* readTDOBit: Implement to return the current value of the JTAG TDO signal.*/
/* read the TDO bit from port */
unsigned char readTDOBit()
unsigned char readTDOBit(jtag_gpio_t* const gpio)
{
delay_jtag(2000);
return CPLD_TDO_STATE;
return gpio_read(gpio->gpio_tdo);;
}
/* waitTime: Implement as follows: */
@ -96,7 +97,7 @@ unsigned char readTDOBit()
/* RECOMMENDED IMPLEMENTATION: Pulse TCK at least microsec times AND */
/* continue pulsing TCK until the microsec wait */
/* requirement is also satisfied. */
void waitTime(long microsec)
void waitTime(jtag_gpio_t* const gpio, long microsec)
{
static long tckCyclesPerMicrosec = 1; /* must be at least 1 */
long tckCycles = microsec * tckCyclesPerMicrosec;
@ -108,6 +109,6 @@ void waitTime(long microsec)
in order to satisfy the microsec wait time requirement. */
for ( i = 0; i < tckCycles; ++i )
{
pulseClock();
pulseClock(gpio);
}
}

View File

@ -7,6 +7,8 @@
#ifndef ports_dot_h
#define ports_dot_h
#include "cpld_jtag.h"
/* these constants are used to send the appropriate ports to setPort */
/* they should be enumerated types, but some of the microcontroller */
/* compilers don't like enumerated types */
@ -15,17 +17,17 @@
#define TDI (short) 2
/* set the port "p" (TCK, TMS, or TDI) to val (0 or 1) */
extern void setPort(short p, short val);
extern void setPort(jtag_gpio_t* const gpio, short p, short val);
/* read the TDO bit and store it in val */
extern unsigned char readTDOBit();
extern unsigned char readTDOBit(jtag_gpio_t* const gpio);
/* make clock go down->up->down*/
extern void pulseClock();
extern void pulseClock(jtag_gpio_t* const gpio);
/* read the next byte of data from the xsvf file */
extern void readByte(unsigned char *data);
extern void waitTime(long microsec);
extern void waitTime(jtag_gpio_t* const gpio, long microsec);
#endif

56
firmware/dfu-util.cmake Normal file
View File

@ -0,0 +1,56 @@
#
# Copyright 2015 Dominic Spill <dominicgs@gmail.com>
#
# This file is part of GreatFET.
#
# 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 2, 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; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
execute_process(
COMMAND dfu-suffix -V
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE DFU_NOT_FOUND
ERROR_QUIET
OUTPUT_VARIABLE DFU_VERSION_STRING
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(DFU_ALL "")
if(NOT DFU_NOT_FOUND)
string(REGEX REPLACE ".*([0-9]+)\\.[0-9]+.*" "\\1" DFU_VERSION_MAJOR "${DFU_VERSION_STRING}")
string(REGEX REPLACE ".*[0-9]+\\.([0-9])+.*" "\\1" DFU_VERSION_MINOR "${DFU_VERSION_STRING}")
MESSAGE( STATUS "DFU utils version: " ${DFU_VERSION_MAJOR} "." ${DFU_VERSION_MINOR})
execute_process(
COMMAND dfu-prefix -V
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE DFU_PREFIX_NOT_FOUND
ERROR_QUIET
OUTPUT_VARIABLE DFU_PREFIX_VERSION_STRING
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(DFU_PREFIX_NOT_FOUND)
set(DFU_COMMAND dfu-suffix --vid=0x1fc9 --pid=0x000c --did=0x0 -s 0 -a _tmp.dfu)
else(DFU_PREFIX_NOT_FOUND)
set(DFU_COMMAND dfu-suffix --vid=0x1fc9 --pid=0x000c --did=0x0 -a _tmp.dfu && dfu-prefix -s 0 -a _tmp.dfu)
endif(DFU_PREFIX_NOT_FOUND)
set(DFU_ALL "ALL")
else(NOT DFU_NOT_FOUND)
MESSAGE(STATUS "dfu-suffix not found: not building DFU file")
endif(NOT DFU_NOT_FOUND)

View File

@ -3,6 +3,7 @@
# Copyright 2012 Michael Ossmann <mike@ossmann.com>
# Copyright 2012 Benjamin Vernoux <titanmkd@gmail.com>
# Copyright 2012 Jared Boone <jared@sharebrained.com>
# Copyright 2016 Dominic Spill <dominicgs@gmail.com>
#
# This file is part of HackRF.
#
@ -26,6 +27,8 @@
enable_language(C CXX ASM)
include(../dfu-util.cmake)
SET(PATH_HACKRF ../..)
SET(PATH_HACKRF_FIRMWARE ${PATH_HACKRF}/firmware)
SET(PATH_HACKRF_FIRMWARE_COMMON ${PATH_HACKRF_FIRMWARE}/common)
@ -49,10 +52,6 @@ if(NOT DEFINED BOARD)
set(BOARD HACKRF_ONE)
endif()
if(NOT DEFINED RUN_FROM)
set(RUN_FROM SPIFI)
endif()
if(BOARD STREQUAL "HACKRF_ONE")
set(MCU_PARTNO LPC4320)
else()
@ -69,15 +68,11 @@ if(NOT DEFINED SRC_M0)
set(SRC_M0 "${PATH_HACKRF_FIRMWARE_COMMON}/m0_sleep.c")
endif()
SET(HACKRF_OPTS "-D${BOARD} -DLPC43XX -D${MCU_PARTNO} -DTX_ENABLE -D'VERSION_STRING=\"git-${VERSION}\"' -DRUN_FROM=${RUN_FROM}")
SET(HACKRF_OPTS "-D${BOARD} -DLPC43XX -D${MCU_PARTNO} -DTX_ENABLE -D'VERSION_STRING=\"git-${VERSION}\"'")
SET(LDSCRIPT_M4 "-T${PATH_HACKRF_FIRMWARE_COMMON}/${MCU_PARTNO}_M4_memory.ld")
if( RUN_FROM STREQUAL "RAM")
SET(LDSCRIPT_M4 "${LDSCRIPT_M4} -Tlibopencm3_lpc43xx.ld")
else()
SET(LDSCRIPT_M4 "${LDSCRIPT_M4} -Tlibopencm3_lpc43xx_rom_to_ram.ld")
endif()
SET(LDSCRIPT_M4 "${LDSCRIPT_M4} -T${PATH_HACKRF_FIRMWARE_COMMON}/LPC43xx_M4_M0_image_from_text.ld")
SET(LDSCRIPT_M4 "-T${PATH_HACKRF_FIRMWARE_COMMON}/${MCU_PARTNO}_M4_memory.ld -Tlibopencm3_lpc43xx_rom_to_ram.ld -T${PATH_HACKRF_FIRMWARE_COMMON}/LPC43xx_M4_M0_image_from_text.ld")
SET(LDSCRIPT_M4_DFU "-T${PATH_HACKRF_FIRMWARE_COMMON}/${MCU_PARTNO}_M4_memory.ld -Tlibopencm3_lpc43xx.ld -T${PATH_HACKRF_FIRMWARE_COMMON}/LPC43xx_M4_M0_image_from_text.ld")
SET(LDSCRIPT_M0 "-T${PATH_HACKRF_FIRMWARE_COMMON}/LPC43xx_M0_memory.ld -Tlibopencm3_lpc43xx_m0.ld")
@ -97,6 +92,7 @@ SET(CPUFLAGS_M4 "-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16")
SET(CFLAGS_M4 "-std=gnu99 ${CFLAGS_COMMON} ${CPUFLAGS_M4} -DLPC43XX_M4")
SET(CXXFLAGS_M4 "-std=gnu++0x ${CFLAGS_COMMON} ${CPUFLAGS_M4} -DLPC43XX_M4")
SET(LDFLAGS_M4 "${LDFLAGS_COMMON} ${CPUFLAGS_M4} ${LDSCRIPT_M4} -Xlinker -Map=m4.map")
SET(LDFLAGS_M4_DFU "${LDFLAGS_COMMON} ${CPUFLAGS_M4} ${LDSCRIPT_M4_DFU} -Xlinker -Map=m4.map")
set(BUILD_SHARED_LIBS OFF)
@ -104,6 +100,27 @@ include_directories("${LIBOPENCM3}/include/")
include_directories("${PATH_HACKRF_FIRMWARE_COMMON}")
macro(DeclareTargets)
SET(SRC_M4
${SRC_M4}
${PATH_HACKRF_FIRMWARE_COMMON}/hackrf_core.c
${PATH_HACKRF_FIRMWARE_COMMON}/sgpio.c
${PATH_HACKRF_FIRMWARE_COMMON}/rf_path.c
${PATH_HACKRF_FIRMWARE_COMMON}/si5351c.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2837.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2837_target.c
${PATH_HACKRF_FIRMWARE_COMMON}/max5864.c
${PATH_HACKRF_FIRMWARE_COMMON}/max5864_target.c
${PATH_HACKRF_FIRMWARE_COMMON}/${MIXER}.c
${PATH_HACKRF_FIRMWARE_COMMON}/i2c_bus.c
${PATH_HACKRF_FIRMWARE_COMMON}/i2c_lpc.c
${PATH_HACKRF_FIRMWARE_COMMON}/${MIXER}_spi.c
${PATH_HACKRF_FIRMWARE_COMMON}/w25q80bv.c
${PATH_HACKRF_FIRMWARE_COMMON}/w25q80bv_target.c
${PATH_HACKRF_FIRMWARE_COMMON}/spi_bus.c
${PATH_HACKRF_FIRMWARE_COMMON}/spi_ssp.c
${PATH_HACKRF_FIRMWARE_COMMON}/gpio_lpc.c
)
configure_file(
${PATH_HACKRF_FIRMWARE_COMMON}/m0_bin.s.cmake
m0_bin.s
@ -134,19 +151,13 @@ macro(DeclareTargets)
COMMAND ${CMAKE_OBJCOPY} -Obinary ${PROJECT_NAME}_m0.elf ${PROJECT_NAME}_m0.bin
)
add_executable(${PROJECT_NAME}.elf
${SRC_M4}
${PATH_HACKRF_FIRMWARE_COMMON}/hackrf_core.c
${PATH_HACKRF_FIRMWARE_COMMON}/sgpio.c
${PATH_HACKRF_FIRMWARE_COMMON}/rf_path.c
${PATH_HACKRF_FIRMWARE_COMMON}/si5351c.c
${PATH_HACKRF_FIRMWARE_COMMON}/max2837.c
${PATH_HACKRF_FIRMWARE_COMMON}/max5864.c
${PATH_HACKRF_FIRMWARE_COMMON}/${MIXER}.c
m0_bin.s
)
# Object files to be linked for both DFU and SPI flash versions
add_library(${PROJECT_NAME}_objects OBJECT ${SRC_M4} m0_bin.s)
set_target_properties(${PROJECT_NAME}_objects PROPERTIES COMPILE_FLAGS "${CFLAGS_M4}")
add_dependencies(${PROJECT_NAME}_objects ${PROJECT_NAME}_m0.bin)
add_dependencies(${PROJECT_NAME}.elf ${PROJECT_NAME}_m0.bin)
# SPI flash version
add_executable(${PROJECT_NAME}.elf $<TARGET_OBJECTS:${PROJECT_NAME}_objects>)
target_link_libraries(
${PROJECT_NAME}.elf
@ -156,15 +167,33 @@ macro(DeclareTargets)
m
)
set_target_properties(${PROJECT_NAME}.elf PROPERTIES COMPILE_FLAGS "${CFLAGS_M4}")
set_target_properties(${PROJECT_NAME}.elf PROPERTIES LINK_FLAGS "${LDFLAGS_M4}")
add_custom_target(
${PROJECT_NAME}.bin
${PROJECT_NAME}.bin ALL
DEPENDS ${PROJECT_NAME}.elf
COMMAND ${CMAKE_OBJCOPY} -Obinary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin
)
# DFU - using a differnet LD script to run directly from RAM
add_executable(${PROJECT_NAME}_dfu.elf $<TARGET_OBJECTS:${PROJECT_NAME}_objects>)
target_link_libraries(
${PROJECT_NAME}_dfu.elf
c
nosys
opencm3_lpc43xx
m
)
set_target_properties(${PROJECT_NAME}_dfu.elf PROPERTIES LINK_FLAGS "${LDFLAGS_M4_DFU}")
add_custom_target(
${PROJECT_NAME}_dfu.bin
DEPENDS ${PROJECT_NAME}_dfu.elf
COMMAND ${CMAKE_OBJCOPY} -Obinary ${PROJECT_NAME}_dfu.elf ${PROJECT_NAME}_dfu.bin
)
add_custom_target(
${PROJECT_NAME}.dfu ALL
DEPENDS ${PROJECT_NAME}.bin

View File

@ -44,7 +44,6 @@ set(SRC_M4
usb_api_transceiver.c
"${PATH_HACKRF_FIRMWARE_COMMON}/usb_queue.c"
"${PATH_HACKRF_FIRMWARE_COMMON}/fault_handler.c"
"${PATH_HACKRF_FIRMWARE_COMMON}/w25q80bv.c"
"${PATH_HACKRF_FIRMWARE_COMMON}/cpld_jtag.c"
"${PATH_HACKRF_FIRMWARE_COMMON}/xapp058/lenval.c"
"${PATH_HACKRF_FIRMWARE_COMMON}/xapp058/micro.c"

View File

@ -24,7 +24,6 @@
#include <libopencm3/cm3/vector.h>
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/m4/nvic.h>
#include <streaming.h>
@ -43,18 +42,15 @@
#include "usb_api_spiflash.h"
#include "usb_api_transceiver.h"
#include "rf_path.h"
#include "sgpio_isr.h"
#include "usb_bulk_buffer.h"
#include "si5351c.h"
#include "w25q80bv.h"
#include "hackrf-ui.h"
static volatile transceiver_mode_t _transceiver_mode = TRANSCEIVER_MODE_OFF;
void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) {
baseband_streaming_disable();
baseband_streaming_disable(&sgpio_config);
usb_endpoint_disable(&usb_endpoint_bulk_in);
usb_endpoint_disable(&usb_endpoint_bulk_out);
@ -62,27 +58,27 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) {
_transceiver_mode = new_transceiver_mode;
if( _transceiver_mode == TRANSCEIVER_MODE_RX ) {
gpio_clear(PORT_LED1_3, PIN_LED3);
gpio_set(PORT_LED1_3, PIN_LED2);
led_off(LED3);
led_on(LED2);
usb_endpoint_init(&usb_endpoint_bulk_in);
rf_path_set_direction(RF_PATH_DIRECTION_RX);
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_RX);
vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx;
} else if (_transceiver_mode == TRANSCEIVER_MODE_TX) {
gpio_clear(PORT_LED1_3, PIN_LED2);
gpio_set(PORT_LED1_3, PIN_LED3);
led_off(LED2);
led_on(LED3);
usb_endpoint_init(&usb_endpoint_bulk_out);
rf_path_set_direction(RF_PATH_DIRECTION_TX);
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_TX);
vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_tx;
} else {
gpio_clear(PORT_LED1_3, PIN_LED2);
gpio_clear(PORT_LED1_3, PIN_LED3);
rf_path_set_direction(RF_PATH_DIRECTION_OFF);
led_off(LED2);
led_off(LED3);
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_OFF);
vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx;
}
if( _transceiver_mode != TRANSCEIVER_MODE_OFF ) {
si5351c_activate_best_clock_source();
baseband_streaming_enable();
si5351c_activate_best_clock_source(&clock_gen);
baseband_streaming_enable(&sgpio_config);
}
}
@ -150,6 +146,7 @@ static const usb_request_handler_fn vendor_request_handler[] = {
NULL,
#endif
usb_vendor_request_set_freq_explicit,
usb_vendor_request_read_wcid, // USB_WCID_VENDOR_REQ
};
static const uint32_t vendor_request_handler_count =
@ -186,16 +183,11 @@ void usb_configuration_changed(
if( device->configuration->number == 1 ) {
// transceiver configuration
cpu_clock_pll1_max_speed();
gpio_set(PORT_LED1_3, PIN_LED1);
} else if( device->configuration->number == 2 ) {
// CPLD update configuration
cpu_clock_pll1_max_speed();
usb_endpoint_init(&usb_endpoint_bulk_out);
start_cpld_update = true;
led_on(LED1);
} else {
/* Configuration number equal 0 means usb bus reset. */
cpu_clock_pll1_low_speed();
gpio_clear(PORT_LED1_3, PIN_LED1);
led_off(LED1);
}
}
@ -233,9 +225,6 @@ int main(void) {
#endif
cpu_clock_init();
/* Code is not running from SPI flash, initialize for flash read/write over USB */
w25q80bv_setup();
usb_set_descriptor_by_serial_number();
usb_set_configuration_changed_cb(usb_configuration_changed);
@ -257,11 +246,7 @@ int main(void) {
usb_run(&usb_device);
ssp1_init();
rf_path_init();
rf_path_init(&rf_path);
unsigned int phase = 0;
while(true) {

View File

@ -22,8 +22,6 @@
#include "usb_api_cpld.h"
#include <libopencm3/lpc43xx/gpio.h>
#include <hackrf_core.h>
#include <cpld_jtag.h>
#include <usb_queue.h>
@ -63,7 +61,6 @@ static void refill_cpld_buffer(void)
void cpld_update(void)
{
#define WAIT_LOOP_DELAY (6000000)
#define ALL_LEDS (PIN_LED1|PIN_LED2|PIN_LED3)
int i;
int error;
@ -72,7 +69,7 @@ void cpld_update(void)
refill_cpld_buffer();
error = cpld_jtag_program(sizeof(cpld_xsvf_buffer),
error = cpld_jtag_program(&jtag_cpld, sizeof(cpld_xsvf_buffer),
cpld_xsvf_buffer,
refill_cpld_buffer);
if(error == 0)
@ -80,17 +77,21 @@ void cpld_update(void)
/* blink LED1, LED2, and LED3 on success */
while (1)
{
gpio_set(PORT_LED1_3, ALL_LEDS); /* LEDs on */
led_on(LED1);
led_on(LED2);
led_on(LED3);
for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */
__asm__("nop");
gpio_clear(PORT_LED1_3, ALL_LEDS); /* LEDs off */
led_off(LED1);
led_off(LED2);
led_off(LED3);
for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */
__asm__("nop");
}
}else
{
/* LED3 (Red) steady on error */
gpio_set(PORT_LED1_3, PIN_LED3); /* LEDs on */
led_on(LED3);
while (1);
}
}

View File

@ -22,17 +22,16 @@
#include "usb_api_register.h"
#include <hackrf_core.h>
#include <usb_queue.h>
#include <max2837.h>
#include <si5351c.h>
#ifndef RAD1O
#include <rffc5071.h>
#endif
#include <stddef.h>
#include <stdint.h>
#include <hackrf_core.h>
usb_request_status_t usb_vendor_request_write_max2837(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage
@ -40,7 +39,7 @@ usb_request_status_t usb_vendor_request_write_max2837(
if( stage == USB_TRANSFER_STAGE_SETUP ) {
if( endpoint->setup.index < MAX2837_NUM_REGS ) {
if( endpoint->setup.value < MAX2837_DATA_REGS_MAX_VALUE ) {
max2837_reg_write(endpoint->setup.index, endpoint->setup.value);
max2837_reg_write(&max2837, endpoint->setup.index, endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK;
}
@ -57,7 +56,7 @@ usb_request_status_t usb_vendor_request_read_max2837(
) {
if( stage == USB_TRANSFER_STAGE_SETUP ) {
if( endpoint->setup.index < MAX2837_NUM_REGS ) {
const uint16_t value = max2837_reg_read(endpoint->setup.index);
const uint16_t value = max2837_reg_read(&max2837, endpoint->setup.index);
endpoint->buffer[0] = value & 0xff;
endpoint->buffer[1] = value >> 8;
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2,
@ -78,7 +77,7 @@ usb_request_status_t usb_vendor_request_write_si5351c(
if( stage == USB_TRANSFER_STAGE_SETUP ) {
if( endpoint->setup.index < 256 ) {
if( endpoint->setup.value < 256 ) {
si5351c_write_single(endpoint->setup.index, endpoint->setup.value);
si5351c_write_single(&clock_gen, endpoint->setup.index, endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK;
}
@ -95,7 +94,7 @@ usb_request_status_t usb_vendor_request_read_si5351c(
) {
if( stage == USB_TRANSFER_STAGE_SETUP ) {
if( endpoint->setup.index < 256 ) {
const uint8_t value = si5351c_read_single(endpoint->setup.index);
const uint8_t value = si5351c_read_single(&clock_gen, endpoint->setup.index);
endpoint->buffer[0] = value;
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1,
NULL, NULL);
@ -117,7 +116,7 @@ usb_request_status_t usb_vendor_request_write_rffc5071(
{
if( endpoint->setup.index < RFFC5071_NUM_REGS )
{
rffc5071_reg_write(endpoint->setup.index, endpoint->setup.value);
rffc5071_reg_write(&rffc5072, endpoint->setup.index, endpoint->setup.value);
usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK;
}
@ -136,7 +135,7 @@ usb_request_status_t usb_vendor_request_read_rffc5071(
{
if( endpoint->setup.index < RFFC5071_NUM_REGS )
{
value = rffc5071_reg_read(endpoint->setup.index);
value = rffc5071_reg_read(&rffc5072, endpoint->setup.index);
endpoint->buffer[0] = value & 0xff;
endpoint->buffer[1] = value >> 8;
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2,

View File

@ -26,16 +26,21 @@
#include <stddef.h>
#include <hackrf_core.h>
#include <w25q80bv.h>
uint8_t spiflash_buffer[W25Q80BV_PAGE_LEN];
/* Buffer size == spi_flash.page_len */
uint8_t spiflash_buffer[256U];
usb_request_status_t usb_vendor_request_erase_spiflash(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
{
if (stage == USB_TRANSFER_STAGE_SETUP) {
spi_bus_start(spi_flash.bus, &ssp_config_w25q80bv);
w25q80bv_setup(&spi_flash);
/* only chip erase is implemented */
w25q80bv_chip_erase();
w25q80bv_chip_erase(&spi_flash);
usb_transfer_schedule_ack(endpoint->in);
}
return USB_REQUEST_STATUS_OK;
@ -50,23 +55,25 @@ usb_request_status_t usb_vendor_request_write_spiflash(
if (stage == USB_TRANSFER_STAGE_SETUP) {
addr = (endpoint->setup.value << 16) | endpoint->setup.index;
len = endpoint->setup.length;
if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES)
|| ((addr + len) > W25Q80BV_NUM_BYTES)) {
if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes)
|| ((addr + len) > spi_flash.num_bytes)) {
return USB_REQUEST_STATUS_STALL;
} else {
usb_transfer_schedule_block(endpoint->out, &spiflash_buffer[0], len,
NULL, NULL);
spi_bus_start(spi_flash.bus, &ssp_config_w25q80bv);
w25q80bv_setup(&spi_flash);
return USB_REQUEST_STATUS_OK;
}
} else if (stage == USB_TRANSFER_STAGE_DATA) {
addr = (endpoint->setup.value << 16) | endpoint->setup.index;
len = endpoint->setup.length;
/* This check is redundant but makes me feel better. */
if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES)
|| ((addr + len) > W25Q80BV_NUM_BYTES)) {
if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes)
|| ((addr + len) > spi_flash.num_bytes)) {
return USB_REQUEST_STATUS_STALL;
} else {
w25q80bv_program(addr, len, &spiflash_buffer[0]);
w25q80bv_program(&spi_flash, addr, len, &spiflash_buffer[0]);
usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK;
}
@ -85,11 +92,11 @@ usb_request_status_t usb_vendor_request_read_spiflash(
{
addr = (endpoint->setup.value << 16) | endpoint->setup.index;
len = endpoint->setup.length;
if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES)
|| ((addr + len) > W25Q80BV_NUM_BYTES)) {
if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes)
|| ((addr + len) > spi_flash.num_bytes)) {
return USB_REQUEST_STATUS_STALL;
} else {
w25q80bv_read(addr, len, &spiflash_buffer[0]);
w25q80bv_read(&spi_flash, addr, len, &spiflash_buffer[0]);
usb_transfer_schedule_block(endpoint->in, &spiflash_buffer[0], len,
NULL, NULL);
return USB_REQUEST_STATUS_OK;
@ -99,8 +106,8 @@ usb_request_status_t usb_vendor_request_read_spiflash(
addr = (endpoint->setup.value << 16) | endpoint->setup.index;
len = endpoint->setup.length;
/* This check is redundant but makes me feel better. */
if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES)
|| ((addr + len) > W25Q80BV_NUM_BYTES))
if ((len > spi_flash.page_len) || (addr > spi_flash.num_bytes)
|| ((addr + len) > spi_flash.num_bytes))
{
return USB_REQUEST_STATUS_STALL;
} else

View File

@ -22,8 +22,6 @@
#include "usb_api_transceiver.h"
#include <libopencm3/lpc43xx/gpio.h>
#include "hackrf-ui.h"
#include <max2837.h>
@ -127,11 +125,11 @@ usb_request_status_t usb_vendor_request_set_amp_enable(
if (stage == USB_TRANSFER_STAGE_SETUP) {
switch (endpoint->setup.value) {
case 0:
rf_path_set_lna(0);
rf_path_set_lna(&rf_path, 0);
usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK;
case 1:
rf_path_set_lna(1);
rf_path_set_lna(&rf_path, 1);
usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK;
default:
@ -147,7 +145,7 @@ usb_request_status_t usb_vendor_request_set_lna_gain(
const usb_transfer_stage_t stage)
{
if( stage == USB_TRANSFER_STAGE_SETUP ) {
const uint8_t value = max2837_set_lna_gain(endpoint->setup.index);
const uint8_t value = max2837_set_lna_gain(&max2837, endpoint->setup.index);
endpoint->buffer[0] = value;
if(value) hackrf_ui_setBBLNAGain(endpoint->setup.index);
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1,
@ -162,7 +160,7 @@ usb_request_status_t usb_vendor_request_set_vga_gain(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
{
if( stage == USB_TRANSFER_STAGE_SETUP ) {
const uint8_t value = max2837_set_vga_gain(endpoint->setup.index);
const uint8_t value = max2837_set_vga_gain(&max2837, endpoint->setup.index);
endpoint->buffer[0] = value;
if(value) hackrf_ui_setBBVGAGain(endpoint->setup.index);
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1,
@ -177,7 +175,7 @@ usb_request_status_t usb_vendor_request_set_txvga_gain(
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
{
if( stage == USB_TRANSFER_STAGE_SETUP ) {
const uint8_t value = max2837_set_txvga_gain(endpoint->setup.index);
const uint8_t value = max2837_set_txvga_gain(&max2837, endpoint->setup.index);
endpoint->buffer[0] = value;
if(value) hackrf_ui_setBBTXVGAGain(endpoint->setup.index);
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1,
@ -194,11 +192,11 @@ usb_request_status_t usb_vendor_request_set_antenna_enable(
if (stage == USB_TRANSFER_STAGE_SETUP) {
switch (endpoint->setup.value) {
case 0:
rf_path_set_antenna(0);
rf_path_set_antenna(&rf_path, 0);
usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK;
case 1:
rf_path_set_antenna(1);
rf_path_set_antenna(&rf_path, 1);
usb_transfer_schedule_ack(endpoint->in);
return USB_REQUEST_STATUS_OK;
default:

View File

@ -57,11 +57,11 @@ uint8_t usb_descriptor_device[] = {
USB_MAX_PACKET0, // bMaxPacketSize0
USB_WORD(USB_VENDOR_ID), // idVendor
USB_WORD(USB_PRODUCT_ID), // idProduct
USB_WORD(0x0100), // bcdDevice
USB_WORD(0x0101), // bcdDevice
0x01, // iManufacturer
0x02, // iProduct
0x05, // iSerialNumber
0x02 // bNumConfigurations
0x04, // iSerialNumber
0x01 // bNumConfigurations
};
uint8_t usb_descriptor_device_qualifier[] = {
@ -72,7 +72,7 @@ uint8_t usb_descriptor_device_qualifier[] = {
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
64, // bMaxPacketSize0
0x02, // bNumOtherSpeedConfigurations
0x01, // bNumOtherSpeedConfigurations
0x00 // bReserved
};
@ -150,79 +150,6 @@ uint8_t usb_descriptor_configuration_high_speed[] = {
0, // TERMINATOR
};
uint8_t usb_descriptor_configuration_cpld_update_full_speed[] = {
9, // bLength
USB_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType
USB_WORD(32), // wTotalLength
0x01, // bNumInterfaces
0x02, // bConfigurationValue
0x04, // iConfiguration
0x80, // bmAttributes: USB-powered
250, // bMaxPower: 500mA
9, // bLength
USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType
0x00, // bInterfaceNumber
0x00, // bAlternateSetting
0x02, // bNumEndpoints
0xFF, // bInterfaceClass: vendor-specific
0xFF, // bInterfaceSubClass
0xFF, // bInterfaceProtocol: vendor-specific
0x00, // iInterface
7, // bLength
USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType
USB_BULK_IN_EP_ADDR, // bEndpointAddress
0x02, // bmAttributes: BULK
USB_WORD(USB_MAX_PACKET_BULK_FS), // wMaxPacketSize
0x00, // bInterval: no NAK
7, // bLength
USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType
USB_BULK_OUT_EP_ADDR, // bEndpointAddress
0x02, // bmAttributes: BULK
USB_WORD(USB_MAX_PACKET_BULK_FS), // wMaxPacketSize
0x00, // bInterval: no NAK
0, // TERMINATOR
};
uint8_t usb_descriptor_configuration_cpld_update_high_speed[] = {
9, // bLength
USB_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType
USB_WORD(32), // wTotalLength
0x01, // bNumInterfaces
0x02, // bConfigurationValue
0x04, // iConfiguration
0x80, // bmAttributes: USB-powered
250, // bMaxPower: 500mA
9, // bLength
USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType
0x00, // bInterfaceNumber
0x00, // bAlternateSetting
0x02, // bNumEndpoints
0xFF, // bInterfaceClass: vendor-specific
0xFF, // bInterfaceSubClass
0xFF, // bInterfaceProtocol: vendor-specific
0x00, // iInterface
7, // bLength
USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType
USB_BULK_IN_EP_ADDR, // bEndpointAddress
0x02, // bmAttributes: BULK
USB_WORD(USB_MAX_PACKET_BULK_HS), // wMaxPacketSize
0x00, // bInterval: no NAK
7, // bLength
USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType
USB_BULK_OUT_EP_ADDR, // bEndpointAddress
0x02, // bmAttributes: BULK
USB_WORD(USB_MAX_PACKET_BULK_HS), // wMaxPacketSize
0x00, // bInterval: no NAK
0, // TERMINATOR
};
uint8_t usb_descriptor_string_languages[] = {
0x04, // bLength
@ -300,7 +227,7 @@ uint8_t usb_descriptor_string_product[] = {
#endif
};
uint8_t usb_descriptor_string_config1_description[] = {
uint8_t usb_descriptor_string_config_description[] = {
24, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'T', 0x00,
@ -316,21 +243,6 @@ uint8_t usb_descriptor_string_config1_description[] = {
'r', 0x00,
};
uint8_t usb_descriptor_string_config2_description[] = {
24, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'C', 0x00,
'P', 0x00,
'L', 0x00,
'D', 0x00,
' ', 0x00,
'u', 0x00,
'p', 0x00,
'd', 0x00,
'a', 0x00,
't', 0x00,
'e', 0x00,
};
uint8_t usb_descriptor_string_serial_number[USB_DESCRIPTOR_STRING_SERIAL_BUF_LEN];
@ -338,8 +250,34 @@ uint8_t* usb_descriptor_strings[] = {
usb_descriptor_string_languages,
usb_descriptor_string_manufacturer,
usb_descriptor_string_product,
usb_descriptor_string_config1_description,
usb_descriptor_string_config2_description,
usb_descriptor_string_config_description,
usb_descriptor_string_serial_number,
0, // TERMINATOR
};
uint8_t wcid_string_descriptor[] = {
18, // bLength
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
'M', 0x00,
'S', 0x00,
'F', 0x00,
'T', 0x00,
'1', 0x00,
'0', 0x00,
'0', 0x00,
USB_WCID_VENDOR_REQ, // vendor request code for further descriptor
0x00
};
uint8_t wcid_feature_descriptor[] = {
0x28, 0x00, 0x00, 0x00, // bLength
USB_WORD(0x0100), // WCID version
USB_WORD(0x0004), // WICD descriptor index
0x01, //bNumSections
0x00,0x00,0x00,0x00,0x00,0x00,0x00, //Reserved
0x00, //bInterfaceNumber
0x01, //Reserved
'W', 'I', 'N', 'U', 'S', 'B', 0x00,0x00, //Compatible ID, padded with zeros
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //Sub-compatible ID
0x00,0x00,0x00,0x00,0x00,0x00 //Reserved
};

View File

@ -25,8 +25,6 @@ extern uint8_t usb_descriptor_device[];
extern uint8_t usb_descriptor_device_qualifier[];
extern uint8_t usb_descriptor_configuration_full_speed[];
extern uint8_t usb_descriptor_configuration_high_speed[];
extern uint8_t usb_descriptor_configuration_cpld_update_full_speed[];
extern uint8_t usb_descriptor_configuration_cpld_update_high_speed[];
extern uint8_t usb_descriptor_string_languages[];
extern uint8_t usb_descriptor_string_manufacturer[];
extern uint8_t usb_descriptor_string_product[];
@ -36,3 +34,7 @@ extern uint8_t usb_descriptor_string_product[];
extern uint8_t usb_descriptor_string_serial_number[];
extern uint8_t* usb_descriptor_strings[];
#define USB_WCID_VENDOR_REQ 0x19
extern uint8_t wcid_string_descriptor[];
extern uint8_t wcid_feature_descriptor[];

View File

@ -38,23 +38,10 @@ usb_configuration_t usb_configuration_full_speed = {
.descriptor = usb_descriptor_configuration_full_speed,
};
usb_configuration_t usb_configuration_cpld_update_full_speed = {
.number = 2,
.speed = USB_SPEED_FULL,
.descriptor = usb_descriptor_configuration_cpld_update_full_speed,
};
usb_configuration_t usb_configuration_cpld_update_high_speed = {
.number = 2,
.speed = USB_SPEED_HIGH,
.descriptor = usb_descriptor_configuration_cpld_update_high_speed,
};
usb_configuration_t* usb_configurations[] = {
&usb_configuration_high_speed,
&usb_configuration_full_speed,
&usb_configuration_cpld_update_full_speed,
&usb_configuration_cpld_update_high_speed,
0,
};
@ -64,4 +51,6 @@ usb_device_t usb_device = {
.qualifier_descriptor = usb_descriptor_device_qualifier,
.configurations = &usb_configurations,
.configuration = 0,
.wcid_string_descriptor = wcid_string_descriptor,
.wcid_feature_descriptor = wcid_feature_descriptor,
};

View File

@ -19,14 +19,7 @@
* Boston, MA 02110-1301, USA.
*/
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/i2c.h>
#include <libopencm3/lpc43xx/ssp.h>
#include "hackrf_core.h"
#include "max2837.h"
#include "rffc5071.h"
int main(void)
{
@ -38,21 +31,20 @@ int main(void)
enable_rf_power();
#endif
cpu_clock_init();
ssp1_init();
gpio_set(PORT_LED1_3, (PIN_LED1)); /* LED1 on */
led_on(LED1);
ssp1_set_mode_max2837();
max2837_setup();
rffc5071_setup();
gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */
max2837_setup(&max2837);
rffc5071_setup(&rffc5072);
led_on(LED2);
max2837_set_frequency(freq);
max2837_start();
max2837_tx();
gpio_set(PORT_LED1_3, (PIN_LED3)); /* LED3 on */
max2837_set_frequency(&max2837, freq);
max2837_start(&max2837);
max2837_tx(&max2837);
led_on(LED3);
while (1);
max2837_stop();
max2837_stop(&max2837);
return 0;
}

View File

@ -20,18 +20,12 @@
* Boston, MA 02110-1301, USA.
*/
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/sgpio.h>
#include <hackrf_core.h>
#include <rf_path.h>
#include <sgpio.h>
#include <tuning.h>
void tx_test() {
sgpio_set_slice_mode(false);
sgpio_configure(TRANSCEIVER_MODE_TX);
// LSB goes out first, samples are 0x<Q1><I1><Q0><I0>
volatile uint32_t buffer[] = {
0xda808080,
@ -41,7 +35,8 @@ void tx_test() {
};
uint32_t i = 0;
sgpio_cpld_stream_enable();
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_TX);
sgpio_cpld_stream_enable(&sgpio_config);
while(true) {
while(SGPIO_STATUS_1 == 0);
@ -51,59 +46,52 @@ void tx_test() {
}
void rx_test() {
sgpio_set_slice_mode(false);
sgpio_configure(TRANSCEIVER_MODE_RX);
volatile uint32_t buffer[4096];
uint32_t i = 0;
int16_t magsq;
uint32_t magsq;
int8_t sigi, sigq;
sgpio_cpld_stream_enable();
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_RX);
sgpio_cpld_stream_enable(&sgpio_config);
gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */
led_on(LED2);
while(true) {
while(SGPIO_STATUS_1 == 0);
gpio_set(PORT_LED1_3, (PIN_LED1)); /* LED1 on */
led_on(LED1);
SGPIO_CLR_STATUS_1 = 1;
buffer[i & 4095] = SGPIO_REG_SS(SGPIO_SLICE_A);
/* find the magnitude squared */
sigi = (buffer[i & 4095] & 0xff) - 0x80;
sigq = ((buffer[i & 4095] >> 8) & 0xff) - 0x80;
magsq = sigi * sigq;
if ((uint16_t)magsq & 0x8000) {
magsq ^= 0xffff;
magsq++;
}
sigi = buffer[i & 4095] & 0xff;
sigq = (buffer[i & 4095] >> 8) & 0xff;
magsq = sigi * sigi + sigq * sigq;
/* illuminate LED3 only when magsq exceeds threshold */
if (magsq > 0x3c00)
gpio_set(PORT_LED1_3, (PIN_LED3)); /* LED3 on */
if (magsq > 0x1000)
led_on(LED3);
else
gpio_clear(PORT_LED1_3, (PIN_LED3)); /* LED3 off */
led_off(LED3);
i++;
}
}
int main(void) {
const uint64_t freq = 2700000000U;
const uint64_t freq = 2441000000U;
sgpio_set_slice_mode(&sgpio_config, false);
pin_setup();
enable_1v8_power();
#ifdef HACKRF_ONE
enable_rf_power();
#endif
cpu_clock_init();
ssp1_init();
rf_path_init();
rf_path_set_direction(RF_PATH_DIRECTION_RX);
rf_path_init(&rf_path);
set_freq(freq);
rx_test();
gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */
led_on(LED2);
while (1) {

View File

@ -19,22 +19,15 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/sgpio.h>
#include <libopencm3/lpc43xx/cgu.h>
#include <libopencm3/cm3/scs.h>
#include <hackrf_core.h>
#include <max5864.h>
#include <sgpio.h>
volatile uint32_t buffer[4096];
void tx_test() {
sgpio_set_slice_mode(false);
sgpio_configure(TRANSCEIVER_MODE_TX);
sgpio_set_slice_mode(&sgpio_config, false);
sgpio_configure(&sgpio_config, TRANSCEIVER_MODE_TX);
// LSB goes out first, samples are 0x<Q1><I1><Q0><I0>
buffer[0] = 0xda808080;
@ -44,7 +37,7 @@ void tx_test() {
uint32_t i = 0;
sgpio_cpld_stream_enable();
sgpio_cpld_stream_enable(&sgpio_config);
while(true) {
while(SGPIO_STATUS_1 == 0);
@ -54,12 +47,12 @@ void tx_test() {
}
void rx_test() {
sgpio_set_slice_mode(false);
sgpio_configure(TRANSCEIVER_MODE_RX);
sgpio_set_slice_mode(&sgpio_config, false);
sgpio_configure(&sgpio_config, TRANSCEIVER_MODE_RX);
uint32_t i = 0;
sgpio_cpld_stream_enable();
sgpio_cpld_stream_enable(&sgpio_config);
while(true) {
while(SGPIO_STATUS_1 == 0);
@ -72,12 +65,12 @@ int main(void) {
pin_setup();
enable_1v8_power();
cpu_clock_init();
ssp1_init();
gpio_set(PORT_LED1_3, PIN_LED1);
led_on(LED1);
ssp1_set_mode_max5864();
max5864_xcvr();
max5864_setup(&max5864);
max5864_xcvr(&max5864);
while (1) {

View File

@ -21,11 +21,8 @@
* Boston, MA 02110-1301, USA.
*/
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/sgpio.h>
#include <libopencm3/lpc43xx/cgu.h>
#include <libopencm3/cm3/scs.h>
#include <hackrf_core.h>
@ -353,8 +350,7 @@ int main(void)
pin_setup();
enable_1v8_power();
cpu_clock_init();
ssp1_init();
gpio_set(PORT_LED1_3, PIN_LED1);
led_on(LED1);
//test_sgpio_sliceA_D();
test_sgpio_interface();

View File

@ -19,13 +19,7 @@
* Boston, MA 02110-1301, USA.
*/
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/i2c.h>
#include <libopencm3/lpc43xx/ssp.h>
#include "hackrf_core.h"
#include "max2837.h"
int main(void)
{
@ -37,19 +31,18 @@ int main(void)
enable_rf_power();
#endif
cpu_clock_init();
ssp1_init();
gpio_set(PORT_LED1_3, (PIN_LED1)); /* LED1 on */
led_on(LED1);
ssp1_set_mode_max2837();
max2837_setup();
gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */
max2837_set_frequency(freq);
max2837_start();
max2837_tx();
gpio_set(PORT_LED1_3, (PIN_LED3)); /* LED3 on */
max2837_setup(&max2837);
led_on(LED2);
max2837_set_frequency(&max2837, freq);
max2837_start(&max2837);
max2837_tx(&max2837);
led_on(LED3);
while (1);
max2837_stop();
max2837_stop(&max2837);
return 0;
}

View File

@ -19,11 +19,7 @@
* Boston, MA 02110-1301, USA.
*/
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include "hackrf_core.h"
#include "w25q80bv.h"
int main(void)
{
@ -39,17 +35,19 @@ int main(void)
/* program test data to SPI flash */
for (i = 0; i < 515; i++)
buf[i] = (i * 3) & 0xFF;
w25q80bv_setup();
w25q80bv_chip_erase();
w25q80bv_program(790, 515, &buf[0]);
w25q80bv_setup(&w25q80bv);
w25q80bv_chip_erase(&w25q80bv);
w25q80bv_program(&w25q80bv, 790, 515, &buf[0]);
/* blink LED1 and LED3 */
while (1)
{
gpio_set(PORT_LED1_3, (PIN_LED1|PIN_LED3)); /* LEDs on */
led_on(LED1);
led_on(LED3);
for (i = 0; i < 8000000; i++) /* Wait a bit. */
__asm__("nop");
gpio_clear(PORT_LED1_3, (PIN_LED1|PIN_LED3)); /* LED off */
led_off(LED1);
led_off(LED3);
for (i = 0; i < 8000000; i++) /* Wait a bit. */
__asm__("nop");
}

View File

@ -19,10 +19,6 @@
* Boston, MA 02110-1301, USA.
*/
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/i2c.h>
#include "hackrf_core.h"
int main(void)
@ -35,23 +31,27 @@ int main(void)
cpu_clock_init();
gpio_set(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LEDs on */
led_on(LED1);
led_on(LED2);
led_on(LED3);
while (1)
{
gpio_set(PORT_LED1_3, (PIN_LED1)); /* LEDs on */
led_on(LED1);
for (i = 0; i < 2000000; i++) /* Wait a bit. */
__asm__("nop");
gpio_set(PORT_LED1_3, (PIN_LED1|PIN_LED2)); /* LEDs on */
led_on(LED2);
for (i = 0; i < 2000000; i++) /* Wait a bit. */
__asm__("nop");
gpio_set(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LED off */
led_on(LED3);
for (i = 0; i < 2000000; i++) /* Wait a bit. */
__asm__("nop");
gpio_clear(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LED off */
led_off(LED1);
led_off(LED2);
led_off(LED3);
for (i = 0; i < 2000000; i++) /* Wait a bit. */
__asm__("nop");
}

View File

@ -19,9 +19,6 @@
* Boston, MA 02110-1301, USA.
*/
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/i2c.h>
#include <libopencm3/lpc43xx/m4/nvic.h>
#include <libopencm3/cm3/systick.h>
#include <libopencm3/cm3/scs.h>
@ -139,19 +136,21 @@ int main(void)
systick_setup();
gpio_set(PORT_LED1_3, (PIN_LED1|PIN_LED2|PIN_LED3)); /* LEDs on */
led_on(LED1);
led_on(LED2);
led_on(LED3);
while (1)
{
gpio_set(PORT_LED1_3, (PIN_LED1)); /* LED1 on */
gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */
gpio_set(PORT_LED1_3, (PIN_LED3)); /* LED3 on */
led_on(LED1);
led_on(LED2);
led_on(LED3);
sys_tick_wait_time_ms(500);
gpio_clear(PORT_LED1_3, (PIN_LED3)); /* LED3 off */
gpio_clear(PORT_LED1_3, (PIN_LED2)); /* LED2 off */
gpio_clear(PORT_LED1_3, (PIN_LED1)); /* LED1 off */
led_off(LED1);
led_off(LED2);
led_off(LED3);
sys_tick_wait_time_ms(500);
}

View File

@ -19,9 +19,6 @@
* Boston, MA 02110-1301, USA.
*/
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/i2c.h>
#include <libopencm3/lpc43xx/m4/nvic.h>
#include <libopencm3/cm3/systick.h>
#include <libopencm3/cm3/scs.h>

View File

@ -19,9 +19,6 @@
* Boston, MA 02110-1301, USA.
*/
#include <libopencm3/lpc43xx/gpio.h>
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/i2c.h>
#include <libopencm3/lpc43xx/m4/nvic.h>
#include <libopencm3/cm3/systick.h>
#include <libopencm3/cm3/scs.h>
@ -138,7 +135,7 @@ extern uint32_t test_nb_instruction_per_sec_150_nop_asm();
extern uint32_t test_nb_instruction_per_sec_200_nop_asm();
extern uint32_t test_nb_instruction_per_sec_1000_nop_asm();
#define LED1_TOGGLE() (gpio_toggle(PORT_LED1_3, (PIN_LED1)))
#define LED1_TOGGLE() (led_toggle(LED1))
int main(void)
{
@ -152,7 +149,7 @@ int main(void)
systick_setup();
gpio_clear(PORT_LED1_3, (PIN_LED1)); /* LED1 off */
led_off(LED1);
/* Test number of instruction per second (MIPS) slow blink ON 1s, OFF 1s */
LED1_TOGGLE();
@ -192,15 +189,15 @@ LED1_TOGGLE();
/* Test finished fast blink */
while (1)
{
gpio_set(PORT_LED1_3, (PIN_LED1)); /* LED1 on */
gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */
gpio_set(PORT_LED1_3, (PIN_LED3)); /* LED3 on */
led_on(LED1);
led_on(LED2);
led_on(LED3);
sys_tick_wait_time_ms(250);
gpio_clear(PORT_LED1_3, (PIN_LED3)); /* LED3 off */
gpio_clear(PORT_LED1_3, (PIN_LED2)); /* LED2 off */
gpio_clear(PORT_LED1_3, (PIN_LED1)); /* LED1 off */
led_off(LED1);
led_off(LED2);
led_off(LED3);
sys_tick_wait_time_ms(250);
}

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@ order of copper layers:
Copper 1: C1F (front)
Copper 2: C2
Copper 3: C3
Copper 4: C1B (back)
Copper 4: C4B (back)
PCB description: 4 layer PCB 0.062 in
Copper 1 0.5 oz foil plated to approximately 0.0017 in

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
(fp_lib_table
(lib (name hackrf)(type Legacy)(uri ${KIPRJMOD}/../kicad/hackrf.mod)(options "")(descr ""))
(lib (name gsg-modules)(type KiCad)(uri ${KIPRJMOD}/../gsg-kicad-lib/gsg-modules.pretty)(options "")(descr ""))
)

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
EESchema-LIBRARY Version 2.3 Date: Thu Feb 13 12:23:41 2014
EESchema-LIBRARY Version 2.3
#encoding utf-8
#
# +1.8V
@ -6,8 +6,8 @@ EESchema-LIBRARY Version 2.3 Date: Thu Feb 13 12:23:41 2014
DEF +1.8V #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 140 20 H I C CNN
F1 "+1.8V" 0 110 30 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
ALIAS 1V8
DRAW
P 3 0 0 0 0 0 0 40 0 40 N
@ -21,8 +21,8 @@ ENDDEF
DEF BALUN T 0 40 Y N 1 F N
F0 "T" 0 250 70 H V C CNN
F1 "BALUN" 0 -300 70 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
A -100 -150 50 899 1 0 1 0 N -100 -100 -50 -150
A -100 -150 50 -1 -899 0 1 0 N -50 -150 -100 -199
@ -55,8 +55,8 @@ ENDDEF
DEF BALUN-B0310J50100AHF T 0 40 Y N 1 F N
F0 "T" 0 200 70 H V C CNN
F1 "BALUN-B0310J50100AHF" 0 -150 70 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
A -150 -50 50 1 1799 0 1 0 N -100 -50 -200 -50
A -150 100 50 -1799 -1 0 1 0 N -200 100 -100 100
@ -77,20 +77,22 @@ ENDDEF
# C
#
DEF C C 0 10 N Y 1 F N
F0 "C" 50 100 50 H V L CNN
F1 "C" 50 -100 50 H V L CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F0 "C" 25 100 50 H V L CNN
F1 "C" 25 -100 50 H V L CNN
F2 "" 38 -150 30 H V C CNN
F3 "" 0 0 60 H V C CNN
$FPLIST
SM*
C?
C1-1
C_????_*
C_????
SMD*_c
Capacitor*
$ENDFPLIST
DRAW
P 2 0 1 20 -100 -30 100 -30 N
P 2 0 1 20 -100 30 100 30 N
X ~ 1 0 200 170 D 40 40 1 1 P
X ~ 2 0 -200 170 U 40 40 1 1 P
P 2 0 1 20 -80 -30 80 -30 N
P 2 0 1 20 -80 30 80 30 N
X ~ 1 0 150 110 D 40 40 1 1 P
X ~ 2 0 -150 110 U 40 40 1 1 P
ENDDRAW
ENDDEF
#
@ -99,8 +101,8 @@ ENDDEF
DEF ~CONN_1 P 0 30 N N 1 F N
F0 "P" 80 0 40 H V L CNN
F1 "CONN_1" 0 55 30 H I C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
C 0 0 31 0 1 0 N
P 2 0 1 0 -30 0 -50 0 N
@ -113,8 +115,8 @@ ENDDEF
DEF CONN_10X2 P 0 10 Y N 1 F N
F0 "P" 0 550 60 H V C CNN
F1 "CONN_10X2" 0 -100 50 V V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -100 500 100 -500 0 1 0 f
X P1 1 -400 450 300 R 60 30 1 1 P I
@ -145,8 +147,8 @@ ENDDEF
DEF CONN_11X2 P 0 10 Y N 1 F N
F0 "P" 0 600 60 H V C CNN
F1 "CONN_11X2" 0 0 50 V V C CNN
F2 "~" 0 -250 60 H V C CNN
F3 "~" 0 -250 60 H V C CNN
F2 "" 0 -250 60 H V C CNN
F3 "" 0 -250 60 H V C CNN
DRAW
S -100 550 100 -550 0 1 0 N
S 1200 650 1200 650 0 1 0 N
@ -180,8 +182,8 @@ ENDDEF
DEF CONN_13X2 P 0 10 Y N 1 F N
F0 "P" 0 700 60 H V C CNN
F1 "CONN_13X2" 0 0 50 V V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -100 650 100 -650 0 1 0 N
X P1 1 -400 600 300 R 40 30 1 1 P I
@ -218,8 +220,8 @@ ENDDEF
DEF CONN_2 P 0 40 Y N 1 F N
F0 "P" -50 0 40 V V C CNN
F1 "CONN_2" 50 0 40 V V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -100 150 100 -150 0 1 0 N
X P1 1 -350 100 250 R 60 60 1 1 P I
@ -232,8 +234,8 @@ ENDDEF
DEF CONN_3X2 P 0 40 Y N 1 F N
F0 "P" 0 250 50 H V C CNN
F1 "CONN_3X2" 0 50 40 V V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -100 200 100 -100 0 1 0 N
X 1 1 -400 150 300 R 60 60 1 1 P I
@ -250,8 +252,8 @@ ENDDEF
DEF CONN_5X2 P 0 40 Y Y 1 F N
F0 "P" 0 300 60 H V C CNN
F1 "CONN_5X2" 0 0 50 V V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -100 250 100 -250 0 1 0 N
X ~ 1 -400 200 300 R 60 60 1 1 P I
@ -272,8 +274,8 @@ ENDDEF
DEF CONN_6 P 0 30 Y N 1 F N
F0 "P" -50 0 60 V V C CNN
F1 "CONN_6" 50 0 60 V V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -100 300 100 -300 0 1 0 N
X 1 1 -350 250 250 R 60 60 1 1 P I
@ -290,8 +292,8 @@ ENDDEF
DEF CONN_8X2 P 0 40 Y Y 1 F N
F0 "P" 0 450 60 H V C CNN
F1 "CONN_8X2" 0 0 50 V V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -100 400 100 -400 0 1 0 N
X ~ 1 -400 350 300 R 60 60 1 1 P I
@ -318,8 +320,8 @@ ENDDEF
DEF CRYSTAL X 0 40 N N 1 F N
F0 "X" 0 150 60 H V C CNN
F1 "CRYSTAL" 0 -150 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
P 2 0 1 16 -100 100 -100 -100 N
P 2 0 1 16 100 100 100 -100 N
@ -334,8 +336,8 @@ ENDDEF
DEF FIL-DEA U 0 40 Y Y 1 F N
F0 "U" 0 50 60 H V C CNN
F1 "FIL-DEA" 0 -50 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -300 200 300 -200 0 1 0 N
X IN 1 -600 -150 300 R 50 50 1 1 B
@ -350,8 +352,8 @@ ENDDEF
DEF FIL-LP0603 U 0 40 Y Y 1 F N
F0 "U" 0 50 60 H V C CNN
F1 "FIL-LP0603" 0 -50 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -300 200 300 -200 0 1 0 N
X OUT 1 -600 150 300 R 50 50 1 1 B
@ -364,10 +366,10 @@ ENDDEF
# FILTER
#
DEF FILTER FB 0 40 Y N 1 F N
F0 "FB" 0 150 60 H V C CNN
F1 "FILTER" 0 -100 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F0 "FB" 0 150 50 H V C CNN
F1 "FILTER" 0 -100 50 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
A -150 0 50 1 1799 0 1 0 N -100 0 -200 0
A -50 0 50 1 1799 0 1 0 N 0 0 -100 0
@ -382,14 +384,14 @@ ENDDEF
#
# GND
#
DEF ~GND #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 0 30 H I C CNN
F1 "GND" 0 -70 30 H I C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
DEF GND #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 -250 50 H I C CNN
F1 "GND" 0 -150 50 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
P 4 0 1 0 -50 0 0 -50 50 0 -50 0 N
X GND 1 0 0 0 U 30 30 1 1 W N
P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N
X GND 1 0 0 0 D 50 50 1 1 W N
ENDDRAW
ENDDEF
#
@ -398,8 +400,8 @@ ENDDEF
DEF GSG-DIODE-TVS-BI D 0 40 N N 1 F N
F0 "D" 0 100 50 H V C CNN
F1 "GSG-DIODE-TVS-BI" 0 -100 40 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
$FPLIST
D?
SO*
@ -419,8 +421,8 @@ ENDDEF
DEF GSG-RF-CONN P 0 0 Y N 1 F N
F0 "P" 0 150 60 H V C CNN
F1 "GSG-RF-CONN" 0 -150 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
C 0 0 100 0 1 0 N
X RF 1 300 0 300 L 50 50 1 1 B
@ -433,8 +435,8 @@ ENDDEF
DEF GSG-USB-MICRO-B-SHIELDED J 0 40 Y Y 1 F N
F0 "J" 150 300 60 H V C CNN
F1 "GSG-USB-MICRO-B-SHIELDED" 400 0 60 V V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
P 4 0 1 0 350 -250 -50 -250 -50 250 350 250 N
X SHIELD 0 250 -450 200 U 50 50 1 1 P
@ -451,8 +453,8 @@ ENDDEF
DEF GSG-XC2C64A-7VQG100C U 0 40 Y Y 1 F N
F0 "U" 0 100 60 H V C CNN
F1 "GSG-XC2C64A-7VQG100C" 0 -100 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -1700 1700 1700 -1700 0 1 0 N
X BANK2F1M12 1 -2000 1200 300 R 50 50 1 1 B
@ -563,8 +565,8 @@ ENDDEF
DEF GSG-XTAL4PIN X 0 40 N N 1 F N
F0 "X" 0 150 60 H V C CNN
F1 "GSG-XTAL4PIN" 0 -150 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
P 2 0 1 16 -100 100 -100 -100 N
P 2 0 1 16 100 100 100 -100 N
@ -579,10 +581,10 @@ ENDDEF
# INDUCTOR
#
DEF INDUCTOR L 0 40 N N 1 F N
F0 "L" -50 0 40 V V C CNN
F1 "INDUCTOR" 100 0 40 V V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F0 "L" -50 0 50 V V C CNN
F1 "INDUCTOR" 100 0 50 V V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
A 0 -150 50 -889 889 0 1 0 N 1 -199 1 -100
A 0 -49 51 -889 889 0 1 0 N 1 -99 1 2
@ -598,8 +600,8 @@ ENDDEF
DEF LED D 0 40 Y N 1 F N
F0 "D" 0 100 50 H V C CNN
F1 "LED" 0 -100 50 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
$FPLIST
LED-3MM
LED-5MM
@ -610,12 +612,12 @@ $FPLIST
LEDV
$ENDFPLIST
DRAW
P 2 0 1 0 50 50 50 -50 N
P 3 0 1 0 -50 50 50 0 -50 -50 F
P 3 0 1 0 65 -40 110 -80 105 -55 N
P 3 0 1 0 80 -25 125 -65 120 -40 N
X A 1 -200 0 150 R 40 40 1 1 P
X K 2 200 0 150 L 40 40 1 1 P
P 2 0 1 0 -50 50 -50 -50 N
P 3 0 1 0 -80 -25 -125 -65 -120 -40 N
P 3 0 1 0 -65 -40 -110 -80 -105 -55 N
P 3 0 1 0 50 50 -50 0 50 -50 F
X K 1 -200 0 150 R 40 40 1 1 P
X A 2 200 0 150 L 40 40 1 1 P
ENDDRAW
ENDDEF
#
@ -624,8 +626,8 @@ ENDDEF
DEF LPC43XXFBD144 U 0 40 Y Y 1 F N
F0 "U" 0 150 60 H V C CNN
F1 "LPC43XXFBD144" 0 -150 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -2400 2400 2400 -2400 0 1 0 N
X P4_0 1 -2700 1750 300 R 50 50 1 1 B
@ -780,8 +782,8 @@ ENDDEF
DEF LXES1TBCC2-004 U 0 40 Y Y 1 F N
F0 "U" 0 250 60 H V C CNN
F1 "LXES1TBCC2-004" 0 -250 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -250 200 250 -200 0 1 0 N
X ESD1 1 -550 100 300 R 50 50 1 1 I
@ -798,8 +800,8 @@ ENDDEF
DEF MAX2837 U 0 40 Y Y 1 F N
F0 "U" 0 50 60 H V C CNN
F1 "MAX2837" 0 -50 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -1000 1000 1000 -1000 0 1 0 N
X EP 0 -1300 900 300 R 50 50 1 1 W
@ -859,8 +861,8 @@ ENDDEF
DEF MAX5864 U 0 40 Y Y 1 F N
F0 "U" 0 50 60 H V C CNN
F1 "MAX5864" 0 -50 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -900 900 900 -900 0 1 0 N
X EP 0 -1200 800 300 R 50 50 1 1 W
@ -920,8 +922,8 @@ ENDDEF
DEF MGA-81563 U 0 40 Y Y 1 F N
F0 "U" 0 50 60 H V C CNN
F1 "MGA-81563" 0 -50 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -300 300 300 -300 0 1 0 N
X GND 1 -100 -450 150 U 50 50 1 1 W
@ -938,8 +940,8 @@ ENDDEF
DEF MOS_P Q 0 40 Y N 1 F N
F0 "Q" 0 190 60 H V R CNN
F1 "MOS_P" 0 -180 60 H V R CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
ALIAS MOSFET_P
DRAW
P 2 0 1 8 -50 -100 -50 100 N
@ -960,19 +962,16 @@ ENDDEF
DEF R R 0 0 N Y 1 F N
F0 "R" 80 0 50 V V C CNN
F1 "R" 0 0 50 V V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" -70 0 30 V V C CNN
F3 "" 0 0 30 H V C CNN
$FPLIST
R?
SM0603
SM0805
R?-*
SM1206
R_*
Resistor_*
$ENDFPLIST
DRAW
S -40 150 40 -150 0 1 12 N
X ~ 1 0 250 100 D 60 60 1 1 P
X ~ 2 0 -250 100 U 60 60 1 1 P
S -40 -100 40 100 0 1 10 N
X ~ 1 0 150 50 D 60 60 1 1 P
X ~ 2 0 -150 50 U 60 60 1 1 P
ENDDRAW
ENDDEF
#
@ -981,8 +980,8 @@ ENDDEF
DEF RF-SHIELD-COVER J 0 40 Y Y 1 F N
F0 "J" 0 250 60 H V C CNN
F1 "RF-SHIELD-COVER" 0 150 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
P 4 0 1 0 -550 -100 -550 100 550 100 550 -100 N
ENDDRAW
@ -993,8 +992,8 @@ ENDDEF
DEF RF-SHIELD-FRAME J 0 40 Y Y 1 F N
F0 "J" 0 500 60 H V C CNN
F1 "RF-SHIELD-FRAME" 0 400 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
P 2 0 1 0 -450 200 -450 100 N
P 2 0 1 0 -450 350 -450 250 N
@ -1025,8 +1024,8 @@ ENDDEF
DEF RFFC5072 U 0 40 Y Y 1 F N
F0 "U" 0 100 60 H V C CNN
F1 "RFFC5072" 0 -100 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -850 850 850 -850 0 1 0 N
X EP 0 -1150 650 300 R 60 60 1 1 W
@ -1070,8 +1069,8 @@ ENDDEF
DEF SI5351C U 0 40 Y Y 1 F N
F0 "U" 0 50 60 H V C CNN
F1 "SI5351C" 0 -50 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -500 500 500 -500 0 1 0 N
X GND 0 -800 400 300 R 50 50 1 1 W
@ -1103,8 +1102,8 @@ ENDDEF
DEF SKY13317 U 0 40 Y Y 1 F N
F0 "U" 0 0 60 H V C CNN
F1 "SKY13317" 0 250 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -250 300 250 -300 0 1 0 N
X GND 0 0 -600 300 U 50 50 1 1 W
@ -1124,8 +1123,8 @@ ENDDEF
DEF SKY13350 U 0 40 Y Y 1 F N
F0 "U" 0 200 60 H V C CNN
F1 "SKY13350" 0 -200 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -300 250 300 -250 0 1 0 N
X VCTL1 1 -450 100 150 R 50 50 1 1 I
@ -1142,8 +1141,8 @@ ENDDEF
DEF SW_PUSH_SHIELDED SW 0 40 N N 1 F N
F0 "SW" 0 150 50 H V C CNN
F1 "SW_PUSH_SHIELDED" 0 -80 50 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -200 200 200 -150 0 1 0 N
S -170 50 170 60 0 1 0 N
@ -1159,8 +1158,8 @@ ENDDEF
DEF TPS62410 U 0 40 Y Y 1 F N
F0 "U" 0 -50 60 H V C CNN
F1 "TPS62410" 0 300 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -350 350 350 -350 0 1 0 N
X PP 0 0 -650 300 U 50 50 1 1 W
@ -1180,28 +1179,28 @@ ENDDEF
# VAA
#
DEF VAA #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 60 30 H I C CNN
F1 "VAA" 0 110 30 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F0 "#PWR" 0 -150 50 H I C CNN
F1 "VAA" 0 150 50 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
X VAA 1 0 0 0 U 40 40 0 0 W N
C 0 60 20 0 1 0 N
P 4 0 1 0 0 40 0 0 0 0 0 0 N
C 0 75 25 0 1 0 N
P 2 0 1 0 0 0 0 50 N
X VAA 1 0 0 0 U 50 50 1 1 W N
ENDDRAW
ENDDEF
#
# VCC
#
DEF VCC #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 100 30 H I C CNN
F1 "VCC" 0 100 30 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F0 "#PWR" 0 -150 50 H I C CNN
F1 "VCC" 0 150 50 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
X VCC 1 0 0 0 U 20 20 0 0 W N
C 0 50 20 0 1 0 N
P 3 0 1 0 0 0 0 30 0 30 N
C 0 75 25 0 1 0 N
P 2 0 1 0 0 0 0 50 N
X VCC 1 0 0 0 U 50 50 1 1 W N
ENDDRAW
ENDDEF
#
@ -1210,8 +1209,8 @@ ENDDEF
DEF W25Q80BV U 0 40 Y Y 1 F N
F0 "U" 0 -250 60 H V C CNN
F1 "W25Q80BV" 0 250 60 H V C CNN
F2 "~" 0 0 60 H V C CNN
F3 "~" 0 0 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
DRAW
S -250 300 250 -300 0 1 0 N
X CS 1 -550 150 300 R 50 50 1 1 I

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
update=Wed Mar 27 00:13:41 2013
update=Wed 13 Jul 2016 05:14:22 PM MDT
version=1
last_client=eeschema
last_client=kicad
[cvpcb]
version=1
NetITyp=0
@ -46,11 +46,6 @@ LibName11=hackrf
[eeschema]
version=1
LibDir=../kicad
NetFmtName=
RptD_X=0
RptD_Y=100
RptLab=1
LabSize=60
[eeschema/libraries]
LibName1=power
LibName2=device
@ -63,23 +58,22 @@ LibName8=cmos4000
LibName9=adc-dac
LibName10=memory
LibName11=xilinx
LibName12=special
LibName13=microcontrollers
LibName14=dsp
LibName15=microchip
LibName16=analog_switches
LibName17=motorola
LibName18=texas
LibName19=intel
LibName20=audio
LibName21=interface
LibName22=digital-audio
LibName23=philips
LibName24=display
LibName25=cypress
LibName26=siliconi
LibName27=opto
LibName28=atmel
LibName29=contrib
LibName30=valves
LibName31=hackrf
LibName12=microcontrollers
LibName13=dsp
LibName14=microchip
LibName15=analog_switches
LibName16=motorola
LibName17=texas
LibName18=intel
LibName19=audio
LibName20=interface
LibName21=digital-audio
LibName22=philips
LibName23=display
LibName24=cypress
LibName25=siliconi
LibName26=opto
LibName27=atmel
LibName28=contrib
LibName29=valves
LibName30=hackrf

View File

@ -10,7 +10,6 @@ LIBS:cmos4000
LIBS:adc-dac
LIBS:memory
LIBS:xilinx
LIBS:special
LIBS:microcontrollers
LIBS:dsp
LIBS:microchip
@ -31,7 +30,7 @@ LIBS:contrib
LIBS:valves
LIBS:hackrf
LIBS:hackrf-one-cache
EELAYER 27 0
EELAYER 25 0
EELAYER END
$Descr User 17000 11000
encoding utf-8

File diff suppressed because it is too large Load Diff

47
hardware/marzipan/README Normal file
View File

@ -0,0 +1,47 @@
Copyright 2012 - 2016 Great Scott Gadgets
These files are part of HackRF.
This is a free hardware design; 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 2, or (at your option)
any later version.
This design 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 design; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street,
Boston, MA 02110-1301, USA.
Marzipan is a wideband software radio transceiver capable of running Linux.
hardware notes:
Schematic and layout files were designed in KiCad, an open source electronic
design automation package.
order of copper layers:
Copper 1: C1F (front)
Copper 2: C2
Copper 3: C3
Copper 4: C4B (back)
PCB description: 4 layer PCB 0.062 in
Copper 1 0.5 oz foil plated to approximately 0.0017 in
Dielectric 1-2 0.0119 in
Copper 2 1 oz foil (0.0014 in)
Dielectric 2-3 0.0280 in
Copper 3 1 oz foil (0.0014 in)
Dielectric 3-4 0.0119 in
Copper 4 0.5 oz foil plated to approximately 0.0017 in
FR4 or similar substrate with Er=4.5 (+/- 0.1)
double side solder mask green
single side silkscreen white
6 mil min trace width and
6 mil min isolation

Some files were not shown because too many files have changed in this diff Show More