remove retired content and move jawbreakercontent
This commit is contained in:
@ -1,168 +0,0 @@
|
||||
================================================
|
||||
LPC4350 SGPIO Experimentation
|
||||
================================================
|
||||
|
||||
The NXP LPC43xx microcontrollers have an interesting, programmable serial peripheral called the SGPIO (Serial GPIO). It consists of a slew of counters and shift registers that can be configured to serialize and deserialize many channels of data. Channels can be grouped to create multi-bit parallel data streams.
|
||||
|
||||
The current HackRF design entails using the SGPIO peripheral to move quadrature baseband receive and transmit data between the USB interface and the baseband ADC/DAC IC. Because the baseband ADC/DAC IC (MAX5864) uses DDR signaling, we expect to use a CPLD to convert bus signaling. The CPLD may also help manage bus turnaround (between transmit and receive modes) or interfacing two narrower but faster interfaces to the LPC43xx to facilitate full-duplex.
|
||||
|
||||
Because the Jellybean board wasn't completed at the time of these experiments, I used the Diolan LPC-4350-DB1-A development board. Despite using an LPC4350 in an BGA256 package, the SGPIO peripheral's signals can be mapped to many different pins. So reworking code to a new set of SGPIO pins should be a trivial matter of switching the SGU configuration for the affected pins.
|
||||
|
||||
|
||||
|
||||
SGPIO Examples
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Some SGPIO peripheral examples can be found in `the LPCWare repository <http://sw.lpcware.com/?p=lpc43xx.git&a=summary>`__. All source I've found so far is focused on generating many I2S interfaces, which is not very similar to HackRF's needs. But reviewing the code is still valuable in grasping how the SGPIO peripheral operates.
|
||||
|
||||
There are a few common details to setting up the SGPIO peripheral:
|
||||
|
||||
.. code-block :: C
|
||||
|
||||
// Configure the PLL to generate a reasonable clock. The SGPIO
|
||||
// will operate with a clock of up to 204MHz (the same as the
|
||||
// M4 clock.
|
||||
CGU_SetPLL1(12);
|
||||
|
||||
// Set the BASE_PERIPH clock to come from PLL1.
|
||||
CGU_EnableEntity(CGU_BASE_PERIPH, ENABLE);
|
||||
CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_PERIPH);
|
||||
|
||||
// Compute and commit clock configuration changes.
|
||||
CGU_UpdateClock();
|
||||
|
||||
|
||||
|
||||
Jiggle SGPIO Pins From GPIO Mode
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
My first test was to ensure I had the right pin(s) hooked up to my scope:
|
||||
|
||||
.. code-block :: C
|
||||
|
||||
// Jiggle one of the SGPIO pins in GPIO mode, to make sure
|
||||
// I'm looking at the right pin on the scope.
|
||||
scu_pinmux(9, 0, MD_PLN_FAST, 0);
|
||||
|
||||
GPIO_SetDir(4, 1L << 12, 1);
|
||||
|
||||
while(1) {
|
||||
volatile int i;
|
||||
GPIO_SetValue(4, 1L << 12);
|
||||
for(i=0; i<1000; i++);
|
||||
GPIO_ClearValue(4, 1L << 12);
|
||||
for(i=0; i<1000; i++);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Jiggle Pins from SGPIO Mode
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can also control SGPIO pins, GPIO-style, from within the SGPIO peripheral. This helped me understand the basics of operating the SGPIO output mux.
|
||||
|
||||
.. code-block :: C
|
||||
|
||||
// Set pin to SGPIO mode, toggle output using SGPIO
|
||||
// peripheral registers.
|
||||
scu_pinmux(9, 0, MD_PLN_FAST, 6); // SGPIO0
|
||||
|
||||
// P_OUT_CFG = 4, gpio_out
|
||||
// P_OE_CFG = X
|
||||
LPC_SGPIO->OUT_MUX_CFG[0] = (0L << 4) | (4L << 0);
|
||||
LPC_SGPIO->GPIO_OENREG |= (1L << 0);
|
||||
|
||||
while(1) {
|
||||
volatile int i;
|
||||
LPC_SGPIO->GPIO_OUTREG |= (1L << 0);
|
||||
for(i=0; i<1000; i++);
|
||||
LPC_SGPIO->GPIO_OUTREG &= ~(1L << 0);
|
||||
for(i=0; i<1000; i++);
|
||||
}
|
||||
|
||||
|
||||
Serializing Data With Slice Clock Source
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
My first full-on SGPIO experiment involved serializing a data pattern from slice A, using slice D to generate a SGPIO_CLK/2 data rate. I derived the code from examples that configured the SGPIO as I2S interfaces:
|
||||
|
||||
.. code-block :: C
|
||||
|
||||
// Disable all counters during configuration
|
||||
LPC_SGPIO->CTRL_ENABLED = 0;
|
||||
|
||||
// Configure pin functions.
|
||||
scu_pinmux(9, 0, MD_PLN_FAST, 6); // SGPIO0
|
||||
scu_pinmux(2, 3, MD_PLN_FAST, 0); // SGPIO12
|
||||
|
||||
// Enable SGPIO pin outputs.
|
||||
LPC_SGPIO->GPIO_OENREG =
|
||||
(1L << 12) | // SGPIO12
|
||||
(1L << 0); // SGPIO0
|
||||
|
||||
// SGPIO pin 0 outputs slice A bit 0.
|
||||
LPC_SGPIO->OUT_MUX_CFG[0] =
|
||||
(0L << 4) | // P_OE_CFG = X
|
||||
(0L << 0); // P_OUT_CFG = 0, dout_doutm1 (1-bit mode)
|
||||
|
||||
// SGPIO pin 12 outputs slice D bit 0.
|
||||
LPC_SGPIO->OUT_MUX_CFG[12] =
|
||||
(0L << 4) | // P_OE_CFG = X
|
||||
(0L << 0); // P_OUT_CFG = 0, dout_doutm1 (1-bit mode)
|
||||
|
||||
// Slice A
|
||||
LPC_SGPIO->SGPIO_MUX_CFG[0] =
|
||||
(0L << 12) | // CONCAT_ORDER = 0 (self-loop)
|
||||
(1L << 11) | // CONCAT_ENABLE = 1 (concatenate data)
|
||||
(0L << 9) | // QUALIFIER_SLICE_MODE = X
|
||||
(0L << 7) | // QUALIFIER_PIN_MODE = X
|
||||
(0L << 5) | // QUALIFIER_MODE = 0 (enable)
|
||||
(0L << 3) | // CLK_SOURCE_SLICE_MODE = 0, slice D
|
||||
(0L << 1) | // CLK_SOURCE_PIN_MODE = X
|
||||
(0L << 0); // EXT_CLK_ENABLE = 0, internal clock signal (slice)
|
||||
|
||||
LPC_SGPIO->SLICE_MUX_CFG[0] =
|
||||
(0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier)
|
||||
(0L << 6) | // PARALLEL_MODE = 0 (shift 1 bit per clock)
|
||||
(0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge)
|
||||
(0L << 3) | // INV_OUT_CLK = 0 (normal clock)
|
||||
(0L << 2) | // CLKGEN_MODE = 0 (use clock from COUNTER)
|
||||
(0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge)
|
||||
(0L << 0); // MATCH_MODE = 0 (do not match data)
|
||||
|
||||
LPC_SGPIO->PRESET[0] = 1;
|
||||
LPC_SGPIO->COUNT[0] = 0;
|
||||
LPC_SGPIO->POS[0] = (0x1FL << 8) | (0x1FL << 0);
|
||||
LPC_SGPIO->REG[0] = 0xAAAAAAAA; // Primary output data register
|
||||
LPC_SGPIO->REG_SS[0] = 0xAAAAAAAA; // Shadow output data register
|
||||
|
||||
// Slice D (clock for Slice A)
|
||||
LPC_SGPIO->SGPIO_MUX_CFG[3] =
|
||||
(0L << 12) | // CONCAT_ORDER = 0 (self-loop)
|
||||
(1L << 11) | // CONCAT_ENABLE = 1 (concatenate data)
|
||||
(0L << 9) | // QUALIFIER_SLICE_MODE = X
|
||||
(0L << 7) | // QUALIFIER_PIN_MODE = X
|
||||
(0L << 5) | // QUALIFIER_MODE = 0 (enable)
|
||||
(0L << 3) | // CLK_SOURCE_SLICE_MODE = 0, slice D
|
||||
(0L << 1) | // CLK_SOURCE_PIN_MODE = X
|
||||
(0L << 0); // EXT_CLK_ENABLE = 0, internal clock signal (slice)
|
||||
|
||||
LPC_SGPIO->SLICE_MUX_CFG[3] =
|
||||
(0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier)
|
||||
(0L << 6) | // PARALLEL_MODE = 0 (shift 1 bit per clock)
|
||||
(0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge)
|
||||
(0L << 3) | // INV_OUT_CLK = 0 (normal clock)
|
||||
(0L << 2) | // CLKGEN_MODE = 0 (use clock from COUNTER)
|
||||
(0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge)
|
||||
(0L << 0); // MATCH_MODE = 0 (do not match data)
|
||||
|
||||
LPC_SGPIO->PRESET[3] = 0;
|
||||
LPC_SGPIO->COUNT[3] = 0;
|
||||
LPC_SGPIO->POS[3] = (0x1FL << 8) | (0x1FL << 0);
|
||||
LPC_SGPIO->REG[0] = 0xAAAAAAAA; // Primary output data register
|
||||
LPC_SGPIO->REG_SS[0] = 0xAAAAAAAA; // Shadow output data register
|
||||
|
||||
// Start SGPIO operation by enabling slice clocks.
|
||||
LPC_SGPIO->CTRL_ENABLED =
|
||||
(1L << 3) | // Slice D
|
||||
(1L << 0); // Slice A
|
@ -1,12 +1,16 @@
|
||||
import sphinx_rtd_theme
|
||||
|
||||
extensions = [
|
||||
'sphinx_rtd_theme'
|
||||
]
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'HackRF'
|
||||
copyright = '2021, Great Scott Gadgets'
|
||||
author = 'Great Scott Gadgets'
|
||||
|
||||
# The short X.Y version
|
||||
version = ''
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = ''
|
||||
|
||||
|
||||
@ -26,7 +30,7 @@ pygments_style = None
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
# run pip install sphinx_rtd_theme if you get sphinx_rtd_theme errors
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
html_css_files = ['status.css']
|
||||
|
||||
|
@ -1,29 +0,0 @@
|
||||
================================================
|
||||
Design Goals
|
||||
================================================
|
||||
|
||||
Eventually, the HackRF project may result in multiple hardware designs, but the initial goal is to build a single wideband transceiver peripheral that can be attached to a general purpose computer for software radio functions.
|
||||
|
||||
Primary goals:
|
||||
|
||||
* half-duplex transceiver
|
||||
* operating freq: 100 MHz to 6 GHz
|
||||
* maximum sample rate: 20 Msps
|
||||
* resolution: 8 bits
|
||||
* interface: High Speed USB
|
||||
* power supply: USB bus power
|
||||
* portable
|
||||
* open source
|
||||
|
||||
Wish list:
|
||||
|
||||
* full-duplex (at reduced max sample rate)
|
||||
* external clock reference
|
||||
* dithering
|
||||
* parallel interface for external FPGA, etc.
|
||||
|
||||
If there is a primary goal we miss, it will probably be the operating frequency range. The wideband front end is the part of the design furthest from completion. At an absolute minimum, the board should do 900 MHz and 2.4 GHz.
|
||||
|
||||
The design is FPGA-less. There will be a tiny bit of DSP capability (ARM Cortex-M4), but mostly we're just trying to get samples to and from a host computer.
|
||||
|
||||
We are trading resolution and DSP capability for cost, portability, and frequency range. Considering that we'll be able to support oversampling for many applications and that we should be able to implement AGC, it should be a pretty good trade.
|
@ -1,98 +0,0 @@
|
||||
================================================
|
||||
Future Hardware Modifications
|
||||
================================================
|
||||
|
||||
Things to consider for post-Jawbreaker hardware designs:
|
||||
|
||||
----
|
||||
|
||||
Antenna
|
||||
^^^^^^^
|
||||
|
||||
The PCB antenna on Jawbreaker was included to facilitate beta testing. Future designs likely will not include a PCB antenna.
|
||||
|
||||
SMA connectors will be PCB edge-mounted.
|
||||
|
||||
----
|
||||
|
||||
Baseband
|
||||
^^^^^^^^
|
||||
|
||||
The interfaces between the MAX2837 and MAX5864 have some signals inverted. Theoretically, that's fine if compensated for in software. However, I'm theorizing that RX/ADC DC offset compensation assumes that both channels have the same DC polarity. I've fixed the inversion in the CPLD. However, a PCB experiment should be conducted to see if the DC offset is reduced by un-inverting the RX Q channel connections to the MAX5864.
|
||||
|
||||
----
|
||||
|
||||
CPLD
|
||||
^^^^
|
||||
|
||||
The CPLD could be removed, but some sort of multiplexer would be needed to meet the MAX5864 i/o requirements. Depending on the particular LPC43xx part used, it might be possible to use the System Control Unit (SCU) for this.
|
||||
|
||||
----
|
||||
|
||||
Clocking
|
||||
^^^^^^^^
|
||||
|
||||
The clock signal from the Si5351C to the LPC43xx's GP_CLKIN pin may need different passives, but the documentation on that clock input is thin (acceptable peak-to-peak voltage anyone?).
|
||||
|
||||
An unpopulated footprint for a 32.768 kHz RTC crystal would be nice. Also break out RTC battery pins to an expansion header.
|
||||
|
||||
----
|
||||
|
||||
USB
|
||||
^^^
|
||||
|
||||
Would support for host mode on the second USB PHY be useful somehow? This is only possible with a larger LPC43xx package that exposes the second PHY's ULPI signals. Unless, of course, a mere full-speed PHY is acceptable.
|
||||
|
||||
----
|
||||
|
||||
Power Management
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
The MAX5864 appears to come up in "Tx" or "Rcvr" mode -- I have observed that the part will pass DA bus data to ID/QD without any SPI configuration. If we're worried about USB power and minimizing current consumption, it might be good to have this device on a power regulator with an ENABLE pin, or have a FET power switch. Yes, let's add a high side switch for the whole RF section.
|
||||
|
||||
----
|
||||
|
||||
Regulators
|
||||
^^^^^^^^^^
|
||||
|
||||
U21 (the TPS62410) FB1 pin is connected on the far side of jumper P8 (VCC), which puts the jumper inside the feedback path. If the jumper trace is cut, the regulator may go nuts because the FB pin is floating.
|
||||
|
||||
----
|
||||
|
||||
Buttons
|
||||
^^^^^^^
|
||||
|
||||
Add a reset button (for the LPC43xx). Maybe add a DFU button too.
|
||||
|
||||
----
|
||||
|
||||
Shielding
|
||||
^^^^^^^^^
|
||||
|
||||
Maybe add a can around the RF section.
|
||||
|
||||
----
|
||||
|
||||
Footprints
|
||||
^^^^^^^^^^
|
||||
|
||||
Tighten up holes for USB connector support legs to improve placement consistency. Make some of the QFN pads bigger (especially on the RF switches) for better soldering.
|
||||
|
||||
----
|
||||
|
||||
Shield Support
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
If support for add-on shields is considered valuable, here are some tweaks I'd suggest:
|
||||
|
||||
Any reason P28 (SD) pin 12 isn't grounded or doing something useful? Same goes for P25 (LPC_ISP) pin 3 -- maybe make it VCC, the signaling voltage for the ISP interface? The SPIFI connector could also use a reference voltage (GND?).
|
||||
|
||||
I'd like to see an I2C bus exposed somewhere, and perhaps an I2S0_RX_SDA signal, so I don't have to steal it from the CPLD interface. The I2S0 will function in "four-wire mode" with only one more pin (RX_SDA), so why not?
|
||||
|
||||
Provide a way to inject a supply voltage into the board? Having diodes managing multiple voltage sources would be lossy, so a more expensive solution would be necessary on the Jawbreaker board, adding cost.
|
||||
|
||||
If an LPC43xx package with a higher pin-count is used, it would be stellar to expose the LCD interface and quadrature encoder peripheral pins.
|
||||
|
||||
The RTC would be handy for stand-alone use. This would require a crystal (32.768kHz) between RTCX1 and RTCX2, and exposing VBAT to a shield for battery backup (disconnecting it from VCC) or providing a coin cell footprint on the HackRF PCB.
|
||||
|
||||
Coalesce separate headers into fewer, larger banks of headers, to reduce the number of unique, small header receptacles required for mating? Reducing the header count will also increase the amount of board space around the perimeter of a shield for components and connectors.
|
@ -7,6 +7,7 @@ Welcome to HackRF's documentation!
|
||||
:caption: User Documentation
|
||||
|
||||
hackrf_one
|
||||
jawbreaker
|
||||
opera_cake
|
||||
faq
|
||||
troubleshooting
|
||||
@ -45,14 +46,3 @@ Welcome to HackRF's documentation!
|
||||
expansion_interface
|
||||
hardware_triggering
|
||||
rf_shield_installation
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Retired Content
|
||||
|
||||
jawbreaker
|
||||
design_goals
|
||||
future_hardware_modifications
|
||||
lemondrop_bringup
|
||||
LPC4350
|
||||
|
||||
|
@ -1,239 +0,0 @@
|
||||
================================================
|
||||
Lemondrop Bring Up
|
||||
================================================
|
||||
|
||||
Board draws approximately 24mA from +3V3 when power is applied. This seems a bit high, but may be expected if not all parts are capable of low-power mode, or aren't configured for low power at power-on. I need to review the schematic and datasheets and see what can be done.
|
||||
|
||||
When I put my finger on the MAX2837, current consumption goes up. This suggests there may be floating nodes in that region of the circuit.
|
||||
|
||||
|
||||
Si5351 I2C
|
||||
~~~~~~~~~~
|
||||
|
||||
Attached crystal is 25MHz. For now, I'm assuming 10pF "internal load capacitance" is good enough to get the crystal oscillating. The crystal datasheet should be reviewed and measurements made...
|
||||
|
||||
Be sure to reference Silicon Labs application note 619 (AN619). The datasheet is a terrible mess (typos and lack of some details). AN619 appears to be less of a mess, on the whole. And as a bonus, AN619 has PDF bookmarks for each register.
|
||||
|
||||
|
||||
|
||||
Connections
|
||||
^^^^^^^^^^^
|
||||
|
||||
* Bus Pirate GND to P7 pin 1
|
||||
* Bus Pirate +3V3 to P7 pin 2 (through multimeter set to 200mA range)
|
||||
* Bus Pirate CLK to P7 pin 3
|
||||
* Bus Pirate MOSI to P7 pin 5
|
||||
|
||||
|
||||
|
||||
Bus Pirate I2C Initialization
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# set mode
|
||||
m
|
||||
# I2C mode
|
||||
4
|
||||
# ~100kHz speed
|
||||
3
|
||||
# power supplies ON
|
||||
W
|
||||
# macro 1: 7-bit address search
|
||||
(1)
|
||||
Searching I2C address space. Found devices at:
|
||||
0xC0(0x60 W) 0xC1(0x60 R)
|
||||
|
||||
I2C A0 address configuration pin (not available on QFN20 package) is apparently forced to "0".
|
||||
|
||||
|
||||
|
||||
Reading registers
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# Read register 0
|
||||
I2C>[0xc0 0[0xc1 r]]
|
||||
...
|
||||
# Register 0: SYS_INIT=0, LOL_B=0, LOL_A=0, LOS=1, REVID=0
|
||||
READ: 0x10
|
||||
...
|
||||
# Read 16 registers, starting with register 0
|
||||
I2C>[0xc0 0[0xc1 r:16]]
|
||||
...
|
||||
READ: 0x10 ACK 0xF8 ACK 0x03 ACK 0x00 ACK 0x00 ACK 0x00 ACK 0x8F ACK 0x01 ACK
|
||||
0x00 ACK 0x00 ACK 0x00 ACK 0x00 ACK 0x00 ACK 0x00 ACK 0x90 ACK 0x00
|
||||
...
|
||||
# Read 16 registers, starting with register 16
|
||||
I2C>[0xc0 16[0xc1 r:16]]
|
||||
...
|
||||
READ: 0x00 ACK 0x00 ACK 0x00 ACK 0x00 ACK 0x00 ACK 0x00 ACK 0x00 ACK 0x00 ACK
|
||||
0x00 ACK 0x00 ACK 0x00 ACK 0x00 ACK 0x00 ACK 0x00 ACK 0x00 ACK 0x00
|
||||
...
|
||||
|
||||
|
||||
|
||||
Writing registers
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
Simple XTAL passthrough to CLK0
|
||||
+++++++++++++++++++++++++++++++
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# Disable all CLKx outputs.
|
||||
[0xC0 3 0xFF]
|
||||
|
||||
# Turn off OEB pin control for all CLKx
|
||||
[0xC0 9 0xFF]
|
||||
|
||||
# Power down all CLKx
|
||||
[0xC0 16 0x80 0x80 0x80 0x80 0x80 0x80 0x80 0x80]
|
||||
|
||||
# Register 183: Crystal Internal Load Capacitance
|
||||
# Reads as 0xE4 on power-up
|
||||
# Set to 10pF (until I find out what loading the crystal/PCB likes best)
|
||||
[0xC0 183 0xE4]
|
||||
|
||||
# Register 187: Fanout Enable
|
||||
# Turn on XO fanout only.
|
||||
[0xC0 187 0x40]
|
||||
|
||||
# Register 15: PLL Input Source
|
||||
# CLKIN_DIV=0 (Divide by 1)
|
||||
# PLLB_SRC=0 (XTAL input)
|
||||
# PLLA_SRC=0 (XTAL input)
|
||||
[0xC0 15 0x00]
|
||||
|
||||
# Registers 16 through 23: CLKx Control
|
||||
# CLK0:
|
||||
# CLK0_PDN=0 (powered up)
|
||||
# MS0_INT=1 (integer mode)
|
||||
# MS0_SRC=0 (PLLA as source for MultiSynth 0)
|
||||
# CLK0_INV=0 (not inverted)
|
||||
# CLK0_SRC=0 (XTAL as clock source for CLK0)
|
||||
# CLK0_IDRV=3 (8mA)
|
||||
[0xC0 16 0x43 0x80 0x80 0x80 0x80 0x80 0x80 0x80]
|
||||
|
||||
# Enable CLK0 output only.
|
||||
[0xC0 3 0xFE]
|
||||
|
||||
|
||||
|
||||
Clocking Scheme (Work In Progress)
|
||||
++++++++++++++++++++++++++++++++++
|
||||
|
||||
From AN619: If Fxtal=25MHz, Fvco = Fxtal * (a + (b / c)). If we want Fvco = 800MHz, a = 32, b = 0, c = don't care.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
MSNA_P1[17:0] = 128 * a + floor(128 * b / c) - 512
|
||||
= 128 * a + floor(0) - 512
|
||||
= 128 * 32 + 0 - 512
|
||||
= 3584 = 0xE00
|
||||
MSNA_P1[17:16] (register 28) = 0x00
|
||||
MSNA_P1[15: 8] (register 29) = 0x0E
|
||||
MSNA_P1[ 7: 0] (register 30) = 0x00
|
||||
MSNA_P2[19:0] = 128 * b - c * floor(128 * b / c)
|
||||
= 128 * 0 - 0 * floor(128 * 0 / X)
|
||||
= 0
|
||||
MSNA_P3[19:0] = 0
|
||||
|
||||
MultiSynth0 should output 40MHz (800MHz VCO divided by 20):
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
a = 20, b = 0, c = X
|
||||
MS0_P1[17: 0] = 128 * a + floor(128 * b / c) - 512
|
||||
= 2048 = 0x800
|
||||
MS0_P1[17:16] (register 44) = 0x00
|
||||
MS0_P1[15: 8] (register 45) = 0x08
|
||||
MS0_P1[ 7: 0] (register 46) = 0x00
|
||||
MS0_P2[19:0] = 0
|
||||
MS0_P3[19:0] = 0
|
||||
|
||||
MultiSynth1 should output 20MHz (800MHz VCO divided by 40) or some smaller integer fraction of the VCO:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
a = 40, b = 0, c = X
|
||||
MS1_P1[17: 0] = 128 * a + floor(128 * b / c) - 512
|
||||
= 4608 = 0x1200
|
||||
MS1_P1[17:16] (register 52) = 0x00
|
||||
MS1_P1[15: 8] (register 53) = 0x12
|
||||
MS1_P1[ 7: 0] (register 54) = 0x00
|
||||
MS1_P2[19:0] = 0
|
||||
MS1_P3[19:0] = 0
|
||||
|
||||
Initialization:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# Disable all CLKx outputs.
|
||||
[0xC0 3 0xFF]
|
||||
|
||||
# Turn off OEB pin control for all CLKx
|
||||
[0xC0 9 0xFF]
|
||||
|
||||
# Power down all CLKx
|
||||
[0xC0 16 0x80 0x80 0x80 0x80 0x80 0x80 0x80 0x80]
|
||||
|
||||
# Register 183: Crystal Internal Load Capacitance
|
||||
# Reads as 0xE4 on power-up
|
||||
# Set to 10pF (until I find out what loading the crystal/PCB likes best)
|
||||
[0xC0 183 0xE4]
|
||||
|
||||
# Register 187: Fanout Enable
|
||||
# Turn on XO and MultiSynth fanout only.
|
||||
[0xC0 187 0x50]
|
||||
|
||||
# Register 15: PLL Input Source
|
||||
# CLKIN_DIV=0 (Divide by 1)
|
||||
# PLLB_SRC=0 (XTAL input)
|
||||
# PLLA_SRC=0 (XTAL input)
|
||||
[0xC0 15 0x00]
|
||||
|
||||
# MultiSynth NA (PLL1)
|
||||
[0xC0 26 0x00 0x00 0x00 0x0E 0x00 0x00 0x00 0x00]
|
||||
|
||||
# MultiSynth NB (PLL2)
|
||||
...
|
||||
|
||||
# MultiSynth 0
|
||||
[0xC0 42 0x00 0x00 0x00 0x08 0x00 0x00 0x00 0x00]
|
||||
|
||||
# MultiSynth 1
|
||||
[0xC0 50 0x00 0x00 0x00 0x12 0x00 0x00 0x00 0x00]
|
||||
|
||||
# Registers 16 through 23: CLKx Control
|
||||
# CLK0:
|
||||
# CLK0_PDN=0 (powered up)
|
||||
# MS0_INT=1 (integer mode)
|
||||
# MS0_SRC=0 (PLLA as source for MultiSynth 0)
|
||||
# CLK0_INV=0 (not inverted)
|
||||
# CLK0_SRC=3 (MS0 as input source)
|
||||
# CLK0_IDRV=3 (8mA)
|
||||
# CLK1:
|
||||
# CLK1_PDN=0 (powered up)
|
||||
# MS1_INT=1 (integer mode)
|
||||
# MS1_SRC=0 (PLLA as source for MultiSynth 1)
|
||||
# CLK1_INV=0 (not inverted)
|
||||
# CLK1_SRC=3 (MS1 as input source)
|
||||
# CLK1_IDRV=3 (8mA)
|
||||
[0xC0 16 0x4F 0x4F 0x80 0x80 0x80 0x80 0x80 0x80]
|
||||
|
||||
# Enable CLK0 output only.
|
||||
[0xC0 3 0xFC]
|
||||
|
||||
|
||||
|
||||
Si5351 output phase relationships
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Tested CLK4 and CLK5 (integer division only):
|
||||
|
||||
With CLK4 set to MS4 and CLK5 set to MS5, even with both multisynths configured identically, there was no consistent phase between the two. Once started, the clocks maintained relative phase with each other, but when stopped and restarted the initial phase offset was unpredictable.
|
||||
|
||||
With CLK4 and CLK5 both set to MS4, the phase of both outputs was identical when no output (R) divider was selected. When an output divider was selected on both MS4 and MS5, the relative phase became predictable only within the constraints of the divider (e.g. with R=2 the relative phase was always either 0 or half a cycle, with R=4 the relative phase was always either 0, a quarter, a half, or three quarters of a cycle). With R=1 on MS4 and R=2 on MS5, the two outputs were consistently in phase with each other. The output (R) dividers supposedly tied to the multisynths are actually tied to the outputs.
|
Reference in New Issue
Block a user