diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 792beec3..a562f7c6 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -27,7 +27,8 @@ #include "rffc5071.h" #include "sgpio.h" #include "rf_path.h" -#include +#include "i2c_bus.h" +#include "i2c_lpc.h" #include #include #include @@ -35,7 +36,28 @@ #define WAIT_CPU_CLOCK_INIT_DELAY (10000) +i2c_bus_t i2c0 = { + .obj = (void*)I2C0_BASE, + .init = i2c_lpc_init, + .transfer = i2c_lpc_transfer, +}; + +i2c_bus_t i2c1 = { + .obj = (void*)I2C1_BASE, + .init = i2c_lpc_init, + .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, }; @@ -268,7 +290,7 @@ 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_init(clock_gen.bus, &i2c_config_si5351c_slow_clock); si5351c_disable_all_outputs(&clock_gen); si5351c_disable_oeb_pin_control(&clock_gen); @@ -340,7 +362,7 @@ void cpu_clock_init(void) //FIXME disable I2C /* Kick I2C0 down to 400kHz when we switch over to APB1 clock = 204MHz */ - i2c0_init(255); + i2c_bus_init(clock_gen.bus, &i2c_config_si5351c_fast_clock); /* * 12MHz clock is entering LPC XTAL1/OSC input now. On @@ -615,6 +637,9 @@ void pin_setup(void) { /* GPIO3[6] on P6_10 as output. */ GPIO3_DIR |= PIN_EN1V8; + /* enable input on SCL and SDA pins */ + SCU_SFSI2C0 = SCU_I2C0_NOMINAL; + rf_path_pin_setup(); /* Configure SSP1 Peripheral (to be moved later in SSP driver) */ diff --git a/firmware/common/i2c_bus.c b/firmware/common/i2c_bus.c new file mode 100644 index 00000000..6b60455a --- /dev/null +++ b/firmware/common/i2c_bus.c @@ -0,0 +1,35 @@ +/* + * 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_init(i2c_bus_t* const bus, const void* const config) { + bus->init(bus, config); +} + +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); +} diff --git a/firmware/common/i2c_bus.h b/firmware/common/i2c_bus.h new file mode 100644 index 00000000..784fb602 --- /dev/null +++ b/firmware/common/i2c_bus.h @@ -0,0 +1,50 @@ +/* + * 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 +#include + +struct i2c_bus_t; +typedef struct i2c_bus_t i2c_bus_t; + +struct i2c_bus_t { + void* const obj; + void (*init)(i2c_bus_t* const bus, const void* const config); + 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_init(i2c_bus_t* const bus, const void* const config); +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__*/ diff --git a/firmware/common/i2c_lpc.c b/firmware/common/i2c_lpc.c new file mode 100644 index 00000000..73c3e92c --- /dev/null +++ b/firmware/common/i2c_lpc.c @@ -0,0 +1,57 @@ +/* + * Copyright 2012 Michael Ossmann + * Copyright 2012 Jared Boone + * + * 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 + +/* FIXME return i2c0 status from each function */ + +void i2c_lpc_init(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_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 +#include + +#include "i2c_bus.h" + +typedef struct i2c_lpc_config_t { + const uint16_t duty_cycle_count; +} i2c_lpc_config_t; + +void i2c_lpc_init(i2c_bus_t* const bus, const void* const config); +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__*/ diff --git a/firmware/common/si5351c_drv.c b/firmware/common/si5351c_drv.c index e2c87eff..2b788842 100644 --- a/firmware/common/si5351c_drv.c +++ b/firmware/common/si5351c_drv.c @@ -22,36 +22,6 @@ #include "si5351c_drv.h" -#include - -#define SI5351C_I2C_ADDR (0x60 << 1) - -/* FIXME return i2c0 status from each function */ - -static void i2c0_transfer(si5351c_driver_t* const drv, - const uint_fast8_t address, - const uint8_t* const data_tx, const size_t count_tx, - uint8_t* const data_rx, const size_t count_rx -) { - (void)drv; - - i2c0_tx_start(); - i2c0_tx_byte((address << 1) | I2C_WRITE); - for(size_t i=0; ii2c_address, data_tx, 1, data_rx, 1); + i2c_bus_transfer(drv->bus, drv->i2c_address, data_tx, 1, data_rx, 1); return data_rx[0]; } @@ -74,5 +44,5 @@ 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) { - i2c0_transfer(drv, drv->i2c_address, data, data_count, NULL, 0); + i2c_bus_transfer(drv->bus, drv->i2c_address, data, data_count, NULL, 0); } diff --git a/firmware/common/si5351c_drv.h b/firmware/common/si5351c_drv.h index 147e91fa..acb71459 100644 --- a/firmware/common/si5351c_drv.h +++ b/firmware/common/si5351c_drv.h @@ -31,7 +31,10 @@ extern "C" #include #include +#include "i2c_bus.h" + typedef struct { + i2c_bus_t* const bus; uint8_t i2c_address; } si5351c_driver_t; diff --git a/firmware/hackrf-common.cmake b/firmware/hackrf-common.cmake index 9b4fb9a9..decd2bed 100644 --- a/firmware/hackrf-common.cmake +++ b/firmware/hackrf-common.cmake @@ -138,6 +138,8 @@ macro(DeclareTargets) ${PATH_HACKRF_FIRMWARE_COMMON}/max2837.c ${PATH_HACKRF_FIRMWARE_COMMON}/max5864.c ${PATH_HACKRF_FIRMWARE_COMMON}/rffc5071.c + ${PATH_HACKRF_FIRMWARE_COMMON}/i2c_bus.c + ${PATH_HACKRF_FIRMWARE_COMMON}/i2c_lpc.c m0_bin.s ) diff --git a/firmware/libopencm3 b/firmware/libopencm3 index 854c112a..aec04e96 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit 854c112a0ea7b27e85a15345507c8a2e13e76607 +Subproject commit aec04e962c2264877580be30fe1e1178ce3f568c