Merge branch 'abstract_i2c' into abstract_buses
Conflicts: firmware/common/hackrf_core.c firmware/common/hackrf_core.h firmware/hackrf-common.cmake
This commit is contained in:
@ -34,7 +34,8 @@
|
|||||||
#include "w25q80bv_target.h"
|
#include "w25q80bv_target.h"
|
||||||
#include "sgpio.h"
|
#include "sgpio.h"
|
||||||
#include "rf_path.h"
|
#include "rf_path.h"
|
||||||
#include <libopencm3/lpc43xx/i2c.h>
|
#include "i2c_bus.h"
|
||||||
|
#include "i2c_lpc.h"
|
||||||
#include <libopencm3/lpc43xx/cgu.h>
|
#include <libopencm3/lpc43xx/cgu.h>
|
||||||
#include <libopencm3/lpc43xx/gpio.h>
|
#include <libopencm3/lpc43xx/gpio.h>
|
||||||
#include <libopencm3/lpc43xx/scu.h>
|
#include <libopencm3/lpc43xx/scu.h>
|
||||||
@ -42,6 +43,33 @@
|
|||||||
|
|
||||||
#define WAIT_CPU_CLOCK_INIT_DELAY (10000)
|
#define WAIT_CPU_CLOCK_INIT_DELAY (10000)
|
||||||
|
|
||||||
|
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 = {
|
const ssp_config_t ssp_config_max2837 = {
|
||||||
/* FIXME speed up once everything is working reliably */
|
/* FIXME speed up once everything is working reliably */
|
||||||
/*
|
/*
|
||||||
@ -209,9 +237,9 @@ bool sample_rate_frac_set(uint32_t rate_num, uint32_t rate_denom)
|
|||||||
|
|
||||||
/* Can we enable integer mode ? */
|
/* Can we enable integer mode ? */
|
||||||
if (a & 0x1 || b)
|
if (a & 0x1 || b)
|
||||||
si5351c_set_int_mode(0, 0);
|
si5351c_set_int_mode(&clock_gen, 0, 0);
|
||||||
else
|
else
|
||||||
si5351c_set_int_mode(0, 1);
|
si5351c_set_int_mode(&clock_gen, 0, 1);
|
||||||
|
|
||||||
/* Final MS values */
|
/* Final MS values */
|
||||||
MSx_P1 = 128*a + (128 * b/c) - 512;
|
MSx_P1 = 128*a + (128 * b/c) - 512;
|
||||||
@ -219,13 +247,13 @@ bool sample_rate_frac_set(uint32_t rate_num, uint32_t rate_denom)
|
|||||||
MSx_P3 = c;
|
MSx_P3 = c;
|
||||||
|
|
||||||
/* MS0/CLK0 is the source for the MAX5864/CPLD (CODEC_CLK). */
|
/* 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). */
|
/* 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) */
|
/* 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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -265,13 +293,13 @@ bool sample_rate_set(const uint32_t sample_rate_hz) {
|
|||||||
* values are irrelevant. */
|
* values are irrelevant. */
|
||||||
|
|
||||||
/* MS0/CLK1 is the source for the MAX5864 codec. */
|
/* 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). */
|
/* 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. */
|
/* 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;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
@ -328,13 +356,13 @@ bool sample_rate_set(const uint32_t sample_rate_hz) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* MS0/CLK0 is the source for the MAX5864/CPLD (CODEC_CLK). */
|
/* 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). */
|
/* 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) */
|
/* 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;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
@ -355,15 +383,15 @@ void cpu_clock_init(void)
|
|||||||
/* use IRC as clock source for APB3 */
|
/* use IRC as clock source for APB3 */
|
||||||
CGU_BASE_APB3_CLK = CGU_BASE_APB3_CLK_CLK_SEL(CGU_SRC_IRC);
|
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_all_outputs(&clock_gen);
|
||||||
si5351c_disable_oeb_pin_control();
|
si5351c_disable_oeb_pin_control(&clock_gen);
|
||||||
si5351c_power_down_all_clocks();
|
si5351c_power_down_all_clocks(&clock_gen);
|
||||||
si5351c_set_crystal_configuration();
|
si5351c_set_crystal_configuration(&clock_gen);
|
||||||
si5351c_enable_xo_and_ms_fanout();
|
si5351c_enable_xo_and_ms_fanout(&clock_gen);
|
||||||
si5351c_configure_pll_sources();
|
si5351c_configure_pll_sources(&clock_gen);
|
||||||
si5351c_configure_pll_multisynth();
|
si5351c_configure_pll_multisynth(&clock_gen);
|
||||||
|
|
||||||
#ifdef JELLYBEAN
|
#ifdef JELLYBEAN
|
||||||
/*
|
/*
|
||||||
@ -379,13 +407,13 @@ void cpu_clock_init(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* MS0/CLK0 is the source for the MAX2837 clock input. */
|
/* 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. */
|
/* 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. */
|
/* 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
|
#endif
|
||||||
|
|
||||||
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
||||||
@ -402,32 +430,32 @@ void cpu_clock_init(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* MS3/CLK3 is the source for the external clock output. */
|
/* 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. */
|
/* 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. */
|
/* 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. */
|
/* MS6/CLK6 is unused. */
|
||||||
/* MS7/CLK7 is the source for the LPC43xx microcontroller. */
|
/* MS7/CLK7 is the source for the LPC43xx microcontroller. */
|
||||||
uint8_t ms7data[] = { 90, 255, 20, 0 };
|
uint8_t ms7data[] = { 90, 255, 20, 0 };
|
||||||
si5351c_write(ms7data, sizeof(ms7data));
|
si5351c_write(&clock_gen, ms7data, sizeof(ms7data));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set to 10 MHz, the common rate between Jellybean and Jawbreaker. */
|
/* Set to 10 MHz, the common rate between Jellybean and Jawbreaker. */
|
||||||
sample_rate_set(10000000);
|
sample_rate_set(10000000);
|
||||||
|
|
||||||
si5351c_set_clock_source(PLL_SOURCE_XTAL);
|
si5351c_set_clock_source(&clock_gen, PLL_SOURCE_XTAL);
|
||||||
// soft reset
|
// soft reset
|
||||||
uint8_t resetdata[] = { 177, 0xac };
|
uint8_t resetdata[] = { 177, 0xac };
|
||||||
si5351c_write(resetdata, sizeof(resetdata));
|
si5351c_write(&clock_gen, resetdata, sizeof(resetdata));
|
||||||
si5351c_enable_clock_outputs();
|
si5351c_enable_clock_outputs(&clock_gen);
|
||||||
|
|
||||||
//FIXME disable I2C
|
//FIXME disable I2C
|
||||||
/* Kick I2C0 down to 400kHz when we switch over to APB1 clock = 204MHz */
|
/* 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
|
* 12MHz clock is entering LPC XTAL1/OSC input now. On
|
||||||
@ -652,6 +680,9 @@ void pin_setup(void) {
|
|||||||
/* GPIO3[6] on P6_10 as output. */
|
/* GPIO3[6] on P6_10 as output. */
|
||||||
GPIO3_DIR |= PIN_EN1V8;
|
GPIO3_DIR |= PIN_EN1V8;
|
||||||
|
|
||||||
|
/* enable input on SCL and SDA pins */
|
||||||
|
SCU_SFSI2C0 = SCU_I2C0_NOMINAL;
|
||||||
|
|
||||||
spi_bus_start(&spi_bus_ssp1, &ssp_config_max2837);
|
spi_bus_start(&spi_bus_ssp1, &ssp_config_max2837);
|
||||||
spi_bus_start(&spi_bus_rffc5071, NULL);
|
spi_bus_start(&spi_bus_rffc5071, NULL);
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ extern "C"
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "si5351c.h"
|
||||||
#include "spi_ssp.h"
|
#include "spi_ssp.h"
|
||||||
|
|
||||||
#include "max2837.h"
|
#include "max2837.h"
|
||||||
@ -358,6 +359,7 @@ typedef enum {
|
|||||||
void delay(uint32_t duration);
|
void delay(uint32_t duration);
|
||||||
|
|
||||||
/* TODO: Hide these configurations */
|
/* 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_w25q80bv;
|
||||||
extern const ssp_config_t ssp_config_max2837;
|
extern const ssp_config_t ssp_config_max2837;
|
||||||
extern const ssp_config_t ssp_config_max5864;
|
extern const ssp_config_t ssp_config_max5864;
|
||||||
|
39
firmware/common/i2c_bus.c
Normal file
39
firmware/common/i2c_bus.c
Normal 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
52
firmware/common/i2c_bus.h
Normal 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
62
firmware/common/i2c_lpc.c
Normal 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
42
firmware/common/i2c_lpc.h
Normal 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__*/
|
@ -21,73 +21,50 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "si5351c.h"
|
#include "si5351c.h"
|
||||||
#include <libopencm3/lpc43xx/i2c.h>
|
|
||||||
|
|
||||||
enum pll_sources active_clock_source;
|
enum pll_sources active_clock_source;
|
||||||
|
|
||||||
/* FIXME return i2c0 status from each function */
|
|
||||||
|
|
||||||
/* write to single register */
|
/* 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();
|
const uint8_t data_tx[] = { reg, val };
|
||||||
i2c0_tx_byte(SI5351C_I2C_ADDR | I2C_WRITE);
|
si5351c_write(drv, data_tx, 2);
|
||||||
i2c0_tx_byte(reg);
|
|
||||||
i2c0_tx_byte(val);
|
|
||||||
i2c0_stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read single register */
|
/* 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;
|
const uint8_t data_tx[] = { reg };
|
||||||
|
uint8_t data_rx[] = { 0x00 };
|
||||||
/* set register address with write */
|
i2c_bus_transfer(drv->bus, drv->i2c_address, data_tx, 1, data_rx, 1);
|
||||||
i2c0_tx_start();
|
return data_rx[0];
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write to one or more contiguous registers. data[0] should be the first
|
* Write to one or more contiguous registers. data[0] should be the first
|
||||||
* register number, one or more values follow.
|
* 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;
|
i2c_bus_transfer(drv->bus, drv->i2c_address, data, data_count, NULL, 0);
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable all CLKx outputs. */
|
/* Disable all CLKx outputs. */
|
||||||
void si5351c_disable_all_outputs()
|
void si5351c_disable_all_outputs(si5351c_driver_t* const drv)
|
||||||
{
|
{
|
||||||
uint8_t data[] = { 3, 0xFF };
|
uint8_t data[] = { 3, 0xFF };
|
||||||
si5351c_write(data, sizeof(data));
|
si5351c_write(drv, data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Turn off OEB pin control for all CLKx */
|
/* 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 };
|
uint8_t data[] = { 9, 0xFF };
|
||||||
si5351c_write(data, sizeof(data));
|
si5351c_write(drv, data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Power down all CLKx */
|
/* 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
|
uint8_t data[] = { 16
|
||||||
, SI5351C_CLK_POWERDOWN
|
, 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_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
|
* Reads as 0xE4 on power-up
|
||||||
* Set to 8pF based on crystal specs and HackRF One testing
|
* 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 };
|
uint8_t data[] = { 183, 0x80 };
|
||||||
si5351c_write(data, sizeof(data));
|
si5351c_write(drv, data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register 187: Fanout Enable
|
* Register 187: Fanout Enable
|
||||||
* Turn on XO and MultiSynth fanout only.
|
* 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 };
|
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)
|
* PLLA_SRC=0 (XTAL)
|
||||||
* PLLB_SRC=1 (CLKIN)
|
* 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 };
|
uint8_t data[] = { 15, 0x08 };
|
||||||
|
|
||||||
si5351c_write(data, sizeof(data));
|
si5351c_write(drv, data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MultiSynth NA (PLLA) and NB (PLLB) */
|
/* 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
|
//init plla to (0x0e00+512)/128*25mhz xtal = 800mhz -> int mode
|
||||||
uint8_t data[] = { 26, 0x00, 0x01, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00 };
|
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 */
|
/* 10 MHz input on CLKIN for PLLB */
|
||||||
data[0] = 34;
|
data[0] = 34;
|
||||||
data[4] = 0x26;
|
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 */
|
/* reset PLLA and PLLB */
|
||||||
uint8_t data[] = { 177, 0xA0 };
|
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 uint32_t p1, const uint32_t p2, const uint32_t p3,
|
||||||
const uint_fast8_t r_div)
|
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),
|
(((p3 >> 16) & 0xF) << 4) | (((p2 >> 16) & 0xF) << 0),
|
||||||
(p2 >> 8) & 0xFF,
|
(p2 >> 8) & 0xFF,
|
||||||
(p2 >> 0) & 0xFF };
|
(p2 >> 0) & 0xFF };
|
||||||
si5351c_write(data, sizeof(data));
|
si5351c_write(drv, data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JELLYBEAN
|
#ifdef JELLYBEAN
|
||||||
@ -232,15 +210,15 @@ void si5351c_configure_multisynth(const uint_fast8_t ms_number,
|
|||||||
* CLK5_SRC=3 (MS5 as input source)
|
* CLK5_SRC=3 (MS5 as input source)
|
||||||
* CLK5_IDRV=3 (8mA)
|
* 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 };
|
uint8_t data[] = { 16, 0x4F, 0x4B, 0x4B, 0x4B, 0x0F, 0x4F, 0xC0, 0xC0 };
|
||||||
si5351c_write(data, sizeof(data));
|
si5351c_write(drv, data, sizeof(data));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined JAWBREAKER || defined HACKRF_ONE)
|
#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;
|
uint8_t pll;
|
||||||
|
|
||||||
@ -261,54 +239,54 @@ 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_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(pll) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA)
|
,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
|
#endif
|
||||||
|
|
||||||
/* Enable CLK outputs 0, 1, 2, 3, 4, 5, 7 only. */
|
/* Enable CLK outputs 0, 1, 2, 3, 4, 5, 7 only. */
|
||||||
void si5351c_enable_clock_outputs()
|
void si5351c_enable_clock_outputs(si5351c_driver_t* const drv)
|
||||||
{
|
{
|
||||||
uint8_t data[] = { 3, 0x40 };
|
uint8_t data[] = { 3, 0x40 };
|
||||||
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};
|
uint8_t data[] = {16, 0};
|
||||||
|
|
||||||
if(ms_number < 8){
|
if(ms_number < 8){
|
||||||
data[0] = 16 + ms_number;
|
data[0] = 16 + ms_number;
|
||||||
data[1] = si5351c_read_single(data[0]);
|
data[1] = si5351c_read_single(drv, data[0]);
|
||||||
|
|
||||||
if(on)
|
if(on)
|
||||||
data[1] |= SI5351C_CLK_INT_MODE;
|
data[1] |= SI5351C_CLK_INT_MODE;
|
||||||
else
|
else
|
||||||
data[1] &= ~(SI5351C_CLK_INT_MODE);
|
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;
|
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) {
|
if (device_status & SI5351C_LOS) {
|
||||||
/* CLKIN not detected */
|
/* CLKIN not detected */
|
||||||
if (active_clock_source == PLL_SOURCE_CLKIN) {
|
if (active_clock_source == PLL_SOURCE_CLKIN) {
|
||||||
si5351c_set_clock_source(PLL_SOURCE_XTAL);
|
si5351c_set_clock_source(drv, PLL_SOURCE_XTAL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* CLKIN detected */
|
/* CLKIN detected */
|
||||||
if (active_clock_source == PLL_SOURCE_XTAL) {
|
if (active_clock_source == PLL_SOURCE_XTAL) {
|
||||||
si5351c_set_clock_source(PLL_SOURCE_CLKIN);
|
si5351c_set_clock_source(drv, PLL_SOURCE_CLKIN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,9 @@ extern "C"
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "i2c_bus.h"
|
||||||
|
|
||||||
#define SI_INTDIV(x) (x*128-512)
|
#define SI_INTDIV(x) (x*128-512)
|
||||||
#define SI5351C_I2C_ADDR (0x60 << 1)
|
|
||||||
|
|
||||||
#define SI5351C_CLK_POWERDOWN (1<<7)
|
#define SI5351C_CLK_POWERDOWN (1<<7)
|
||||||
#define SI5351C_CLK_INT_MODE (1<<6)
|
#define SI5351C_CLK_INT_MODE (1<<6)
|
||||||
@ -62,26 +63,32 @@ enum pll_sources {
|
|||||||
PLL_SOURCE_CLKIN = 1,
|
PLL_SOURCE_CLKIN = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
void si5351c_disable_all_outputs();
|
typedef struct {
|
||||||
void si5351c_disable_oeb_pin_control();
|
i2c_bus_t* const bus;
|
||||||
void si5351c_power_down_all_clocks();
|
uint8_t i2c_address;
|
||||||
void si5351c_set_crystal_configuration();
|
} si5351c_driver_t;
|
||||||
void si5351c_enable_xo_and_ms_fanout();
|
|
||||||
void si5351c_configure_pll_sources(void);
|
void si5351c_disable_all_outputs(si5351c_driver_t* const drv);
|
||||||
void si5351c_configure_pll_multisynth(void);
|
void si5351c_disable_oeb_pin_control(si5351c_driver_t* const drv);
|
||||||
void si5351c_reset_pll(void);
|
void si5351c_power_down_all_clocks(si5351c_driver_t* const drv);
|
||||||
void si5351c_configure_multisynth(const uint_fast8_t ms_number,
|
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 uint32_t p1, const uint32_t p2, const uint32_t p3,
|
||||||
const uint_fast8_t r_div);
|
const uint_fast8_t r_div);
|
||||||
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);
|
||||||
void si5351c_enable_clock_outputs();
|
void si5351c_enable_clock_outputs(si5351c_driver_t* const drv);
|
||||||
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);
|
||||||
|
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);
|
void si5351c_write_single(si5351c_driver_t* const drv, uint8_t reg, uint8_t val);
|
||||||
uint8_t si5351c_read_single(uint8_t reg);
|
uint8_t si5351c_read_single(si5351c_driver_t* const drv, uint8_t reg);
|
||||||
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);
|
||||||
void si5351c_set_clock_source(const enum pll_sources source);
|
|
||||||
void si5351c_activate_best_clock_source(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -139,6 +139,8 @@ macro(DeclareTargets)
|
|||||||
${PATH_HACKRF_FIRMWARE_COMMON}/max5864.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/max5864.c
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/max5864_target.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/max5864_target.c
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/rffc5071.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/rffc5071.c
|
||||||
|
${PATH_HACKRF_FIRMWARE_COMMON}/i2c_bus.c
|
||||||
|
${PATH_HACKRF_FIRMWARE_COMMON}/i2c_lpc.c
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/rffc5071_spi.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/rffc5071_spi.c
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/w25q80bv.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/w25q80bv.c
|
||||||
${PATH_HACKRF_FIRMWARE_COMMON}/w25q80bv_target.c
|
${PATH_HACKRF_FIRMWARE_COMMON}/w25q80bv_target.c
|
||||||
|
@ -75,7 +75,7 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( _transceiver_mode != TRANSCEIVER_MODE_OFF ) {
|
if( _transceiver_mode != TRANSCEIVER_MODE_OFF ) {
|
||||||
si5351c_activate_best_clock_source();
|
si5351c_activate_best_clock_source(&clock_gen);
|
||||||
baseband_streaming_enable();
|
baseband_streaming_enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,9 @@
|
|||||||
|
|
||||||
#include "usb_api_register.h"
|
#include "usb_api_register.h"
|
||||||
|
|
||||||
|
#include <hackrf_core.h>
|
||||||
#include <usb_queue.h>
|
#include <usb_queue.h>
|
||||||
#include <max2837.h>
|
#include <max2837.h>
|
||||||
#include <si5351c.h>
|
|
||||||
#include <rffc5071.h>
|
#include <rffc5071.h>
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -77,7 +77,7 @@ usb_request_status_t usb_vendor_request_write_si5351c(
|
|||||||
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
||||||
if( endpoint->setup.index < 256 ) {
|
if( endpoint->setup.index < 256 ) {
|
||||||
if( endpoint->setup.value < 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);
|
usb_transfer_schedule_ack(endpoint->in);
|
||||||
return USB_REQUEST_STATUS_OK;
|
return USB_REQUEST_STATUS_OK;
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ usb_request_status_t usb_vendor_request_read_si5351c(
|
|||||||
) {
|
) {
|
||||||
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
if( stage == USB_TRANSFER_STAGE_SETUP ) {
|
||||||
if( endpoint->setup.index < 256 ) {
|
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;
|
endpoint->buffer[0] = value;
|
||||||
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1,
|
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
Submodule firmware/libopencm3 updated: 854c112a0e...10503c7cc1
Reference in New Issue
Block a user