Compare commits

...
This repository has been archived on 2022-02-18. You can view files and clone it, but cannot push or open issues or pull requests.

70 Commits

Author SHA1 Message Date
Dimitri Stolnikov ba4fd96622 cross platform usleep() 2015-12-11 18:45:23 +01:00
Harald Welte 6a2d224311 slim_pro.c: Fix format string related compiler warning 2015-11-07 15:57:16 +01:00
Steve Markgraf effcaa75bf cmake: detect libusb on FreeBSD
Source:
http://patch-tracker.debian.org/patch/series/view/libosmosdr/0.1.7.cd37e9-2/libusb-freebsd

Signed-off-by: Steve Markgraf <steve@steve-m.de>
2013-11-17 19:17:02 +01:00
Dimitri Stolnikov cd37e9fab1 software/libosmosdr: remove spaces from Makefile template 2012-12-08 20:04:48 +01:00
Dimitri Stolnikov d79e4f8dca don't install udev rules by default, as it may pollute the system
For cmake call with -DINSTALL_UDEV_RULES=ON for the rules to be
installed during the default install/uninstall stages.

For autotools call "make install-udev-rules" or "make uninstall-udev-

The rules file will be installed to "/etc/udev/rules.d".
2012-09-08 16:45:01 +02:00
Dimitri Stolnikov b81bf9a481 install (and uninstall) udev rules file 2012-09-02 22:15:36 +02:00
Dimitri Stolnikov a09144bc88 implement a more robust cancelation mechanism of async reader 2012-08-08 21:20:59 +02:00
Dimitri Stolnikov 14f7dd4461 disable e4k enhanced mixer gain as it seems to have no effect 2012-08-05 16:36:58 +02:00
Dimitri Stolnikov edbcf3352d change si570.h permissions to 644 2012-07-14 19:35:41 +02:00
Harald Welte dc23dc5a81 include auto-generated GIT_REVISION into the DFU and firmware builds
At the moment it is only shown on the serial console, though.
2012-06-25 15:09:55 +02:00
Dimitri Stolnikov 233c5b7201 fix symbol visibility for automake builds 2012-06-13 01:30:08 +02:00
Dimitri Stolnikov 9e2a7e199a sanitize internal and external return codes 2012-06-09 19:46:05 +02:00
Dimitri Stolnikov e91056e736 automake: define pkg-config variables 2012-06-07 22:39:19 +02:00
Dimitri Stolnikov a630fc0810 implement setting the sample rate 2012-06-06 00:44:04 +02:00
Christian Daniel 323af344fa set TWI/I2C speed to 400kHz - all devices on the OsmoSDR support this 2012-06-05 21:28:58 +02:00
Christian Daniel 2dd491881e e4k: fix return value of debug function 2012-06-05 21:28:34 +02:00
Christian Daniel 1982ab41fe USB: fix statemachine to prevent bulk ep hang 2012-06-05 20:51:00 +02:00
Christian Daniel bf8d829201 req queue: resize buffers and fix irq enable/disable 2012-06-05 20:50:38 +02:00
Christian Daniel 26bea49a7e remove generic USB debugging printf 2012-06-05 20:50:05 +02:00
Christian Daniel d62195b046 proper e4k init 2012-06-05 20:48:22 +02:00
Christian Daniel b93708ed1d add lots of debugging stuff 2012-06-05 20:48:09 +02:00
Dimitri Stolnikov 41eb541606 fix access violation error 2012-06-02 16:49:51 +02:00
Dimitri Stolnikov 292a986830 introduce getters for tuner parameters (gain, type) 2012-06-02 01:41:04 +02:00
Christian Daniel a2382d66d8 fix fix of fix for mixer_gain API 2012-06-01 00:31:39 +02:00
Christian Daniel d8d2cfc785 fix typo 2012-06-01 00:31:12 +02:00
Christian Daniel 4eed4e7870 provide accessors for expanded USB API 2012-06-01 00:17:33 +02:00
Christian Daniel 35355c704c expand USB API 2012-06-01 00:17:15 +02:00
Christian Daniel a5d9d2de81 swap I/Q by default (OsmoSDR is q first) 2012-06-01 00:16:28 +02:00
Christian Daniel 399d41474f added accessor functions for specific FPGA registers 2012-06-01 00:15:55 +02:00
Christian Daniel 83340d0b37 new fpga firmware - sorry, only one blob
new features:

- bit to swap I and Q (spectrum inversion)

- make GPS PPS input usable as clock reference (PPS acts as clock gate
  for a counter)

- change unused pins into GPIOs (input, output, etc. configuration via
  SPI register bank)

- LED connected to FPGA can be switched on and off

have a look at the updated register description ODF/PDF
2012-05-30 22:28:38 +02:00
Christian Daniel 1c329c8165 fix mixer setting in libosmosdr 2012-05-30 22:03:27 +02:00
Christian Daniel dda6e9c4cb add workaround for E4K gap between 325-350 MHz 2012-05-30 21:59:36 +02:00
Christian Daniel 83ebd2b310 add a few debug strings 2012-05-30 21:59:07 +02:00
Steve Markgraf e69305dedd fix build of usb-dfu-project
Signed-off-by: Steve Markgraf <steve@steve-m.de>
2012-05-29 15:27:50 +02:00
Dimitri Stolnikov e1cef7b07b fix vid case in udev rules file 2012-05-27 19:28:36 +02:00
Dimitri Stolnikov c9e015c711 fix c&p error 2012-05-27 15:34:49 +02:00
Dimitri Stolnikov 4c49d57323 fix gain setting in CLI tool 2012-05-27 15:19:14 +02:00
Dimitri Stolnikov bcc45534de add preliminary tuner control 2012-05-27 15:17:39 +02:00
Christian Daniel f3f7a28cf8 add bulk mode and initial USB API 2012-05-26 22:19:49 +02:00
Christian Daniel 65f6e41c56 export subsystem structs and add support for bulk mode 2012-05-26 22:19:08 +02:00
Christian Daniel e28725c0dc remove a few debug messages to clean the output 2012-05-26 22:17:43 +02:00
Christian Daniel 3ee2b7e52d add bulk EP descriptors (switchable by #define) 2012-05-26 22:17:08 +02:00
Christian Daniel 6023743202 add an API function to directly write to an SI570 register 2012-05-26 22:14:33 +02:00
Christian Daniel 180193cecf import modified E4000 driver from rtl-sdr 2012-05-26 22:13:59 +02:00
Dimitri Stolnikov 5b2f5902b0 libosmosdr: update USB endpoint used for IQ streaming 2012-05-25 00:15:41 +02:00
Dimitri Stolnikov 8650ea86db add osmo_sdr utility 2012-05-20 16:44:57 +02:00
Dimitri Stolnikov 7d90bb808a introduce api function to read usb string descriptors
This API allows to read manufacturer and product names as well as the
serial number advertized by the device on the bus.
2012-05-20 16:43:59 +02:00
Dimitri Stolnikov 129324b3dd rename osmosdr.c to libosmosdr.c 2012-05-20 14:02:53 +02:00
Christian Daniel be360a2d60 added register description for FPGA firmware 2012-05-17 22:55:31 +02:00
Christian Daniel 5dcfd6a156 added DFU functionality for the FPGA - crudely removed stuff from the loader to make it fit into the 16k 2012-05-17 22:47:51 +02:00
Christian Daniel c46bad77e5 add vmelinearize utility, which combines algo and data-file from Diamond into a single DFUable file 2012-05-17 22:28:19 +02:00
Christian Daniel 2672f450de added fpga firmware images corresponding to source code 2012-05-17 22:22:37 +02:00
Christian Daniel c62f5734b7 added fpga source and project files for hardware v2 2012-05-17 22:18:26 +02:00
Christian Daniel 0f007d876a added schematics and board layout for hardware v2 (release) 2012-05-17 22:17:48 +02:00
Dimitri Stolnikov d01cbad359 add api version information to the library when building with cmake 2012-05-15 18:14:20 +02:00
Dimitri Stolnikov 5140eade9f fix a typo in Makefile.am 2012-05-14 20:46:50 +02:00
Dimitri Stolnikov 790aa13a5b fix a memory leak by unreferencing libusb devices 2012-05-12 16:08:02 +02:00
Dimitri Stolnikov c4ed664383 install pkg-config file when building with cmake 2012-05-12 16:07:41 +02:00
Dimitri Stolnikov ce0473f5fe initial commit of libosmosdr files
this is largely based on the code of rtl-sdr project.
2012-05-12 00:23:41 +02:00
Harald Welte ad240d9de9 update the readme 2012-05-08 21:17:22 +02:00
Harald Welte aa3c92f0ff rename sdr-test-project to osmosr-project 2012-05-08 21:12:47 +02:00
Dimitri Stolnikov 707d664b73 remove gr-osmo-sdr block files
Further development will be happening in git://git.osmocom.org/gr-osmosdr repository.
2012-04-06 16:22:37 +02:00
Sylvain Munaut ca53c22150 fw/tuner_e4k: Add some more magic init
It comes from the kernel driver. No idea what it does really ...

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2012-04-02 09:06:20 +02:00
Sylvain Munaut 088d53127b fw/tuner_e4k: Add function to enable/disable the IF channel filter
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2012-04-02 09:06:12 +02:00
Sylvain Munaut 6593b2be38 fw/tuner_e4k: Disable auto gain adjustement during DC table gen
We need them to be fixed during that time, so disable all auto
stuff

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2012-04-02 09:06:06 +02:00
Sylvain Munaut f1939647b4 fw/tuner_e4k: Avoid dual read of DC4 when generating DC table
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2012-04-02 09:06:00 +02:00
Sylvain Munaut 20487e8cb3 fw/tuner_e4k: DC offset table gen doc fixes
No we don't need to wait. I checked if the value ever changed after
the first read and it doesn't. Other e4k drivers don't wait either.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2012-04-02 09:05:55 +02:00
Sylvain Munaut a99f1b530e fw/tuner_e4k: Use signed int for if1_gain in the gain combination array
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2012-04-02 09:05:50 +02:00
Sylvain Munaut 0bcf409c54 fw/tuner_e4k: Mixer gain is 4 or 12 dB, not 0/12
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2012-04-02 09:05:46 +02:00
Sylvain Munaut 1d28c3065b fw/tuner_e4k: Fix the array_size of the filter fw settings.
This was causing the array length to be '1' and so we always
took the first possible setting (the widest) ...

Certainly not good when you only have a 500 kHz sample rate.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2012-04-02 09:05:40 +02:00
171 changed files with 14217 additions and 18021 deletions

View File

@ -5,3 +5,19 @@ repository: git://git.gnumonks.org/at91lib.git
You need to put the at91lib and osmo-sdr into the same parent directory
or adjust the paths in sdr-test-project/Makefile to match your layout.
There are two independent progams you can build:
1) usb-dfu-project
This is the bootloader that we flash into the DFU partition
at the start of the flash
2) osmosdr-project
This is the actual OsmoSDR firmware. There are two builds:
a) smo-sdr-test-osmo-sdr-at91sam3u4-dfu.bin
This is the image that you can flash into the DFU partition
using DFU itself
b) smo-sdr-test-osmo-sdr-at91sam3u4-flash.bin
This is a self-contained program that you can flash to the
beginning of the flash (in case you don't want to use DFU)

View File

@ -30,5 +30,6 @@ extern unsigned char fastsource_interfaces[3];
void fastsource_init(void);
void fastsource_start(void);
void fastsource_dump(void);
void usb_submit_req_ctx(struct req_ctx *rctx);

View File

@ -8,11 +8,19 @@ enum osdr_fpga_reg {
OSDR_FPGA_REG_ADC_TIMING = 3,
OSDR_FPGA_REG_DUMMY = 4,
OSDR_FPGA_REG_ADC_VAL = 5,
OSDR_FPGA_REG_DECIMATION = 6,
OSDR_FPGA_REG_IQ_OFS = 7,
OSDR_FPGA_REG_IQ_GAIN = 8,
OSDR_FPGA_REG_IQ_SWAP = 9,
};
void osdr_fpga_power(int on);
void osdr_fpga_init(uint32_t masterClock);
uint32_t osdr_fpga_reg_read(uint8_t reg);
void osdr_fpga_reg_write(uint8_t reg, uint32_t val);
void osdr_fpga_set_decimation(uint8_t val);
void osdr_fpga_set_iq_swap(uint8_t val);
void osdr_fpga_set_iq_gain(uint16_t igain, uint16_t qgain);
void osdr_fpga_set_iq_ofs(int16_t iofs, int16_t qofs);
#endif

View File

@ -50,4 +50,6 @@ extern uint8_t req_ctx_num(struct req_ctx *ctx);
void req_ctx_enqueue(struct llist_head *list, struct req_ctx *rctx);
struct req_ctx *req_ctx_dequeue(struct llist_head *list);
void req_ctx_dump();
#endif /* _REQ_CTX_H */

3
firmware/include/si570.h Executable file → Normal file
View File

@ -48,6 +48,7 @@ struct si570_ctx {
//API
int si570_init(struct si570_ctx *ctx, void *i2c_dev, uint8_t i2c_addr);
int si570_reinit(struct si570_ctx *ctx);
int si570_read_calibration(struct si570_ctx *ctx);
int si570_reset(struct si570_ctx *ctx);
//mode of operation
@ -56,5 +57,7 @@ int si570_get_lock(struct si570_ctx *ctx);
int si570_set_freq(struct si570_ctx *ctx, uint32_t freq, int trim);
//dump all registers
void si570_regdump(struct si570_ctx *ctx);
//write register(s)
int si570_reg_write(struct si570_ctx *ctx, uint8_t reg, int len, const uint8_t* data);
#endif //__SI570_H__

View File

@ -19,6 +19,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define E4K_CHECK_ADDR 0x02
#define E4K_CHECK_VAL 0x40
enum e4k_reg {
E4K_REG_MASTER1 = 0x00,
E4K_REG_MASTER2 = 0x01,
@ -186,6 +189,7 @@ struct e4k_state {
uint8_t i2c_addr;
enum e4k_band band;
struct e4k_pll_params vco;
void *rtl_dev;
};
int e4k_init(struct e4k_state *e4k);
@ -194,22 +198,23 @@ int e4k_mixer_gain_set(struct e4k_state *e4k, int8_t value);
int e4k_commonmode_set(struct e4k_state *e4k, int8_t value);
int e4k_tune_freq(struct e4k_state *e4k, uint32_t freq);
int e4k_tune_params(struct e4k_state *e4k, struct e4k_pll_params *p);
int e4k_compute_pll_params(struct e4k_pll_params *oscp, uint32_t fosc, uint32_t intended_flo);
uint32_t e4k_compute_pll_params(struct e4k_pll_params *oscp, uint32_t fosc, uint32_t intended_flo);
int e4k_if_filter_bw_get(struct e4k_state *e4k, enum e4k_if_filter filter);
int e4k_if_filter_bw_set(struct e4k_state *e4k, enum e4k_if_filter filter,
uint32_t bandwidth);
int e4k_if_filter_bw_set(struct e4k_state *e4k, enum e4k_if_filter filter, uint32_t bandwidth);
int e4k_if_filter_chan_enable(struct e4k_state *e4k, int on);
int e4k_rf_filter_set(struct e4k_state *e4k);
int e4k_reg_write(struct e4k_state *e4k, uint8_t reg, uint8_t val);
int e4k_reg_read(struct e4k_state *e4k, uint8_t reg);
int sam3u_e4k_init(struct e4k_state *e4k, void *i2c, uint8_t slave_addr);
void sam3u_e4k_power(struct e4k_state *e4k, int on);
void sam3u_e4k_stby(struct e4k_state *e4k, int on);
uint8_t e4k_reg_read(struct e4k_state *e4k, uint8_t reg);
int e4k_manual_dc_offset(struct e4k_state *e4k, int8_t iofs, int8_t irange, int8_t qofs, int8_t qrange);
int e4k_dc_offset_calibrate(struct e4k_state *e4k);
int e4k_dc_offset_gen_table(struct e4k_state *e4k);
int e4k_set_lna_gain(struct e4k_state *e4k, int32_t gain);
int e4k_enable_manual_gain(struct e4k_state *e4k, uint8_t manual);
int e4k_set_enh_gain(struct e4k_state *e4k, int32_t gain);
int e4k_dump(struct e4k_state *e4k);
#endif /* _E4K_TUNER_H */

View File

@ -69,6 +69,10 @@ include $(AT91LIB)/boards/$(BOARD)/board.mak
BIN = bin
OBJ = obj
GIT_REVISION := $(shell ../../git-version-gen ../../.tarball_version)
ASFLAGS += -DGIT_REVISION=\"$(GIT_REVISION)\"
CFLAGS += -DGIT_REVISION=\"$(GIT_REVISION)\"
#-------------------------------------------------------------------------------
# Tools
#-------------------------------------------------------------------------------

View File

@ -58,7 +58,7 @@
#define SSC_MCK 49152000
// TWI clock
#define TWI_CLOCK 100000
#define TWI_CLOCK 400000
// PMC define
#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
@ -88,8 +88,8 @@ static const Pin pins[] = {PINS_TWI0, PIN_PCK0, PINS_LEDS, PINS_SPI0,
PINS_MISC, PINS_SSC, PINS_FPGA_JTAG};
static Twid twid;
static struct e4k_state e4k;
static struct si570_ctx si570;
struct e4k_state e4k;
struct si570_ctx si570;
static void set_si570_freq(uint32_t freq)
{
@ -335,6 +335,12 @@ static int cmd_tuner_iqofs(struct cmd_state *cs, enum cmd_op op,
return e4k_manual_dc_offset(&e4k, iofs, irange, qofs, qrange);
}
static int cmd_tuner_dump(struct cmd_state *cs, enum cmd_op op,
const char *cmd, int argc, char ** argv)
{
return e4k_dump(&e4k);
}
static int cmd_dfu(struct cmd_state *cs, enum cmd_op op,
const char *cmd, int argc, char ** argv)
{
@ -345,6 +351,8 @@ static int cmd_dfu(struct cmd_state *cs, enum cmd_op op,
static struct cmd cmds[] = {
{ "tuner.init", CMD_OP_EXEC, cmd_tuner_init,
"Initialize the tuner" },
{ "tuner.dump", CMD_OP_EXEC, cmd_tuner_dump,
"Dump E4k registers" },
{ "tuner.freq", CMD_OP_SET|CMD_OP_GET, cmd_rf_freq,
"Tune to the specified frequency" },
{ "tuner.gain", CMD_OP_SET, cmd_tuner_gain,
@ -392,8 +400,6 @@ int main(void)
// Initialize the DBGU
TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
printf("trace configured!!\n");
// Switch to Main clock
AT91C_BASE_PMC->PMC_MCKR = (AT91C_BASE_PMC->PMC_MCKR & ~AT91C_PMC_CSS) | AT91C_PMC_CSS_MAIN_CLK;
while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0);
@ -418,11 +424,9 @@ int main(void)
TWI_ConfigureMaster(AT91C_BASE_TWI0, TWI_CLOCK, SSC_MCK);
TWID_Initialize(&twid, AT91C_BASE_TWI0);
printf("-- osmo-sdr testing project %s --\n\r", SOFTPACK_VERSION);
printf("-- %s\n\r", BOARD_NAME);
printf("-- OsmoSDR firmware (" BOARD_NAME ") " GIT_REVISION " --\n\r");
printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
req_ctx_init();
PIO_InitializeInterrupts(0);
@ -439,29 +443,28 @@ int main(void)
set_si570_freq(30000000);
sam3u_e4k_init(&e4k, &twid, E4K_I2C_ADDR);
e4k.vco.fosc = 30000000;
osdr_fpga_init(SSC_MCK);
osdr_fpga_reg_write(OSDR_FPGA_REG_ADC_TIMING, (1 << 8) | 255);
osdr_fpga_reg_write(OSDR_FPGA_REG_PWM1, (1 << 400) | 800);
//osdr_fpga_reg_write(OSDR_FPGA_REG_ADC_TIMING, (1 << 8) | 255);
//osdr_fpga_reg_write(OSDR_FPGA_REG_PWM1, (1 << 400) | 800);
osdr_fpga_set_iq_swap(0);
ssc_init();
e4k_init(&e4k);
e4k_init(&e4k);
// Enter menu loop
while (1) {
if (DBGU_IsRxReady()) {
if (DBGU_IsRxReady()) {
key = DBGU_GetChar();
// Process user input
if (uart_cmd_char(&cmd_state, key) == 1) {
//ssc_stats();
}
}
/* Try to (re-)start the SSC DMA if the IN ISO EP is open but the
* SSC DMA is not active */
if (fastsource_interfaces[2] == 1 && !ssc_active())
ssc_dma_start();
if (uart_cmd_char(&cmd_state, key) == 1) {
//ssc_stats();
}
}
ssc_dma_start();
fastsource_start();
}
}

View File

@ -17,7 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
@ -34,11 +33,18 @@
#include <usb/common/audio/AUDGenericRequest.h>
#include <usb/common/audio/AUDFeatureUnitRequest.h>
#include <usb/common/audio/AUDFeatureUnitDescriptor.h>
#include <common.h>
#include <fast_source_descr.h>
#include <fast_source.h>
#include <tuner_e4k.h>
#include <si570.h>
#include <osdr_fpga.h>
#define OSMOSDR_CTRL_WRITE 0x07
#define OSMOSDR_CTRL_READ 0x87
extern const USBDDriverDescriptors auddFastSourceDriverDescriptors;
unsigned char fastsource_interfaces[3];
static USBDDriver fast_source_driver;
@ -87,6 +93,268 @@ static void fastsource_set_feat_cur_val(uint8_t entity, uint8_t channel,
USBD_Stall(0);
}
static void handle_osmosdr_read(const USBGenericRequest* request)
{
int len = USBGenericRequest_GetLength(request);
printf("OsmoSDR GET request: type:%d, request:%d, value:%d, index: %d, length: %d\n\r",
USBGenericRequest_GetType(request),
USBGenericRequest_GetRequest(request),
USBGenericRequest_GetValue(request),
USBGenericRequest_GetIndex(request),
len);
USBD_Stall(0);
}
static uint32_t read_bytewise32(const uint8_t* data)
{
return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
}
static uint16_t read_bytewise16(const uint8_t* data)
{
return (data[0] << 8) | data[1];
}
typedef struct Request_ {
uint16_t func;
uint16_t len;
} Request;
#define FUNC(group, function) ((group << 8) | function)
#define GROUP_GENERAL 0x00
#define GROUP_FPGA_V2 0x01
#define GROUP_VCXO_SI570 0x02
#define GROUP_TUNER_E4K 0x03
const static Request g_writeRequests[] = {
// general api
{ FUNC(GROUP_GENERAL, 0x00), 0 }, // init whatever
{ FUNC(GROUP_GENERAL, 0x01), 0 }, // power down
{ FUNC(GROUP_GENERAL, 0x02), 0 }, // power up
// fpga commands
{ FUNC(GROUP_FPGA_V2, 0x00), 0 }, // fpga init
{ FUNC(GROUP_FPGA_V2, 0x01), 5 }, // osdr_fpga_reg_write(uint8_t reg, uint32_t val)
{ FUNC(GROUP_FPGA_V2, 0x02), 1 }, // osdr_fpga_set_decimation(uint8_t val)
{ FUNC(GROUP_FPGA_V2, 0x03), 1 }, // osdr_fpga_set_iq_swap(uint8_t val)
{ FUNC(GROUP_FPGA_V2, 0x04), 4 }, // osdr_fpga_set_iq_gain(uint16_t igain, uint16_t qgain)
{ FUNC(GROUP_FPGA_V2, 0x05), 4 }, // osdr_fpga_set_iq_ofs(int16_t iofs, int16_t qofs)
// si570 vcxo commads
{ FUNC(GROUP_VCXO_SI570, 0x00), 0 }, // si570_init()
{ FUNC(GROUP_VCXO_SI570, 0x01), 16 }, // si570_reg_write
{ FUNC(GROUP_VCXO_SI570, 0x02), 8 }, // si570_set_freq(uint32_t freq, int trim);
// e4000 tuner commands
{ FUNC(GROUP_TUNER_E4K, 0x00), 0 }, // e4k_init()
{ FUNC(GROUP_TUNER_E4K, 0x01), 0 }, // reg write
{ FUNC(GROUP_TUNER_E4K, 0x02), 5 }, // e4k_if_gain_set(uint8_t stage, int8_t value)
{ FUNC(GROUP_TUNER_E4K, 0x03), 1 }, // e4k_mixer_gain_set(struct e4k_state *e4k, int8_t value)
{ FUNC(GROUP_TUNER_E4K, 0x04), 1 }, // e4k_commonmode_set(int8_t value)
{ FUNC(GROUP_TUNER_E4K, 0x05), 4 }, // e4k_tune_freq(uint32_t freq)
{ FUNC(GROUP_TUNER_E4K, 0x06), 5 }, // e4k_if_filter_bw_set(enum e4k_if_filter filter, uint32_t bandwidth)
{ FUNC(GROUP_TUNER_E4K, 0x07), 1 }, // e4k_if_filter_chan_enable(int on)
{ FUNC(GROUP_TUNER_E4K, 0x08), 4 }, // e4k_manual_dc_offset(int8_t iofs, int8_t irange, int8_t qofs, int8_t qrange)
{ FUNC(GROUP_TUNER_E4K, 0x09), 0 }, // e4k_dc_offset_calibrate()
{ FUNC(GROUP_TUNER_E4K, 0x0a), 0 }, // e4k_dc_offset_gen_table()
{ FUNC(GROUP_TUNER_E4K, 0x0b), 4 }, // e4k_set_lna_gain(int32_t gain)
{ FUNC(GROUP_TUNER_E4K, 0x0c), 1 }, // e4k_enable_manual_gain(uint8_t manual)
{ FUNC(GROUP_TUNER_E4K, 0x0d), 4 }, // e4k_set_enh_gain(int32_t gain)
};
typedef struct WriteState_ {
uint8_t data[16];
uint16_t func;
} WriteState;
static WriteState g_writeState;
extern struct e4k_state e4k;
extern struct si570_ctx si570;
static void finalize_write(void *pArg, unsigned char status, unsigned int transferred, unsigned int remaining)
{
int res;
if((status != 0) ||(remaining != 0)) {
USBD_Stall(0);
return;
}
printf("Func: %04x ...", g_writeState.func);
switch(g_writeState.func) {
// general api
case FUNC(GROUP_GENERAL, 0x00): // init all
printf("general_init()");
res = 0; // no op so far
break;
case FUNC(GROUP_GENERAL, 0x01): // power down
printf("general_power_down()");
osdr_fpga_power(0);
sam3u_e4k_stby(&e4k, 1);
sam3u_e4k_power(&e4k, 0);
res = 0;
break;
case FUNC(GROUP_GENERAL, 0x02): // power up
printf("general_power_up()");
osdr_fpga_power(1);
sam3u_e4k_power(&e4k, 1);
sam3u_e4k_stby(&e4k, 0);
res = 0;
break;
// fpga commands
case FUNC(GROUP_FPGA_V2, 0x00): // fpga init
printf("fpga_v2_init()");
res = 0; // no op so far
break;
case FUNC(GROUP_FPGA_V2, 0x01):
printf("fpga_v2_reg_write()");
osdr_fpga_reg_write(g_writeState.data[0], read_bytewise32(g_writeState.data + 1));
res = 0;
break;
case FUNC(GROUP_FPGA_V2, 0x02):
printf("osdr_fpga_set_decimation()");
osdr_fpga_set_decimation(g_writeState.data[0]);
res = 0;
break;
case FUNC(GROUP_FPGA_V2, 0x03):
printf("osdr_fpga_set_iq_swap()");
osdr_fpga_set_iq_swap(g_writeState.data[0]);
res = 0;
break;
case FUNC(GROUP_FPGA_V2, 0x04):
printf("osdr_fpga_set_iq_gain()");
osdr_fpga_set_iq_gain(read_bytewise16(g_writeState.data), read_bytewise16(g_writeState.data + 2));
res = 0;
break;
case FUNC(GROUP_FPGA_V2, 0x05):
printf("osdr_fpga_set_iq_ofs()");
osdr_fpga_set_iq_ofs(read_bytewise16(g_writeState.data), read_bytewise16(g_writeState.data + 2));
res = 0;
break;
// si570 vcxo commands
case FUNC(GROUP_VCXO_SI570, 0x00): // si570_init()
printf("si570_init()");
res = si570_reinit(&si570);
break;
case FUNC(GROUP_VCXO_SI570, 0x01):
printf("si570_reg_write()");
res = si570_reg_write(&si570, g_writeState.data[0], g_writeState.data[1], g_writeState.data + 2);
break;
case FUNC(GROUP_VCXO_SI570, 0x02):
printf("si570_set_freq()");
res = si570_set_freq(&si570, read_bytewise32(g_writeState.data), read_bytewise32(g_writeState.data + 4));
break;
// e4000 tuner commands
case FUNC(GROUP_TUNER_E4K, 0x00):
printf("e4k_init()");
res = e4k_init(&e4k);
break;
case FUNC(GROUP_TUNER_E4K, 0x01): // reg write
printf("e4k_reg_write()");
res = -1;
break;
case FUNC(GROUP_TUNER_E4K, 0x02):
printf("e4k_if_gain_set()");
res = e4k_if_gain_set(&e4k, g_writeState.data[0], read_bytewise32(g_writeState.data + 1));
break;
case FUNC(GROUP_TUNER_E4K, 0x03):
printf("e4k_mixer_gain_set()");
res = e4k_mixer_gain_set(&e4k, g_writeState.data[0]);
break;
case FUNC(GROUP_TUNER_E4K, 0x04):
printf("e4K_commonmode_set()");
res = e4k_commonmode_set(&e4k, g_writeState.data[0]);
break;
case FUNC(GROUP_TUNER_E4K, 0x05):
printf("e4k_tune_freq()");
res = e4k_tune_freq(&e4k, read_bytewise32(g_writeState.data));
break;
case FUNC(GROUP_TUNER_E4K, 0x06):
printf("e4k_if_filter_bw_set()");
res = e4k_if_filter_bw_set(&e4k, g_writeState.data[0], read_bytewise32(g_writeState.data + 1));
break;
case FUNC(GROUP_TUNER_E4K, 0x07):
printf("e4k_if_filter_chan_enable()");
res = e4k_if_filter_chan_enable(&e4k, g_writeState.data[0]);
break;
case FUNC(GROUP_TUNER_E4K, 0x08):
printf("e4k_manual_dc_offset()");
res = e4k_manual_dc_offset(&e4k, g_writeState.data[0], g_writeState.data[1], g_writeState.data[2], g_writeState.data[3]);
break;
case FUNC(GROUP_TUNER_E4K, 0x09):
printf("e4k_dc_offset_calibrate()");
res = e4k_dc_offset_calibrate(&e4k);
break;
case FUNC(GROUP_TUNER_E4K, 0x0a):
printf("e4k_dc_offset_gen_table()");
res = e4k_dc_offset_gen_table(&e4k);
break;
case FUNC(GROUP_TUNER_E4K, 0x0b):
printf("e4k_set_lna_gain()");
res = e4k_set_lna_gain(&e4k, read_bytewise32(g_writeState.data));
if(res == -EINVAL)
res = -1;
else res = 0;
break;
case FUNC(GROUP_TUNER_E4K, 0x0c):
printf("e4k_enable_manual_gain()");
res = e4k_enable_manual_gain(&e4k, g_writeState.data[0]);
break;
case FUNC(GROUP_TUNER_E4K, 0x0d):
printf("e4k_set_enh_gain()");
res = e4k_set_enh_gain(&e4k, read_bytewise32(g_writeState.data));
break;
default:
res = -1;
break;
}
printf(" res: %d\n\r", res);
if(res == 0)
USBD_Write(0, 0, 0, 0, 0);
else USBD_Stall(0);
}
static void handle_osmosdr_write(const USBGenericRequest* request)
{
uint16_t func = USBGenericRequest_GetValue(request);
int len = USBGenericRequest_GetLength(request);
int i;
/*
printf("OsmoSDR SET request: type:%d, request:%d, value:%04x, index: %04x, length: %d\n\r",
USBGenericRequest_GetType(request),
USBGenericRequest_GetRequest(request),
USBGenericRequest_GetValue(request),
USBGenericRequest_GetIndex(request),
len);
*/
for(i = 0; i < ARRAY_SIZE(g_writeRequests); i++) {
if(g_writeRequests[i].func == func)
break;
}
if(i == ARRAY_SIZE(g_writeRequests)) {
USBD_Stall(0);
return;
}
if(len != g_writeRequests[i].len) {
USBD_Stall(0);
return;
}
g_writeState.func = func;
if(len > 0)
USBD_Read(0, g_writeState.data, len, finalize_write, 0);
else finalize_write(NULL, 0, 0, 0);
}
/* handler for EP0 (control) requests */
void fastsource_req_hdlr(const USBGenericRequest *request)
{
@ -100,6 +368,13 @@ void fastsource_req_hdlr(const USBGenericRequest *request)
case USBGenericRequest_CLASS:
/* continue below */
break;
case USBGenericRequest_VENDOR:
if(USBGenericRequest_GetRequest(request) == OSMOSDR_CTRL_WRITE)
handle_osmosdr_write(request);
else if(USBGenericRequest_GetRequest(request) == OSMOSDR_CTRL_READ)
handle_osmosdr_read(request);
else USBD_Stall(0);
return;
default:
TRACE_WARNING("Unsupported request type %u\n\r",
USBGenericRequest_GetType(request));
@ -140,6 +415,7 @@ void fastsource_req_hdlr(const USBGenericRequest *request)
USBD_Stall(0);
}
break;
default:
TRACE_WARNING("Unsupported request %u\n\r",
USBGenericRequest_GetIndex(request));
@ -152,6 +428,7 @@ void fastsource_req_hdlr(const USBGenericRequest *request)
void fastsource_init(void)
{
memset(&usb_state, 0, sizeof(usb_state));
memset(fastsource_interfaces, 0x00, sizeof(fastsource_interfaces));
INIT_LLIST_HEAD(&usb_state.queue);
@ -184,6 +461,7 @@ static void wr_compl_cb(void *arg, unsigned char status, unsigned int transferre
static int refill_dma(void)
{
struct req_ctx *rctx;
int res;
rctx = req_ctx_dequeue(&usb_state.queue);
if (!rctx) {
@ -194,9 +472,9 @@ static int refill_dma(void)
req_ctx_set_state(rctx, RCTX_STATE_UDP_EP2_BUSY);
if (USBD_Write(EP_NR, rctx->data, rctx->tot_len, wr_compl_cb,
rctx) != USBD_STATUS_SUCCESS) {
TRACE_WARNING("USB EP busy while re-filling USB DMA\n\r");
if ((res = USBD_Write(EP_NR, rctx->data, rctx->tot_len, wr_compl_cb, rctx)) != USBD_STATUS_SUCCESS) {
TRACE_WARNING("USB EP busy while re-filling USB DMA: %d\n\r", res);
req_ctx_set_state(rctx, RCTX_STATE_FREE);
usb_state.active = 0;
return -EBUSY;
}
@ -208,10 +486,11 @@ static int refill_dma(void)
/* user API: requests us to start transmitting data via USB IN EP */
void fastsource_start(void)
{
if (!usb_state.active) {
usb_state.active = 1;
if(USBD_GetState() != USBD_STATE_CONFIGURED)
return;
if (!usb_state.active)
refill_dma();
}
}
/* Use every Nth sample for computing statistics. At fpga.adc_clkdiv=2 we can
@ -300,9 +579,20 @@ void USBDDriverCallbacks_InterfaceSettingChanged(unsigned char interface,
unsigned char setting)
{
printf("USB_IF_CHANGED(%u, %u)\n\r", interface, setting);
if ((interface == AUDDLoopRecDriverDescriptors_STREAMINGIN)
&& (setting == 0))
LED_Clear(USBD_LEDOTHER);
else
LED_Set(USBD_LEDOTHER);
}
void fastsource_dump(void)
{
struct req_ctx *rctx, *rctx2;
printf("usb pending:");
llist_for_each_entry_safe(rctx, rctx2, &usb_state.queue, list)
printf(" %02d", req_ctx_num(rctx));
printf("\n\r");
}

View File

@ -53,6 +53,10 @@
#include <usb/device/dfu/dfu.h>
// #define AUDIOSOURCE 1
#undef AUDIOSOURCE
//------------------------------------------------------------------------------
// Definitions
//------------------------------------------------------------------------------
@ -76,6 +80,8 @@
#define AUDDLoopRecDriverDescriptors_RELEASE 0x0100
//------------------------------------------------------------------------------
#ifdef AUDIOSOURCE
//------------------------------------------------------------------------------
// Internal types
//------------------------------------------------------------------------------
@ -1460,3 +1466,212 @@ const USBDDriverDescriptors auddFastSourceDriverDescriptors = {
4 // Number of string descriptors
};
#else
typedef struct {
/// Size of the descriptor in bytes.
unsigned char bLength;
/// Descriptor type (USBGenericDescriptor_ENDPOINT).
unsigned char bDescriptorType;
/// Address and direction of the endpoint.
unsigned char bEndpointAddress;
/// Endpoint type and additional characteristics (for isochronous endpoints).
unsigned char bmAttributes;
/// Maximum packet size (in bytes) of the endpoint.
unsigned short wMaxPacketSize;
/// Polling rate of the endpoint.
unsigned char bInterval;
} __attribute__ ((packed)) BulkEndpointDescriptor; // GCC
typedef struct {
/// Standard configuration.
USBConfigurationDescriptor configuration;
/// Audio stream interface.
USBInterfaceDescriptor stream;
/// Streaming out endpoint descriptor.
BulkEndpointDescriptor bulkInEndpoint;
} __attribute__ ((packed)) BulkDriverConfigurationDescriptors; // GCC
const USBDeviceDescriptor deviceDescriptor = {
sizeof(USBDeviceDescriptor),
USBGenericDescriptor_DEVICE,
USBDeviceDescriptor_USB2_00,
0, // class - all defined at interface level
0, // subclass
0, // protocol
CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
AUDDLoopRecDriverDescriptors_VENDORID,
AUDDLoopRecDriverDescriptors_PRODUCTID,
AUDDLoopRecDriverDescriptors_RELEASE,
1, // Manufacturer string descriptor index
2, // Product string descriptor index
3, // Index of serial number string descriptor
1 // One possible configuration
};
/// configuration descriptors for bulk
const BulkDriverConfigurationDescriptors configurationDescriptors = {
// Configuration descriptor
{
sizeof(USBConfigurationDescriptor),
USBGenericDescriptor_CONFIGURATION,
sizeof(BulkDriverConfigurationDescriptors),
1, // This configuration has 1 interfaces
1, // This is configuration #1
0, // No string descriptor
BOARD_USB_BMATTRIBUTES,
USBConfigurationDescriptor_POWER(100)
},
// Bulk interface standard descriptor
{
sizeof(USBInterfaceDescriptor),
USBGenericDescriptor_INTERFACE,
0, // interface number
0, // This is alternate setting #0
1, // This interface uses one endpoint
254, // class
0, // subclass
0, // protocol
0 // No string descriptor
},
{
sizeof(BulkEndpointDescriptor),
USBGenericDescriptor_ENDPOINT,
USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_IN,
AUDDLoopRecDriverDescriptors_DATAIN),
USBEndpointDescriptor_BULK,
0x200, // packet size
0 // Polling interval = 0 ms
},
};
/// configuration descriptors for bulk
const BulkDriverConfigurationDescriptors otherConfigurationDescriptors = {
// Configuration descriptor
{
sizeof(USBConfigurationDescriptor),
USBGenericDescriptor_OTHERSPEEDCONFIGURATION,
sizeof(BulkDriverConfigurationDescriptors),
1, // This configuration has 1 interface
1, // This is configuration #1
0, // No string descriptor
BOARD_USB_BMATTRIBUTES,
USBConfigurationDescriptor_POWER(100)
},
// Bulk interface standard descriptor
{
sizeof(USBInterfaceDescriptor),
USBGenericDescriptor_INTERFACE,
0, // interface number
0, // This is alternate setting #0
1, // This interface uses one endpoint
254, // class
0, // subclass
0, // protocol
0 // No string descriptor
},
{
sizeof(BulkEndpointDescriptor),
USBGenericDescriptor_ENDPOINT,
USBEndpointDescriptor_ADDRESS(
USBEndpointDescriptor_IN,
AUDDLoopRecDriverDescriptors_DATAIN),
USBEndpointDescriptor_BULK,
0x200, // packet size
0 // Polling interval = 0 ms
},
};
/// String descriptor with the supported languages.
const unsigned char languageIdDescriptor[] = {
USBStringDescriptor_LENGTH(1),
USBGenericDescriptor_STRING,
USBStringDescriptor_ENGLISH_US
};
/// USB device qualifier descriptor.
const USBDeviceQualifierDescriptor qualifierDescriptor = {
sizeof(USBDeviceQualifierDescriptor),
USBGenericDescriptor_DEVICEQUALIFIER,
USBDeviceDescriptor_USB2_00,
0, // class
0, // subclass
0, // protocol
CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
1, // Device has one possible configuration
0 // Reserved
};
/// Manufacturer name.
const unsigned char manufacturerDescriptor[] = {
USBStringDescriptor_LENGTH(8),
USBGenericDescriptor_STRING,
USBStringDescriptor_UNICODE('s'),
USBStringDescriptor_UNICODE('y'),
USBStringDescriptor_UNICODE('s'),
USBStringDescriptor_UNICODE('m'),
USBStringDescriptor_UNICODE('o'),
USBStringDescriptor_UNICODE('c'),
USBStringDescriptor_UNICODE('o'),
USBStringDescriptor_UNICODE('m'),
};
/// Product name.
const unsigned char productDescriptor[] = {
USBStringDescriptor_LENGTH(7),
USBGenericDescriptor_STRING,
USBStringDescriptor_UNICODE('O'),
USBStringDescriptor_UNICODE('s'),
USBStringDescriptor_UNICODE('m'),
USBStringDescriptor_UNICODE('o'),
USBStringDescriptor_UNICODE('S'),
USBStringDescriptor_UNICODE('D'),
USBStringDescriptor_UNICODE('R'),
};
/// Product serial number.
const unsigned char serialNumberDescriptor[] = {
USBStringDescriptor_LENGTH(3),
USBGenericDescriptor_STRING,
USBStringDescriptor_UNICODE('6'),
USBStringDescriptor_UNICODE('6'),
USBStringDescriptor_UNICODE('6')
};
/// Array of pointers to the four string descriptors.
const unsigned char *stringDescriptors[] = {
languageIdDescriptor,
manufacturerDescriptor,
productDescriptor,
serialNumberDescriptor,
};
const USBDDriverDescriptors auddFastSourceDriverDescriptors = {
&deviceDescriptor,
(const USBConfigurationDescriptor *) &configurationDescriptors,
#if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
&qualifierDescriptor,
(const USBConfigurationDescriptor *) &otherConfigurationDescriptors,
&deviceDescriptor,
(const USBConfigurationDescriptor *) &configurationDescriptors,
&qualifierDescriptor,
(const USBConfigurationDescriptor *) &otherConfigurationDescriptors,
#else
0, 0, 0, 0, 0, 0,
#endif
stringDescriptors,
4 // Number of string descriptors
};
#endif

View File

@ -106,6 +106,26 @@ void osdr_fpga_power(int on)
PIO_Clear(&fon_pin);
}
void osdr_fpga_set_decimation(uint8_t val)
{
osdr_fpga_reg_write(OSDR_FPGA_REG_DECIMATION, val);
}
void osdr_fpga_set_iq_swap(uint8_t val)
{
osdr_fpga_reg_write(OSDR_FPGA_REG_IQ_SWAP, (val & 1) ^ 1);
}
void osdr_fpga_set_iq_gain(uint16_t igain, uint16_t qgain)
{
osdr_fpga_reg_write(OSDR_FPGA_REG_IQ_GAIN, ((uint32_t)igain) | (((uint32_t)qgain) << 16));
}
void osdr_fpga_set_iq_ofs(int16_t iofs, int16_t qofs)
{
osdr_fpga_reg_write(OSDR_FPGA_REG_IQ_OFS, (((uint32_t)iofs) & 0xffff) | ((((uint32_t)qofs) << 16) & 0xffff0000));
}
/***********************************************************************
* command integration

View File

@ -107,8 +107,7 @@ static void __refill_dma()
struct req_ctx *rctx;
/* obtain an unused request context from pool */
rctx = req_ctx_find_get(0, RCTX_STATE_FREE,
RCTX_STATE_SSC_RX_PENDING);
rctx = req_ctx_find_get(0, RCTX_STATE_FREE, RCTX_STATE_SSC_RX_PENDING);
if (!rctx) {
break;
}
@ -129,8 +128,10 @@ static void __refill_dma()
req_ctx_enqueue(&ssc_state.pending_rctx, rctx);
ssc_state.hdma_chain_len++;
}
/*
if (ssc_state.hdma_chain_len <= 1)
TRACE_ERROR("Unable to get rctx for SSC DMA refill\n\r");
*/
}
int ssc_dma_start(void)
@ -140,12 +141,12 @@ int ssc_dma_start(void)
__refill_dma();
if (ssc_state.active) {
TRACE_WARNING("Cannot start SSC DMA, active == 1\n\r");
//TRACE_WARNING("Cannot start SSC DMA, active == 1\n\r");
return -EBUSY;
}
if (llist_empty(&ssc_state.pending_rctx)) {
TRACE_WARNING("Cannot start SSC DMA, no rctx pending\n\r");
//TRACE_WARNING("Cannot start SSC DMA, no rctx pending\n\r");
return -ENOMEM;
}
@ -276,7 +277,16 @@ static int cmd_ssc_stats(struct cmd_state *cs, enum cmd_op op,
static int cmd_ssc_dump(struct cmd_state *cs, enum cmd_op op,
const char *cmd, int argc, char **argv)
{
struct req_ctx *rctx, *rctx2;
dma_dump_regs();
req_ctx_dump();
printf("ssc pending:");
llist_for_each_entry_safe(rctx, rctx2, &ssc_state.pending_rctx, list)
printf(" %02d", req_ctx_num(rctx));
printf("\n\r");
fastsource_dump();
}
static struct cmd cmds[] = {
@ -324,5 +334,3 @@ int ssc_init(void)
return 0;
}

View File

@ -28,11 +28,11 @@
#include "req_ctx.h"
#define local_irq_save(x) __disable_fault_irq()
#define local_irq_restore(x) __enable_fault_irq()
#define local_irq_save(x) do { __disable_fault_irq(); __disable_irq(); } while(0)
#define local_irq_restore(x) do { __enable_fault_irq(); __enable_irq(); } while(0)
#define NUM_RCTX_SMALL 16
#define NUM_RCTX_LARGE 2
#define NUM_RCTX_SMALL 20
#define NUM_RCTX_LARGE 0
#define NUM_REQ_CTX (NUM_RCTX_SMALL+NUM_RCTX_LARGE)
@ -99,6 +99,7 @@ void req_ctx_init(void)
for (i = 0; i < NUM_RCTX_LARGE; i++) {
req_ctx[NUM_RCTX_SMALL+i].size = RCTX_SIZE_LARGE;
req_ctx[NUM_RCTX_SMALL+i].data = rctx_data_large[i];
req_ctx[NUM_RCTX_SMALL+i].state = RCTX_STATE_FREE;
}
}
@ -129,3 +130,15 @@ void req_ctx_enqueue(struct llist_head *list, struct req_ctx *rctx)
llist_add_tail(&rctx->list, list);
local_irq_restore(flags);
}
void req_ctx_dump()
{
int i;
local_irq_save(flags);
printf("ctx status: ");
for(i = 0; i < NUM_REQ_CTX; i++)
printf(" %02x", req_ctx[i].state);
local_irq_restore(flags);
printf("\n\r");
}

View File

@ -92,7 +92,13 @@ int si570_init(struct si570_ctx *ctx, void *i2c_dev, uint8_t i2c_addr)
{
ctx->i2c = i2c_dev;
ctx->slave_addr = i2c_addr;
ctx->init = 0;
return si570_reinit(ctx);
}
int si570_reinit(struct si570_ctx *ctx)
{
TRACE_DEBUG("si570_init()\r\n");
if (0 != si570_reset(ctx)) {
@ -112,6 +118,7 @@ int si570_init(struct si570_ctx *ctx, void *i2c_dev, uint8_t i2c_addr)
return 0;
}
void si570_print_info(struct si570_ctx *ctx)
{
TRACE_DEBUG("SI570 XTAL: %u Hz REF: %u Hz\n", ctx->xtal >> 3, ctx->info->init_freq * 1000);
@ -295,3 +302,9 @@ void si570_regdump(struct si570_ctx *ctx)
data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7]);
}
//write register(s)
int si570_reg_write(struct si570_ctx *ctx, uint8_t reg, int len, const uint8_t* data)
{
return smbus8_write_bytes(ctx->i2c, ctx->slave_addr, reg, data, len);
}

View File

@ -1,4 +1,3 @@
/* (C) 2011-2012 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
@ -22,12 +21,11 @@
#include <errno.h>
#include <string.h>
#include <common.h>
#include <logging.h>
#include <reg_field.h>
#include <tuner_e4k.h>
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
/* If this is defined, the limits are somewhat relaxed compared to what the
* vendor claims is possible */
#define OUT_OF_SPEC
@ -48,7 +46,7 @@ static const uint8_t width2mask[] = {
0, 1, 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 0xff
};
/***********************************************************************
/***********************************************************************
* Register Access */
#if 0
@ -132,8 +130,7 @@ static int e4k_field_read(struct e4k_state *e4k, const struct reg_field *field)
return rc;
}
/***********************************************************************
/***********************************************************************
* Filter Control */
static const uint32_t rf_filt_center_uhf[] = {
@ -152,7 +149,7 @@ static const uint32_t rf_filt_center_l[] = {
static int closest_arr_idx(const uint32_t *arr, unsigned int arr_size, uint32_t freq)
{
unsigned int i, bi;
unsigned int i, bi = 0;
uint32_t best_delta = 0xffffffff;
/* iterate over the array containing a list of the center
@ -174,31 +171,23 @@ static int choose_rf_filter(enum e4k_band band, uint32_t freq)
int rc;
switch (band) {
case E4K_BAND_VHF2:
if (freq < MHZ(268))
case E4K_BAND_VHF2:
case E4K_BAND_VHF3:
rc = 0;
else
rc = 8;
break;
case E4K_BAND_VHF3:
if (freq < MHZ(509))
rc = 0;
else
rc = 8;
break;
case E4K_BAND_UHF:
rc = closest_arr_idx(rf_filt_center_uhf,
ARRAY_SIZE(rf_filt_center_uhf),
freq);
break;
case E4K_BAND_L:
rc = closest_arr_idx(rf_filt_center_l,
ARRAY_SIZE(rf_filt_center_l),
freq);
break;
default:
rc -EINVAL;
break;
break;
case E4K_BAND_UHF:
rc = closest_arr_idx(rf_filt_center_uhf,
ARRAY_SIZE(rf_filt_center_uhf),
freq);
break;
case E4K_BAND_L:
rc = closest_arr_idx(rf_filt_center_l,
ARRAY_SIZE(rf_filt_center_l),
freq);
break;
default:
rc = -EINVAL;
break;
}
return rc;
@ -245,26 +234,26 @@ static const uint32_t ifch_filter_bw[] = {
};
static const uint32_t *if_filter_bw[] = {
[E4K_IF_FILTER_MIX] = mix_filter_bw,
[E4K_IF_FILTER_CHAN] = ifch_filter_bw,
[E4K_IF_FILTER_RC] = ifrc_filter_bw,
mix_filter_bw,
ifch_filter_bw,
ifrc_filter_bw,
};
static const uint32_t if_filter_bw_len[] = {
[E4K_IF_FILTER_MIX] = ARRAY_SIZE(&mix_filter_bw),
[E4K_IF_FILTER_CHAN] = ARRAY_SIZE(&ifch_filter_bw),
[E4K_IF_FILTER_RC] = ARRAY_SIZE(&ifrc_filter_bw),
ARRAY_SIZE(mix_filter_bw),
ARRAY_SIZE(ifch_filter_bw),
ARRAY_SIZE(ifrc_filter_bw),
};
static const struct reg_field if_filter_fields[] = {
[E4K_IF_FILTER_MIX] = {
.reg = E4K_REG_FILT2, .shift = 4, .width = 4,
{
E4K_REG_FILT2, 4, 4,
},
[E4K_IF_FILTER_CHAN] = {
.reg = E4K_REG_FILT3, .shift = 0, .width = 5,
{
E4K_REG_FILT3, 0, 5,
},
[E4K_IF_FILTER_RC] = {
.reg = E4K_REG_FILT2, .shift = 0, .width = 4,
{
E4K_REG_FILT2, 0, 4,
}
};
@ -287,7 +276,6 @@ int e4k_if_filter_bw_set(struct e4k_state *e4k, enum e4k_if_filter filter,
uint32_t bandwidth)
{
int bw_idx;
uint8_t mask;
const struct reg_field *field;
if (filter >= ARRAY_SIZE(if_filter_bw))
@ -300,6 +288,17 @@ int e4k_if_filter_bw_set(struct e4k_state *e4k, enum e4k_if_filter filter,
return e4k_field_write(e4k, field, bw_idx);
}
/*! \brief Enables / Disables the channel filter
* \param[in] e4k reference to the tuner chip
* \param[in] on 1=filter enabled, 0=filter disabled
* \returns 0 success, negative errors
*/
int e4k_if_filter_chan_enable(struct e4k_state *e4k, int on)
{
return e4k_reg_set_mask(e4k, E4K_REG_FILT3, E4K_FILT3_DISABLE,
on ? 0 : E4K_FILT3_DISABLE);
}
int e4k_if_filter_bw_get(struct e4k_state *e4k, enum e4k_if_filter filter)
{
const uint32_t *arr;
@ -321,7 +320,7 @@ int e4k_if_filter_bw_get(struct e4k_state *e4k, enum e4k_if_filter filter)
}
/***********************************************************************
/***********************************************************************
* Frequency Control */
#define E4K_FVCO_MIN_KHZ 2600000 /* 2.6 GHz */
@ -330,16 +329,29 @@ int e4k_if_filter_bw_get(struct e4k_state *e4k, enum e4k_if_filter filter)
#ifdef OUT_OF_SPEC
#define E4K_FLO_MIN_MHZ 50
#define E4K_FLO_MAX_MHZ 1900
#define E4K_FLO_MAX_MHZ 2200UL
#else
#define E4K_FLO_MIN_MHZ 64
#define E4K_FLO_MAX_MHZ 1700
#endif
/* \brief table of R dividers in case 3phase mixing is enabled,
* the values have to be halved if it's 2phase */
static const uint8_t vco_r_table_3ph[] = {
4, 8, 12, 16, 24, 32, 40, 48
struct pll_settings {
uint32_t freq;
uint8_t reg_synth7;
uint8_t mult;
};
static const struct pll_settings pll_vars[] = {
{KHZ(72400), (1 << 3) | 7, 48},
{KHZ(81200), (1 << 3) | 6, 40},
{KHZ(108300), (1 << 3) | 5, 32},
{KHZ(162500), (1 << 3) | 4, 24},
{KHZ(216600), (1 << 3) | 3, 16},
{KHZ(325000), (1 << 3) | 2, 12},
{KHZ(350000), (1 << 3) | 1, 8},
{KHZ(432000), (0 << 3) | 3, 8},
{KHZ(667000), (0 << 3) | 2, 6},
{KHZ(1200000), (0 << 3) | 1, 4}
};
static int is_fvco_valid(uint32_t fvco_z)
@ -347,7 +359,7 @@ static int is_fvco_valid(uint32_t fvco_z)
/* check if the resulting fosc is valid */
if (fvco_z/1000 < E4K_FVCO_MIN_KHZ ||
fvco_z/1000 > E4K_FVCO_MAX_KHZ) {
LOGP(DTUN, LOGL_ERROR, "Fvco %u invalid\n", fvco_z);
printf("Fvco %u invalid\n\r", fvco_z);
return 0;
}
@ -357,17 +369,7 @@ static int is_fvco_valid(uint32_t fvco_z)
static int is_fosc_valid(uint32_t fosc)
{
if (fosc < MHZ(16) || fosc > MHZ(30)) {
LOGP(DTUN, LOGL_ERROR, "Fosc %u invalid\n", fosc);
return 0;
}
return 1;
}
static int is_flo_valid(uint32_t flo)
{
if (flo < MHZ(E4K_FLO_MIN_MHZ) || flo > MHZ(E4K_FLO_MAX_MHZ)) {
LOGP(DTUN, LOGL_ERROR, "Flo %u invalid\n", flo);
printf("Fosc %u invalid\n\r", fosc);
return 0;
}
@ -377,7 +379,7 @@ static int is_flo_valid(uint32_t flo)
static int is_z_valid(uint32_t z)
{
if (z > 255) {
LOGP(DTUN, LOGL_ERROR, "Z %u invalid\n", z);
printf("Z %u invalid\n\r", z);
return 0;
}
@ -388,7 +390,7 @@ static int is_z_valid(uint32_t z)
static int use_3ph_mixing(uint32_t flo)
{
/* this is a magic number somewhre between VHF and UHF */
if (flo < MHZ(300))
if (flo < MHZ(350))
return 1;
return 0;
@ -396,7 +398,7 @@ static int use_3ph_mixing(uint32_t flo)
/* \brief compute Fvco based on Fosc, Z and X
* \returns positive value (Fvco in Hz), 0 in case of error */
static unsigned int compute_fvco(uint32_t f_osc, uint8_t z, uint16_t x)
static uint64_t compute_fvco(uint32_t f_osc, uint8_t z, uint16_t x)
{
uint64_t fvco_z, fvco_x, fvco;
@ -408,26 +410,21 @@ static unsigned int compute_fvco(uint32_t f_osc, uint8_t z, uint16_t x)
*/
fvco_z = (uint64_t)f_osc * z;
#if 0
if (!is_fvco_valid(fvco_z))
return 0;
#endif
fvco_x = ((uint64_t)f_osc * x) / E4K_PLL_Y;
fvco = fvco_z + fvco_x;
/* this shouldn't happen, but better to check explicitly for integer
* overflows before converting uint64_t to "int" */
if (fvco > UINT_MAX) {
LOGP(DTUN, LOGL_ERROR, "Fvco %llu > INT_MAX\n", fvco);
return 0;
}
return fvco;
}
static int compute_flo(uint32_t f_osc, uint8_t z, uint16_t x, uint8_t r)
static uint32_t compute_flo(uint32_t f_osc, uint8_t z, uint16_t x, uint8_t r)
{
unsigned int fvco = compute_fvco(f_osc, z, x);
uint64_t fvco = compute_fvco(f_osc, z, x);
if (fvco == 0)
return -EINVAL;
@ -448,7 +445,9 @@ static int e4k_band_set(struct e4k_state *e4k, enum e4k_band band)
e4k_reg_write(e4k, E4K_REG_BIAS, 0);
break;
}
/* workaround: if we don't reset this register before writing to it,
* we get a gap between 325-350 MHz */
rc = e4k_reg_set_mask(e4k, E4K_REG_SYNTH1, 0x06, 0);
rc = e4k_reg_set_mask(e4k, E4K_REG_SYNTH1, 0x06, band << 1);
if (rc >= 0)
e4k->band = band;
@ -456,116 +455,71 @@ static int e4k_band_set(struct e4k_state *e4k, enum e4k_band band)
return rc;
}
#if 0
static int compute_lowest_r_idx(uint32_t flo, uint32_t fosc)
{
int three_phase_mixing = use_3ph_mixing(intended_flo);
uint32_t r_ideal;
/* determine what would be the idael R divider, taking into account
* fractional remainder of the division */
r_ideal = flo / fosc;
if (flo % fosc)
r_ideal++;
/* find the next best (bigger) possible R value */
for (i = 0; i < ARRAY_SIZE(vco_r_table_3ph); i++) {
uint32_t r = vco_r_table_3ph[i];
if (!three_phase_mixing)
r = r / 2;
if (r < r_ideal)
continue;
return i;
}
/* this shouldn't happen!!! */
return 0;
}
#endif
/*! \brief Compute PLL parameters for givent target frequency
* \param[out] oscp Oscillator parameters, if computation successful
* \param[in] fosc Clock input frequency applied to the chip (Hz)
* \param[in] intended_flo target tuning frequency (Hz)
* \returns actual PLL frequency, as close as possible to intended_flo,
* negative in case of error
* 0 in case of error
*/
int e4k_compute_pll_params(struct e4k_pll_params *oscp, uint32_t fosc, uint32_t intended_flo)
uint32_t e4k_compute_pll_params(struct e4k_pll_params *oscp, uint32_t fosc, uint32_t intended_flo)
{
int i;
int three_phase_mixing = use_3ph_mixing(intended_flo);
uint32_t i;
uint8_t r = 2;
uint64_t intended_fvco, remainder;
uint64_t z = 0;
uint32_t x;
int flo;
int three_phase_mixing = 0;
oscp->r_idx = 0;
if (!is_fosc_valid(fosc))
return -EINVAL;
return 0;
if (!is_flo_valid(intended_flo))
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(vco_r_table_3ph); i++) {
uint8_t r = vco_r_table_3ph[i];
uint64_t intended_fvco, z, remainder;
uint32_t x;
int flo;
if (!three_phase_mixing)
r = r / 2;
LOGP(DTUN, LOGL_DEBUG, "Fint=%u, R=%u\n", intended_flo, r);
/* flo(max) = 1700MHz, R(max) = 48, we need 64bit! */
intended_fvco = (uint64_t)intended_flo * r;
/* check if fvco is in range, if not continue */
if (intended_fvco > UINT_MAX) {
LOGP(DTUN, LOGL_DEBUG, "intended_fvco > UINT_MAX\n");
continue;
for(i = 0; i < ARRAY_SIZE(pll_vars); ++i) {
if(intended_flo < pll_vars[i].freq) {
three_phase_mixing = (pll_vars[i].reg_synth7 & 0x08) ? 1 : 0;
oscp->r_idx = pll_vars[i].reg_synth7;
r = pll_vars[i].mult;
break;
}
if (!is_fvco_valid(intended_fvco))
continue;
/* compute integral component of multiplier */
z = intended_fvco / fosc;
if (!is_z_valid(z))
continue;
/* compute fractional part. this will not overflow,
* as fosc(max) = 30MHz and z(max) = 255 */
remainder = intended_fvco - (fosc * z);
/* remainder(max) = 30MHz, E4K_PLL_Y = 65536 -> 64bit! */
x = (remainder * E4K_PLL_Y) / fosc;
/* x(max) as result of this computation is 65536 */
flo = compute_flo(fosc, z, x, r);
if (flo < 0)
continue;
oscp->fosc = fosc;
oscp->flo = flo;
oscp->intended_flo = intended_flo;
oscp->r = r;
oscp->r_idx = i;
oscp->threephase = three_phase_mixing;
oscp->x = x;
oscp->z = z;
return flo;
}
LOGP(DTUN, LOGL_ERROR, "No valid set of PLL params found for %u\n",
intended_flo);
return -EINVAL;
printf("Fint=%u, R=%u\n\r", intended_flo, r);
/* flo(max) = 1700MHz, R(max) = 48, we need 64bit! */
intended_fvco = (uint64_t)intended_flo * r;
/* compute integral component of multiplier */
z = intended_fvco / fosc;
/* compute fractional part. this will not overflow,
* as fosc(max) = 30MHz and z(max) = 255 */
remainder = intended_fvco - (fosc * z);
/* remainder(max) = 30MHz, E4K_PLL_Y = 65536 -> 64bit! */
x = (remainder * E4K_PLL_Y) / fosc;
/* x(max) as result of this computation is 65536 */
flo = compute_flo(fosc, z, x, r);
oscp->fosc = fosc;
oscp->flo = flo;
oscp->intended_flo = intended_flo;
oscp->r = r;
// oscp->r_idx = pll_vars[i].reg_synth7 & 0x0;
oscp->threephase = three_phase_mixing;
oscp->x = x;
oscp->z = z;
return flo;
}
int e4k_tune_params(struct e4k_state *e4k, struct e4k_pll_params *p)
{
uint8_t val;
/* program R index + 3phase/2phase */
val = (p->r_idx & 0x7) | ((p->threephase & 0x1) << 3);
e4k_reg_write(e4k, E4K_REG_SYNTH7, val);
/* program R + 3phase/2phase */
e4k_reg_write(e4k, E4K_REG_SYNTH7, p->r_idx);
/* program Z */
e4k_reg_write(e4k, E4K_REG_SYNTH3, p->z);
/* program X */
@ -577,7 +531,7 @@ int e4k_tune_params(struct e4k_state *e4k, struct e4k_pll_params *p)
memcpy(&e4k->vco, p, sizeof(e4k->vco));
/* set the band */
if (e4k->vco.flo < MHZ(139))
if (e4k->vco.flo < MHZ(140))
e4k_band_set(e4k, E4K_BAND_VHF2);
else if (e4k->vco.flo < MHZ(350))
e4k_band_set(e4k, E4K_BAND_VHF3);
@ -603,19 +557,28 @@ int e4k_tune_params(struct e4k_state *e4k, struct e4k_pll_params *p)
*/
int e4k_tune_freq(struct e4k_state *e4k, uint32_t freq)
{
int rc;
uint32_t rc;
struct e4k_pll_params p;
/* determine PLL parameters */
rc = e4k_compute_pll_params(&p, e4k->vco.fosc, freq);
if (rc < 0)
return rc;
if (!rc)
return -EINVAL;
/* actually tune to those parameters */
return e4k_tune_params(e4k, &p);
rc = e4k_tune_params(e4k, &p);
/* check PLL lock */
rc = e4k_reg_read(e4k, E4K_REG_SYNTH1);
if (!(rc & 0x01)) {
printf("[E4K] PLL not locked!\n\r");
return -1;
}
return 0;
}
/***********************************************************************
/***********************************************************************
* Gain Control */
static const int8_t if_stage1_gain[] = {
@ -635,33 +598,105 @@ static const int8_t if_stage56_gain[] = {
};
static const int8_t *if_stage_gain[] = {
[1] = if_stage1_gain,
[2] = if_stage23_gain,
[3] = if_stage23_gain,
[4] = if_stage4_gain,
[5] = if_stage56_gain,
[6] = if_stage56_gain
0,
if_stage1_gain,
if_stage23_gain,
if_stage23_gain,
if_stage4_gain,
if_stage56_gain,
if_stage56_gain
};
static const uint8_t if_stage_gain_len[] = {
[0] = 0,
[1] = ARRAY_SIZE(if_stage1_gain),
[2] = ARRAY_SIZE(if_stage23_gain),
[3] = ARRAY_SIZE(if_stage23_gain),
[4] = ARRAY_SIZE(if_stage4_gain),
[5] = ARRAY_SIZE(if_stage56_gain),
[6] = ARRAY_SIZE(if_stage56_gain)
0,
ARRAY_SIZE(if_stage1_gain),
ARRAY_SIZE(if_stage23_gain),
ARRAY_SIZE(if_stage23_gain),
ARRAY_SIZE(if_stage4_gain),
ARRAY_SIZE(if_stage56_gain),
ARRAY_SIZE(if_stage56_gain)
};
static const struct reg_field if_stage_gain_regs[] = {
[1] = { .reg = E4K_REG_GAIN3, .shift = 0, .width = 1 },
[2] = { .reg = E4K_REG_GAIN3, .shift = 1, .width = 2 },
[3] = { .reg = E4K_REG_GAIN3, .shift = 3, .width = 2 },
[4] = { .reg = E4K_REG_GAIN3, .shift = 5, .width = 2 },
[5] = { .reg = E4K_REG_GAIN4, .shift = 0, .width = 3 },
[6] = { .reg = E4K_REG_GAIN4, .shift = 3, .width = 3 }
{ 0, 0, 0 },
{ E4K_REG_GAIN3, 0, 1 },
{ E4K_REG_GAIN3, 1, 2 },
{ E4K_REG_GAIN3, 3, 2 },
{ E4K_REG_GAIN3, 5, 2 },
{ E4K_REG_GAIN4, 0, 3 },
{ E4K_REG_GAIN4, 3, 3 }
};
static const int32_t lnagain[] = {
-50, 0,
-25, 1,
0, 4,
25, 5,
50, 6,
75, 7,
100, 8,
125, 9,
150, 10,
175, 11,
200, 12,
250, 13,
300, 14,
};
static const int32_t enhgain[] = {
10, 30, 50, 70
};
int e4k_set_lna_gain(struct e4k_state *e4k, int32_t gain)
{
uint32_t i;
for(i = 0; i < ARRAY_SIZE(lnagain)/2; ++i) {
if(lnagain[i*2] == gain) {
e4k_reg_set_mask(e4k, E4K_REG_GAIN1, 0xf, lnagain[i*2+1]);
return gain;
}
}
return -EINVAL;
}
int e4k_set_enh_gain(struct e4k_state *e4k, int32_t gain)
{
uint32_t i;
for(i = 0; i < ARRAY_SIZE(enhgain); ++i) {
if(enhgain[i] == gain) {
e4k_reg_set_mask(e4k, E4K_REG_AGC11, 0x7, E4K_AGC11_LNA_GAIN_ENH | (i << 1));
return gain;
}
}
e4k_reg_set_mask(e4k, E4K_REG_AGC11, 0x7, 0);
/* special case: 0 = off*/
if(0 == gain)
return 0;
else
return -EINVAL;
}
int e4k_enable_manual_gain(struct e4k_state *e4k, uint8_t manual)
{
if (manual) {
/* Set LNA mode to manual */
e4k_reg_set_mask(e4k, E4K_REG_AGC1, E4K_AGC1_MOD_MASK, E4K_AGC_MOD_SERIAL);
/* Set Mixer Gain Control to manual */
e4k_reg_set_mask(e4k, E4K_REG_AGC7, E4K_AGC7_MIX_GAIN_AUTO, 0);
} else {
/* Set LNA mode to auto */
e4k_reg_set_mask(e4k, E4K_REG_AGC1, E4K_AGC1_MOD_MASK, E4K_AGC_MOD_IF_SERIAL_LNA_AUTON);
/* Set Mixer Gain Control to auto */
e4k_reg_set_mask(e4k, E4K_REG_AGC7, E4K_AGC7_MIX_GAIN_AUTO, 1);
e4k_reg_set_mask(e4k, E4K_REG_AGC11, 0x7, 0);
}
return 0;
}
static int find_stage_gain(uint8_t stage, int8_t val)
{
const int8_t *arr;
@ -707,7 +742,7 @@ int e4k_mixer_gain_set(struct e4k_state *e4k, int8_t value)
uint8_t bit;
switch (value) {
case 0:
case 4:
bit = 0;
break;
case 12:
@ -730,7 +765,7 @@ int e4k_commonmode_set(struct e4k_state *e4k, int8_t value)
return e4k_reg_set_mask(e4k, E4K_REG_DC7, 7, value);
}
/***********************************************************************
/***********************************************************************
* DC Offset */
int e4k_manual_dc_offset(struct e4k_state *e4k, int8_t iofs, int8_t irange, int8_t qofs, int8_t qrange)
@ -776,33 +811,40 @@ static const int8_t if_gains_max[] = {
struct gain_comb {
int8_t mixer_gain;
uint8_t if1_gain;
int8_t if1_gain;
uint8_t reg;
};
static const struct gain_comb dc_gain_comb[] = {
{ 0, -3, 0x50 },
{ 0, 6, 0x51 },
{ 4, -3, 0x50 },
{ 4, 6, 0x51 },
{ 12, -3, 0x52 },
{ 12, 6, 0x53 },
{ 12, 6, 0x53 },
};
#define TO_LUT(offset, range) (offset | (range << 6))
int e4k_dc_offset_gen_table(struct e4k_state *e4k)
{
int i;
uint32_t i;
/* FIXME: read ont current gain values and write them back
* before returning to the caller */
/* disable auto mixer gain */
e4k_reg_set_mask(e4k, E4K_REG_AGC7, E4K_AGC7_MIX_GAIN_AUTO, 0);
/* set LNA/IF gain to full manual */
e4k_reg_set_mask(e4k, E4K_REG_AGC1, E4K_AGC1_MOD_MASK,
E4K_AGC_MOD_SERIAL);
/* set all 'other' gains to maximum */
for (i = 2; i <= 6; i++)
e4k_if_gain_set(e4k, i, if_gains_max[i]);
/* iterate over all mixer + if_stage_1 gain combinations */
for (i = 0; i < ARRAY_SIZE(dc_gain_comb); i++) {
uint8_t offs_i, offs_q, range_i, range_q;
uint8_t offs_i, offs_q, range, range_i, range_q;
/* set the combination of mixer / if1 gain */
e4k_mixer_gain_set(e4k, dc_gain_comb[i].mixer_gain);
@ -810,34 +852,35 @@ int e4k_dc_offset_gen_table(struct e4k_state *e4k)
/* perform actual calibration */
e4k_dc_offset_calibrate(e4k);
/* FIXME: do we have to wait? */
/* extract I/Q offset and range values */
offs_i = e4k_reg_read(e4k, E4K_REG_DC2) & 0x3F;
offs_q = e4k_reg_read(e4k, E4K_REG_DC3) & 0x3F;
range_i = e4k_reg_read(e4k, E4K_REG_DC4) & 0x3;
range_q = (e4k_reg_read(e4k, E4K_REG_DC4) >> 4) & 0x3;
LOGP(DTUN, LOGL_DEBUG, "Table %u I=%u/%u, Q=%u/%u\n",
offs_i = e4k_reg_read(e4k, E4K_REG_DC2) & 0x3f;
offs_q = e4k_reg_read(e4k, E4K_REG_DC3) & 0x3f;
range = e4k_reg_read(e4k, E4K_REG_DC4);
range_i = range & 0x3;
range_q = (range >> 4) & 0x3;
/*
fprintf(stderr, "Table %u I=%u/%u, Q=%u/%u\n",
i, range_i, offs_i, range_q, offs_q);
*/
/* write into the table */
e4k_reg_write(e4k, dc_gain_comb[i].reg,
TO_LUT(offs_q, range_q));
e4k_reg_write(e4k, dc_gain_comb[i].reg+0x10,
e4k_reg_write(e4k, dc_gain_comb[i].reg + 0x10,
TO_LUT(offs_i, range_i));
}
return 0;
}
/***********************************************************************
/***********************************************************************
* Initialization */
static int magic_init(struct e4k_state *e4k)
{
e4k_reg_write(e4k, 0x7e, 0x01);
e4k_reg_write(e4k, 0x7f, 0xfe);
e4k_reg_write(e4k, 0x82, 0x00);
e4k_reg_write(e4k, 0x86, 0x50); /* polarity A */
e4k_reg_write(e4k, 0x87, 0x20);
e4k_reg_write(e4k, 0x88, 0x01);
@ -854,45 +897,89 @@ int e4k_init(struct e4k_state *e4k)
/* make a dummy i2c read or write command, will not be ACKed! */
e4k_reg_read(e4k, 0);
/* write some magic values into registers */
/* Make sure we reset everything and clear POR indicator */
e4k_reg_write(e4k, E4K_REG_MASTER1,
E4K_MASTER1_RESET |
E4K_MASTER1_NORM_STBY |
E4K_MASTER1_POR_DET
);
/* Configure clock input */
e4k_reg_write(e4k, E4K_REG_CLK_INP, 0x00);
/* Disable clock output */
e4k_reg_write(e4k, E4K_REG_REF_CLK, 0x00);
e4k_reg_write(e4k, E4K_REG_CLKOUT_PWDN, 0x96);
/* Write some magic values into registers */
magic_init(e4k);
#if 0
/* Set common mode voltage a bit higher for more margin 850 mv */
e4k_commonmode_set(e4k, 4);
/* Initialize DC offset lookup tables */
e4k_dc_offset_gen_table(e4k);
/* Enable time variant DC correction */
e4k_reg_write(e4k, E4K_REG_DCTIME1, 0x01);
e4k_reg_write(e4k, E4K_REG_DCTIME2, 0x01);
#endif
/* Set LNA mode to manual */
e4k_reg_write(e4k, E4K_REG_AGC4, 0x10); /* High threshold */
e4k_reg_write(e4k, E4K_REG_AGC5, 0x04); /* Low threshold */
e4k_reg_write(e4k, E4K_REG_AGC6, 0x1a); /* LNA calib + loop rate */
/* Set LNA mode to autnonmous */
e4k_reg_set_mask(e4k, E4K_REG_AGC1, E4K_AGC1_MOD_MASK,
E4K_AGC_MOD_IF_SERIAL_LNA_AUTON);
E4K_AGC_MOD_SERIAL);
/* Set Miser Gain Control to autonomous */
e4k_reg_set_mask(e4k, E4K_REG_AGC7, E4K_AGC7_MIX_GAIN_AUTO,
E4K_AGC7_MIX_GAIN_AUTO);
/* Set Mixer Gain Control to manual */
e4k_reg_set_mask(e4k, E4K_REG_AGC7, E4K_AGC7_MIX_GAIN_AUTO, 0);
#if 0
/* Enable LNA Gain enhancement */
e4k_reg_set_mask(e4k, E4K_REG_AGC11, 0x7,
E4K_AGC11_LNA_GAIN_ENH | (2 << 1));
/* Enable automatic IF gain mode switching */
e4k_reg_set_mask(e4k, E4K_REG_AGC8, 0x1, E4K_AGC8_SENS_LIN_AUTO);
#endif
/* FIXME: do we need to program Output Common Mode voltage ? */
/* Use auto-gain as default */
e4k_enable_manual_gain(e4k, 0);
/* FIXME: initialize DC offset lookup tables */
/* Disable Clock output, write 0x96 into 0x7A */
e4k_reg_write(e4k, E4K_REG_CLKOUT_PWDN, E4K_CLKOUT_DISABLE);
/* Clear the reset-detect register */
e4k_reg_set_mask(e4k, E4K_REG_MASTER1, E4K_MASTER1_POR_DET, E4K_MASTER1_POR_DET);
/* Select moderate gain levels */
e4k_if_gain_set(e4k, 1, 6);
e4k_if_gain_set(e4k, 2, 0);
e4k_if_gain_set(e4k, 3, 0);
e4k_if_gain_set(e4k, 4, 0);
e4k_if_gain_set(e4k, 5, 9);
e4k_if_gain_set(e4k, 6, 9);
/* Set the most narrow filter we can possibly use */
e4k_if_filter_bw_set(e4k, E4K_IF_FILTER_MIX, KHZ(1900));
e4k_if_filter_bw_set(e4k, E4K_IF_FILTER_RC, KHZ(1000));
e4k_if_filter_bw_set(e4k, E4K_IF_FILTER_CHAN, KHZ(2150));
#if 0
/* Select moderate gain levels */
e4k_if_gain_set(e4k, 1, 6);
e4k_if_gain_set(e4k, 2, 3);
e4k_if_gain_set(e4k, 3, 3);
e4k_if_gain_set(e4k, 4, 1);
e4k_if_gain_set(e4k, 5, 9);
e4k_if_gain_set(e4k, 6, 9);
#endif
e4k_if_filter_chan_enable(e4k, 1);
/* Disable time variant DC correction and LUT */
e4k_reg_set_mask(e4k, E4K_REG_DC5, 0x03, 0);
e4k_reg_set_mask(e4k, E4K_REG_DCTIME1, 0x03, 0);
e4k_reg_set_mask(e4k, E4K_REG_DCTIME2, 0x03, 0);
return 0;
}
int e4k_dump(struct e4k_state *e4k)
{
int i;
for(i = 0; i < 64; i++)
printf("0x%02x: 0x%02x 0x%02x: 0x%02x 0x%02x: 0x%02x 0x%02x: 0x%02x\n\r",
i, e4k_reg_read(e4k, i),
i + 64, e4k_reg_read(e4k, i + 64),
i + 128, e4k_reg_read(e4k, i + 128),
i + 192, e4k_reg_read(e4k, i + 192)
);
return 0;
}

View File

@ -44,7 +44,7 @@ int e4k_reg_write(struct e4k_state *e4k, uint8_t reg, uint8_t val)
return 0;
}
int e4k_reg_read(struct e4k_state *e4k, uint8_t reg)
uint8_t e4k_reg_read(struct e4k_state *e4k, uint8_t reg)
{
unsigned char rc;
uint8_t val;

View File

@ -69,6 +69,10 @@ include $(AT91LIB)/boards/$(BOARD)/board.mak
BIN = bin
OBJ = obj
GIT_REVISION := $(shell ../../git-version-gen ../../.tarball_version)
ASFLAGS += -DGIT_REVISION=\"$(GIT_REVISION)\"
CFLAGS += -DGIT_REVISION=\"$(GIT_REVISION)\"
#-------------------------------------------------------------------------------
# Tools
#-------------------------------------------------------------------------------
@ -138,6 +142,8 @@ VPATH += $(USB)/common/audio
# Objects built from C source files
C_OBJECTS += main.o
C_OBJECTS += hardware.o
C_OBJECTS += slimpro.o
C_OBJECTS += dfu_desc.o
C_OBJECTS += sam3u_chipid_usbserial.o
C_OBJECTS += USBD_UDPHS.o

View File

@ -0,0 +1,226 @@
/**************************************************************
*
* Lattice Semiconductor Corp. Copyright 2008
*
*
***************************************************************/
/**************************************************************
*
* Revision History of hardware.c
*
*
* 09/11/07 NN type cast all the mismatch variables
***************************************************************/
#include <stdio.h>
#include <unistd.h>
#include "opcode.h"
#include "hardware.h"
/*************************************************************
* *
* EXTERNAL FUNCTION *
* *
*************************************************************/
extern void ispVMStateMachine( char a_cNextState );
/*************************************************************
* *
* READPORT *
* *
* INPUT: *
* None. *
* *
* RETURN: *
* Returns the bit read back from the device. *
* *
* DESCRIPTION: *
* This function is used to read the TDO pin from the *
* input port. *
* *
* NOTE: This function should be modified in an embedded *
* system! *
* *
*************************************************************/
int readPort()
{
uint32_t value;
value = *((volatile uint32_t*)(0x400e0e00 + 0x3c));
if(value & (1 << 6))
return 1;
else return 0;
}
/*************************************************************
* *
* WRITEPORT *
* *
* INPUT: *
* a_ucPins: a byte to indicate which pin will be *
* depending on the value. *
* *
* a_ucValue: the value to determine of the pin above *
* will be written out or not. *
* *
* RETURN: *
* None. *
* *
* DESCRIPTION: *
* To apply the specified value to the pins indicated. *
* This routine will likely be modified for specific *
* systems. As an example, this code is for the PC, as *
* described below. *
* *
* This routine uses the IBM-PC standard Parallel port, *
* along with the schematic shown in Lattice *
* documentation, to apply the signals to the programming *
* loop. *
* *
* NOTE: This function should be modified in an embedded *
* system! *
* *
*************************************************************/
void writePort( unsigned int a_ucPins, unsigned int a_ucValue )
{
uint32_t value = 0;
if(a_ucPins & pinTDI)
value |= (1 << 8);
if(a_ucPins & pinTCK)
value |= (1 << 7);
if(a_ucPins & pinTMS)
value |= (1 << 5);
if(a_ucValue)
*((volatile uint32_t*)(0x400e0e00 + 0x30)) = value;
else *((volatile uint32_t*)(0x400e0e00 + 0x34)) = value;
}
/*************************************************************
* *
* ISPVMDELAY *
* *
* INPUT: *
* a_uiDelay: delay in milliseconds *
* *
* RETURN: *
* None. *
* *
* DESCRIPTION: *
* The user must implement a delay to observe a_uiDelay, *
* where a_uiDelay is the number of milliseconds that must *
* pass before data is read from in_port. Since platforms and*
* processor speeds vary greatly, this task is left to the *
* user. This subroutine is called upon to provide a delay *
* from 1 millisecond to a few hundreds milliseconds each time*
* That is the reason behind using unsigned long integer in *
* this subroutine. It is OK to provide longer delay than *
* required. It is not acceptable if the delay is shorter than*
* required. *
* *
* Note: user must re - implement to target specific hardware.*
* *
* Example: Use the for loop to create the microsecond delay. *
* Loop 1K times to produce the milliseconds delay. *
* *
* Let the CPU clock (system clock) be F Mhz. *
* *
* Let the for loop represented by the 2 lines of *
* machine code: *
* LOOP: DEC RA; *
* JNZ LOOP; *
* Let the for loop number for one microsecond be L. *
* Lets assume 4 system clocks for each line of *
* machine code. *
* Then 1 us = 1/F (microseconds per clock) *
* x (2 lines) x (4 clocks per line) x L*
* = 8L/F *
* Or L = F/8; *
* *
* Convert the unit in microseconds to *
* milliseconds. *
* L = F/8 x 1000; *
* Lets assume the CPU clock is set to 48MHZ. The C *
* code then is: *
* *
* unsigned int F = 48; //MHZ. *
* unsigned int L = F/8; //microseconds. *
* unsigned int index, m; *
* *
* *
* if (L < 1) L = 1; //minimum is i microsecond. *
* for (index=0; index < a_uiDelay * L; index++) *
* { *
* //loop 1K times to produce milliseconds delay *
* for (m=0; m<1000; m++); //milliseconds *
* } *
* return 0; *
* *
* *
*************************************************************/
/* the unit of a_uiDelay is milliseconds */
void ispVMDelay( unsigned int a_uiDelay )
{
// yes, this is more or less calibrated - cd
volatile int i, j;
for(i = 0; i < a_uiDelay; i++) {
for(j = 0; j < 5000; j++)
asm("nop");
}
}
/*************************************************************
* *
* ENABLEHARDWARE *
* *
* INPUT: *
* None. *
* *
* RETURN: *
* None. *
* *
* DESCRIPTION: *
* This function is called to enable the hardware. *
* *
* NOTE: This function should be modified in an embedded *
* system! *
* *
*************************************************************/
void EnableHardware()
{
ispVMStateMachine(RESET);
}
/*************************************************************
* *
* DISABLEHARDWARE *
* *
* INPUT: *
* None. *
* *
* RETURN: *
* None. *
* *
* DESCRIPTION: *
* This function is called to disable the hardware. *
* *
* NOTE: This function should be modified in an embedded *
* system! *
* *
*************************************************************/
void DisableHardware()
{
ispVMStateMachine(RESET);
}

View File

@ -0,0 +1,11 @@
#ifndef INCLUDE_HARDWARE_H
#define INCLUDE_HARDWARE_H
#include <stdint.h>
const uint8_t* g_ispAlgo;
size_t g_ispAlgoSize;
const uint8_t* g_ispData;
size_t g_ispDataSize;
#endif // INCLUDE_HARDWARE_H

View File

@ -62,6 +62,8 @@
#include "dfu_desc.h"
#include "opcode.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/*----------------------------------------------------------------------------
@ -104,12 +106,12 @@ static void ISR_Vbus(const Pin *pPin)
/* Check current level on VBus */
if (PIO_Get(&pinVbus))
{
TRACE_INFO("VBUS conn\n\r");
//TRACE_INFO("VBUS conn\n\r");
USBD_Connect();
}
else
{
TRACE_INFO("VBUS discon\n\r");
//TRACE_INFO("VBUS discon\n\r");
USBD_Disconnect();
}
}
@ -133,7 +135,7 @@ static void VBus_Configure( void )
}
else
{
TRACE_INFO("discon\n\r");
//TRACE_INFO("discon\n\r");
USBD_Disconnect();
}
}
@ -209,7 +211,7 @@ void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
void USBDDriverCallbacks_InterfaceSettingChanged(unsigned char interface,
unsigned char setting)
{
TRACE_INFO("DFU: IfSettingChgd(if=%u, alt=%u)\n\r", interface, setting);
//TRACE_INFO("DFU: IfSettingChgd(if=%u, alt=%u)\n\r", interface, setting);
}
#define BOOT_FLASH_SIZE (16 * 1024)
@ -233,8 +235,8 @@ static const struct flash_part flash_parts[] = {
.size = AT91C_IRAM_SIZE,
},
[ALTIF_FPGA] = {
.base_addr = AT91C_IFLASH1,
.size = AT91C_IFLASH1_SIZE,
.base_addr = 0,
.size = 16*1024*1024, // really no limit
},
};
@ -242,11 +244,13 @@ static const struct flash_part flash_parts[] = {
int USBDFU_handle_upload(uint8_t altif, unsigned int offset,
uint8_t *buf, unsigned int req_len)
{
return -EINVAL;
#if 0
struct flash_part *part;
void *end, *addr;
uint32_t real_len;
TRACE_INFO("DFU: handle_upload(%u, %u, %u)\n\r", altif, offset, req_len);
//TRACE_INFO("DFU: handle_upload(%u, %u, %u)\n\r", altif, offset, req_len);
if (altif > ARRAY_SIZE(flash_parts))
return -EINVAL;
@ -265,6 +269,94 @@ int USBDFU_handle_upload(uint8_t altif, unsigned int offset,
LED_Clear(USBD_LEDOTHER);
return real_len;
#endif
}
extern unsigned short g_usDataType;
static uint8_t fpgaBuf[1024];
static uint fpgaBufStart; // file offset of first byte in buffer
static uint fpgaBufEnd;
static uint fpgaBufFill;
static uint fpgaBufRPtr;
static uint fpgaPushedAddr;
short int ispProcessVME();
void EnableHardware();
void fpgaPushAddr()
{
fpgaPushedAddr = fpgaBufRPtr;
}
void fpgaPopAddr()
{
printf("*");
fpgaBufRPtr = fpgaPushedAddr;
}
uint8_t fpgaGetByte()
{
uint8_t res = fpgaBuf[fpgaBufRPtr - fpgaBufStart];
fpgaBufRPtr++;
return res;
}
static int fpgaFlash(unsigned int offset, const uint8_t* buf, unsigned int len)
{
int i;
if(offset == 0) {
for(i = 0; i < len; i++)
fpgaBuf[i] = buf[i];
fpgaBufStart = 0;
fpgaBufEnd = len;
fpgaBufFill = len;
fpgaBufRPtr = 0;
*((uint32_t*)(0x400e0410)) = (1 << 11);
*((uint32_t*)(0x400e0e00 + 0x44)) = (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8);
*((uint32_t*)(0x400e0e00 + 0x60)) = (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8);
*((uint32_t*)(0x400e0e00 + 0x54)) = (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8);
*((uint32_t*)(0x400e0e00 + 0x10)) = (1 << 5) | (1 << 7) | (1 << 8);
*((uint32_t*)(0x400e0e00 + 0x00)) = (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8);
if(fpgaGetByte())
g_usDataType = COMPRESS;
else g_usDataType = 0;
EnableHardware();
} else {
for(i = 0; i < len; i++)
fpgaBuf[fpgaBufFill + i] = buf[i];
fpgaBufEnd += len;
fpgaBufFill += len;
}
/*
printf("\n\rs:%d,e:%d,f:%d,r:%d,p:%d\n",
fpgaBufStart, fpgaBufEnd, fpgaBufFill, fpgaBufRPtr, fpgaPushedAddr);
*/
while(fpgaBufEnd - fpgaBufRPtr > 192) {
if((i = ispProcessVME()) < 0)
return -1;
}
if(fpgaBufFill > 384) {
uint moveby = fpgaBufFill - 384;
uint movelen = fpgaBufFill - movelen;
for(i = 0; i < movelen; i++)
fpgaBuf[i] = fpgaBuf[i + moveby];
fpgaBufStart += moveby;
fpgaBufFill -= moveby;
/*
printf("\n\rs:%d,e:%d,f:%d,r:%d,p:%d\n",
fpgaBufStart, fpgaBufEnd, fpgaBufFill, fpgaBufRPtr, fpgaPushedAddr);
*/
}
return 0;
}
/* DFU callback */
@ -286,14 +378,13 @@ int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
end = part->base_addr + part->size;
if (addr + len > end) {
TRACE_ERROR("Cannot write beyond end of DFU partition %u\n\r", altif);
TRACE_ERROR("Write beyond end (%u)\n\r", altif);
g_dfu.status = DFU_STATUS_errADDRESS;
return DFU_RET_STALL;
}
switch (altif) {
case ALTIF_APP:
case ALTIF_FPGA:
/* SAM3U Errata 46.2.1.3 */
SetFlashWaitState(6);
LED_Set(USBD_LEDOTHER);
@ -302,13 +393,26 @@ int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
/* SAM3U Errata 46.2.1.3 */
SetFlashWaitState(2);
if (rc != 0) {
TRACE_ERROR("Error during write of DFU partition %u\n\r", altif);
TRACE_ERROR("Write error (%u)\n\r", altif);
g_dfu.status = DFU_STATUS_errPROG;
return DFU_RET_STALL;
}
break;
case ALTIF_FPGA:
LED_Set(USBD_LEDOTHER);
rc = fpgaFlash(offset, buf, len);
LED_Clear(USBD_LEDOTHER);
/* SAM3U Errata 46.2.1.3 */
if (rc != 0) {
TRACE_ERROR("FPGA error (ofs %d)\n\r", fpgaBufRPtr);
g_dfu.status = DFU_STATUS_errPROG;
return DFU_RET_STALL;
}
break;
default:
TRACE_WARNING("Write to DFU partition %u not implemented\n\r", altif);
TRACE_WARNING("Not implemented (%u)\n\r", altif);
g_dfu.status = DFU_STATUS_errTARGET;
break;
}
@ -330,11 +434,11 @@ void dfu_drv_updstatus(void)
*----------------------------------------------------------------------------*/
extern void USBD_IrqHandler(void);
/*
static const char *rst_type_strs[8] = {
"General", "Backup", "Watchdog", "Softare", "User", "5", "6", "7"
};
*/
int main(void)
{
volatile uint8_t usbConn = 0;
@ -342,12 +446,11 @@ int main(void)
TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
printf("-- USB DFU Test %s --\n\r", SOFTPACK_VERSION);
printf("-- %s\n\r", BOARD_NAME);
printf("-- Osmocom USB DFU (" BOARD_NAME ") " GIT_REVISION " --\n\r");
printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
rst_type = (RSTC_GetStatus() >> 8) & 0x7;
printf("-- Reset type: %s --\n\r", rst_type_strs[rst_type]);
//printf("-- Reset type: %s --\n\r", rst_type_strs[rst_type]);
chipid_to_usbserial();

View File

@ -0,0 +1,135 @@
/**************************************************************
*
* Revision History of opcode.h
*
*
* 09/11/07 NN Updated to support version 1.3
* This version supported new POLING STATUS LOOP opcodes
* for Flash programming of the Lattice FPGA devices
* #define LOOP = 0x58
* #define ENDLOOP = 0x59
***************************************************************/
/*************************************************************
* *
* LATTICE CABLE DEFINTIONS. *
* *
* Define these only if the lattice cable is being used. *
* *
*************************************************************/
#define pinTDI 1
#define pinTCK 2
#define pinTMS 4
#define pinENABLE 8
#define pinTRST 16
#define pinCE 32
#define pinTDO 64
/*************************************************************
* *
* ERROR DEFINITIONS *
* *
*************************************************************/
#define ERR_VERIFY_FAIL -1
#define ERR_FIND_ALGO_FILE -2
#define ERR_FIND_DATA_FILE -3
#define ERR_WRONG_VERSION -4
#define ERR_ALGO_FILE_ERROR -5
#define ERR_DATA_FILE_ERROR -6
#define ERR_OUT_OF_MEMORY -7
/*************************************************************
* *
* DATA TYPE REGISTER BIT DEFINITIONS *
* *
*************************************************************/
#define SIR_DATA 0x0001 /*** Current command is SIR ***/
#define SDR_DATA 0x0002 /*** Current command is SDR ***/
#define TDI_DATA 0x0004 /*** Command contains TDI ***/
#define TDO_DATA 0x0008 /*** Command contains TDO ***/
#define MASK_DATA 0x0010 /*** Command contains MASK ***/
#define DTDI_DATA 0x0020 /*** Verification flow ***/
#define DTDO_DATA 0x0040 /*** Verification flow ***/
#define COMPRESS 0x0080 /*** Compressed data file ***/
#define COMPRESS_FRAME 0x0100 /*** Compressed data frame ***/
/*************************************************************
* *
* USED JTAG STATE *
* *
*************************************************************/
#define RESET 0x00
#define IDLE 0x01
#define IRPAUSE 0x02
#define DRPAUSE 0x03
#define SHIFTIR 0x04
#define SHIFTDR 0x05
#define DRCAPTURE 0x06
/*************************************************************
* *
* VME OPCODE DEFINITIONS *
* *
* These are the opcodes found in the VME file. Although *
* most of them are similar to SVF commands, a few opcodes *
* are available only in VME format. *
* *
*************************************************************/
#define STATE 0x10
#define SIR 0x11
#define SDR 0x12
#define TCK 0x1B
#define WAIT 0x1A
#define ENDDR 0x02
#define ENDIR 0x03
#define HIR 0x06
#define TIR 0x07
#define HDR 0x08
#define TDR 0x09
#define TDI 0x13
#define CONTINUE 0x70
#define TDO 0x14
#define MASK 0x15
#define LOOP 0x58
#define ENDLOOP 0x59
#define LCOUNT 0x66
#define LDELAY 0x67
#define LSDR 0x68
#define ENDSTATE 0x69
#define ENDVME 0x7F
/*************************************************************
* *
* Begin future opcodes at 0xA0 to avoid conflict with Full *
* VME opcodes. *
* *
*************************************************************/
#define BEGIN_REPEAT 0xA0
#define END_REPEAT 0xA1
#define END_FRAME 0xA2
#define DATA 0xA3
#define PROGRAM 0xA4
#define VERIFY 0xA5
#define DTDI 0xA6
#define DTDO 0xA7
/*************************************************************
* *
* Opcode for discrete pins toggling *
* *
*************************************************************/
#define signalENABLE 0x1C /*assert the ispEN pin*/
#define signalTMS 0x1D /*assert the MODE or TMS pin*/
#define signalTCK 0x1E /*assert the SCLK or TCK pin*/
#define signalTDI 0x1F /*assert the SDI or TDI pin*/
#define signalTRST 0x20 /*assert the RESET or TRST pin*/
#define signalTDO 0x21 /*assert the RESET or TDO pin*/
#define signalCableEN 0x22 /*assert the RESET or CableEN pin*/

File diff suppressed because it is too large Load Diff

View File

@ -145,4 +145,11 @@ void fastsource_start(void)
USBD_Write(EP_NR, test_data, sizeof(test_data), wr_compl_cb, NULL);
}
void fastsource_dump(void)
{
printf("usb pending: ");
printf("ssc pending:");
llist_for_each_entry_safe(rctx, rctx2, &ssc_state.pending_rctx, list)
printf(" %d", req_ctx_num(rctx));
printf("\r\n");
}

View File

@ -16,3 +16,4 @@
void fastsource_init(void);
void fastsource_start(void);
void fastsource_req_hdlr(const USBGenericRequest *request);
void fastsource_dump(void);

1340
fpga/hw-v2/Edfmap.ini Normal file

File diff suppressed because it is too large Load Diff

125
fpga/hw-v2/bde.set Normal file
View File

@ -0,0 +1,125 @@
##########
BUS DEFAULT NAME
BUS
##########
BUS DEFAULT TYPE
STD_LOGIC_VECTOR
##########
BUS GLOBAL CONNECTOR
GlobalBus
##########
BUS INDEX END
0
##########
BUS INDEX START
7
##########
BUS TERMINAL BUFFER
BusBuffer
##########
BUS TERMINAL IN
BusInput
##########
BUS TERMINAL INOUT
BusBidirectional
##########
BUS TERMINAL OUT
BusOutput
##########
CHECK DIAGRAM
YES
##########
DEFAULT BDE LANGUAGE
VHDL
##########
FILE HEADER
--
-- file <GENERATEDFILE>
-- generated <TIME>
-- from <SOURCEFILE>
-- by <GENERATORVERSION>
--
##########
GLOBAL CONNECTOR
Global
##########
GND DEFAULT TYPE
STD_LOGIC
##########
GND DEFAULT VALUE
'0'
##########
HANGING WIRE DEFAULT TYPE
STD_LOGIC
##########
HANGING WIRE DEFAULT VALUE
'Z'
##########
INCLUDE ACTIVE LIBRARY CLAUSE
0
##########
INCREMENT NET FACTOR
1
##########
INCREMENT NET START
0
##########
INCREMENT NETS
0
##########
LIBRARIES
library IEEE;
use IEEE.std_logic_1164.all;
##########
TERMINAL BUFFER
Buffer
##########
TERMINAL IN
Input
##########
TERMINAL INOUT
Bidirectional
##########
TERMINAL OUT
Output
##########
USE GLOBAL DEFAULTS
1
##########
VCC DEFAULT TYPE
STD_LOGIC
##########
VCC DEFAULT VALUE
'1'
##########
VERILOG DANGLING DEFAULT VALUE
1'bZ
##########
VERILOG DESIGN UNIT HEADER
`timescale 1ps / 1ps
##########
VERILOG FILE HEADER
//
// file <GENERATEDFILE>
// generated <TIME>
// from <SOURCEFILE>
// by <GENERATORVERSION>
//
##########
VERILOG GND DEFAULT TYPE
supply0
##########
VERILOG GND DEFAULT VALUE
1'b0
##########
VERILOG VCC DEFAULT TYPE
supply1
##########
VERILOG VCC DEFAULT VALUE
1'b1
##########
WIRE DEFAULT NAME
NET
##########
WIRE DEFAULT TYPE
STD_LOGIC

View File

@ -0,0 +1,22 @@
.\src\mt_toolbox\mt_toolbox.vhd
.\src\mt_toolbox\mt_clktools.vhd
.\src\mt_toolbox\mt_synctools.vhd
.\src\mt_filter\mt_filter.vhd
.\src\mt_filter\mt_fil_storage_slow.vhd
.\src\mt_filter\mt_fil_mac_slow.vhd
.\src\mt_filter\mt_fir_symmetric_slow.vhd
.\src\usbrx\usbrx.vhd
.\src\usbrx\filter\usbrx_halfband.vhd
.\src\usbrx\datapath\usbrx_ad7357.vhd
.\src\usbrx\datapath\usbrx_offset.vhd
.\src\usbrx\datapath\usbrx_decimate.vhd
.\src\usbrx\datapath\usbrx_ssc.vhd
.\src\usbrx\toplevel\usbrx_clkgen.vhd
.\src\usbrx\toplevel\usbrx_clkref.vhd
.\src\usbrx\toplevel\usbrx_gpio.vhd
.\src\usbrx\toplevel\usbrx_spi.vhd
.\src\usbrx\toplevel\usbrx_regbank.vhd
.\src\usbrx\toplevel\usbrx_pwm.vhd
.\src\usbrx\toplevel\usbrx_toplevel.vhd
.\src\testbench\tb_filter.vhd
.\src\testbench\tb_usbrx.vhd

52
fpga/hw-v2/compile.cfg Normal file
View File

@ -0,0 +1,52 @@
[View]
Entity=
Architecture=
TopLevelType=
[file:.\src\usbrx\toplevel\usbrx_toplevel.vhd]
Enabled=1
[file:.\src\usbrx\toplevel\usbrx_clkgen.vhd]
Enabled=1
[file:.\src\mt_toolbox\mt_toolbox.vhd]
Enabled=1
[file:.\src\usbrx\toplevel\usbrx_spi.vhd]
Enabled=1
[file:.\src\usbrx\toplevel\usbrx_regbank.vhd]
Enabled=1
[file:.\src\testbench\tb_usbrx.vhd]
Enabled=1
VerilogLanguage=7
LIB=
[file:.\src\usbrx\toplevel\usbrx_pwm.vhd]
Enabled=1
[file:.\src\mt_filter\mt_filter.vhd]
Enabled=1
[file:.\src\usbrx\filter\usbrx_halfband.vhd]
Enabled=1
[file:.\src\usbrx\datapath\usbrx_decimate.vhd]
Enabled=1
[file:.\src\usbrx\datapath\usbrx_ad7357.vhd]
Enabled=1
[file:.\src\usbrx\datapath\usbrx_ssc.vhd]
Enabled=1
[file:.\src\usbrx\usbrx.vhd]
Enabled=1
[file:.\src\usbrx\datapath\usbrx_offset.vhd]
Enabled=1
[file:.\src\mt_filter\mt_fil_storage_slow.vhd]
Enabled=1
[file:.\src\mt_filter\mt_fil_mac_slow.vhd]
Enabled=1
[file:.\src\mt_filter\mt_fir_symmetric_slow.vhd]
Enabled=1
[file:.\src\mt_toolbox\mt_clktools.vhd]
Enabled=1
[file:.\src\testbench\tb_filter.vhd]
LIB=
Enabled=1
VerilogLanguage=7
[file:.\src\usbrx\toplevel\usbrx_clkref.vhd]
Enabled=1
[file:.\src\mt_toolbox\mt_synctools.vhd]
Enabled=1
[file:.\src\usbrx\toplevel\usbrx_gpio.vhd]
Enabled=1

View File

@ -0,0 +1,49 @@
<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE ispXCF SYSTEM "IspXCF.dtd" >
<ispXCF version="1.4">
<Comment></Comment>
<Chain>
<Comm>JTAG</Comm>
<Device>
<SelectedProg value="TRUE"/>
<Pos>1</Pos>
<Vendor>Lattice</Vendor>
<Family>LatticeXP2</Family>
<Name>LFXP2-5E</Name>
<IDCode>0x01299043</IDCode>
<Package>All</Package>
<PON>LFXP2-5E</PON>
<Bypass>
<InstrLen>8</InstrLen>
<InstrVal>11111111</InstrVal>
<BScanLen>1</BScanLen>
<BScanVal>0</BScanVal>
</Bypass>
<File>../diamond/usbrx_vhdl/usbrx_vhdl_usbrx_vhdl.jed</File>
<FileTime>5/2/2012 11:21:53</FileTime>
<JedecChecksum>0xA75C</JedecChecksum>
<Operation>FLASH Erase,Program,Verify,Refresh</Operation>
<Option>
<SVFVendor>JTAG STANDARD</SVFVendor>
<IOState>Leave Alone</IOState>
<PreloadLength>394</PreloadLength>
<Reinitialize value="TRUE"/>
<SVFProcessor>SVF Processor</SVFProcessor>
<Usercode>0xFFFFFFFF</Usercode>
<AccessMode>FLASH</AccessMode>
</Option>
</Device>
</Chain>
<ProjectOptions>
<Program>SEQUENTIAL</Program>
<Process>ENTIRED CHAIN</Process>
<OperationOverride>No Override</OperationOverride>
<StartTAP>TLR</StartTAP>
<EndTAP>TLR</EndTAP>
<VerifyUsercode value="FALSE"/>
</ProjectOptions>
<CableOptions>
<CableName>USB2</CableName>
<PortAdd>FTUSB-0</PortAdd>
</CableOptions>
</ispXCF>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,9 @@
[Runmanager]
Geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x1\x1c\0\0\0\xd8\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\x1\0\0)
windowState=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\x1\0\0\0\0\0\0\0\x1\xff\xff\xff\xff\x3\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0)
headerState=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x13\0\xfc\a\0\0\0\t\0\0\0\x10\0\0\0\x64\0\0\0\xf\0\0\0\x64\0\0\0\xe\0\0\0\x64\0\0\0\r\0\0\0\x64\0\0\0\f\0\0\0\x64\0\0\0\v\0\0\0\x64\0\0\0\n\0\0\0\x64\0\0\0\x12\0\0\0\x64\0\0\0\x11\0\0\0\x64\0\0\x3\xa7\0\0\0\x13\x1\x1\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x3\0\0\0#\0\0\0\x1\0\0\0\x2\0\0\x3\x84\0\0\0\t\0\0\0\0\0\0\0\0\0\0\0\t\0\0\0\0)
[usbrx_vhdl%3CStrategy1%3E]
isChecked=false
isHidden=false
isExpanded=false

View File

@ -0,0 +1,4 @@
[General]
PAR.auto_tasks=PARTrace, IOTiming
Map.auto_tasks=@Invalid()
Export.auto_tasks=TimingSimFileVHD, Bitgen

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE strategy>
<Strategy version="1.0" predefined="0" description="" label="Strategy1">
<Property name="PROP_MAP_TimingDriven" value="True" time="0"/>
<Property name="PROP_MAP_TimingDrivenNodeRep" value="True" time="0"/>
<Property name="PROP_MAP_TimingDrivenPack" value="True" time="0"/>
</Strategy>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Report>
<ReportView version="2.0">
<Implement name="usbrx_vhdl">
<ToolReport id="toolhle_genhierarchy" path="hdldiagram_gen_hierarchy.html" status="2"/>
<ToolReport id="toolhle_runbkm" path="" status="2"/>
<ToolReport id="toolpio" path="" status="2"/>
<ToolReport id="toolsso" path="" status="2"/>
</Implement>
</ReportView>

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<BaliProject version="1.3" title="usbrx_vhdl" device="LFXP2-5E-5M132C" default_implementation="usbrx_vhdl">
<Options/>
<Implementation title="usbrx_vhdl" dir="usbrx_vhdl" description="usbrx_vhdl" default_strategy="Strategy1">
<Options top="usbrx_toplevel"/>
<Source name="../src/mt_toolbox/mt_toolbox.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/toplevel/usbrx_clkgen.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/toplevel/usbrx_toplevel.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/toplevel/usbrx_pwm.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/toplevel/usbrx_regbank.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/toplevel/usbrx_spi.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/mt_filter/mt_filter.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/filter/usbrx_halfband.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/datapath/usbrx_ssc.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/datapath/usbrx_ad7357.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/datapath/usbrx_decimate.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/datapath/usbrx_offset.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/usbrx.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/mt_filter/mt_fil_mac_slow.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/mt_filter/mt_fil_storage_slow.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/mt_filter/mt_fir_symmetric_slow.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/mt_toolbox/mt_clktools.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/mt_toolbox/mt_synctools.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/toplevel/usbrx_clkref.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/toplevel/usbrx_gpio.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../deploy/usbrx.xcf" type="ispVM Download Project" type_short="ispVM" excluded="TRUE">
<Options/>
</Source>
<Source name="usbrx_vhdl.lpf" type="Logic Preference" type_short="LPF">
<Options/>
</Source>
</Implementation>
<Strategy name="Strategy1" file="Strategy1.sty"/>
</BaliProject>

View File

@ -0,0 +1,132 @@
BLOCK RESETPATHS ;
BLOCK ASYNCPATHS ;
LOCATE COMP "clk_in_pclk" SITE "H1" ;
LOCATE COMP "adc_cs" SITE "G1" ;
LOCATE COMP "adc_sck" SITE "B1" ;
LOCATE COMP "adc_sd1" SITE "D1" ;
LOCATE COMP "adc_sd2" SITE "E1" ;
LOCATE COMP "ctl_int" SITE "P2" ;
LOCATE COMP "ctl_cs" SITE "P4" ;
LOCATE COMP "ctl_sck" SITE "P5" ;
LOCATE COMP "ctl_mosi" SITE "P6" ;
LOCATE COMP "ctl_miso" SITE "P7" ;
LOCATE COMP "dingsrst" SITE "P10" ;
LOCATE COMP "dings" SITE "P9" ;
LOCATE COMP "rx_clk" SITE "B14" ;
LOCATE COMP "rx_syn" SITE "D14" ;
LOCATE COMP "rx_dat" SITE "E14" ;
LOCATE COMP "tx_clk" SITE "A14" ;
LOCATE COMP "tx_syn" SITE "G14" ;
LOCATE COMP "tx_dat" SITE "F14" ;
LOCATE COMP "gain0" SITE "P1" ;
LOCATE COMP "gain1" SITE "N1" ;
LOCATE COMP "gps_1pps" SITE "P14" ;
LOCATE COMP "gps_10k" SITE "N14" ;
LOCATE COMP "gpio_0" SITE "A1" ;
LOCATE COMP "gpio_1" SITE "A2" ;
LOCATE COMP "gpio_2" SITE "A3" ;
LOCATE COMP "gpio_3" SITE "A5" ;
LOCATE COMP "gpio_4" SITE "A7" ;
LOCATE COMP "gpio_5" SITE "A8" ;
LOCATE COMP "gpio_6" SITE "A9" ;
LOCATE COMP "gpio_7" SITE "A10" ;
LOCATE COMP "gpio_8" SITE "A11" ;
LOCATE COMP "gpio_9" SITE "A13" ;
LOCATE COMP "led" SITE "M7" ;
LOCATE COMP "vgnd_0" SITE "B3" ;
LOCATE COMP "vgnd_1" SITE "C5" ;
LOCATE COMP "vgnd_2" SITE "C8" ;
LOCATE COMP "vgnd_3" SITE "B2" ;
LOCATE COMP "vgnd_4" SITE "C2" ;
LOCATE COMP "vgnd_5" SITE "D2" ;
LOCATE COMP "vgnd_6" SITE "M6" ;
LOCATE COMP "vgnd_7" SITE "N2" ;
LOCATE COMP "vgnd_8" SITE "N3" ;
LOCATE COMP "vgnd_9" SITE "D12" ;
LOCATE COMP "vgnd_10" SITE "D13" ;
LOCATE COMP "vgnd_11" SITE "M10" ;
LOCATE COMP "vcc33_0" SITE "B6" ;
LOCATE COMP "vcc33_1" SITE "C7" ;
LOCATE COMP "vcc33_2" SITE "C10" ;
LOCATE COMP "vcc33_3" SITE "D3" ;
LOCATE COMP "vcc33_4" SITE "E3" ;
LOCATE COMP "vcc33_5" SITE "G2" ;
LOCATE COMP "vcc33_6" SITE "H2" ;
LOCATE COMP "vcc33_7" SITE "M4" ;
LOCATE COMP "vcc33_8" SITE "M5" ;
LOCATE COMP "vcc33_9" SITE "P13" ;
LOCATE COMP "vcc33_10" SITE "M13" ;
LOCATE COMP "vcc33_11" SITE "N13" ;
LOCATE COMP "vcc12_0" SITE "B9" ;
LOCATE COMP "vcc12_1" SITE "B10" ;
LOCATE COMP "vcc12_2" SITE "C9" ;
LOCATE COMP "vcc12_3" SITE "H13" ;
LOCATE COMP "vcc12_4" SITE "H14" ;
IOBUF PORT "clk_in_pclk" IO_TYPE=LVCMOS33 ;
IOBUF PORT "adc_cs" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "adc_sck" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "adc_sd1" IO_TYPE=LVCMOS33 ;
IOBUF PORT "adc_sd2" IO_TYPE=LVCMOS33 ;
IOBUF PORT "ctl_int" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "ctl_cs" IO_TYPE=LVCMOS33 ;
IOBUF PORT "ctl_sck" IO_TYPE=LVCMOS33 ;
IOBUF PORT "ctl_mosi" IO_TYPE=LVCMOS33 ;
IOBUF PORT "ctl_miso" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "dingsrst" IO_TYPE=LVCMOS33 ;
IOBUF PORT "dings" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gps_10k" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "rx_clk" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "rx_syn" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "rx_dat" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "tx_clk" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "tx_syn" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "tx_dat" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gain0" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gain1" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gps_1pps" IO_TYPE=LVCMOS33 ;
IOBUF PORT "gpio_0" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_1" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_2" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_3" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_4" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_5" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_6" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_7" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_8" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_9" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "led" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_0" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_1" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_2" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_3" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_4" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_5" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_6" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_7" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_8" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_9" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_10" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_11" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc33_0" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc33_1" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc33_2" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc33_3" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc33_4" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc33_5" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc33_6" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc33_7" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc33_8" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc33_9" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc33_10" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc33_11" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc33_12" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc12_0" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc12_1" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc12_2" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc12_3" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vcc12_4" IO_TYPE=LVCMOS33 DRIVE=4 ;
FREQUENCY PORT "clk_in_pclk" 30.000000 MHz ;
FREQUENCY NET "clk_80_c" 80.000000 MHz ;
SYSCONFIG INBUF=OFF ;

View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE strategy>
<Strategy version="1.0" predefined="0" description="" label=""/>

2
fpga/hw-v2/library.cfg Normal file
View File

@ -0,0 +1,2 @@
$include = "$VSIMSALIBRARYCFG"
usbrx_vhdl = "./usbrx_vhdl.LIB" 1322060719953

1
fpga/hw-v2/projlib.cfg Normal file
View File

@ -0,0 +1 @@
usbrx_vhdl = "./usbrx_vhdl.LIB" 1322060719655

View File

@ -0,0 +1,146 @@
---------------------------------------------------------------------------------------------------
-- Filename : mt_fil_mac_slow.vhd
-- Project : maintech filter toolbox
-- Purpose : MAC cell for FIR-like filters
-- - version for 'slow' filter versions
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- mt_fil_mac_slow ------------------------------------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.mt_filter.all;
entity mt_fil_mac_slow is
port (
-- common
clk : in std_logic;
reset : in std_logic;
-- control-path
start : in std_logic;
active : in std_logic;
presub : in std_logic;
-- data input
smp1 : in fir_dataword18;
smp2 : in fir_dataword18;
coeff : in fir_dataword18;
-- data output
dnew : out std_logic;
dout : out fir_dataword18
);
end mt_fil_mac_slow;
architecture rtl of mt_fil_mac_slow is
-- rounding constant (16 bits will get truncated)
constant RNDVAL : natural := (2**16/2);
-- control signals
signal done : std_logic;
signal active_del : std_logic_vector(2 downto 0);
signal start_del : std_logic_vector(2 downto 0);
signal done_del : std_logic_vector(2 downto 0);
-- data registers
signal psreg : std_logic;
signal dreg : signed(17 downto 0);
signal b0reg : signed(17 downto 0);
signal b1reg : signed(18 downto 0);
signal a0reg : signed(17 downto 0);
signal a1reg : signed(17 downto 0);
signal mreg : signed(35 downto 0);
signal preg : signed(35 downto 0);
begin
-- create done-flag after 'active' goes low or 'start' is set while still active
done <= (start or (not active)) and active_del(0);
-- create delayed control-signals
process(clk)
begin
if rising_edge(clk) then
active_del <= active_del(active_del'left-1 downto 0) & active;
start_del <= start_del(start_del'left-1 downto 0) & start;
done_del <= done_del(done_del'left-1 downto 0) & done;
end if;
end process;
-- do math
process(clk)
begin
if rising_edge(clk) then
-- simple storage registers
psreg <= presub;
dreg <= smp1;
b0reg <= smp2;
a0reg <= coeff;
a1reg <= a0reg;
-- pre-adder
if psreg='1'
then b1reg <= resize(b0reg,19) - resize(dreg,19);
else b1reg <= resize(b0reg,19) + resize(dreg,19);
end if;
-- multiplier
mreg <= a1reg * b1reg(18 downto 1);
-- post-adder / accumulator
if active_del(2)='1' then
if start_del(2)='1'
then preg <= mreg + to_signed(RNDVAL,36);
else preg <= mreg + preg;
end if;
end if;
end if;
end process;
-- update output
process(reset, clk)
begin
if reset='1' then
dnew <= '0';
dout <= (others=>'0');
elsif rising_edge(clk) then
if done_del(2)='1' then
dnew <= '1';
if preg(35)='0' and preg(34 downto 33)/="00" then
dout <= to_signed(2**17-1,18);
elsif preg(35)='1' and preg(34 downto 33)/="11" then
dout <= to_signed(-(2**17),18);
else
dout <= preg(33 downto 16);
end if;
else
dnew <= '0';
end if;
end if;
end process;
end rtl;

View File

@ -0,0 +1,403 @@
---------------------------------------------------------------------------------------------------
-- Filename : mt_fil_storage_slow.vhd
-- Project : maintech filter toolbox
-- Purpose : basic data storage for FIR-like filters
-- - version for 'slow' filter versions
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- mt_fil_dstorage_slow ------------------------------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.mt_filter.all;
entity mt_fil_dstorage_slow is
generic (
CHANNELS : natural;
DEPTH : natural;
RAMSTYLE : string
);
port (
-- common
clk : in std_logic;
reset : in std_logic;
-- control
chan : in unsigned(log2(CHANNELS)-1 downto 0);
load : in std_logic;
start : in std_logic;
stop : in std_logic;
active : in std_logic;
-- datapath
din : in fir_dataword18;
dout1 : out fir_dataword18;
dout2 : out fir_dataword18
);
end mt_fil_dstorage_slow;
architecture rtl of mt_fil_dstorage_slow is
--
-- types & rams
--
-- derived constants
constant MEMSIZE : natural := CHANNELS * DEPTH;
-- internal types
subtype offset_t is unsigned(log2(DEPTH)-1 downto 0);
subtype addr_t is unsigned(log2(MEMSIZE)-1 downto 0);
subtype data_t is fir_dataword18;
type atab_t is array(CHANNELS-1 downto 0) of addr_t;
type pram_t is array(CHANNELS-1 downto 0) of offset_t;
type sram_t is array(MEMSIZE-1 downto 0) of data_t;
-- create address tables
function get_addr_tab return atab_t is
variable res : atab_t;
begin
for i in res'range loop
res(i) := to_unsigned(i*DEPTH, addr_t'length);
end loop;
return res;
end get_addr_tab;
constant addr_tab : atab_t := get_addr_tab;
-- ram ports
signal sram1_we : std_logic;
signal sram1_waddr : addr_t;
signal sram1_wdata : data_t;
signal sram1_re : std_logic;
signal sram1_raddr : addr_t;
signal sram1_rdata : data_t := (others=>'0');
signal sram2_we : std_logic;
signal sram2_waddr : addr_t;
signal sram2_wdata : data_t;
signal sram2_re : std_logic;
signal sram2_raddr : addr_t;
signal sram2_rdata : data_t := (others=>'0');
-- actual rams
signal pram : pram_t := (others=>(others=>'0'));
signal sram1 : sram_t := (others=>(others=>'0'));
signal sram2 : sram_t := (others=>(others=>'0'));
-- configure rams
attribute syn_ramstyle of pram : signal is "logic";
attribute syn_ramstyle of sram1 : signal is RAMSTYLE;
attribute syn_ramstyle of sram2 : signal is RAMSTYLE&",no_rw_check";
--
-- status
--
-- delayed control signals
signal start_del : std_logic_vector(1 downto 0);
signal load_del : std_logic_vector(2 downto 0);
signal active_del : std_logic_vector(1 downto 0);
signal stop_del : std_logic_vector(2 downto 0);
-- status
signal selchan : unsigned(log2(CHANNELS)-1 downto 0);
signal baseaddr : addr_t;
signal woffset : offset_t;
signal roffset1 : offset_t;
signal roffset2 : offset_t;
begin
-- validate generics
assert DEPTH>1
report "mt_fil_dstorage_slow: DEPTH must be larger than 1"
severity FAILURE;
-- control logic
process(clk, reset)
variable offset : offset_t;
begin
if reset='1' then
start_del <= (others=>'0');
load_del <= (others=>'0');
active_del <= (others=>'0');
stop_del <= (others=>'0');
selchan <= (others=>'0');
baseaddr <= (others=>'0');
woffset <= (others=>'0');
roffset1 <= (others=>'0');
roffset2 <= (others=>'0');
sram1_re <= '0';
sram1_we <= '0';
sram1_raddr <= (others=>'0');
sram1_waddr <= (others=>'0');
sram1_wdata <= (others=>'0');
sram2_re <= '0';
sram2_we <= '0';
sram2_raddr <= (others=>'0');
sram2_waddr <= (others=>'0');
sram2_wdata <= (others=>'0');
elsif rising_edge(clk) then
-- set default values
sram1_re <= '0';
sram1_we <= '0';
sram2_re <= '0';
sram2_we <= '0';
-- create delayed flags
start_del <= start_del(start_del'left-1 downto 0) & start;
load_del <= load_del(load_del'left-1 downto 0) & load;
active_del <= active_del(active_del'left-1 downto 0) & active;
stop_del <= stop_del(stop_del'left-1 downto 0) & stop;
-- init status on start of burst
if start='1' then
-- remember channel
selchan <= chan;
-- get base-address for selected channels
baseaddr <= addr_tab(to_integer(chan));
-- init pointers
offset := pram(to_integer(chan));
woffset <= offset;
roffset1 <= offset;
if offset=(DEPTH-1)
then roffset2 <= to_unsigned(0,roffset2'length);
else roffset2 <= offset + 1;
end if;
end if;
-- store sample into ram and increment write-pointer if 'load'-flag is set
if load_del(0)='1' then
-- write sample into ram
sram1_we <= '1';
sram1_waddr <= baseaddr + woffset;
sram1_wdata <= din;
-- update write-pointer
woffset <= roffset2; -- 'roffset2' is actually "((woffset+1) mod DEPTH)" here
end if;
if load_del(1)='1' then
-- write-back updated write-pointer
pram(to_integer(selchan)) <= woffset;
end if;
-- carry sample from sram1 into sram2 if 'stop'-flag is set
if load_del(1)='1' then
sram2_waddr <= baseaddr + woffset;
end if;
if stop_del(2)='1' then
sram2_we <= '1';
sram2_wdata <= sram1_rdata;
end if;
-- issue read-requests when active
if active_del(0)='1' then
-- read samples from ram
sram1_re <= '1';
sram2_re <= '1';
sram1_raddr <= baseaddr + roffset1;
sram2_raddr <= baseaddr + roffset2;
-- update read-pointers
if roffset1=0
then roffset1 <= to_unsigned(DEPTH-1,roffset1'length);
else roffset1 <= roffset1 - 1;
end if;
if roffset2=(DEPTH-1)
then roffset2 <= to_unsigned(0,roffset2'length);
else roffset2 <= roffset2 + 1;
end if;
end if;
end if;
end process;
-- set output
dout1 <= sram1_rdata when load_del(2)='0' else din;
dout2 <= sram2_rdata;
-- infer rams
process(clk)
begin
if rising_edge(clk) then
if sram1_we='1' then
sram1(to_integer(sram1_waddr)) <= sram1_wdata;
end if;
if sram1_re='1' then
sram1_rdata <= sram1(to_integer(sram1_raddr));
end if;
if sram2_we='1' then
sram2(to_integer(sram2_waddr)) <= sram2_wdata;
end if;
if sram2_re='1' then
sram2_rdata <= sram2(to_integer(sram2_raddr));
end if;
end if;
end process;
end rtl;
-------------------------------------------------------------------------------
-- mt_fil_storage_slow --------------------------------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.mt_filter.all;
entity mt_fil_storage_slow is
generic (
COEFFS : fir_coefficients; -- coefficients
DCHAN : natural; -- number of data channels
TAPS : natural; -- number of samples in each segment
RAMSTYLE : string; -- ram style for inferred memories
ROMSTYLE : string -- ram style for coefficent rom
);
port (
-- common
clk : in std_logic;
reset : in std_logic;
-- config
chan : in unsigned(log2(DCHAN)-1 downto 0);
-- input
in_load : in std_logic;
in_start : in std_logic;
in_stop : in std_logic;
in_active : in std_logic;
in_data : in fir_dataword18;
-- output
out_load : out std_logic;
out_start : out std_logic;
out_stop : out std_logic;
out_active : out std_logic;
out_data1 : out fir_dataword18;
out_data2 : out fir_dataword18;
out_coeff : out fir_dataword18
);
end mt_fil_storage_slow;
architecture rtl of mt_fil_storage_slow is
-- status
signal del_load : std_logic_vector(1 downto 0);
signal del_start : std_logic_vector(1 downto 0);
signal del_stop : std_logic_vector(1 downto 0);
signal del_active : std_logic_vector(1 downto 0);
signal cind : unsigned(log2(TAPS)-1 downto 0);
-- coeff rom
constant rom_size : natural := 1 * (2**log2(TAPS));
type rom_t is array (0 to rom_size-1) of fir_dataword18;
function generate_rom return rom_t is
variable rom : rom_t;
variable ssize : natural;
begin
ssize := 2**log2(TAPS);
rom := (others=>(others=>'0'));
for t in 0 to TAPS-1 loop
rom(t) := to_signed(COEFFS(t), 18);
end loop;
return rom;
end generate_rom;
signal rom : rom_t := generate_rom;
-- don't waste blockram
attribute syn_romstyle of rom : signal is ROMSTYLE;
attribute syn_ramstyle of rom : signal is ROMSTYLE;
begin
-- data-buffer
dbuf: entity mt_fil_dstorage_slow
generic map (
CHANNELS => DCHAN,
DEPTH => TAPS,
RAMSTYLE => RAMSTYLE
)
port map (
clk => clk,
reset => reset,
chan => chan,
load => in_load,
start => in_start,
stop => in_stop,
active => in_active,
din => in_data,
dout1 => out_data1,
dout2 => out_data2
);
-- control logic
process(clk, reset)
begin
if reset='1' then
del_load <= (others=>'0');
del_start <= (others=>'0');
del_stop <= (others=>'0');
del_active <= (others=>'0');
out_load <= '0';
out_start <= '0';
out_stop <= '0';
out_active <= '0';
out_coeff <= (others=>'0');
cind <= (others=>'0');
elsif rising_edge(clk) then
-- create delayed control flags
del_load <= del_load(del_load'left-1 downto 0) & in_load;
del_start <= del_start(del_start'left-1 downto 0) & in_start;
del_stop <= del_stop(del_stop'left-1 downto 0) & in_stop;
del_active <= del_active(del_active'left-1 downto 0) & in_active;
-- output delayed control flags
out_load <= del_load(1);
out_start <= del_start(1);
out_stop <= del_stop(1);
out_active <= del_active(1);
-- update coeff-indices
if del_start(0)='1' then
cind <= to_unsigned(0, cind'length);
elsif del_active(0)='1' then
cind <= cind + 1;
end if;
-- output coefficent
out_coeff <= rom(to_integer(cind));
end if;
end process;
end rtl;

View File

@ -0,0 +1,46 @@
---------------------------------------------------------------------------------------------------
-- Filename : mt_filter.vhd
-- Project : maintech filter toolbox
-- Purpose : maintech filter toolbox package
--
-- Description : declaration of common types, functions and attributes
-- used throughout the filter toolbox
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package mt_filter is
--
-- FIR filter types
--
subtype fir_dataword18 is signed(17 downto 0);
type fir_databus18 is array (natural range <>) of fir_dataword18;
subtype fir_coefficient is integer range -2**17 to 2**17-1;
type fir_coefficients is array (natural range <>) of fir_coefficient;
end mt_filter;
package body mt_filter is
-- nothing so far
end mt_filter;

View File

@ -0,0 +1,219 @@
---------------------------------------------------------------------------------------------------
-- Filename : mt_fir_symmetric_slow.vhd
-- Project : maintech filter toolbox
-- Purpose : Symmetric FIR filter
-- - multiplexed input/output for all data-channels
-- - single MAC-cell for all calculations
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.mt_filter.all;
entity mt_fir_symmetric_slow is
generic (
CHANNELS : natural; -- number of data channels
TAPS : natural; -- number of filter taps (AFTER folding)
COEFFS : fir_coefficients; -- coefficent sets
RAMSTYLE : string; -- ram style for inferred memories
ROMSTYLE : string -- ram style for coefficent rom
);
port(
-- common
clk : in std_logic;
reset : in std_logic;
-- input port
in_clk : in std_logic;
in_ack : out std_logic;
in_chan : in unsigned(log2(CHANNELS)-1 downto 0);
in_data : in fir_dataword18;
-- output port
out_clk : out std_logic;
out_chan : out unsigned(log2(CHANNELS)-1 downto 0);
out_data : out fir_dataword18
);
end mt_fir_symmetric_slow;
architecture rtl of mt_fir_symmetric_slow is
-- internal types
subtype chan_t is unsigned(log2(CHANNELS)-1 downto 0);
type chan_array_t is array(natural range<>) of chan_t;
-- control signals
signal active : std_logic;
signal shiftcnt : unsigned(log2(TAPS)-1 downto 0);
signal ochan : chan_array_t(3 downto 0);
-- storage ports
signal st_chan : chan_t;
signal st_start : std_logic;
signal st_stop : std_logic;
signal st_active : std_logic;
signal st_din : fir_dataword18;
-- storage <-> MAC
signal st_mac_start : std_logic;
signal st_mac_stop : std_logic;
signal st_mac_active : std_logic;
signal st_mac_dout1 : fir_dataword18;
signal st_mac_dout2 : fir_dataword18;
signal st_mac_coeff : fir_dataword18;
-- MAC output
signal mac_dnew : std_logic;
signal mac_dout : fir_dataword18;
begin
-- control logic
process(clk, reset)
begin
if reset='1' then
active <= '0';
shiftcnt <= (others=>'0');
ochan <= (others=>(others=>'0'));
st_start <= '0';
st_stop <= '0';
st_active <= '0';
in_ack <= '0';
out_clk <= '0';
out_data <= (others=>'0');
out_chan <= (others=>'0');
elsif rising_edge(clk) then
-- set default values
in_ack <= '0';
out_clk <= '0';
st_start <= '0';
st_stop <= '0';
st_active <= '0';
-- get current status
if active='0' then
--> idle
-- check for new request
if in_clk='1' then
--> input new sample and start burst from storage to MAC cell
shiftcnt <= to_unsigned(TAPS-1, shiftcnt'length);
st_start <= '1';
st_active <= '1';
active <= '1';
end if;
else
--> active
-- control storage
if shiftcnt/=0 then
--> continue with burst
shiftcnt <= shiftcnt-1;
st_active <= '1';
if shiftcnt=1 then
-- last cycle of burst
st_stop <= '1';
in_ack <= '1';
active <= '0';
end if;
end if;
end if;
-- check if new result is ready
if mac_dnew='1' then
--> MAC done, update output
out_clk <= '1';
out_chan <= ochan(ochan'left);
out_data <= mac_dout;
end if;
-- delay channel-number to compensate for MAC delay
ochan <= ochan(ochan'left-1 downto 0) & ochan(0);
if st_mac_start='1' then
ochan(0) <= in_chan;
end if;
end if;
end process;
-- connect storage input
st_chan <= in_chan;
st_din <= in_data;
-- data storage
st: entity mt_fil_storage_slow
generic map (
COEFFS => COEFFS,
DCHAN => CHANNELS,
TAPS => TAPS,
RAMSTYLE => RAMSTYLE,
ROMSTYLE => ROMSTYLE
)
port map (
-- common
clk => clk,
reset => reset,
-- config
chan => st_chan,
-- input
in_load => st_start,
in_start => st_start,
in_stop => st_stop,
in_active => st_active,
in_data => st_din,
-- output
out_load => open,
out_start => st_mac_start,
out_stop => st_mac_stop,
out_active => st_mac_active,
out_data1 => st_mac_dout1,
out_data2 => st_mac_dout2,
out_coeff => st_mac_coeff
);
-- do create MAC cell
mac: entity mt_fil_mac_slow
port map (
-- common
clk => clk,
reset => reset,
-- control-path
start => st_mac_start,
active => st_mac_active,
presub => '0',
-- data input
smp1 => st_mac_dout1,
smp2 => st_mac_dout2,
coeff => st_mac_coeff,
-- data output
dnew => mac_dnew,
dout => mac_dout
);
end rtl;

View File

@ -0,0 +1,141 @@
---------------------------------------------------------------------------------------------------
-- Filename : mt_clktools.vhd
-- Project : maintech IP-Core toolbox
-- Purpose : Basic tools for clock/reset-generation
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- mt_reset_gen ---------------------------------------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity mt_reset_gen is
port (
clk : in std_logic; -- some direct clock-input
ext_rst : in std_logic; -- external reset
pll_locked : in std_logic; -- PLLs locked?
reset_pll : out std_logic; -- reset signal for PLLs
reset_sys : out std_logic -- global reset signal
);
end mt_reset_gen;
architecture rtl of mt_reset_gen is
-- reset generation
signal rst_roc2pll : std_logic_vector(15 downto 0) := (others=>'1'); -- delay between rst_roc <-> rst_pll
signal rst_pll2go : std_logic_vector( 5 downto 0) := (others=>'1'); -- delay between reset_pll <-> reset_I
signal reset_pll_i : std_logic := '1'; -- inner version of 'reset_pll'
signal reset_sys_i : std_logic; -- inner version of 'reset_sys'
-- TODO
signal lockcnt : unsigned(15 downto 0) := (others=>'0');
signal relock : std_logic := '0';
begin
-- generate PLL-reset
process(clk)
begin
if rising_edge(clk) then
-- if ext_rst='0' or relock='1' then
if relock='1' then
rst_roc2pll <= (others=>'1');
reset_pll_i <= '1';
else
rst_roc2pll <= '0' & rst_roc2pll(rst_roc2pll'high downto 1);
reset_pll_i <= rst_roc2pll(0);
end if;
end if;
end process;
-- TODO
process(clk)
begin
if rising_edge(clk) then
-- if ext_rst='0' or pll_locked='1' or relock='1' then
if pll_locked='1' or relock='1' then
lockcnt <= to_unsigned(0,16);
relock <= '0';
else
lockcnt <= lockcnt+1;
if lockcnt=30000-1 then
relock <= '1';
end if;
end if;
end if;
end process;
-- generate system-reset
process(clk, reset_pll_i)
begin
if reset_pll_i = '1' then
reset_sys_i <= '1';
rst_pll2go <= (others=>'1');
elsif rising_edge(clk) then
if pll_locked='0' then
rst_pll2go <= (others=>'1');
reset_sys_i <= '1';
else
rst_pll2go <= '0' & rst_pll2go(rst_pll2go'high downto 1);
reset_sys_i <= rst_pll2go(0);
end if;
end if;
end process;
-- output reset-signal
reset_sys <= reset_sys_i;
-- output PLL-reset
reset_pll <= reset_pll_i;
end;
-------------------------------------------------------------------------------
-- mt_reset_sync --------------------------------------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity mt_reset_sync is
port (
clk : in std_logic;
rst_in : in std_logic;
rst_out : out std_logic
);
end mt_reset_sync;
architecture rtl of mt_reset_sync is
signal taps : std_logic_vector(3 downto 0);
begin
process(clk, rst_in)
begin
if rst_in='1' then
taps <= (others=>'1');
rst_out <= '1';
elsif rising_edge(clk) then
taps <= "0" & taps(taps'high downto 1);
rst_out <= taps(0);
end if;
end process;
end;

View File

@ -0,0 +1,135 @@
-----------------------------------------------------------------------------------
-- Filename : mt_synctools.vhd
-- Project : maintech IP-Core toolbox
-- Purpose : Basic tools for clock-domain-crossings
--
-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- mt_sync_dualff (dual flip-flop synchronizer) -------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.mt_toolbox.all;
entity mt_sync_dualff is
port(
-- input
i_data : in std_logic;
-- output
o_clk : in std_logic;
o_data : out std_logic
);
end mt_sync_dualff;
architecture rtl of mt_sync_dualff is
-- signals
signal sreg : std_logic := '0';
signal oreg : std_logic := '0';
-- no SRL16s here...
attribute shreg_extract of sreg : signal is "no";
attribute shreg_extract of oreg : signal is "no";
begin
process(o_clk)
begin
if rising_edge(o_clk) then
sreg <= i_data;
oreg <= sreg;
end if;
end process;
o_data <= oreg;
end rtl;
-------------------------------------------------------------------------------
-- mt_sync_feedback (feedback synchronizer) -----------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.mt_toolbox.all;
entity mt_sync_feedback is
port(
-- input
i_clk : in std_logic;
i_data : in std_logic;
-- output
o_clk : in std_logic;
o_data : out std_logic
);
end mt_sync_feedback;
architecture rtl of mt_sync_feedback is
signal flip_i : std_logic := '0';
signal flip_s1 : std_logic := '0';
signal flip_s2 : std_logic := '0';
signal flip_s3 : std_logic := '0';
signal oreg : std_logic := '0';
attribute syn_keep of flip_i : signal is true;
attribute syn_keep of flip_s1 : signal is true;
attribute syn_keep of flip_s2 : signal is true;
attribute syn_keep of flip_s3 : signal is true;
attribute syn_keep of oreg : signal is true;
begin
process(i_clk)
begin
if rising_edge(i_clk) then
-- update flip-bit on request
if i_data='1' then
flip_i <= not flip_i;
end if;
-- debug check
assert not (i_data='1' and flip_s1/=flip_i)
report "mt_sync_feedback: pulses too close, failed to synchronize"
severity failure;
end if;
end process;
process(o_clk)
begin
if rising_edge(o_clk) then
-- synchronize flip-bit
flip_s1 <= flip_i;
flip_s2 <= flip_s1;
flip_s3 <= flip_s2;
-- create output-request
oreg <= flip_s3 xor flip_s2;
end if;
end process;
-- set output
o_data <= oreg;
end rtl;

View File

@ -0,0 +1,183 @@
---------------------------------------------------------------------------------------------------
-- Filename : mt_toolbox.vhd
-- Project : maintech IP-Core toolbox
-- Purpose : maintech toolbox package
--
-- Description : declaration of common types, functions and attributes
-- used throughout the toolbox
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package mt_toolbox is
--
-- basic types
--
subtype slv8_t is std_logic_vector(7 downto 0);
subtype slv16_t is std_logic_vector(15 downto 0);
subtype slv32_t is std_logic_vector(31 downto 0);
subtype byte_t is unsigned(7 downto 0);
subtype word_t is unsigned(15 downto 0);
subtype dword_t is unsigned(31 downto 0);
type slv8_array_t is array (natural range<>) of slv8_t;
type slv16_array_t is array (natural range<>) of slv16_t;
type slv32_array_t is array (natural range<>) of slv32_t;
type byte_array_t is array (natural range<>) of byte_t;
type word_array_t is array (natural range<>) of word_t;
type dword_array_t is array (natural range<>) of dword_t;
--
-- simple helper functions
--
function log2(x: natural) return positive;
--
-- type conversion helper
--
function to_slv8(x: std_logic) return std_logic_vector;
function to_slv8(x: std_logic_vector) return std_logic_vector;
function to_slv8(x: unsigned) return std_logic_vector;
function to_slv8(x: signed) return std_logic_vector;
function to_slv8(x: natural) return std_logic_vector;
function to_slv16(x: std_logic) return std_logic_vector;
function to_slv16(x: std_logic_vector) return std_logic_vector;
function to_slv16(x: unsigned) return std_logic_vector;
function to_slv16(x: signed) return std_logic_vector;
function to_slv16(x: natural) return std_logic_vector;
function to_slv32(x: std_logic) return std_logic_vector;
function to_slv32(x: std_logic_vector) return std_logic_vector;
function to_slv32(x: unsigned) return std_logic_vector;
function to_slv32(x: signed) return std_logic_vector;
function to_slv32(x: natural) return std_logic_vector;
--
-- common attributes
--
attribute syn_keep : boolean;
attribute syn_ramstyle : string;
attribute syn_romstyle : string;
attribute shreg_extract : string;
end mt_toolbox;
package body mt_toolbox is
--
-- simple helper functions
--
-- calculate ceiling base 2 logarithm (returns always >=1)
function log2(x: natural) return positive is
variable x_tmp: natural;
variable y: positive;
begin
x_tmp := x-1;
y := 1;
while x_tmp > 1 loop
y := y+1;
x_tmp := x_tmp/2;
end loop;
return y;
end;
-- to_slv8 (pack basic types into "std_logic_vector(7 downto 0)")
function to_slv8(x: std_logic) return std_logic_vector is
variable res : std_logic_vector(7 downto 0);
begin
res := (0=>x,others=>'0');
return res;
end to_slv8;
function to_slv8(x: std_logic_vector) return std_logic_vector is
variable res : std_logic_vector(7 downto 0);
begin
res := (others=>'0');
res(x'length-1 downto 0) := x;
return res;
end to_slv8;
function to_slv8(x: unsigned) return std_logic_vector is
begin
return to_slv8(std_logic_vector(x));
end to_slv8;
function to_slv8(x: signed) return std_logic_vector is
begin
return to_slv8(std_logic_vector(x));
end to_slv8;
function to_slv8(x: natural) return std_logic_vector is
begin
return to_slv8(to_unsigned(x,8));
end to_slv8;
-- to_slv16 (pack basic types into "std_logic_vector(15 downto 0)")
function to_slv16(x: std_logic) return std_logic_vector is
variable res : std_logic_vector(15 downto 0);
begin
res := (0=>x,others=>'0');
return res;
end to_slv16;
function to_slv16(x: std_logic_vector) return std_logic_vector is
variable res : std_logic_vector(15 downto 0);
begin
res := (others=>'0');
res(x'length-1 downto 0) := x;
return res;
end to_slv16;
function to_slv16(x: unsigned) return std_logic_vector is
begin
return to_slv16(std_logic_vector(x));
end to_slv16;
function to_slv16(x: signed) return std_logic_vector is
begin
return to_slv16(std_logic_vector(x));
end to_slv16;
function to_slv16(x: natural) return std_logic_vector is
begin
return to_slv16(to_unsigned(x,16));
end to_slv16;
-- to_slv32 (pack basic types into "std_logic_vector(31 downto 0)")
function to_slv32(x: std_logic) return std_logic_vector is
variable res : std_logic_vector(31 downto 0);
begin
res := (0=>x,others=>'0');
return res;
end to_slv32;
function to_slv32(x: std_logic_vector) return std_logic_vector is
variable res : std_logic_vector(31 downto 0);
begin
res := (others=>'0');
res(x'length-1 downto 0) := x;
return res;
end to_slv32;
function to_slv32(x: unsigned) return std_logic_vector is
begin
return to_slv32(std_logic_vector(x));
end to_slv32;
function to_slv32(x: signed) return std_logic_vector is
begin
return to_slv32(std_logic_vector(x));
end to_slv32;
function to_slv32(x: natural) return std_logic_vector is
begin
return to_slv32(to_unsigned(x,32));
end to_slv32;
end mt_toolbox;

View File

@ -0,0 +1,131 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_toplevel.vhd
-- Project : OsmoSDR FPGA Firmware Testbench
-- Purpose : Decimation Filter Stimulus
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.mt_filter.all;
use work.usbrx.all;
entity tb_filter is
end tb_filter;
architecture rtl of tb_filter is
-- common
signal clk : std_logic := '1';
signal reset : std_logic := '1';
-- config
signal config : usbrx_fil_config_t;
-- input
signal in_clk : std_logic;
signal in_i : signed(15 downto 0);
signal in_q : signed(15 downto 0);
-- output
signal out_clk : std_logic;
signal out_i : signed(15 downto 0);
signal out_q : signed(15 downto 0);
begin
-- generate clock
clk <= not clk after 500ns / 100.0;
reset <= '1', '0' after 123ns;
-- set config
config.decim <= "110";
-- input control
process
variable t : real := 0.0;
variable f : real := 1.0;
begin
in_clk <= '0';
in_i <= to_signed(0,16);
in_q <= to_signed(0,16);
wait until rising_edge(clk) and reset='0';
loop
-- wait some time
for i in 0 to 38 loop
wait until rising_edge(clk);
end loop;
-- get sample data
in_i <= to_signed(integer(cos(t)*10000.0),16);
in_q <= to_signed(0,16);
-- input sample
in_clk <= '1';
wait until rising_edge(clk);
in_clk <= '0';
-- update time
t := t + f/2000000.0*2.0*MATH_PI;
if t >= 2.0*MATH_PI then
t := t - 2.0*MATH_PI;
end if;
-- update frequency
f := f + 1.0;
if f>1000000.0 then
f := 1.0;
end if;
end loop;
wait;
end process;
-- create filter core
uut: entity usbrx_decimate
port map (
-- common
clk => clk,
reset => reset,
-- config
config => config,
-- input
in_clk => in_clk,
in_i => in_i,
in_q => in_q,
-- output
out_clk => out_clk,
out_i => out_i,
out_q => out_q
);
end rtl;

View File

@ -0,0 +1,376 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_toplevel.vhd
-- Project : OsmoSDR FPGA Firmware Testbench
-- Purpose : Toplevel Stimulus
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
entity tb_usbrx is
end tb_usbrx;
architecture rtl of tb_usbrx is
-- common
signal clk_in_pclk : std_logic := '1';
-- special control
signal dings : std_logic;
signal dingsrst : std_logic;
-- ADC interface
signal adc_cs : std_logic;
signal adc_sck : std_logic;
signal adc_sd1 : std_logic;
signal adc_sd2 : std_logic;
-- control SPI
signal ctl_int : std_logic;
signal ctl_cs : std_logic;
signal ctl_sck : std_logic;
signal ctl_mosi : std_logic;
signal ctl_miso : std_logic;
-- data SPIs
signal rx_clk : std_logic;
signal rx_syn : std_logic;
signal rx_dat : std_logic;
-- data SPIs
signal tx_clk : std_logic := '1';
signal tx_syn : std_logic;
signal tx_dat : std_logic;
-- gain PWMs
signal gain0 : std_logic;
signal gain1 : std_logic;
-- GPS
signal gps_1pps : std_logic;
signal gps_10k : std_logic;
-- gpios
signal gpio : std_logic_vector(9 downto 0);
-- virtual GNDs/VCCs
signal vgnd : std_logic_vector(11 downto 0);
signal vcc33 : std_logic_vector(11 downto 0);
signal vcc12 : std_logic_vector(4 downto 0);
begin
-- generate clocks
clk_in_pclk <= not clk_in_pclk after 500 ns / 30.0;
tx_clk <= '0'; --not tx_clk after 500 ns / 24.0;
-- special control
dings <= '0';
dingsrst <= '1'; --, '0' after 100 us, '1' after 200 us;
-- data SPIs
tx_syn <= '0';
tx_dat <= '0';
-- GPS
-- gps_1pps <= '0';
gps_10k <= '0';
-- gpios
gpio <= (others=>'H');
-- generate pps signal
-- (set every millisecond instead of every second
-- to speed to simulation time)
process
variable cnt : natural;
begin
gps_1pps <= '0';
cnt := 1;
loop
wait for (cnt * 1 ms) - now;
gps_1pps <= '1';
wait for 1us;
gps_1pps <= '0';
cnt := cnt+1;
end loop;
wait;
end process;
-- dummy ADC model
process
-- constant word1 : unsigned(15 downto 0) := "0010000000000001";
-- constant word2 : unsigned(15 downto 0) := "0001111111111110";
-- constant word1 : unsigned(15 downto 0) := "0001111111111111";
-- constant word2 : unsigned(15 downto 0) := "0001111111111111";
variable word1 : unsigned(15 downto 0) := "0011010111001101";
variable word2 : unsigned(15 downto 0) := "0001001111000101";
variable sreg1 : unsigned(15 downto 0);
variable sreg2 : unsigned(15 downto 0);
variable cnt : natural;
begin
adc_sd1 <= 'Z';
adc_sd2 <= 'Z';
cnt := 0;
loop
wait until falling_edge(adc_cs);
word1 := to_unsigned(8192 + cnt, 16);
word2 := to_unsigned(8192 - cnt, 16);
cnt := (cnt + 1) mod 8192;
sreg1 := word1;
sreg2 := word2;
adc_sd1 <= transport 'X', sreg1(15) after 5ns;
adc_sd2 <= transport 'X', sreg2(15) after 5ns;
sreg1 := shift_left(sreg1,1);
sreg2 := shift_left(sreg2,1);
il: loop
wait until rising_edge(adc_cs) or falling_edge(adc_sck);
exit when rising_edge(adc_cs);
adc_sd1 <= transport 'X', sreg1(15) after 11.0ns;
adc_sd2 <= transport 'X', sreg2(15) after 11.0ns;
sreg1 := shift_left(sreg1,1);
sreg2 := shift_left(sreg2,1);
end loop;
adc_sd1 <= transport 'X', 'Z' after 9.5ns;
adc_sd2 <= transport 'X', 'Z' after 9.5ns;
end loop;
end process;
-- SPI interface
process
-- write cycle
procedure spi_write(addr: in integer; data: in slv32_t) is
variable sreg : std_logic_vector(39 downto 0);
begin
-- assemble message
sreg(39) := '0';
sreg(38 downto 32) := std_logic_vector(to_unsigned(addr,7));
sreg(31 downto 0) := data;
-- assert CS
ctl_sck <= '1';
ctl_mosi <= '1';
ctl_cs <= '0';
wait for 250ns;
-- clock out data
for i in 39 downto 0 loop
ctl_sck <= '0';
ctl_mosi <= sreg(i);
wait for 250ns;
ctl_sck <= '1';
wait for 250ns;
end loop;
-- deassert CS
wait for 250ns;
ctl_cs <= '1';
wait for 250ns;
end procedure spi_write;
-- write cycle
procedure spi_writem(addr,count: in integer; data: in slv32_array_t) is
variable sreg : std_logic_vector(31 downto 0);
begin
-- assert CS
ctl_sck <= '1';
ctl_mosi <= '1';
ctl_cs <= '0';
wait for 250ns;
-- write command
sreg(7) := '0';
sreg(6 downto 0) := std_logic_vector(to_unsigned(addr,7));
for i in 7 downto 0 loop
ctl_sck <= '0';
ctl_mosi <= sreg(i);
wait for 250ns;
ctl_sck <= '1';
wait for 250ns;
end loop;
--write data
for j in 0 to count-1 loop
sreg := data(j);
for i in 31 downto 0 loop
ctl_sck <= '0';
ctl_mosi <= sreg(i);
wait for 250ns;
ctl_sck <= '1';
wait for 250ns;
end loop;
end loop;
-- deassert CS
wait for 250ns;
ctl_cs <= '1';
wait for 250ns;
end procedure spi_writem;
-- read cycle
procedure spi_read(addr,count: in integer; data: out slv32_array_t) is
variable sreg : std_logic_vector(7 downto 0);
begin
-- assemble message
sreg(7) := '1';
sreg(6 downto 0) := std_logic_vector(to_unsigned(addr,7));
-- assert CS
ctl_sck <= '1';
ctl_mosi <= '1';
ctl_cs <= '0';
wait for 250ns;
-- clock out command
for i in 7 downto 0 loop
ctl_sck <= '0';
ctl_mosi <= sreg(i);
wait for 250ns;
ctl_sck <= '1';
wait for 250ns;
end loop;
wait for 50us;
-- read data
for j in 0 to count-1 loop
for i in 31 downto 0 loop
ctl_sck <= '0';
wait for 250ns;
data(j)(i) := ctl_miso;
ctl_sck <= '1';
wait for 250ns;
if i=24 or i=16 or i=8 then
wait for 50us;
end if;
end loop;
end loop;
-- deassert CS
wait for 250ns;
ctl_cs <= '1';
wait for 250ns;
end procedure spi_read;
variable temp : slv32_array_t(0 to 5);
begin
ctl_cs <= '1';
ctl_sck <= '1';
ctl_mosi <= '1';
wait for 30us;
-- spi_write(4,x"00000001");
-- spi_read(0,1,temp);
-- spi_read(0,1,temp);
-- wait;
--
-- temp(0) := x"00000000";
-- temp(1) := x"12345678";
-- temp(2) := x"9ABCDEF0";
-- temp(3) := x"11233435";
-- temp(4) := x"23652662";
-- temp(5) := x"98735773";
-- spi_writem(0,6,temp);
--
-- temp := (others=>x"00000000");
-- spi_read(0,6,temp);
wait;
end process;
-- unit under test
uut: entity usbrx_toplevel
port map (
-- common
clk_in_pclk => clk_in_pclk,
-- special control
dings => dings,
dingsrst => dingsrst,
-- ADC interface
adc_cs => adc_cs,
adc_sck => adc_sck,
adc_sd1 => adc_sd1,
adc_sd2 => adc_sd2,
-- control SPI
ctl_int => ctl_int,
ctl_cs => ctl_cs,
ctl_sck => ctl_sck,
ctl_mosi => ctl_mosi,
ctl_miso => ctl_miso,
-- data SPIs
rx_clk => rx_clk,
rx_syn => rx_syn,
rx_dat => rx_dat,
-- data SPIs
tx_clk => tx_clk,
tx_syn => tx_syn,
tx_dat => tx_dat,
-- gain PWMs
gain0 => gain0,
gain1 => gain1,
-- GPS
gps_1pps => gps_1pps,
gps_10k => gps_10k,
-- gpios
gpio => gpio,
-- virtual GNDs/VCCs
vgnd => vgnd,
vcc33 => vcc33,
vcc12 => vcc12
);
end rtl;

View File

@ -0,0 +1,299 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_ad7357.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : AD7357 Interface
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library xp2;
use xp2.all;
use xp2.components.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.usbrx.all;
entity usbrx_ad7357 is
port(
-- common
clk : in std_logic;
reset : in std_logic;
-- config
config : in usbrx_adc_config_t;
-- ADC interface
adc_cs : out std_logic;
adc_sck : out std_logic;
adc_sd1 : in std_logic;
adc_sd2 : in std_logic;
-- output
out_clk : out std_logic;
out_i : out unsigned(13 downto 0);
out_q : out unsigned(13 downto 0)
);
end usbrx_ad7357;
architecture rtl of usbrx_ad7357 is
-- internal types
type state_t is (S_ACQUISITION, S_CONVERT);
-- main status
signal state : state_t;
signal counter : unsigned(7 downto 0);
-- SCK generator
signal cg_div : unsigned(7 downto 0);
signal cg_count : unsigned(7 downto 0);
signal cg_phase : std_logic;
signal cg_ddr_a : std_logic;
signal cg_ddr_b : std_logic;
signal cg_renxt : std_logic;
signal cg_redge : std_logic;
-- chip select (+ delayed versions)
signal css : std_logic_vector(3 downto 0);
-- latch input on rising/falling edge of current cycle
-- (+ delayed versions)
signal latch_r : std_logic_vector(3 downto 0);
signal latch_f : std_logic_vector(3 downto 0);
-- input register stage #1
signal sd1_s1r : std_logic; -- SD1 - rising edge
signal sd1_s1f : std_logic; -- SD1 - falling edge
signal sd2_s1r : std_logic; -- SD2 - rising edge
signal sd2_s1f : std_logic; -- SD2 - falling edge
-- input register stage #2
signal sd1_s2r : std_logic; -- SD1 - rising edge
signal sd1_s2f : std_logic; -- SD1 - falling edge
signal sd2_s2r : std_logic; -- SD2 - rising edge
signal sd2_s2f : std_logic; -- SD2 - falling edge
-- input shift registers
signal sreg1 : std_logic_vector(13 downto 0);
signal sreg2 : std_logic_vector(13 downto 0);
-- output latches
signal onew : std_logic;
signal oreg1 : std_logic_vector(13 downto 0);
signal oreg2 : std_logic_vector(13 downto 0);
begin
-- SCL clock generator logic
process(clk)
begin
if rising_edge(clk) then
-- set default values
cg_renxt <= '0';
cg_redge <= cg_renxt;
latch_r <= latch_r(latch_r'left-1 downto 0) & '0';
latch_f <= latch_f(latch_f'left-1 downto 0) & '0';
-- get config
cg_div <= config.clkdiv;
-- get operation mode
if cg_div=0 or cg_div=1 then
--> full speed, just pass through clock
cg_ddr_a <= '0';
cg_ddr_b <= '1';
cg_renxt <= '1';
latch_f(0) <= '1';
else
--> divided clock, update divider-logic
if cg_count=0 then
-- toggle clock on FE in middle of cycle
cg_count <= cg_div - 2;
cg_phase <= not cg_phase;
cg_ddr_a <= cg_phase;
cg_ddr_b <= not cg_phase;
cg_renxt <= not cg_phase;
latch_r(0) <= cg_phase;
elsif cg_count=1 then
-- toggle clock on RE after this cycle
cg_count <= cg_div - 1;
cg_phase <= '0'; --not cg_phase;
cg_ddr_a <= '1'; --cg_phase;
cg_ddr_b <= '1'; --cg_phase;
latch_f(0) <= '1';
else
-- leave clock unchanged
cg_count <= cg_count - 2;
cg_ddr_a <= cg_phase;
cg_ddr_b <= cg_phase;
end if;
-- failsafe
if cg_count=1 and cg_div(0)='0' then
cg_count <= cg_div - 2;
end if;
end if;
-- handle reset
if reset='1' then
cg_div <= (others=>'1');
cg_count <= (others=>'0');
cg_phase <= '0';
cg_renxt <= '0';
cg_redge <= '0';
cg_ddr_a <= '1';
cg_ddr_b <= '1';
latch_r <= (others=>'0');
latch_f <= (others=>'0');
end if;
end if;
end process;
-- output register for SCLK
oddr: ODDRXC
port map (
clk => clk,
rst => reset,
da => cg_ddr_a,
db => cg_ddr_b,
q => adc_sck
);
-- main control logig
process(clk)
begin
if rising_edge(clk) then
-- set default values
css <= css(css'left-1 downto 0) & css(0);
-- update status
case state is
when S_ACQUISITION =>
-- doing ACQUISITION, wait until ready to start conversion
if cg_redge='1' then
-- new SCLK cycle, check if wait-counter has ellapsed
counter <= counter - 1;
if counter<=1 then
--> counter ellapsed, start conversion
state <= S_CONVERT;
counter <= to_unsigned(15,counter'length);
css(0) <= '0';
end if;
end if;
when S_CONVERT =>
-- doing conversion, wait until all bits are clocked out
if cg_redge='1' then
-- new SCLK cycle, check if bit-counter has ellapsed
counter <= counter - 1;
if counter=0 then
-- all bits received, return to ACQUISITION state
state <= S_ACQUISITION;
counter <= config.acqlen;
css(0) <= '1';
end if;
end if;
end case;
-- handle reset
if reset='1' then
state <= S_ACQUISITION; -- TODO
counter <= (others=>'0');
css <= (others=>'1');
end if;
end if;
end process;
-- output chip-select
adc_cs <= css(0);
-- input capture registers
iddr1: IDDRXC
port map (
clk => clk,
rst => '0',
ce => '1',
d => adc_sd1,
qa => sd1_s1r,
qb => sd1_s1f
);
iddr2: IDDRXC
port map (
clk => clk,
rst => '0',
ce => '1',
d => adc_sd2,
qa => sd2_s1r,
qb => sd2_s1f
);
-- input data handling
process(clk)
begin
if rising_edge(clk) then
-- set default valies
onew <= '0';
-- register input-bits once more
sd1_s2r <= sd1_s1r;
sd1_s2f <= sd1_s1f;
sd2_s2r <= sd2_s1r;
sd2_s2f <= sd2_s1f;
-- update shift-registers
if latch_r(3)='1' then
sreg1 <= sreg1(12 downto 0) & sd1_s2r;
sreg2 <= sreg2(12 downto 0) & sd2_s2r;
elsif latch_f(3)='1' then
sreg1 <= sreg1(12 downto 0) & sd1_s2f;
sreg2 <= sreg2(12 downto 0) & sd2_s2f;
end if;
-- latch away shift-register when requested
if css(2)='1' and css(3)='0' then
onew <= '1';
oreg1 <= sreg1;
oreg2 <= sreg2;
end if;
-- handle reset
if reset='1' then
sd1_s2r <= '0';
sd1_s2f <= '0';
sd2_s2r <= '0';
sd2_s2f <= '0';
sreg1 <= (others=>'0');
sreg2 <= (others=>'0');
oreg1 <= (others=>'0');
oreg2 <= (others=>'0');
onew <= '0';
end if;
end if;
end process;
-- set output
out_clk <= onew;
out_i <= unsigned(oreg1);
out_q <= unsigned(oreg2);
end rtl;

View File

@ -0,0 +1,218 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_decimate.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : Variable decimation filter
-- (possible factors: 1,2,4,8,16,32,64)
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- decimation filter ----------------------------------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.mt_filter.all;
use work.usbrx.all;
entity usbrx_decimate is
port (
-- common
clk : in std_logic;
reset : in std_logic;
-- config
config : in usbrx_fil_config_t;
-- input
in_clk : in std_logic;
in_i : in signed(15 downto 0);
in_q : in signed(15 downto 0);
-- output
out_clk : out std_logic;
out_i : out signed(15 downto 0);
out_q : out signed(15 downto 0)
);
end usbrx_decimate;
architecture rtl of usbrx_decimate is
-- config
signal active : std_logic_vector(5 downto 0);
-- adapted input
signal in_si : fir_dataword18;
signal in_sq : fir_dataword18;
-- filter input
signal fil_in_clk : std_logic_vector(5 downto 0);
signal fil_in_i : fir_databus18(5 downto 0);
signal fil_in_q : fir_databus18(5 downto 0);
-- filter output
signal fil_out_clk : std_logic_vector(5 downto 0);
signal fil_out_i : fir_databus18(5 downto 0);
signal fil_out_q : fir_databus18(5 downto 0);
-- unclipped output
signal nxt_clk : std_logic;
signal nxt_i : fir_dataword18;
signal nxt_q : fir_dataword18;
begin
-- convert input into 18bit signed
in_si <= signed(in_i) & "00";
in_sq <= signed(in_q) & "00";
-- control logic
process(clk)
variable tmp_i,tmp_q : fir_dataword18;
begin
if rising_edge(clk) then
-- get active stages
case to_integer(config.decim) is
when 0 => active <= "000000";
when 1 => active <= "000001";
when 2 => active <= "000011";
when 3 => active <= "000111";
when 4 => active <= "001111";
when 5 => active <= "011111";
when others => active <= "111111";
end case;
-- select output
case to_integer(config.decim) is
when 0 =>
nxt_clk <= in_clk;
nxt_i <= in_si;
nxt_q <= in_sq;
when 1 =>
nxt_clk <= fil_out_clk(0);
nxt_i <= fil_out_i(0);
nxt_q <= fil_out_q(0);
when 2 =>
nxt_clk <= fil_out_clk(1);
nxt_i <= fil_out_i(1);
nxt_q <= fil_out_q(1);
when 3 =>
nxt_clk <= fil_out_clk(2);
nxt_i <= fil_out_i(2);
nxt_q <= fil_out_q(2);
when 4 =>
nxt_clk <= fil_out_clk(3);
nxt_i <= fil_out_i(3);
nxt_q <= fil_out_q(3);
when 5 =>
nxt_clk <= fil_out_clk(4);
nxt_i <= fil_out_i(4);
nxt_q <= fil_out_q(4);
when others =>
nxt_clk <= fil_out_clk(5);
nxt_i <= fil_out_i(5);
nxt_q <= fil_out_q(5);
end case;
-- set output
out_clk <= nxt_clk;
if nxt_clk='1' then
tmp_i := nxt_i + 2;
tmp_q := nxt_q + 2;
out_i <= tmp_i(17 downto 2);
out_q <= tmp_q(17 downto 2);
end if;
-- handle reset
if reset='1' then
active <= (others=>'0');
nxt_clk <= '0';
nxt_i <= (others=>'0');
nxt_q <= (others=>'0');
out_clk <= '0';
out_i <= (others=>'0');
out_q <= (others=>'0');
end if;
end if;
end process;
process(in_clk,in_si,in_sq,fil_out_clk,fil_out_i,fil_out_q,active)
begin
-- feed first filter stage
fil_in_clk(0) <= in_clk and active(0);
fil_in_i(0) <= in_si;
fil_in_q(0) <= in_sq;
-- chain remaining filter stages
for i in 1 to 5 loop
fil_in_clk(i) <= fil_out_clk(i-1) and active(i-1);
fil_in_i(i) <= fil_out_i(i-1);
fil_in_q(i) <= fil_out_q(i-1);
end loop;
end process;
-- filter instance #1 (stage 0)
hbf1: entity usbrx_halfband
generic map (
N => 1
)
port map (
-- common
clk => clk,
reset => reset,
-- input
in_clk => fil_in_clk(0 downto 0),
in_i => fil_in_i(0 downto 0),
in_q => fil_in_q(0 downto 0),
-- output
out_clk => fil_out_clk(0 downto 0),
out_i => fil_out_i(0 downto 0),
out_q => fil_out_q(0 downto 0)
);
-- filter instance #2 (stage 1-5)
hbf2: entity usbrx_halfband
generic map (
N => 5
)
port map (
-- common
clk => clk,
reset => reset,
-- input
in_clk => fil_in_clk(5 downto 1),
in_i => fil_in_i(5 downto 1),
in_q => fil_in_q(5 downto 1),
-- output
out_clk => fil_out_clk(5 downto 1),
out_i => fil_out_i(5 downto 1),
out_q => fil_out_q(5 downto 1)
);
end rtl;

View File

@ -0,0 +1,126 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_halfband.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : Programmable sample value offset
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.usbrx.all;
entity usbrx_offset is
port (
-- common
clk : in std_logic;
reset : in std_logic;
-- config
config : in usbrx_off_config_t;
-- input
in_clk : in std_logic;
in_i : in unsigned(13 downto 0);
in_q : in unsigned(13 downto 0);
-- output
out_clk : out std_logic;
out_i : out signed(15 downto 0);
out_q : out signed(15 downto 0)
);
end usbrx_offset;
architecture rtl of usbrx_offset is
-- clip & saturate sample
function doClipValue(x : signed) return signed is
variable xnorm : signed(x'length-1 downto 0) := x;
begin
if xnorm >= 32768 then
-- overflow
return to_signed(+32767,16);
elsif xnorm < -32768 then
-- underflow
return to_signed(-32768,16);
else
-- in range
return xnorm(15 downto 0);
end if;
end doClipValue;
-- multiplier input
signal mula_i, mula_q : signed(17 downto 0) := (others=>'0');
signal mulb_i, mulb_q : signed(17 downto 0) := (others=>'0');
-- multiplier output
signal mout_i, mout_q : signed(18 downto 0) := (others=>'0');
begin
-- control logic
process(clk)
variable mtmp_i, mtmp_q : signed(35 downto 0);
variable atmp_i, atmp_q : signed(19 downto 0);
begin
if rising_edge(clk) then
-- passthough clock
out_clk <= in_clk;
-- handle data
if in_clk='1' then
-- apply swap-flag & convert input into 18bit signed
if config.swap='0' then
mula_i <= signed(in_i xor "10000000000000") & "0000";
mula_q <= signed(in_q xor "10000000000000") & "0000";
else
mula_i <= signed(in_q xor "10000000000000") & "0000";
mula_q <= signed(in_i xor "10000000000000") & "0000";
end if;
-- apply gain
mulb_i <= signed("00" & config.igain);
mulb_q <= signed("00" & config.qgain);
mtmp_i := mula_i * mulb_i;
mtmp_q := mula_q * mulb_q;
mout_i <= mtmp_i(34 downto 16);
mout_q <= mtmp_q(34 downto 16);
-- add offset (also adds 0.5 for rounding of multiplier-output)
atmp_i := resize(mout_i,20) + resize(config.ioff&"1",20);
atmp_q := resize(mout_q,20) + resize(config.qoff&"1",20);
-- clip output
out_i <= doClipValue(atmp_i(19 downto 1));
out_q <= doClipValue(atmp_q(19 downto 1));
end if;
-- handle reset
if reset='1' then
out_clk <= '0';
out_i <= (others=>'0');
out_q <= (others=>'0');
end if;
end if;
end process;
end rtl;

View File

@ -0,0 +1,191 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_ssc.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : ATSAM3U SSC Interface
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.usbrx.all;
entity usbrx_ssc is
port(
-- common
clk : in std_logic;
reset : in std_logic;
-- config
config : in usbrx_ssc_config_t;
-- output
in_clk : in std_logic;
in_i : in signed(15 downto 0);
in_q : in signed(15 downto 0);
-- SSC interface
ssc_clk : out std_logic;
ssc_syn : out std_logic;
ssc_dat : out std_logic
);
end usbrx_ssc;
architecture rtl of usbrx_ssc is
-- CLK generator
signal cg_div : unsigned(7 downto 0);
signal cg_phase : std_logic;
signal cg_tick : std_logic;
-- shift register
signal sreg : std_logic_vector(31 downto 0);
signal remain : unsigned(5 downto 0);
signal nxtsyn : std_logic;
-- input latch
signal lreg : std_logic_vector(31 downto 0);
signal filled : std_logic;
-- helper function
function to_signed(x : unsigned) return signed is
begin
return signed((not x(x'left)) & x(x'left-1 downto 0));
end to_signed;
function pack(i,q : unsigned) return slv32_t is
variable res : slv32_t := (others=>'0');
begin
res(31 downto 32-i'length) := std_logic_vector(to_signed(i));
res(15 downto 16-q'length) := std_logic_vector(to_signed(q));
return res;
end pack;
function pack(i,q : signed) return slv32_t is
variable res : slv32_t := (others=>'0');
begin
res(31 downto 32-i'length) := std_logic_vector(i);
res(15 downto 16-q'length) := std_logic_vector(q);
return res;
end pack;
-- debug
signal counter1 : unsigned(15 downto 0);
signal counter2 : unsigned(15 downto 0);
begin
-- clock generator
process(clk)
begin
if rising_edge(clk) then
-- set default values
cg_tick <= '0';
-- update clock-divider
if cg_div=0 then
-- toggle phase
cg_phase <= not cg_phase;
cg_div <= config.clkdiv;
-- set 'tick'-flag when generating falling edge
if cg_phase='1' then
cg_tick <= '1';
end if;
else
-- stay in current phase
cg_div <= cg_div-1;
end if;
-- update output
ssc_clk <= cg_phase;
-- handle reset
if reset='1' then
cg_div <= (others=>'0');
cg_phase <= '0';
cg_tick <= '0';
ssc_clk <= '0';
end if;
end if;
end process;
-- output shift register
process(clk)
begin
if rising_edge(clk) then
-- wait for output-clock
if cg_tick='1' then
-- update output
ssc_dat <= sreg(sreg'left);
ssc_syn <= nxtsyn;
sreg <= sreg(sreg'left-1 downto 0) & '0';
nxtsyn <= '0';
-- consume bit
if remain > 0 then
remain <= remain - 1;
end if;
-- reload shift-register when possible
if filled='1' and remain<=1 then
filled <= '0';
remain <= to_unsigned(32, remain'length);
nxtsyn <= '1';
sreg <= lreg;
end if;
end if;
-- handle incoming samples
if in_clk='1' then
if filled='0' then
-- latch sample
lreg <= pack(in_i,in_q);
filled <= '1';
-- apply test-mode
if config.tmode='1' then
lreg <= pack(counter1,counter2);
counter1 <= counter1 + 1;
counter2 <= counter2 - 1;
end if;
else
--> overflow
report "usbrx_ssc: input too fast"
severity warning;
end if;
end if;
-- handle reset
if reset='1' then
sreg <= (others=>'0');
remain <= (others=>'0');
nxtsyn <= '0';
lreg <= (others=>'0');
filled <= '0';
ssc_syn <= '0';
ssc_dat <= '0';
counter1 <= (others=>'0');
counter2 <= (others=>'1');
end if;
end if;
end process;
end rtl;

View File

@ -0,0 +1,505 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_halfband.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : Multichannel Halfband Decimation Filter
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- halfband decimation filter - input cache/control ---------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.mt_filter.all;
entity usbrx_halfband_ictrl is
generic (
N : natural := 3
);
port (
-- common
clk : in std_logic;
reset : in std_logic;
-- input
in_clk : in std_logic_vector(N-1 downto 0);
in_i : in fir_databus18(N-1 downto 0);
in_q : in fir_databus18(N-1 downto 0);
-- output
out_ready : in std_logic;
out_clk : out std_logic;
out_chan : out unsigned(log2(N)-1 downto 0);
out_i0 : out fir_dataword18;
out_i1 : out fir_dataword18;
out_q0 : out fir_dataword18;
out_q1 : out fir_dataword18
);
end usbrx_halfband_ictrl;
architecture rtl of usbrx_halfband_ictrl is
-- control
signal phase : std_logic_vector(N-1 downto 0);
signal tmp_i : fir_databus18(N-1 downto 0);
signal tmp_q : fir_databus18(N-1 downto 0);
signal oclk : std_logic;
-- output
signal pending : std_logic_vector(N-1 downto 0);
signal cache_i0 : fir_databus18(N-1 downto 0);
signal cache_i1 : fir_databus18(N-1 downto 0);
signal cache_q0 : fir_databus18(N-1 downto 0);
signal cache_q1 : fir_databus18(N-1 downto 0);
begin
-- control logic
process(clk)
variable found : std_logic;
begin
if rising_edge(clk) then
-- set default values
oclk <= '0';
-- check if we are allowed to output the next entry
if out_ready='1' and oclk='0' then
-- search for pending cache-entry
found := '0';
for i in 0 to N-1 loop
if found='0' and pending(i)='1' then
--> output entry
oclk <= '1';
out_chan <= to_unsigned(i,out_chan'length);
out_i0 <= cache_i0(i);
out_i1 <= cache_i1(i);
out_q0 <= cache_q0(i);
out_q1 <= cache_q1(i);
-- update status
pending(i) <= '0';
found := '1';
end if;
end loop;
end if;
-- handle incoming samples
for i in in_clk'range loop
if in_clk(i)='1' then
-- write sample into cache
if phase(i)='0' then
tmp_i(i) <= in_i(i);
tmp_q(i) <= in_q(i);
else
pending(i) <= '1';
cache_i0(i) <= tmp_i(i);
cache_q0(i) <= tmp_q(i);
cache_i1(i) <= in_i(i);
cache_q1(i) <= in_q(i);
end if;
phase(i) <= not phase(i);
-- debug check
assert phase(i)='0' or pending(i)='0'
report "usbrx_halfband_ictrl: input too fast"
severity error;
end if;
end loop;
-- handle reset
if reset='1' then
phase <= (others=>'0');
tmp_i <= (others=>(others=>'0'));
tmp_q <= (others=>(others=>'0'));
pending <= (others=>'0');
cache_i0 <= (others=>(others=>'0'));
cache_i1 <= (others=>(others=>'0'));
cache_q0 <= (others=>(others=>'0'));
cache_q1 <= (others=>(others=>'0'));
oclk <= '0';
out_chan <= (others=>'0');
out_i0 <= (others=>'0');
out_i1 <= (others=>'0');
out_q0 <= (others=>'0');
out_q1 <= (others=>'0');
end if;
end if;
end process;
-- connect output-clock
out_clk <= oclk;
end rtl;
-------------------------------------------------------------------------------
-- halfband decimation filter - output control --------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.mt_filter.all;
entity usbrx_halfband_octrl is
generic (
N : natural := 3
);
port (
-- common
clk : in std_logic;
reset : in std_logic;
-- input
in_clk : in std_logic;
in_chan : in unsigned(log2(2*N)-1 downto 0);
in_data : in fir_dataword18;
-- output
out_clk : out std_logic_vector(N-1 downto 0);
out_i : out fir_databus18(N-1 downto 0);
out_q : out fir_databus18(N-1 downto 0)
);
end usbrx_halfband_octrl;
architecture rtl of usbrx_halfband_octrl is
-- cache
signal tmp_i : fir_databus18(N-1 downto 0);
begin
-- control logic
process(clk)
variable sel : natural range 0 to N-1;
begin
if rising_edge(clk) then
-- set default values
out_clk <= (others=>'0');
-- handle input
if in_clk='1' then
sel := to_integer(in_chan)/2;
for i in out_clk'range loop
if sel=i then
if in_chan(0)='0' then
-- cache result
tmp_i(i) <= in_data;
else
-- output result
out_clk(i) <= '1';
out_i(i) <= tmp_i(i);
out_q(i) <= in_data;
end if;
end if;
end loop;
end if;
-- handle reset
if reset='1' then
tmp_i <= (others=>(others=>'0'));
out_clk <= (others=>'0');
out_i <= (others=>(others=>'0'));
out_q <= (others=>(others=>'0'));
end if;
end if;
end process;
end rtl;
-------------------------------------------------------------------------------
-- halfband decimation filter -------------------------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.mt_filter.all;
entity usbrx_halfband is
generic (
N : natural := 3
);
port (
-- common
clk : in std_logic;
reset : in std_logic;
-- input
in_clk : in std_logic_vector(N-1 downto 0);
in_i : in fir_databus18(N-1 downto 0);
in_q : in fir_databus18(N-1 downto 0);
-- output
out_clk : out std_logic_vector(N-1 downto 0);
out_i : out fir_databus18(N-1 downto 0);
out_q : out fir_databus18(N-1 downto 0)
);
end usbrx_halfband;
architecture rtl of usbrx_halfband is
-- internal types
type state_t is (S_IDLE, S_FILTER_I, S_FILTER_Q, S_COOLDOWN);
-- status
signal state : state_t;
-- input control
signal ic_ready : std_logic;
signal ic_clk : std_logic;
signal ic_chan : unsigned(log2(N)-1 downto 0);
signal ic_i0 : fir_dataword18;
signal ic_i1 : fir_dataword18;
signal ic_q0 : fir_dataword18;
signal ic_q1 : fir_dataword18;
-- next output
signal on_clk : std_logic;
signal on_chan : unsigned(log2(2*N)-1 downto 0);
signal on_dat1 : fir_dataword18;
signal on_dat2 : fir_dataword18;
-- output control
signal oc_iclk : std_logic;
signal oc_ichan : unsigned(log2(2*N)-1 downto 0);
signal oc_idata : fir_dataword18;
-- FIR input
signal fir_iclk : std_logic;
signal fir_iack : std_logic;
signal fir_idata : fir_dataword18;
signal fir_ichan : unsigned(log2(2*N)-1 downto 0);
-- FIR output
signal fir_oclk : std_logic;
signal fir_ochan : unsigned(log2(2*N)-1 downto 0);
signal fir_odata : fir_dataword18;
-- center samples
signal cent_i : fir_databus18(N-1 downto 0);
signal cent_q : fir_databus18(N-1 downto 0);
-- coefficients for 2x-FIR-interpolator
-- (halfband, order 48, wpass 0.40)
constant coeffs : fir_coefficients(0 to 11) := (
-52, 151, -354, 715,
-1307, 2227, -3614, 5691,
-8907, 14403, -26386, 82957
);
begin
-- control logic
process(clk)
variable sel : natural range 0 to N-1;
begin
if rising_edge(clk) then
-- set default values
fir_iclk <= '0';
oc_iclk <= '0';
on_clk <= '0';
-- filter control
case state is
when S_IDLE =>
-- wait for new sample-pair
if ic_clk='1' then
-- start filter (I)
fir_iclk <= '1';
fir_idata <= ic_i1;
fir_ichan <= resize(ic_chan & "0", fir_ichan'length);
-- update status
state <= S_FILTER_I;
end if;
when S_FILTER_I =>
-- wait until filtering is done
if fir_iack='1' then
-- start filter (Q)
fir_iclk <= '1';
fir_idata <= ic_q1;
fir_ichan <= resize(ic_chan & "1", fir_ichan'length);
-- update status
state <= S_FILTER_Q;
end if;
when S_FILTER_Q =>
-- wait until filtering is done
if fir_iack='1' then
-- update status
state <= S_COOLDOWN;
end if;
when S_COOLDOWN =>
-- TODO: get rid of state
if fir_oclk='1' then
state <= S_IDLE;
end if;
end case;
-- fetch FIR result and corresonding center-sample
if fir_oclk='1' then
on_clk <= '1';
on_chan <= fir_ochan;
on_dat1 <= fir_odata;
sel := to_integer(fir_ochan)/2;
if fir_ochan(0)='0'
then on_dat2 <= cent_i(sel);
else on_dat2 <= cent_q(sel);
end if;
end if;
-- create final result
if on_clk='1' then
oc_iclk <= '1';
oc_ichan <= on_chan;
oc_idata <= resize((resize(on_dat1,19) + resize(on_dat2,19)) / 2,18);
end if;
-- handle reset
if reset='1' then
state <= S_IDLE;
fir_iclk <= '0';
fir_idata <= (others=>'0');
fir_ichan <= (others=>'0');
oc_iclk <= '0';
oc_ichan <= (others=>'0');
oc_idata <= (others=>'0');
on_clk <= '0';
on_chan <= (others=>'0');
on_dat1 <= (others=>'0');
on_dat2 <= (others=>'0');
end if;
end if;
end process;
-- create ready-flag
ic_ready <= '1' when state=S_IDLE else '0';
-- shift register for center-sample
sreg: for i in 0 to N-1 generate
subtype entry_t is signed(35 downto 0);
type sreg_t is array(natural range<>) of entry_t;
signal sreg : sreg_t(11 downto 0) := (others=>(others=>'0'));
begin
-- infer shift-register
process(clk)
variable temp : entry_t;
begin
if rising_edge(clk) then
if ic_clk='1' and to_integer(ic_chan)=i then
temp := ic_q0 & ic_i0;
sreg <= sreg(sreg'left-1 downto 0) & temp;
end if;
end if;
end process;
-- output center-sample
cent_i(i) <= sreg(sreg'left)(17 downto 0);
cent_q(i) <= sreg(sreg'left)(35 downto 18);
end generate;
-- input control
ic: entity usbrx_halfband_ictrl
generic map (
N => N
)
port map (
-- common
clk => clk,
reset => reset,
-- input
in_clk => in_clk,
in_i => in_i,
in_q => in_q,
-- output
out_ready => ic_ready,
out_clk => ic_clk,
out_chan => ic_chan,
out_i0 => ic_i0,
out_i1 => ic_i1,
out_q0 => ic_q0,
out_q1 => ic_q1
);
-- FIR filter core
fir: entity mt_fir_symmetric_slow
generic map (
CHANNELS => 2*N,
TAPS => 12,
COEFFS => coeffs,
RAMSTYLE => "block_ram",
ROMSTYLE => "logic"
)
port map (
-- common
clk => clk,
reset => reset,
-- input port
in_clk => fir_iclk,
in_ack => fir_iack,
in_data => fir_idata,
in_chan => fir_ichan,
-- output port
out_clk => fir_oclk,
out_chan => fir_ochan,
out_data => fir_odata
);
-- output control
oc: entity usbrx_halfband_octrl
generic map (
N => N
)
port map (
-- common
clk => clk,
reset => reset,
-- input
in_clk => oc_iclk,
in_chan => oc_ichan,
in_data => oc_idata,
-- output
out_clk => out_clk,
out_i => out_i,
out_q => out_q
);
end rtl;

View File

@ -0,0 +1,154 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_clkgen.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : Clock Management
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.numeric_std.all;
library xp2;
use xp2.all;
use xp2.components.all;
library work;
use work.all;
use work.mt_toolbox.all;
entity usbrx_clkgen is
port(
-- clock input
clk_30_pclk : in std_logic; -- 30MHz
ext_rst : in std_logic; -- external reset
-- system clock
clk_30 : out std_logic; -- 30MHz clock
clk_80 : out std_logic; -- 80MHz clock
rst_30 : out std_logic; -- 30MHz reset
rst_80 : out std_logic -- 80MHz reset
);
end usbrx_clkgen;
architecture rtl of usbrx_clkgen is
-- reset generation
signal rst_pll : std_logic; -- reset signal for PLLs
signal pll_locked : std_logic; -- PLLs locked
signal reset_i : std_logic; -- reset-signal
-- system clock management
signal clk_80_pll : std_logic;
-- enusure that signal-names are kept (important for timing contraints)
attribute syn_keep of clk_80_pll : signal is true;
-- component declaration
component EPLLD1
generic (CLKOK_BYPASS : in String; CLKOS_BYPASS : in String;
CLKOP_BYPASS : in String; DUTY : in Integer;
PHASEADJ : in String; PHASE_CNTL : in String;
CLKOK_DIV : in Integer; CLKFB_DIV : in Integer;
CLKOP_DIV : in Integer; CLKI_DIV : in Integer;
FIN : in String);
port (CLKI: in std_logic; CLKFB: in std_logic; RST: in std_logic;
RSTK: in std_logic; DPAMODE: in std_logic; DRPAI3: in std_logic;
DRPAI2: in std_logic; DRPAI1: in std_logic; DRPAI0: in std_logic;
DFPAI3: in std_logic; DFPAI2: in std_logic; DFPAI1: in std_logic;
DFPAI0: in std_logic; PWD: in std_logic; CLKOP: out std_logic;
CLKOS: out std_logic; CLKOK: out std_logic; LOCK: out std_logic;
CLKINTFB: out std_logic);
end component;
begin
--
-- reset generation
--
-- generate asynchronous reset-signal
rg: entity mt_reset_gen
port map (
clk => clk_30_pclk,
ext_rst => ext_rst,
pll_locked => pll_locked,
reset_pll => rst_pll,
reset_sys => reset_i
);
-- sync reset to clock-domains
rs30: entity mt_reset_sync
port map (
clk => clk_30_pclk,
rst_in => reset_i,
rst_out => rst_30
);
rs80: entity mt_reset_sync
port map (
clk => clk_80_pll,
rst_in => reset_i,
rst_out => rst_80
);
--
-- system clock
--
-- PLL for system-clock
pll : EPLLD1
generic map (
FIN => "30.0",
CLKOK_BYPASS => "DISABLED",
CLKOS_BYPASS => "DISABLED",
CLKOP_BYPASS => "DISABLED",
PHASE_CNTL => "STATIC",
DUTY => 8,
PHASEADJ => "0.0",
CLKOK_DIV => 2,
CLKOP_DIV => 8,
CLKFB_DIV => 8,
CLKI_DIV => 3
)
port map (
CLKI => clk_30_pclk,
CLKFB => clk_80_pll,
RST => rst_pll,
RSTK => '0',
DPAMODE => '0',
DRPAI3 => '0',
DRPAI2 => '0',
DRPAI1 => '0',
DRPAI0 => '0',
DFPAI3 => '0',
DFPAI2 => '0',
DFPAI1 => '0',
DFPAI0 => '0',
PWD => '0',
CLKOP => clk_80_pll,
CLKOS => open,
CLKOK => open,
LOCK => pll_locked,
CLKINTFB=> open
);
-- output clocks
clk_30 <= clk_30_pclk;
clk_80 <= clk_80_pll;
end rtl;

View File

@ -0,0 +1,158 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_clkref.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : Reference Clock Measurement
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.usbrx.all;
entity usbrx_clkref is
port(
-- system clocks
clk_sys : in std_logic;
rst_sys : in std_logic;
-- reference signal
clk_ref : in std_logic;
rst_ref : in std_logic;
-- 1pps signal
gps_1pps : in std_logic;
-- status
status : out usbrx_ref_status_t
);
end usbrx_clkref;
architecture rtl of usbrx_clkref is
-- deglitcher
signal dgl_hist : std_logic_vector(3 downto 0);
signal dgl_out : std_logic;
-- edge detection
signal pps_last : std_logic;
-- active counters
signal cnt_lsb : unsigned(24 downto 0);
-- latched counters
signal lat_upd : std_logic;
signal lat_lsb : unsigned(24 downto 0);
signal lat_msb : unsigned(6 downto 0);
-- output register
signal out_upd : std_logic;
signal out_lsb : unsigned(24 downto 0);
signal out_msb : unsigned(6 downto 0);
begin
-- reference counter
process(clk_ref)
variable cnt0,cnt1 : natural range 0 to 4;
variable re : boolean;
begin
if rising_edge(clk_ref) then
-- set default values
lat_upd <= '0';
-- deglitch pps signal
dgl_hist <= dgl_hist(dgl_hist'left-1 downto 0) & gps_1pps;
cnt0 := 0;
cnt1 := 0;
for i in dgl_hist'range loop
if dgl_hist(i)='0' then
cnt0 := cnt0 + 1;
end if;
if dgl_hist(i)='1' then
cnt1 := cnt1 + 1;
end if;
end loop;
if cnt0 >= 3 then
dgl_out <= '0';
elsif cnt1 >= 3 then
dgl_out <= '1';
end if;
-- detect rising edge on pps
pps_last <= dgl_out;
re := (dgl_out='1' and pps_last='0');
-- update counters
if re then
cnt_lsb <= to_unsigned(0, cnt_lsb'length);
lat_lsb <= cnt_lsb;
lat_msb <= lat_msb + 1;
lat_upd <= '1';
else
cnt_lsb <= cnt_lsb + 1;
end if;
-- handle reset
if rst_ref='1' then
dgl_hist <= (others=>'0');
dgl_out <= '0';
pps_last <= '0';
cnt_lsb <= (others=>'0');
lat_upd <= '0';
lat_lsb <= (others=>'0');
lat_msb <= (others=>'0');
end if;
end if;
end process;
-- bring update-pulse into correct clock domain
syn: entity mt_sync_feedback
port map (
i_clk => clk_ref,
i_data => lat_upd,
o_clk => clk_sys,
o_data => out_upd
);
-- output register
process(clk_sys)
begin
if rising_edge(clk_sys) then
-- update output when requested
if out_upd='1' then
out_lsb <= lat_lsb;
out_msb <= lat_msb;
end if;
-- handle reset
if rst_sys='1' then
out_lsb <= (others=>'0');
out_msb <= (others=>'0');
end if;
end if;
end process;
-- output status
status.lsb <= out_lsb;
status.msb <= out_msb;
end rtl;

View File

@ -0,0 +1,72 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_gpio.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : GPIO Block
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.usbrx.all;
entity usbrx_gpio is
port(
-- common
clk : in std_logic;
reset : in std_logic;
-- GPIOs
gpio : inout std_logic_vector(10 downto 0);
-- config / status
config : in usbrx_gpio_config_t;
status : out usbrx_gpio_status_t
);
end usbrx_gpio;
architecture rtl of usbrx_gpio is
-- register
signal ireg : std_logic_vector(10 downto 0) := (others=>'0');
signal oreg : std_logic_vector(10 downto 0) := (others=>'0');
signal oena : std_logic_vector(10 downto 0) := (others=>'0');
begin
-- create output-driver
od: for i in gpio'range generate
begin
gpio(i) <= oreg(i) when oena(i)='1' else 'Z';
end generate;
-- IOBs
process(clk)
begin
if rising_edge(clk) then
ireg <= to_X01(gpio);
oreg <= config.odata;
oena <= config.oena;
end if;
end process;
end rtl;

View File

@ -0,0 +1,100 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_pwm.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : PWM Generator
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.usbrx.all;
entity usbrx_pwm is
port(
-- common
clk : in std_logic;
reset : in std_logic;
-- config
config : in usbrx_pwm_config_t;
-- PWM output
pwm0 : out std_logic;
pwm1 : out std_logic
);
end usbrx_pwm;
architecture rtl of usbrx_pwm is
-- status
signal counter0 : unsigned(15 downto 0);
signal counter1 : unsigned(15 downto 0);
signal out0 : std_logic;
signal out1 : std_logic;
begin
process(clk)
begin
if rising_edge(clk) then
-- update counter #0
counter0 <= counter0 - 1;
if counter0 = 0 then
counter0 <= config.freq0;
end if;
-- update counter #1
counter1 <= counter1 - 1;
if counter1 = 0 then
counter1 <= config.freq1;
end if;
-- update output #0
if counter0 < config.duty0
then out0 <= '1';
else out0 <= '0';
end if;
-- update output #1
if counter1 < config.duty1
then out1 <= '1';
else out1 <= '0';
end if;
-- output register
pwm0 <= out0;
pwm1 <= out1;
-- handle reset
if reset='1' then
counter0 <= (others=>'0');
counter1 <= (others=>'0');
out0 <= '0';
out1 <= '0';
pwm0 <= '0';
pwm1 <= '0';
end if;
end if;
end process;
end rtl;

View File

@ -0,0 +1,240 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_regbank.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : Registerbank
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.usbrx.all;
entity usbrx_regbank is
port(
-- common
clk : in std_logic;
reset : in std_logic;
-- config
cfg_pwm : out usbrx_pwm_config_t;
cfg_gpio : out usbrx_gpio_config_t;
cfg_adc : out usbrx_adc_config_t;
cfg_ssc : out usbrx_ssc_config_t;
cfg_fil : out usbrx_fil_config_t;
cfg_off : out usbrx_off_config_t;
-- status
stat_ref : in usbrx_ref_status_t;
stat_gpio : in usbrx_gpio_status_t;
-- SPI interface
spi_ncs : in std_logic;
spi_sclk : in std_logic;
spi_mosi : in std_logic;
spi_miso : out std_logic
);
end usbrx_regbank;
architecture rtl of usbrx_regbank is
-- bus interface
signal bus_rena : std_logic;
signal bus_wena : std_logic;
signal bus_addr : unsigned(6 downto 0);
signal bus_rdata : std_logic_vector(31 downto 0);
signal bus_wdata : std_logic_vector(31 downto 0);
-- registers
signal reg_pwm1 : std_logic_vector(31 downto 0);
signal reg_pwm2 : std_logic_vector(31 downto 0);
signal reg_adc : std_logic_vector(15 downto 0);
signal reg_ssc1 : std_logic_vector(0 downto 0);
signal reg_ssc2 : std_logic_vector(7 downto 0);
signal reg_fil : std_logic_vector(2 downto 0);
signal reg_off : std_logic_vector(31 downto 0);
signal reg_gain : std_logic_vector(31 downto 0);
signal reg_swap : std_logic_vector(0 downto 0);
signal reg_ioe : std_logic_vector(10 downto 0);
signal reg_iod : std_logic_vector(10 downto 0);
-- avoid block-ram inference
attribute syn_romstyle : string;
attribute syn_romstyle of rtl : architecture is "logic";
begin
-- SPI slave
spi: entity usbrx_spi
port map (
-- common
clk => clk,
reset => reset,
-- SPI interface
spi_ncs => spi_ncs,
spi_sclk => spi_sclk,
spi_mosi => spi_mosi,
spi_miso => spi_miso,
-- bus interface
bus_rena => bus_rena,
bus_wena => bus_wena,
bus_addr => bus_addr,
bus_rdata => bus_rdata,
bus_wdata => bus_wdata
);
-- handle requests
process(reset, clk)
begin
if reset = '1' then
bus_rdata <= (others=>'0');
reg_pwm1 <= x"17701F3F";
reg_pwm2 <= x"07D01F3F";
reg_adc <= x"0401";
reg_ssc1 <= "0";
reg_ssc2 <= x"01";
reg_fil <= "011";
reg_off <= x"00000000";
reg_gain <= x"80008000";
reg_swap <= "0";
reg_ioe <= "00000000000";
reg_iod <= "00000000000";
elsif rising_edge(clk) then
-- output zeros by default
bus_rdata <= (others=>'0');
-- handle requests
case to_integer(bus_addr) is
when 0 =>
-- identification
bus_rdata <= x"DEADBEEF";
when 1 =>
-- PWM #1
bus_rdata <= reg_pwm1;
if bus_wena='1' then
reg_pwm1 <= bus_wdata(31 downto 0);
end if;
when 2 =>
-- PWM #2
bus_rdata <= reg_pwm2;
if bus_wena='1' then
reg_pwm2 <= bus_wdata(31 downto 0);
end if;
when 3 =>
-- ADC interface
bus_rdata <= to_slv32(reg_adc);
if bus_wena='1' then
reg_adc <= bus_wdata(15 downto 0);
end if;
when 4 =>
-- SSC interface
bus_rdata( 0 downto 0) <= reg_ssc1;
bus_rdata(15 downto 8) <= reg_ssc2;
if bus_wena='1' then
reg_ssc1 <= bus_wdata( 0 downto 0);
reg_ssc2 <= bus_wdata(15 downto 8);
end if;
when 5 =>
-- <unused>
null;
when 6 =>
-- decimation filter
bus_rdata <= to_slv32(reg_fil);
if bus_wena='1' then
reg_fil <= bus_wdata(2 downto 0);
end if;
when 7 =>
-- sample offset
bus_rdata <= reg_off;
if bus_wena='1' then
reg_off <= bus_wdata(31 downto 0);
end if;
when 8 =>
-- sample gain
bus_rdata <= reg_gain;
if bus_wena='1' then
reg_gain <= bus_wdata(31 downto 0);
end if;
when 9 =>
-- sample swap
bus_rdata(0 downto 0) <= reg_swap;
if bus_wena='1' then
reg_swap <= bus_wdata( 0 downto 0);
end if;
when 10 =>
-- GPIO - output enable
bus_rdata(10 downto 0) <= reg_ioe;
if bus_wena='1' then
reg_ioe <= bus_wdata(10 downto 0);
end if;
when 11 =>
-- GPIO - output data
bus_rdata(10 downto 0) <= reg_iod;
if bus_wena='1' then
reg_iod <= bus_wdata(10 downto 0);
end if;
when 12 =>
-- GPIO - input data
bus_rdata(10 downto 0) <= stat_gpio.idata;
when 13 =>
-- reference frequency
bus_rdata(24 downto 0) <= std_logic_vector(stat_ref.lsb);
bus_rdata(31 downto 25) <= std_logic_vector(stat_ref.msb);
when others =>
-- invalid address
null;
end case;
end if;
end process;
-- map registers to config
cfg_pwm.freq0 <= unsigned(reg_pwm1(15 downto 0));
cfg_pwm.freq1 <= unsigned(reg_pwm2(15 downto 0));
cfg_pwm.duty0 <= unsigned(reg_pwm1(31 downto 16));
cfg_pwm.duty1 <= unsigned(reg_pwm2(31 downto 16));
cfg_adc.clkdiv <= unsigned(reg_adc( 7 downto 0));
cfg_adc.acqlen <= unsigned(reg_adc(15 downto 8));
cfg_ssc.tmode <= reg_ssc1(0);
cfg_ssc.clkdiv <= unsigned(reg_ssc2);
cfg_fil.decim <= unsigned(reg_fil);
cfg_fil.decim <= unsigned(reg_fil);
cfg_off.ioff <= signed(reg_off(15 downto 0));
cfg_off.qoff <= signed(reg_off(31 downto 16));
cfg_off.igain <= unsigned(reg_gain(15 downto 0));
cfg_off.qgain <= unsigned(reg_gain(31 downto 16));
cfg_off.swap <= reg_swap(0);
cfg_gpio.oena <= reg_ioe;
cfg_gpio.odata <= reg_iod;
end rtl;

View File

@ -0,0 +1,215 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_spi.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : SPI Slave Implementation
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
entity usbrx_spi is
port(
-- common
clk : in std_logic;
reset : in std_logic;
-- SPI interface
spi_ncs : in std_logic;
spi_sclk : in std_logic;
spi_mosi : in std_logic;
spi_miso : out std_logic;
-- bus interface
bus_rena : out std_logic;
bus_wena : out std_logic;
bus_addr : out unsigned(6 downto 0);
bus_rdata : in std_logic_vector(31 downto 0);
bus_wdata : out std_logic_vector(31 downto 0)
);
end usbrx_spi;
architecture rtl of usbrx_spi is
-- internal types
type state_t is (S_COMMAND, S_WRITE, S_READ2, S_READ3, S_READ4);
-- IO-registers
signal iob_ncs : std_logic;
signal iob_sclk : std_logic;
signal iob_mosi : std_logic;
-- synchronized inputs
signal sync_ncs : std_logic;
signal sync_sclk : std_logic;
signal sync_mosi : std_logic;
-- edge detection
signal last_sclk : std_logic;
signal last_re : std_logic;
signal last_fe : std_logic;
-- SPI slave
signal state : state_t;
signal remain : unsigned(5 downto 0);
signal sireg : std_logic_vector(31 downto 0);
signal soreg : std_logic_vector(32 downto 0);
signal addr : unsigned(6 downto 0);
begin
-- IOBs
process(clk)
begin
if rising_edge(clk) then
iob_ncs <= spi_ncs;
iob_sclk <= spi_sclk;
iob_mosi <= spi_mosi;
if iob_ncs='0'
then spi_miso <= soreg(32);
else spi_miso <= '1';
end if;
end if;
end process;
-- input synchronizer
process(clk,reset)
begin
if reset = '1' then
sync_ncs <= '1';
sync_sclk <= '0';
sync_mosi <= '0';
elsif rising_edge(clk) then
sync_ncs <= iob_ncs;
sync_sclk <= iob_sclk;
sync_mosi <= iob_mosi;
end if;
end process;
-- SPI slave
process(clk,reset)
variable re,fe : std_logic;
begin
if reset = '1' then
last_sclk <= '0';
last_re <= '0';
last_fe <= '0';
state <= S_COMMAND;
remain <= (others=>'0');
sireg <= (others=>'1');
soreg <= (others=>'1');
addr <= (others=>'0');
bus_rena <= '0';
bus_wena <= '0';
bus_addr <= (others=>'0');
bus_wdata <= (others=>'0');
elsif rising_edge(clk) then
-- set default values
bus_rena <= '0';
bus_wena <= '0';
-- detect edges on clock line
last_sclk <= sync_sclk;
re := sync_sclk and (not last_sclk);
fe := (not sync_sclk) and last_sclk;
last_re <= re;
last_fe <= fe;
-- update shift-registers
if re='1' then
sireg <= sireg(30 downto 0) & sync_mosi;
end if;
if fe='1' then
soreg <= soreg(31 downto 0) & '1';
end if;
-- check state of chip-select
if sync_ncs='1' then
--> CS deasserted, reset slave
state <= S_COMMAND;
remain <= to_unsigned(7,6);
else
--> CS asserted, tick state-machine
case state is
when S_COMMAND =>
-- wait until 8 bits were received
if last_re='1' then
remain <= remain - 1;
if remain=0 then
--> got 8 bits, decode address & direction
addr <= unsigned(sireg(6 downto 0));
remain <= to_unsigned(31,6);
if sireg(7)='1' then
state <= S_READ2;
bus_rena <= '1';
bus_addr <= unsigned(sireg(6 downto 0));
else
state <= S_WRITE;
end if;
end if;
end if;
when S_WRITE =>
-- wait until 32 bits were received
if last_re='1' then
remain <= remain - 1;
if remain=0 then
-- issue write-request
bus_wena <= '1';
bus_addr <= addr;
bus_wdata <= sireg;
-- continue with next word
addr <= addr + 1;
remain <= to_unsigned(31,6);
end if;
end if;
when S_READ2 =>
-- wait-state
state <= S_READ3;
when S_READ3 =>
-- load shift-register
soreg <= soreg(32) & bus_rdata;
state <= S_READ4;
remain <= to_unsigned(31,6);
when S_READ4 =>
-- wait until 32 bits were transmitted
if fe='1' then
remain <= remain - 1;
if remain=0 then
-- continue with next word
bus_rena <= '1';
bus_addr <= addr + 1;
addr <= addr + 1;
state <= S_READ2;
end if;
end if;
end case;
end if;
end if;
end process;
end rtl;

View File

@ -0,0 +1,309 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_toplevel.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : Toplevel component
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.usbrx.all;
entity usbrx_toplevel is
port (
-- common
clk_in_pclk : in std_logic;
-- special control
dings : in std_logic;
dingsrst : in std_logic;
-- ADC interface
adc_cs : out std_logic;
adc_sck : out std_logic;
adc_sd1 : in std_logic;
adc_sd2 : in std_logic;
-- control SPI
ctl_int : out std_logic;
ctl_cs : in std_logic;
ctl_sck : in std_logic;
ctl_mosi : in std_logic;
ctl_miso : out std_logic;
-- data SPIs
rx_clk : out std_logic;
rx_syn : out std_logic;
rx_dat : out std_logic;
-- data SPIs
tx_clk : in std_logic;
tx_syn : in std_logic;
tx_dat : in std_logic;
-- gain PWMs
gain0 : out std_logic;
gain1 : out std_logic;
-- GPS
gps_1pps : in std_logic;
gps_10k : in std_logic;
-- gpios
led : inout std_logic;
gpio : inout std_logic_vector(9 downto 0);
-- virtual GNDs/VCCs
vgnd : out std_logic_vector(11 downto 0);
vcc33 : inout std_logic_vector(11 downto 0);
vcc12 : inout std_logic_vector(4 downto 0)
);
end usbrx_toplevel;
architecture rtl of usbrx_toplevel is
-- clocks
signal clk_30 : std_logic;
signal clk_80 : std_logic;
signal rst_30 : std_logic;
signal rst_80 : std_logic;
-- config
signal cfg_pwm : usbrx_pwm_config_t;
signal cfg_gpio : usbrx_gpio_config_t;
signal cfg_adc : usbrx_adc_config_t;
signal cfg_ssc : usbrx_ssc_config_t;
signal cfg_fil : usbrx_fil_config_t;
signal cfg_off : usbrx_off_config_t;
-- status
signal stat_ref : usbrx_ref_status_t;
signal stat_gpio : usbrx_gpio_status_t;
-- ADC <-> offset
signal adc_off_clk : std_logic;
signal adc_off_i : unsigned(13 downto 0);
signal adc_off_q : unsigned(13 downto 0);
-- offset <-> filter
signal off_fil_clk : std_logic;
signal off_fil_i : signed(15 downto 0);
signal off_fil_q : signed(15 downto 0);
-- filter <-> output
signal fil_out_clk : std_logic;
signal fil_out_i : signed(15 downto 0);
signal fil_out_q : signed(15 downto 0);
-- enusure that signal-names are kept (important for timing contraints)
attribute syn_keep of clk_in_pclk : signal is true;
begin
-- house-keeping
cg: entity usbrx_clkgen
port map (
-- clock input
clk_30_pclk => clk_in_pclk,
ext_rst => dingsrst,
-- system clock
clk_30 => clk_30,
clk_80 => clk_80,
rst_30 => rst_30,
rst_80 => rst_80
);
-- register bank
rb: entity usbrx_regbank
port map (
-- common
clk => clk_80,
reset => rst_80,
-- config
cfg_pwm => cfg_pwm,
cfg_adc => cfg_adc,
cfg_ssc => cfg_ssc,
cfg_fil => cfg_fil,
cfg_off => cfg_off,
cfg_gpio => cfg_gpio,
-- status
stat_ref => stat_ref,
stat_gpio => stat_gpio,
-- SPI interface
spi_ncs => ctl_cs,
spi_sclk => ctl_sck,
spi_mosi => ctl_mosi,
spi_miso => ctl_miso
);
-- reference clock measurement
refclk: entity usbrx_clkref
port map (
-- system clocks
clk_sys => clk_80,
rst_sys => rst_80,
-- reference signal
clk_ref => clk_30,
rst_ref => rst_30,
-- 1pps signal
gps_1pps => gps_1pps,
-- status
status => stat_ref
);
-- GPIOs
io: entity usbrx_gpio
port map (
-- common
clk => clk_80,
reset => rst_80,
-- GPIOs
gpio(9 downto 0) => gpio,
gpio(10) => led,
-- config / status
config => cfg_gpio,
status => stat_gpio
);
-- gain PWMs
pwm: entity usbrx_pwm
port map (
-- common
clk => clk_80,
reset => rst_80,
-- config
config => cfg_pwm,
-- PWM output
pwm0 => gain0,
pwm1 => gain1
);
-- A/D interface
adc: entity usbrx_ad7357
port map (
-- common
clk => clk_80,
reset => rst_80,
-- config
config => cfg_adc,
-- ADC interface
adc_cs => adc_cs,
adc_sck => adc_sck,
adc_sd1 => adc_sd1,
adc_sd2 => adc_sd2,
-- output
out_clk => adc_off_clk,
out_i => adc_off_i,
out_q => adc_off_q
);
-- offset stage
off: entity usbrx_offset
port map (
-- common
clk => clk_80,
reset => rst_80,
-- config
config => cfg_off,
-- input
in_clk => adc_off_clk,
in_i => adc_off_i,
in_q => adc_off_q,
-- output
out_clk => off_fil_clk,
out_i => off_fil_i,
out_q => off_fil_q
);
-- decimation filter
fil: entity usbrx_decimate
port map (
-- common
clk => clk_80,
reset => rst_80,
-- config
config => cfg_fil,
-- input
in_clk => off_fil_clk,
in_i => off_fil_i,
in_q => off_fil_q,
-- output
out_clk => fil_out_clk,
out_i => fil_out_i,
out_q => fil_out_q
);
-- SSC output
ssc: entity usbrx_ssc
port map (
-- common
clk => clk_80,
reset => rst_80,
-- config
config => cfg_ssc,
-- output
in_clk => fil_out_clk,
in_i => fil_out_i,
in_q => fil_out_q,
-- SSC interface
ssc_clk => rx_clk,
ssc_syn => rx_syn,
ssc_dat => rx_dat
);
-- drive unused IOs
ctl_int <= '1';
-- virtual GNDs/VCCs
vgnd <= (others=>'0');
vcc12 <= (others=>'Z');
vcc33 <= (others=>'1');
end rtl;

View File

@ -0,0 +1,86 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : OsmoSDR package
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- 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 as version 3 of the License, or --
-- --
-- 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 V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package usbrx is
-- PWM config
type usbrx_pwm_config_t is record
freq0 : unsigned(15 downto 0);
freq1 : unsigned(15 downto 0);
duty0 : unsigned(15 downto 0);
duty1 : unsigned(15 downto 0);
end record;
-- ADC interface config
type usbrx_adc_config_t is record
clkdiv : unsigned(7 downto 0);
acqlen : unsigned(7 downto 0);
end record;
-- SSC interface config
type usbrx_ssc_config_t is record
clkdiv : unsigned(7 downto 0);
tmode : std_logic;
end record;
-- offset stage config
type usbrx_off_config_t is record
swap : std_logic;
ioff : signed(15 downto 0);
qoff : signed(15 downto 0);
igain : unsigned(15 downto 0);
qgain : unsigned(15 downto 0);
end record;
-- decimation filter config
type usbrx_fil_config_t is record
decim : unsigned(2 downto 0);
end record;
-- clock reference status
type usbrx_ref_status_t is record
lsb : unsigned(24 downto 0);
msb : unsigned(6 downto 0);
end record;
-- GPIO config
type usbrx_gpio_config_t is record
oena : std_logic_vector(10 downto 0);
odata : std_logic_vector(10 downto 0);
end record;
-- clock reference status
type usbrx_gpio_status_t is record
idata : std_logic_vector(10 downto 0);
end record;
end usbrx;
package body usbrx is
-- nothing so far
end usbrx;

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<XML>
<document type="stimulators" version="1">
<set name="ASDB Stimulators" active="1">
<stimulator>
<signal_path value="/tb_usbrx/uut/off/config.igain"/>
<rawdescription value="VAL:FRM:Override:x&quot;9000&quot;:&lt;= x&quot;9000&quot;:1:"/>
</stimulator>
<stimulator>
<signal_path value="/tb_usbrx/uut/off/in_i"/>
<rawdescription value="VAL:FRM:Override:10#4000:&lt;= 10#4000:0:"/>
</stimulator>
</set>
</document>
</XML>

View File

@ -0,0 +1,2 @@
i<>.\src\usbrx\toplevel\usbrx_toplevel.vhd
i<>.\src\mt_toolbox\mt_synctools.vhd

155
fpga/hw-v2/usbrx_vhdl.adf Normal file
View File

@ -0,0 +1,155 @@
[Project]
Current Flow=Generic
VCS=0
version=3
Current Config=compile
[Configurations]
compile=usbrx_vhdl
[Library]
usbrx_vhdl=.\usbrx_vhdl.LIB
[Settings]
AccessRead=0
AccessReadWrite=0
AccessACCB=0
AccessACCR=0
AccessReadWriteSLP=0
AccessReadTopLevel=1
DisableC=1
ENABLE_ADV_DATAFLOW=0
FLOW_TYPE=HDL
LANGUAGE=VHDL
REFRESH_FLOW=1
FAMILY=Lattice XP2
fileopeninsrc=1
fileopenfolder=C:\DVB\sr_systems\sr-usbrx\osmo-sdr\fpga\hw-v2\src\mt_toolbox
IMPL_TOOL=
SYNTH_TOOL=
NoWarningsSDF=0
SDFErrorLimit=0
EnableSDFErrorLimit=0
ChangeSDFErrorToWarning=0
NoTchkMsg=0
NoTimingChecks=0
HESPrepare=0
EnableXtrace=0
SplitNetVectors=0
StackMemorySize=32
RetvalMemorySize=32
VsimAdditionalOptions=
DisableVitalMsg=0
VitalAccel=1
VitalGlitches=0
DisableIEEEWarnings=0
[LocalVerilogSets]
EnableSLP=1
EnableDebug=0
[LocalVhdlSets]
CompileWithDebug=1
DisableVHDL87Key=0
EnableVHDL93Key=0
EnableVHDL2002Key=1
EnableVHDL2006Key=0
EnableVHDL2008Key=0
NetlistCompilation=1
Syntax RelaxLRM=0
MaxErrorsKey=100
OptimizationLevel=3
DisableRangeChecks=0
ProtectLevel=0
AdditionalOptions=
IncrementalCompilation=0
[$LibMap$]
usbrx_vhdl=.
Active_lib=
[HierarchyViewer]
SortInfo=u
HierarchyInformation=
ShowHide=ShowTopLevel
Selected=
[Folders]
Name3=Makefiles
Directory3=C:\
Extension3=mak
Name4=Memory
Directory4=C:\
Extension4=mem;mif;hex
Name5=Dll Libraries
Directory5=C:\
Extension5=dll
Name6=PDF
Directory6=C:\
Extension6=pdf
Name7=HTML
Directory7=C:\
Extension7=
[sdf.c.structure_con]
[sdf.ea.tb_usbrx-rtl]
0=src\testbench\usbrx_vhdl_usbrx_vhdl_vho.sdf| /tb_usbrx/uut, Average, No
[Groups]
mt_toolbox=1
mt_filter=1
usbrx=1
usbrx\filter=1
usbrx\datapath=1
usbrx\toplevel=1
testbench=1
[Files]
mt_toolbox/mt_toolbox.vhd=-1
mt_toolbox/mt_clktools.vhd=-1
mt_toolbox/mt_synctools.vhd=-1
mt_filter/mt_filter.vhd=-1
mt_filter/mt_fil_storage_slow.vhd=-1
mt_filter/mt_fil_mac_slow.vhd=-1
mt_filter/mt_fir_symmetric_slow.vhd=-1
usbrx/usbrx.vhd=-1
usbrx\filter/usbrx_halfband.vhd=-1
usbrx\datapath/usbrx_ad7357.vhd=-1
usbrx\datapath/usbrx_offset.vhd=-1
usbrx\datapath/usbrx_decimate.vhd=-1
usbrx\datapath/usbrx_ssc.vhd=-1
usbrx\toplevel/usbrx_clkgen.vhd=-1
usbrx\toplevel/usbrx_clkref.vhd=-1
usbrx\toplevel/usbrx_gpio.vhd=-1
usbrx\toplevel/usbrx_spi.vhd=-1
usbrx\toplevel/usbrx_regbank.vhd=-1
usbrx\toplevel/usbrx_pwm.vhd=-1
usbrx\toplevel/usbrx_toplevel.vhd=-1
testbench/tb_filter.vhd=-1
testbench/tb_usbrx.vhd=-1
[Files.Data]
.\src\mt_toolbox\mt_toolbox.vhd=VHDL Source Code
.\src\mt_toolbox\mt_clktools.vhd=VHDL Source Code
.\src\mt_toolbox\mt_synctools.vhd=VHDL Source Code
.\src\mt_filter\mt_filter.vhd=VHDL Source Code
.\src\mt_filter\mt_fil_storage_slow.vhd=VHDL Source Code
.\src\mt_filter\mt_fil_mac_slow.vhd=VHDL Source Code
.\src\mt_filter\mt_fir_symmetric_slow.vhd=VHDL Source Code
.\src\usbrx\usbrx.vhd=VHDL Source Code
.\src\usbrx\filter\usbrx_halfband.vhd=VHDL Source Code
.\src\usbrx\datapath\usbrx_ad7357.vhd=VHDL Source Code
.\src\usbrx\datapath\usbrx_offset.vhd=VHDL Source Code
.\src\usbrx\datapath\usbrx_decimate.vhd=VHDL Source Code
.\src\usbrx\datapath\usbrx_ssc.vhd=VHDL Source Code
.\src\usbrx\toplevel\usbrx_clkgen.vhd=VHDL Source Code
.\src\usbrx\toplevel\usbrx_clkref.vhd=VHDL Source Code
.\src\usbrx\toplevel\usbrx_gpio.vhd=VHDL Source Code
.\src\usbrx\toplevel\usbrx_spi.vhd=VHDL Source Code
.\src\usbrx\toplevel\usbrx_regbank.vhd=VHDL Source Code
.\src\usbrx\toplevel\usbrx_pwm.vhd=VHDL Source Code
.\src\usbrx\toplevel\usbrx_toplevel.vhd=VHDL Source Code
.\src\testbench\tb_filter.vhd=VHDL Source Code
.\src\testbench\tb_usbrx.vhd=VHDL Test Bench

15
fpga/hw-v2/usbrx_vhdl.aws Normal file
View File

@ -0,0 +1,15 @@
[Version]
Version=8.3
[Designs]
usbrx_vhdl=.\usbrx_vhdl.adf
[Settings]
Active=usbrx_vhdl
[Browser]
sort=type
mode=none
[Order]
order=1
macro=
[Expand]
usbrx_vhdl=1
timingsim=0

151
git-version-gen Executable file
View File

@ -0,0 +1,151 @@
#!/bin/sh
# Print a version string.
scriptversion=2010-01-28.01
# Copyright (C) 2007-2010 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
# It may be run two ways:
# - from a git repository in which the "git describe" command below
# produces useful output (thus requiring at least one signed tag)
# - from a non-git-repo directory containing a .tarball-version file, which
# presumes this script is invoked like "./git-version-gen .tarball-version".
# In order to use intra-version strings in your project, you will need two
# separate generated version string files:
#
# .tarball-version - present only in a distribution tarball, and not in
# a checked-out repository. Created with contents that were learned at
# the last time autoconf was run, and used by git-version-gen. Must not
# be present in either $(srcdir) or $(builddir) for git-version-gen to
# give accurate answers during normal development with a checked out tree,
# but must be present in a tarball when there is no version control system.
# Therefore, it cannot be used in any dependencies. GNUmakefile has
# hooks to force a reconfigure at distribution time to get the value
# correct, without penalizing normal development with extra reconfigures.
#
# .version - present in a checked-out repository and in a distribution
# tarball. Usable in dependencies, particularly for files that don't
# want to depend on config.h but do want to track version changes.
# Delete this file prior to any autoconf run where you want to rebuild
# files to pick up a version string change; and leave it stale to
# minimize rebuild time after unrelated changes to configure sources.
#
# It is probably wise to add these two files to .gitignore, so that you
# don't accidentally commit either generated file.
#
# Use the following line in your configure.ac, so that $(VERSION) will
# automatically be up-to-date each time configure is run (and note that
# since configure.ac no longer includes a version string, Makefile rules
# should not depend on configure.ac for version updates).
#
# AC_INIT([GNU project],
# m4_esyscmd([build-aux/git-version-gen .tarball-version]),
# [bug-project@example])
#
# Then use the following lines in your Makefile.am, so that .version
# will be present for dependencies, and so that .tarball-version will
# exist in distribution tarballs.
#
# BUILT_SOURCES = $(top_srcdir)/.version
# $(top_srcdir)/.version:
# echo $(VERSION) > $@-t && mv $@-t $@
# dist-hook:
# echo $(VERSION) > $(distdir)/.tarball-version
case $# in
1) ;;
*) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version"; exit 1;;
esac
tarball_version_file=$1
nl='
'
# First see if there is a tarball-only version file.
# then try "git describe", then default.
if test -f $tarball_version_file
then
v=`cat $tarball_version_file` || exit 1
case $v in
*$nl*) v= ;; # reject multi-line output
[0-9]*) ;;
*) v= ;;
esac
test -z "$v" \
&& echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2
fi
if test -n "$v"
then
: # use $v
elif
v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
|| git describe --abbrev=4 HEAD 2>/dev/null` \
&& case $v in
[0-9]*) ;;
v[0-9]*) ;;
*) (exit 1) ;;
esac
then
# Is this a new git that lists number of commits since the last
# tag or the previous older version that did not?
# Newer: v6.10-77-g0f8faeb
# Older: v6.10-g0f8faeb
case $v in
*-*-*) : git describe is okay three part flavor ;;
*-*)
: git describe is older two part flavor
# Recreate the number of commits and rewrite such that the
# result is the same as if we were using the newer version
# of git describe.
vtag=`echo "$v" | sed 's/-.*//'`
numcommits=`git rev-list "$vtag"..HEAD | wc -l`
v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
;;
esac
# Change the first '-' to a '.', so version-comparing tools work properly.
# Remove the "g" in git describe's output string, to save a byte.
v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
else
v=UNKNOWN
fi
v=`echo "$v" |sed 's/^v//'`
# Don't declare a version "dirty" merely because a time stamp has changed.
git status > /dev/null 2>&1
dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=
case "$dirty" in
'') ;;
*) # Append the suffix only if there isn't one already.
case $v in
*-dirty) ;;
*) v="$v-dirty" ;;
esac ;;
esac
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
echo "$v" | tr -d '\012'
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View File

@ -1,26 +0,0 @@
# Copyright 2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
include(GrPython)
GR_PYTHON_INSTALL(
PROGRAMS
osmosdr_source.py
DESTINATION bin
)

View File

@ -1,325 +0,0 @@
<?xml version='1.0' encoding='ASCII'?>
<flow_graph>
<timestamp>Thu Nov 12 11:26:07 2009</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
<value>osmosdr_source_c</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>10e3</value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 170)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>sink</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>Input</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>20</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0.002</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(691, 222)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>osmosdr_source_c</key>
<param>
<key>id</key>
<value>sqr</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(709, 344)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>gr_throttle</key>
<param>
<key>id</key>
<value>thr</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(497, 340)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>gr_vector_source_x</key>
<param>
<key>id</key>
<value>src</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>vector</key>
<value>[float(n)-50 for n in range(100)]</value>
</param>
<param>
<key>repeat</key>
<value>True</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(246, 332)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>sink2</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>Output</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0.002</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(869, 324)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<connection>
<source_block_id>thr</source_block_id>
<sink_block_id>sqr</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>src</source_block_id>
<sink_block_id>thr</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>thr</source_block_id>
<sink_block_id>sink</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>sqr</source_block_id>
<sink_block_id>sink2</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

View File

@ -1,60 +0,0 @@
#!/usr/bin/env python
##################################################
# Gnuradio Python Flow Graph
# Title: OsmoSDR Source
# Generated: Thu Nov 12 11:26:07 2009
##################################################
import osmosdr
from gnuradio import eng_notation
from gnuradio import gr
from gnuradio.eng_option import eng_option
from gnuradio.gr import firdes
from gnuradio.wxgui import fftsink2
from grc_gnuradio import wxgui as grc_wxgui
from optparse import OptionParser
import wx
class osmosdr_source_c(grc_wxgui.top_block_gui):
def __init__(self):
grc_wxgui.top_block_gui.__init__(self, title="OsmoSDR Source")
##################################################
# Variables
##################################################
self.samp_rate = samp_rate = 96e3
##################################################
# Blocks
##################################################
self.sink = fftsink2.fft_sink_c(
self.GetWin(),
fft_size=1024,
sample_rate=samp_rate,
ref_scale=2.0,
ref_level=-30,
y_divs=10,
fft_rate=10,
average=True,
avg_alpha=0.5
)
self.Add(self.sink.win)
self.src = osmosdr.source_c()
##################################################
# Connections
##################################################
self.connect((self.src, 0), (self.sink, 0))
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.sink.set_sample_rate(self.samp_rate)
if __name__ == '__main__':
parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
(options, args) = parser.parse_args()
tb = osmosdr_source_c()
tb.Run(True)

View File

@ -1,138 +0,0 @@
# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)
#
# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for
# parsing the arguments given to that macro or function.
# It processes the arguments and defines a set of variables which hold the
# values of the respective options.
#
# The <options> argument contains all options for the respective macro,
# i.e. keywords which can be used when calling the macro without any value
# following, like e.g. the OPTIONAL keyword of the install() command.
#
# The <one_value_keywords> argument contains all keywords for this macro
# which are followed by one value, like e.g. DESTINATION keyword of the
# install() command.
#
# The <multi_value_keywords> argument contains all keywords for this macro
# which can be followed by more than one value, like e.g. the TARGETS or
# FILES keywords of the install() command.
#
# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
# keywords listed in <options>, <one_value_keywords> and
# <multi_value_keywords> a variable composed of the given <prefix>
# followed by "_" and the name of the respective keyword.
# These variables will then hold the respective value from the argument list.
# For the <options> keywords this will be TRUE or FALSE.
#
# All remaining arguments are collected in a variable
# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see whether
# your macro was called with unrecognized parameters.
#
# As an example here a my_install() macro, which takes similar arguments as the
# real install() command:
#
# function(MY_INSTALL)
# set(options OPTIONAL FAST)
# set(oneValueArgs DESTINATION RENAME)
# set(multiValueArgs TARGETS CONFIGURATIONS)
# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
# ...
#
# Assume my_install() has been called like this:
# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
#
# After the cmake_parse_arguments() call the macro will have set the following
# variables:
# MY_INSTALL_OPTIONAL = TRUE
# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
# MY_INSTALL_DESTINATION = "bin"
# MY_INSTALL_RENAME = "" (was not used)
# MY_INSTALL_TARGETS = "foo;bar"
# MY_INSTALL_CONFIGURATIONS = "" (was not used)
# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
#
# You can the continue and process these variables.
#
# Keywords terminate lists of values, e.g. if directly after a one_value_keyword
# another recognized keyword follows, this is interpreted as the beginning of
# the new option.
# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in
# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would
# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
#=============================================================================
# Copyright 2010 Alexander Neundorf <neundorf@kde.org>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
return()
endif()
set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
# first set all result variables to empty/FALSE
foreach(arg_name ${_singleArgNames} ${_multiArgNames})
set(${prefix}_${arg_name})
endforeach(arg_name)
foreach(option ${_optionNames})
set(${prefix}_${option} FALSE)
endforeach(option)
set(${prefix}_UNPARSED_ARGUMENTS)
set(insideValues FALSE)
set(currentArgName)
# now iterate over all arguments and fill the result variables
foreach(currentArg ${ARGN})
list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
if(insideValues)
if("${insideValues}" STREQUAL "SINGLE")
set(${prefix}_${currentArgName} ${currentArg})
set(insideValues FALSE)
elseif("${insideValues}" STREQUAL "MULTI")
list(APPEND ${prefix}_${currentArgName} ${currentArg})
endif()
else(insideValues)
list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
endif(insideValues)
else()
if(NOT ${optionIndex} EQUAL -1)
set(${prefix}_${currentArg} TRUE)
set(insideValues FALSE)
elseif(NOT ${singleArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "SINGLE")
elseif(NOT ${multiArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "MULTI")
endif()
endif()
endforeach(currentArg)
# propagate the result variables to the caller:
foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
endforeach(arg_name)
set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs)

View File

@ -1,26 +0,0 @@
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_GNURADIO_AUDIO gnuradio-audio)
FIND_PATH(
GNURADIO_AUDIO_INCLUDE_DIRS
NAMES gr_audio_api.h
HINTS $ENV{GNURADIO_AUDIO_DIR}/include/gnuradio
${PC_GNURADIO_AUDIO_INCLUDEDIR}
PATHS /usr/local/include/gnuradio
/usr/include/gnuradio
)
FIND_LIBRARY(
GNURADIO_AUDIO_LIBRARIES
NAMES gnuradio-audio
HINTS $ENV{GNURADIO_AUDIO_DIR}/lib
${PC_GNURADIO_AUDIO_LIBDIR}
PATHS /usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_AUDIO DEFAULT_MSG GNURADIO_AUDIO_LIBRARIES GNURADIO_AUDIO_INCLUDE_DIRS)
MARK_AS_ADVANCED(GNURADIO_AUDIO_LIBRARIES GNURADIO_AUDIO_INCLUDE_DIRS)

View File

@ -1,26 +0,0 @@
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_GNURADIO_CORE gnuradio-core)
FIND_PATH(
GNURADIO_CORE_INCLUDE_DIRS
NAMES gr_random.h
HINTS $ENV{GNURADIO_CORE_DIR}/include/gnuradio
${PC_GNURADIO_CORE_INCLUDEDIR}
PATHS /usr/local/include/gnuradio
/usr/include/gnuradio
)
FIND_LIBRARY(
GNURADIO_CORE_LIBRARIES
NAMES gnuradio-core
HINTS $ENV{GNURADIO_CORE_DIR}/lib
${PC_GNURADIO_CORE_LIBDIR}
PATHS /usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_CORE DEFAULT_MSG GNURADIO_CORE_LIBRARIES GNURADIO_CORE_INCLUDE_DIRS)
MARK_AS_ADVANCED(GNURADIO_CORE_LIBRARIES GNURADIO_CORE_INCLUDE_DIRS)

View File

@ -1,26 +0,0 @@
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_GRUEL gruel)
FIND_PATH(
GRUEL_INCLUDE_DIRS
NAMES gruel/attributes.h
HINTS $ENV{GRUEL_DIR}/include
${PC_GRUEL_INCLUDEDIR}
PATHS /usr/local/include
/usr/include
)
FIND_LIBRARY(
GRUEL_LIBRARIES
NAMES gruel
HINTS $ENV{GRUEL_DIR}/lib
${PC_GRUEL_LIBDIR}
PATHS /usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GRUEL DEFAULT_MSG GRUEL_LIBRARIES GRUEL_INCLUDE_DIRS)
MARK_AS_ADVANCED(GRUEL_LIBRARIES GRUEL_INCLUDE_DIRS)

View File

@ -1,210 +0,0 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_MISC_UTILS_CMAKE)
return()
endif()
set(__INCLUDED_GR_MISC_UTILS_CMAKE TRUE)
########################################################################
# Set global variable macro.
# Used for subdirectories to export settings.
# Example: include and library paths.
########################################################################
function(GR_SET_GLOBAL var)
set(${var} ${ARGN} CACHE INTERNAL "" FORCE)
endfunction(GR_SET_GLOBAL)
########################################################################
# Set the pre-processor definition if the condition is true.
# - def the pre-processor definition to set and condition name
########################################################################
function(GR_ADD_COND_DEF def)
if(${def})
add_definitions(-D${def})
endif(${def})
endfunction(GR_ADD_COND_DEF)
########################################################################
# Check for a header and conditionally set a compile define.
# - hdr the relative path to the header file
# - def the pre-processor definition to set
########################################################################
function(GR_CHECK_HDR_N_DEF hdr def)
include(CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX(${hdr} ${def})
GR_ADD_COND_DEF(${def})
endfunction(GR_CHECK_HDR_N_DEF)
########################################################################
# Include subdirectory macro.
# Sets the CMake directory variables,
# includes the subdirectory CMakeLists.txt,
# resets the CMake directory variables.
#
# This macro includes subdirectories rather than adding them
# so that the subdirectory can affect variables in the level above.
# This provides a work-around for the lack of convenience libraries.
# This way a subdirectory can append to the list of library sources.
########################################################################
macro(GR_INCLUDE_SUBDIRECTORY subdir)
#insert the current directories on the front of the list
list(INSERT _cmake_source_dirs 0 ${CMAKE_CURRENT_SOURCE_DIR})
list(INSERT _cmake_binary_dirs 0 ${CMAKE_CURRENT_BINARY_DIR})
#set the current directories to the names of the subdirs
set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${subdir})
set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${subdir})
#include the subdirectory CMakeLists to run it
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
#reset the value of the current directories
list(GET _cmake_source_dirs 0 CMAKE_CURRENT_SOURCE_DIR)
list(GET _cmake_binary_dirs 0 CMAKE_CURRENT_BINARY_DIR)
#pop the subdir names of the front of the list
list(REMOVE_AT _cmake_source_dirs 0)
list(REMOVE_AT _cmake_binary_dirs 0)
endmacro(GR_INCLUDE_SUBDIRECTORY)
########################################################################
# Check if a compiler flag works and conditionally set a compile define.
# - flag the compiler flag to check for
# - have the variable to set with result
########################################################################
macro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(${flag} ${have})
if(${have})
add_definitions(${flag})
endif(${have})
endmacro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE)
########################################################################
# Generates the .la libtool file
# This appears to generate libtool files that cannot be used by auto*.
# Usage GR_LIBTOOL(TARGET [target] DESTINATION [dest])
# Notice: there is not COMPONENT option, these will not get distributed.
########################################################################
function(GR_LIBTOOL)
if(NOT DEFINED GENERATE_LIBTOOL)
set(GENERATE_LIBTOOL OFF) #disabled by default
endif()
if(GENERATE_LIBTOOL)
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_LIBTOOL "" "TARGET;DESTINATION" "" ${ARGN})
find_program(LIBTOOL libtool)
if(LIBTOOL)
include(CMakeMacroLibtoolFile)
CREATE_LIBTOOL_FILE(${GR_LIBTOOL_TARGET} /${GR_LIBTOOL_DESTINATION})
endif(LIBTOOL)
endif(GENERATE_LIBTOOL)
endfunction(GR_LIBTOOL)
########################################################################
# Do standard things to the library target
# - set target properties
# - make install rules
# Also handle gnuradio custom naming conventions w/ extras mode.
########################################################################
function(GR_LIBRARY_FOO target)
#parse the arguments for component names
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_LIBRARY "" "RUNTIME_COMPONENT;DEVEL_COMPONENT" "" ${ARGN})
#set additional target properties
set_target_properties(${target} PROPERTIES SOVERSION ${LIBVER})
#install the generated files like so...
install(TARGETS ${target}
LIBRARY DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .so/.dylib file
ARCHIVE DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_DEVEL_COMPONENT} # .lib file
RUNTIME DESTINATION ${GR_RUNTIME_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .dll file
)
#extras mode enabled automatically on linux
if(NOT DEFINED LIBRARY_EXTRAS)
set(LIBRARY_EXTRAS ${LINUX})
endif()
#special extras mode to enable alternative naming conventions
if(LIBRARY_EXTRAS)
#create .la file before changing props
GR_LIBTOOL(TARGET ${target} DESTINATION ${GR_LIBRARY_DIR})
#give the library a special name with ultra-zero soversion
set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_NAME ${target}-${LIBVER} SOVERSION "0.0.0")
set(target_name lib${target}-${LIBVER}.so.0.0.0)
#custom command to generate symlinks
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
COMMAND ${CMAKE_COMMAND} -E touch ${target_name} #so the symlinks point to something valid so cmake 2.6 will install
)
#and install the extra symlinks
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT}
)
endif(LIBRARY_EXTRAS)
endfunction(GR_LIBRARY_FOO)
########################################################################
# Create a dummy custom command that depends on other targets.
# Usage:
# GR_GEN_TARGET_DEPS(unique_name target_deps <target1> <target2> ...)
# ADD_CUSTOM_COMMAND(<the usual args> ${target_deps})
#
# Custom command cant depend on targets, but can depend on executables,
# and executables can depend on targets. So this is the process:
########################################################################
function(GR_GEN_TARGET_DEPS name var)
file(
WRITE ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in
"int main(void){return 0;}\n"
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in
${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp
)
add_executable(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp)
if(ARGN)
add_dependencies(${name} ${ARGN})
endif(ARGN)
if(CMAKE_CROSSCOMPILING)
set(${var} "DEPENDS;${name}" PARENT_SCOPE) #cant call command when cross
else()
set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE)
endif()
endfunction(GR_GEN_TARGET_DEPS)

View File

@ -1,46 +0,0 @@
# Copyright 2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_PLATFORM_CMAKE)
return()
endif()
set(__INCLUDED_GR_PLATFORM_CMAKE TRUE)
########################################################################
# Setup additional defines for OS types
########################################################################
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(LINUX TRUE)
endif()
if(LINUX AND EXISTS "/etc/debian_version")
set(DEBIAN TRUE)
endif()
if(LINUX AND EXISTS "/etc/redhat-release")
set(REDHAT TRUE)
endif()
########################################################################
# when the library suffix should be 64 (applies to redhat linux family)
########################################################################
if(NOT DEFINED LIB_SUFFIX AND REDHAT AND CMAKE_SYSTEM_PROCESSOR MATCHES "64$")
set(LIB_SUFFIX 64)
endif()
set(LIB_SUFFIX ${LIB_SUFFIX} CACHE STRING "lib directory suffix")

View File

@ -1,227 +0,0 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_PYTHON_CMAKE)
return()
endif()
set(__INCLUDED_GR_PYTHON_CMAKE TRUE)
########################################################################
# Setup the python interpreter:
# This allows the user to specify a specific interpreter,
# or finds the interpreter via the built-in cmake module.
########################################################################
#this allows the user to override PYTHON_EXECUTABLE
if(PYTHON_EXECUTABLE)
set(PYTHONINTERP_FOUND TRUE)
#otherwise if not set, try to automatically find it
else(PYTHON_EXECUTABLE)
#use the built-in find script
find_package(PythonInterp)
#and if that fails use the find program routine
if(NOT PYTHONINTERP_FOUND)
find_program(PYTHON_EXECUTABLE NAMES python python2.7 python2.6 python2.5)
if(PYTHON_EXECUTABLE)
set(PYTHONINTERP_FOUND TRUE)
endif(PYTHON_EXECUTABLE)
endif(NOT PYTHONINTERP_FOUND)
endif(PYTHON_EXECUTABLE)
#make the path to the executable appear in the cmake gui
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter")
#make sure we can use -B with python (introduced in 2.6)
if(PYTHON_EXECUTABLE)
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -B -c ""
OUTPUT_QUIET ERROR_QUIET
RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT
)
if(PYTHON_HAS_DASH_B_RESULT EQUAL 0)
set(PYTHON_DASH_B "-B")
endif()
endif(PYTHON_EXECUTABLE)
########################################################################
# Check for the existence of a python module:
# - desc a string description of the check
# - mod the name of the module to import
# - cmd an additional command to run
# - have the result variable to set
########################################################################
macro(GR_PYTHON_CHECK_MODULE desc mod cmd have)
message(STATUS "")
message(STATUS "Python checking for ${desc}")
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "
#########################################
try: import ${mod}
except: exit(-1)
try: assert ${cmd}
except: exit(-1)
#########################################"
RESULT_VARIABLE ${have}
)
if(${have} EQUAL 0)
message(STATUS "Python checking for ${desc} - found")
set(${have} TRUE)
else(${have} EQUAL 0)
message(STATUS "Python checking for ${desc} - not found")
set(${have} FALSE)
endif(${have} EQUAL 0)
endmacro(GR_PYTHON_CHECK_MODULE)
########################################################################
# Sets the python installation directory GR_PYTHON_DIR
########################################################################
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "
from distutils import sysconfig
print sysconfig.get_python_lib(plat_specific=True, prefix='')
" OUTPUT_VARIABLE GR_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE
)
file(TO_CMAKE_PATH ${GR_PYTHON_DIR} GR_PYTHON_DIR)
########################################################################
# Create an always-built target with a unique name
# Usage: GR_UNIQUE_TARGET(<description> <dependencies list>)
########################################################################
function(GR_UNIQUE_TARGET desc)
file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5]
print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))"
OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE)
add_custom_target(${_target} ALL DEPENDS ${ARGN})
endfunction(GR_UNIQUE_TARGET)
########################################################################
# Install python sources (also builds and installs byte-compiled python)
########################################################################
function(GR_PYTHON_INSTALL)
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN})
####################################################################
if(GR_PYTHON_INSTALL_FILES)
####################################################################
install(${ARGN}) #installs regular python files
#create a list of all generated files
unset(pysrcfiles)
unset(pycfiles)
unset(pyofiles)
foreach(pyfile ${GR_PYTHON_INSTALL_FILES})
get_filename_component(pyfile ${pyfile} ABSOLUTE)
list(APPEND pysrcfiles ${pyfile})
#determine if this file is in the source or binary directory
file(RELATIVE_PATH source_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${pyfile})
string(LENGTH "${source_rel_path}" source_rel_path_len)
file(RELATIVE_PATH binary_rel_path ${CMAKE_CURRENT_BINARY_DIR} ${pyfile})
string(LENGTH "${binary_rel_path}" binary_rel_path_len)
#and set the generated path appropriately
if(${source_rel_path_len} GREATER ${binary_rel_path_len})
set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${binary_rel_path})
else()
set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${source_rel_path})
endif()
list(APPEND pycfiles ${pygenfile}c)
list(APPEND pyofiles ${pygenfile}o)
#ensure generation path exists
get_filename_component(pygen_path ${pygenfile} PATH)
file(MAKE_DIRECTORY ${pygen_path})
endforeach(pyfile)
#the command to generate the pyc files
add_custom_command(
DEPENDS ${pysrcfiles} OUTPUT ${pycfiles}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pycfiles}
)
#the command to generate the pyo files
add_custom_command(
DEPENDS ${pysrcfiles} OUTPUT ${pyofiles}
COMMAND ${PYTHON_EXECUTABLE} -O ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pyofiles}
)
#create install rule and add generated files to target list
set(python_install_gen_targets ${pycfiles} ${pyofiles})
install(FILES ${python_install_gen_targets}
DESTINATION ${GR_PYTHON_INSTALL_DESTINATION}
COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
)
####################################################################
elseif(GR_PYTHON_INSTALL_PROGRAMS)
####################################################################
file(TO_NATIVE_PATH ${PYTHON_EXECUTABLE} pyexe_native)
foreach(pyfile ${GR_PYTHON_INSTALL_PROGRAMS})
get_filename_component(pyfile_name ${pyfile} NAME)
get_filename_component(pyfile ${pyfile} ABSOLUTE)
string(REPLACE "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" pyexefile "${pyfile}.exe")
list(APPEND python_install_gen_targets ${pyexefile})
get_filename_component(pyexefile_path ${pyexefile} PATH)
file(MAKE_DIRECTORY ${pyexefile_path})
add_custom_command(
OUTPUT ${pyexefile} DEPENDS ${pyfile}
COMMAND ${PYTHON_EXECUTABLE} -c
\"open('${pyexefile}', 'w').write('\#!${pyexe_native}\\n'+open('${pyfile}').read())\"
COMMENT "Shebangin ${pyfile_name}"
)
#on windows, python files need an extension to execute
get_filename_component(pyfile_ext ${pyfile} EXT)
if(WIN32 AND NOT pyfile_ext)
set(pyfile_name "${pyfile_name}.py")
endif()
install(PROGRAMS ${pyexefile} RENAME ${pyfile_name}
DESTINATION ${GR_PYTHON_INSTALL_DESTINATION}
COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
)
endforeach(pyfile)
endif()
GR_UNIQUE_TARGET("pygen" ${python_install_gen_targets})
endfunction(GR_PYTHON_INSTALL)
########################################################################
# Write the python helper script that generates byte code files
########################################################################
file(WRITE ${CMAKE_BINARY_DIR}/python_compile_helper.py "
import sys, py_compile
files = sys.argv[1:]
srcs, gens = files[:len(files)/2], files[len(files)/2:]
for src, gen in zip(srcs, gens):
py_compile.compile(file=src, cfile=gen, doraise=True)
")

View File

@ -1,229 +0,0 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_SWIG_CMAKE)
return()
endif()
set(__INCLUDED_GR_SWIG_CMAKE TRUE)
include(GrPython)
########################################################################
# Builds a swig documentation file to be generated into python docstrings
# Usage: GR_SWIG_MAKE_DOCS(output_file input_path input_path....)
#
# Set the following variable to specify extra dependent targets:
# - GR_SWIG_DOCS_SOURCE_DEPS
# - GR_SWIG_DOCS_TARGET_DEPS
########################################################################
function(GR_SWIG_MAKE_DOCS output_file)
find_package(Doxygen)
if(DOXYGEN_FOUND)
#setup the input files variable list, quote formated
set(input_files)
unset(INPUT_PATHS)
foreach(input_path ${ARGN})
if (IS_DIRECTORY ${input_path}) #when input path is a directory
file(GLOB input_path_h_files ${input_path}/*.h)
else() #otherwise its just a file, no glob
set(input_path_h_files ${input_path})
endif()
list(APPEND input_files ${input_path_h_files})
set(INPUT_PATHS "${INPUT_PATHS} \"${input_path}\"")
endforeach(input_path)
#determine the output directory
get_filename_component(name ${output_file} NAME_WE)
get_filename_component(OUTPUT_DIRECTORY ${output_file} PATH)
set(OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}/${name}_swig_docs)
make_directory(${OUTPUT_DIRECTORY})
#generate the Doxyfile used by doxygen
configure_file(
${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.swig_doc.in
${OUTPUT_DIRECTORY}/Doxyfile
@ONLY)
#Create a dummy custom command that depends on other targets
include(GrMiscUtils)
GR_GEN_TARGET_DEPS(_${name}_tag tag_deps ${GR_SWIG_DOCS_TARGET_DEPS})
#call doxygen on the Doxyfile + input headers
add_custom_command(
OUTPUT ${OUTPUT_DIRECTORY}/xml/index.xml
DEPENDS ${input_files} ${GR_SWIG_DOCS_SOURCE_DEPS} ${tag_deps}
COMMAND ${DOXYGEN_EXECUTABLE} ${OUTPUT_DIRECTORY}/Doxyfile
COMMENT "Generating doxygen xml for ${name} docs"
)
#call the swig_doc script on the xml files
add_custom_command(
OUTPUT ${output_file}
DEPENDS ${input_files} ${OUTPUT_DIRECTORY}/xml/index.xml
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_SOURCE_DIR}/docs/doxygen/swig_doc.py
${OUTPUT_DIRECTORY}/xml
${output_file}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/doxygen
)
else(DOXYGEN_FOUND)
file(WRITE ${output_file} "\n") #no doxygen -> empty file
endif(DOXYGEN_FOUND)
endfunction(GR_SWIG_MAKE_DOCS)
########################################################################
# Build a swig target for the common gnuradio use case. Usage:
# GR_SWIG_MAKE(target ifile ifile ifile...)
#
# Set the following variables before calling:
# - GR_SWIG_FLAGS
# - GR_SWIG_INCLUDE_DIRS
# - GR_SWIG_LIBRARIES
# - GR_SWIG_SOURCE_DEPS
# - GR_SWIG_TARGET_DEPS
# - GR_SWIG_DOC_FILE
# - GR_SWIG_DOC_DIRS
########################################################################
macro(GR_SWIG_MAKE name)
set(ifiles ${ARGN})
#do swig doc generation if specified
if (GR_SWIG_DOC_FILE)
set(GR_SWIG_DOCS_SOURCE_DEPS ${GR_SWIG_SOURCE_DEPS})
set(GR_SWIG_DOCS_TAREGT_DEPS ${GR_SWIG_TARGET_DEPS})
GR_SWIG_MAKE_DOCS(${GR_SWIG_DOC_FILE} ${GR_SWIG_DOC_DIRS})
list(APPEND GR_SWIG_SOURCE_DEPS ${GR_SWIG_DOC_FILE})
endif()
#append additional include directories
find_package(PythonLibs)
list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH}) #deprecated name (now dirs)
list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS})
list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR})
#determine include dependencies for swig file
execute_process(
COMMAND ${PYTHON_EXECUTABLE}
${CMAKE_BINARY_DIR}/get_swig_deps.py
"${ifiles}" "${GR_SWIG_INCLUDE_DIRS}"
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE SWIG_MODULE_${name}_EXTRA_DEPS
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
#Create a dummy custom command that depends on other targets
include(GrMiscUtils)
GR_GEN_TARGET_DEPS(_${name}_swig_tag tag_deps ${GR_SWIG_TARGET_DEPS})
set(tag_file ${CMAKE_CURRENT_BINARY_DIR}/${name}.tag)
add_custom_command(
OUTPUT ${tag_file}
DEPENDS ${GR_SWIG_SOURCE_DEPS} ${tag_deps}
COMMAND ${CMAKE_COMMAND} -E touch ${tag_file}
)
#append the specified include directories
include_directories(${GR_SWIG_INCLUDE_DIRS})
list(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${tag_file})
#setup the swig flags with flags and include directories
set(CMAKE_SWIG_FLAGS -fvirtual -modern -keyword -w511 -module ${name} ${GR_SWIG_FLAGS})
foreach(dir ${GR_SWIG_INCLUDE_DIRS})
list(APPEND CMAKE_SWIG_FLAGS "-I${dir}")
endforeach(dir)
#set the C++ property on the swig .i file so it builds
set_source_files_properties(${ifiles} PROPERTIES CPLUSPLUS ON)
#setup the actual swig library target to be built
include(UseSWIG)
SWIG_ADD_MODULE(${name} python ${ifiles})
SWIG_LINK_LIBRARIES(${name} ${PYTHON_LIBRARIES} ${GR_SWIG_LIBRARIES})
endmacro(GR_SWIG_MAKE)
########################################################################
# Install swig targets generated by GR_SWIG_MAKE. Usage:
# GR_SWIG_INSTALL(
# TARGETS target target target...
# [DESTINATION destination]
# [COMPONENT component]
# )
########################################################################
macro(GR_SWIG_INSTALL)
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_SWIG_INSTALL "" "DESTINATION;COMPONENT" "TARGETS" ${ARGN})
foreach(name ${GR_SWIG_INSTALL_TARGETS})
install(TARGETS ${SWIG_MODULE_${name}_REAL_NAME}
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
COMPONENT ${GR_SWIG_INSTALL_COMPONENT}
)
include(GrPython)
GR_PYTHON_INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}.py
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
COMPONENT ${GR_SWIG_INSTALL_COMPONENT}
)
GR_LIBTOOL(
TARGET ${SWIG_MODULE_${name}_REAL_NAME}
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
)
endforeach(name)
endmacro(GR_SWIG_INSTALL)
########################################################################
# Generate a python file that can determine swig dependencies.
# Used by the make macro above to determine extra dependencies.
# When you build C++, CMake figures out the header dependencies.
# This code essentially performs that logic for swig includes.
########################################################################
file(WRITE ${CMAKE_BINARY_DIR}/get_swig_deps.py "
import os, sys, re
include_matcher = re.compile('[#|%]include\\s*[<|\"](.*)[>|\"]')
include_dirs = sys.argv[2].split(';')
def get_swig_incs(file_path):
file_contents = open(file_path, 'r').read()
return include_matcher.findall(file_contents, re.MULTILINE)
def get_swig_deps(file_path, level):
deps = [file_path]
if level == 0: return deps
for inc_file in get_swig_incs(file_path):
for inc_dir in include_dirs:
inc_path = os.path.join(inc_dir, inc_file)
if not os.path.exists(inc_path): continue
deps.extend(get_swig_deps(inc_path, level-1))
return deps
if __name__ == '__main__':
ifiles = sys.argv[1].split(';')
deps = sum([get_swig_deps(ifile, 3) for ifile in ifiles], [])
#sys.stderr.write(';'.join(set(deps)) + '\\n\\n')
print(';'.join(set(deps)))
")

View File

@ -1,133 +0,0 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_TEST_CMAKE)
return()
endif()
set(__INCLUDED_GR_TEST_CMAKE TRUE)
########################################################################
# Add a unit test and setup the environment for a unit test.
# Takes the same arguments as the ADD_TEST function.
#
# Before calling set the following variables:
# GR_TEST_TARGET_DEPS - built targets for the library path
# GR_TEST_LIBRARY_DIRS - directories for the library path
# GR_TEST_PYTHON_DIRS - directories for the python path
########################################################################
function(GR_ADD_TEST test_name)
if(WIN32)
#Ensure that the build exe also appears in the PATH.
list(APPEND GR_TEST_TARGET_DEPS ${ARGN})
#In the land of windows, all libraries must be in the PATH.
#Since the dependent libraries are not yet installed,
#we must manually set them in the PATH to run tests.
#The following appends the path of a target dependency.
foreach(target ${GR_TEST_TARGET_DEPS})
get_target_property(location ${target} LOCATION)
if(location)
get_filename_component(path ${location} PATH)
string(REGEX REPLACE "\\$\\(.*\\)" ${CMAKE_BUILD_TYPE} path ${path})
list(APPEND GR_TEST_LIBRARY_DIRS ${path})
endif(location)
endforeach(target)
#SWIG generates the python library files into a subdirectory.
#Therefore, we must append this subdirectory into PYTHONPATH.
#Only do this for the python directories matching the following:
foreach(pydir ${GR_TEST_PYTHON_DIRS})
get_filename_component(name ${pydir} NAME)
if(name MATCHES "^(swig|lib|src)$")
list(APPEND GR_TEST_PYTHON_DIRS ${pydir}/${CMAKE_BUILD_TYPE})
endif()
endforeach(pydir)
endif(WIN32)
file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} srcdir)
file(TO_NATIVE_PATH "${GR_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list?
file(TO_NATIVE_PATH "${GR_TEST_PYTHON_DIRS}" pypath) #ok to use on dir list?
set(environs "GR_DONT_LOAD_PREFS=1" "srcdir=${srcdir}")
#http://www.cmake.org/pipermail/cmake/2009-May/029464.html
#Replaced this add test + set environs code with the shell script generation.
#Its nicer to be able to manually run the shell script to diagnose problems.
#ADD_TEST(${ARGV})
#SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}")
if(UNIX)
set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH")
#set both LD and DYLD paths to cover multiple UNIX OS library paths
list(APPEND libpath "$LD_LIBRARY_PATH" "$DYLD_LIBRARY_PATH")
list(APPEND pypath "$PYTHONPATH")
#replace list separator with the path separator
string(REPLACE ";" ":" libpath "${libpath}")
string(REPLACE ";" ":" pypath "${pypath}")
list(APPEND environs "PATH=${binpath}" "LD_LIBRARY_PATH=${libpath}" "DYLD_LIBRARY_PATH=${libpath}" "PYTHONPATH=${pypath}")
#generate a bat file that sets the environment and runs the test
find_program(SHELL sh)
set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh)
file(WRITE ${sh_file} "#!${SHELL}\n")
#each line sets an environment variable
foreach(environ ${environs})
file(APPEND ${sh_file} "export ${environ}\n")
endforeach(environ)
#load the command to run with its arguments
foreach(arg ${ARGN})
file(APPEND ${sh_file} "${arg} ")
endforeach(arg)
file(APPEND ${sh_file} "\n")
#make the shell file executable
execute_process(COMMAND chmod +x ${sh_file})
add_test(${test_name} ${SHELL} ${sh_file})
endif(UNIX)
if(WIN32)
list(APPEND libpath ${DLL_PATHS} "%PATH%")
list(APPEND pypath "%PYTHONPATH%")
#replace list separator with the path separator (escaped)
string(REPLACE ";" "\\;" libpath "${libpath}")
string(REPLACE ";" "\\;" pypath "${pypath}")
list(APPEND environs "PATH=${libpath}" "PYTHONPATH=${pypath}")
#generate a bat file that sets the environment and runs the test
set(bat_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.bat)
file(WRITE ${bat_file} "@echo off\n")
#each line sets an environment variable
foreach(environ ${environs})
file(APPEND ${bat_file} "SET ${environ}\n")
endforeach(environ)
#load the command to run with its arguments
foreach(arg ${ARGN})
file(APPEND ${bat_file} "${arg} ")
endforeach(arg)
file(APPEND ${bat_file} "\n")
add_test(${test_name} ${bat_file})
endif(WIN32)
endfunction(GR_ADD_TEST)

View File

@ -1,35 +0,0 @@
# Copyright 2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
########################################################################
# Setup dependencies
########################################################################
find_package(Doxygen)
########################################################################
# Begin conditional configuration
########################################################################
if(ENABLE_DOXYGEN)
########################################################################
# Add subdirectories
########################################################################
add_subdirectory(doxygen)
endif(ENABLE_DOXYGEN)

View File

@ -1,52 +0,0 @@
# Copyright 2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
########################################################################
# Create the doxygen configuration file
########################################################################
file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} top_srcdir)
file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} top_builddir)
file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} abs_top_srcdir)
file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} abs_top_builddir)
set(HAVE_DOT ${DOXYGEN_DOT_FOUND})
set(enable_html_docs YES)
set(enable_latex_docs NO)
set(enable_xml_docs YES)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in
${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
@ONLY)
set(BUILT_DIRS ${CMAKE_CURRENT_BINARY_DIR}/xml ${CMAKE_CURRENT_BINARY_DIR}/html)
########################################################################
# Make and install doxygen docs
########################################################################
add_custom_command(
OUTPUT ${BUILT_DIRS}
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating documentation with doxygen"
)
add_custom_target(doxygen_target ALL DEPENDS ${BUILT_DIRS})
install(DIRECTORY ${BUILT_DIRS} DESTINATION ${GR_PKG_DOC_DIR})

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
/Makefile
/Makefile.in

View File

@ -1,52 +0,0 @@
#
# Copyright 2007,2009,2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
include $(top_srcdir)/Makefile.common
EXTRA_DIST = \
example/aadvark.cc \
example/aadvark.h \
example/Doxyfile \
example/xml/aadvark_8cc.xml \
example/xml/aadvark_8h.xml \
example/xml/classAadvark.xml \
example/xml/combine.xslt \
example/xml/compound.xsd \
example/xml/index.xml \
example/xml/index.xsd
if PYTHON
utilspythondir = $(grpythondir)/doxyxml
TESTS = \
run_tests
nobase_utilspython_PYTHON = \
__init__.py \
base.py \
doxyindex.py \
text.py \
generated/__init__.py \
generated/index.py \
generated/indexsuper.py \
generated/compound.py \
generated/compoundsuper.py
endif

View File

@ -1,82 +0,0 @@
#
# Copyright 2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""
Python interface to contents of doxygen xml documentation.
Example use:
See the contents of the example folder for the C++ and
doxygen-generated xml used in this example.
>>> # Parse the doxygen docs.
>>> import os
>>> this_dir = os.path.dirname(globals()['__file__'])
>>> xml_path = this_dir + "/example/xml/"
>>> di = DoxyIndex(xml_path)
Get a list of all top-level objects.
>>> print([mem.name() for mem in di.members()])
[u'Aadvark', u'aadvarky_enough', u'main']
Get all functions.
>>> print([mem.name() for mem in di.in_category(DoxyFunction)])
[u'aadvarky_enough', u'main']
Check if an object is present.
>>> di.has_member(u'Aadvark')
True
>>> di.has_member(u'Fish')
False
Get an item by name and check its properties.
>>> aad = di.get_member(u'Aadvark')
>>> print(aad.brief_description)
Models the mammal Aadvark.
>>> print(aad.detailed_description)
Sadly the model is incomplete and cannot capture all aspects of an aadvark yet.
<BLANKLINE>
This line is uninformative and is only to test line breaks in the comments.
>>> [mem.name() for mem in aad.members()]
[u'aadvarkness', u'print', u'Aadvark', u'get_aadvarkness']
>>> aad.get_member(u'print').brief_description
u'Outputs the vital aadvark statistics.'
"""
from doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther
def _test():
import os
this_dir = os.path.dirname(globals()['__file__'])
xml_path = this_dir + "/example/xml/"
di = DoxyIndex(xml_path)
# Get the Aadvark class
aad = di.get_member('Aadvark')
aad.brief_description
import doctest
return doctest.testmod()
if __name__ == "__main__":
_test()

View File

@ -1,219 +0,0 @@
#
# Copyright 2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""
A base class is created.
Classes based upon this are used to make more user-friendly interfaces
to the doxygen xml docs than the generated classes provide.
"""
import os
import pdb
from xml.parsers.expat import ExpatError
from generated import compound
class Base(object):
class Duplicate(StandardError):
pass
class NoSuchMember(StandardError):
pass
class ParsingError(StandardError):
pass
def __init__(self, parse_data, top=None):
self._parsed = False
self._error = False
self._parse_data = parse_data
self._members = []
self._dict_members = {}
self._in_category = {}
self._data = {}
if top is not None:
self._xml_path = top._xml_path
# Set up holder of references
else:
top = self
self._refs = {}
self._xml_path = parse_data
self.top = top
@classmethod
def from_refid(cls, refid, top=None):
""" Instantiate class from a refid rather than parsing object. """
# First check to see if its already been instantiated.
if top is not None and refid in top._refs:
return top._refs[refid]
# Otherwise create a new instance and set refid.
inst = cls(None, top=top)
inst.refid = refid
inst.add_ref(inst)
return inst
@classmethod
def from_parse_data(cls, parse_data, top=None):
refid = getattr(parse_data, 'refid', None)
if refid is not None and top is not None and refid in top._refs:
return top._refs[refid]
inst = cls(parse_data, top=top)
if refid is not None:
inst.refid = refid
inst.add_ref(inst)
return inst
def add_ref(self, obj):
if hasattr(obj, 'refid'):
self.top._refs[obj.refid] = obj
mem_classes = []
def get_cls(self, mem):
for cls in self.mem_classes:
if cls.can_parse(mem):
return cls
raise StandardError(("Did not find a class for object '%s'." \
% (mem.get_name())))
def convert_mem(self, mem):
try:
cls = self.get_cls(mem)
converted = cls.from_parse_data(mem, self.top)
if converted is None:
raise StandardError('No class matched this object.')
self.add_ref(converted)
return converted
except StandardError, e:
print e
@classmethod
def includes(cls, inst):
return isinstance(inst, cls)
@classmethod
def can_parse(cls, obj):
return False
def _parse(self):
self._parsed = True
def _get_dict_members(self, cat=None):
"""
For given category a dictionary is returned mapping member names to
members of that category. For names that are duplicated the name is
mapped to None.
"""
self.confirm_no_error()
if cat not in self._dict_members:
new_dict = {}
for mem in self.in_category(cat):
if mem.name() not in new_dict:
new_dict[mem.name()] = mem
else:
new_dict[mem.name()] = self.Duplicate
self._dict_members[cat] = new_dict
return self._dict_members[cat]
def in_category(self, cat):
self.confirm_no_error()
if cat is None:
return self._members
if cat not in self._in_category:
self._in_category[cat] = [mem for mem in self._members
if cat.includes(mem)]
return self._in_category[cat]
def get_member(self, name, cat=None):
self.confirm_no_error()
# Check if it's in a namespace or class.
bits = name.split('::')
first = bits[0]
rest = '::'.join(bits[1:])
member = self._get_dict_members(cat).get(first, self.NoSuchMember)
# Raise any errors that are returned.
if member in set([self.NoSuchMember, self.Duplicate]):
raise member()
if rest:
return member.get_member(rest, cat=cat)
return member
def has_member(self, name, cat=None):
try:
mem = self.get_member(name, cat=cat)
return True
except self.NoSuchMember:
return False
def data(self):
self.confirm_no_error()
return self._data
def members(self):
self.confirm_no_error()
return self._members
def process_memberdefs(self):
mdtss = []
for sec in self._retrieved_data.compounddef.sectiondef:
mdtss += sec.memberdef
# At the moment we lose all information associated with sections.
# Sometimes a memberdef is in several sectiondef.
# We make sure we don't get duplicates here.
uniques = set([])
for mem in mdtss:
converted = self.convert_mem(mem)
pair = (mem.name, mem.__class__)
if pair not in uniques:
uniques.add(pair)
self._members.append(converted)
def retrieve_data(self):
filename = os.path.join(self._xml_path, self.refid + '.xml')
try:
self._retrieved_data = compound.parse(filename)
except ExpatError:
print('Error in xml in file %s' % filename)
self._error = True
self._retrieved_data = None
def check_parsed(self):
if not self._parsed:
self._parse()
def confirm_no_error(self):
self.check_parsed()
if self._error:
raise self.ParsingError()
def error(self):
self.check_parsed()
return self._error
def name(self):
# first see if we can do it without processing.
if self._parse_data is not None:
return self._parse_data.name
self.check_parsed()
return self._retrieved_data.compounddef.name

View File

@ -1,237 +0,0 @@
#
# Copyright 2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""
Classes providing more user-friendly interfaces to the doxygen xml
docs than the generated classes provide.
"""
import os
from generated import index
from base import Base
from text import description
class DoxyIndex(Base):
"""
Parses a doxygen xml directory.
"""
__module__ = "gnuradio.utils.doxyxml"
def _parse(self):
if self._parsed:
return
super(DoxyIndex, self)._parse()
self._root = index.parse(os.path.join(self._xml_path, 'index.xml'))
for mem in self._root.compound:
converted = self.convert_mem(mem)
# For files we want the contents to be accessible directly
# from the parent rather than having to go through the file
# object.
if self.get_cls(mem) == DoxyFile:
if mem.name.endswith('.h'):
self._members += converted.members()
self._members.append(converted)
else:
self._members.append(converted)
def generate_swig_doc_i(self):
"""
%feature("docstring") gr_make_align_on_samplenumbers_ss::align_state "
Wraps the C++: gr_align_on_samplenumbers_ss::align_state";
"""
pass
class DoxyCompMem(Base):
kind = None
def __init__(self, *args, **kwargs):
super(DoxyCompMem, self).__init__(*args, **kwargs)
@classmethod
def can_parse(cls, obj):
return obj.kind == cls.kind
def set_descriptions(self, parse_data):
bd = description(getattr(parse_data, 'briefdescription', None))
dd = description(getattr(parse_data, 'detaileddescription', None))
self._data['brief_description'] = bd
self._data['detailed_description'] = dd
class DoxyCompound(DoxyCompMem):
pass
class DoxyMember(DoxyCompMem):
pass
class DoxyFunction(DoxyMember):
__module__ = "gnuradio.utils.doxyxml"
kind = 'function'
def _parse(self):
if self._parsed:
return
super(DoxyFunction, self)._parse()
self.set_descriptions(self._parse_data)
self._data['params'] = []
prms = self._parse_data.param
for prm in prms:
self._data['params'].append(DoxyParam(prm))
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
params = property(lambda self: self.data()['params'])
Base.mem_classes.append(DoxyFunction)
class DoxyParam(DoxyMember):
__module__ = "gnuradio.utils.doxyxml"
def _parse(self):
if self._parsed:
return
super(DoxyParam, self)._parse()
self.set_descriptions(self._parse_data)
self._data['declname'] = self._parse_data.declname
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
declname = property(lambda self: self.data()['declname'])
class DoxyClass(DoxyCompound):
__module__ = "gnuradio.utils.doxyxml"
kind = 'class'
def _parse(self):
if self._parsed:
return
super(DoxyClass, self)._parse()
self.retrieve_data()
if self._error:
return
self.set_descriptions(self._retrieved_data.compounddef)
# Sectiondef.kind tells about whether private or public.
# We just ignore this for now.
self.process_memberdefs()
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
Base.mem_classes.append(DoxyClass)
class DoxyFile(DoxyCompound):
__module__ = "gnuradio.utils.doxyxml"
kind = 'file'
def _parse(self):
if self._parsed:
return
super(DoxyFile, self)._parse()
self.retrieve_data()
self.set_descriptions(self._retrieved_data.compounddef)
if self._error:
return
self.process_memberdefs()
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
Base.mem_classes.append(DoxyFile)
class DoxyNamespace(DoxyCompound):
__module__ = "gnuradio.utils.doxyxml"
kind = 'namespace'
Base.mem_classes.append(DoxyNamespace)
class DoxyGroup(DoxyCompound):
__module__ = "gnuradio.utils.doxyxml"
kind = 'group'
def _parse(self):
if self._parsed:
return
super(DoxyGroup, self)._parse()
self.retrieve_data()
if self._error:
return
cdef = self._retrieved_data.compounddef
self._data['title'] = description(cdef.title)
# Process inner groups
grps = cdef.innergroup
for grp in grps:
converted = DoxyGroup.from_refid(grp.refid, top=self.top)
self._members.append(converted)
# Process inner classes
klasses = cdef.innerclass
for kls in klasses:
converted = DoxyClass.from_refid(kls.refid, top=self.top)
self._members.append(converted)
# Process normal members
self.process_memberdefs()
title = property(lambda self: self.data()['title'])
Base.mem_classes.append(DoxyGroup)
class DoxyFriend(DoxyMember):
__module__ = "gnuradio.utils.doxyxml"
kind = 'friend'
Base.mem_classes.append(DoxyFriend)
class DoxyOther(Base):
__module__ = "gnuradio.utils.doxyxml"
kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum', 'dir', 'page'])
@classmethod
def can_parse(cls, obj):
return obj.kind in cls.kinds
Base.mem_classes.append(DoxyOther)

View File

@ -1,50 +0,0 @@
/* -*- c++ -*- */
/*
* Copyright 2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <iostream>
#include "aadvark.h"
void Aadvark::print() {
std::cout << "aadvark is " << aadvarkness << "/10 aadvarky" << std::endl;
}
Aadvark::Aadvark(int aaness): aadvarkness(aaness) {}
bool aadvarky_enough(Aadvark aad) {
if (aad.get_aadvarkness() > 6)
return true;
else
return false;
}
int Aadvark::get_aadvarkness() {
return aadvarkness;
}
int main() {
Aadvark arold = Aadvark(6);
arold.print();
if (aadvarky_enough(arold))
std::cout << "He is aadvarky enough" << std::endl;
else
std::cout << "He is not aadvarky enough" << std::endl;
}

View File

@ -1,44 +0,0 @@
/* -*- c++ -*- */
/*
* Copyright 2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <iostream>
/*!
* \brief Models the mammal Aadvark.
*
* Sadly the model is incomplete and cannot capture all aspects of an aadvark yet.
*
* This line is uninformative and is only to test line breaks in the comments.
*/
class Aadvark {
public:
//! \brief Outputs the vital aadvark statistics.
void print();
//! \param aaness The aadvarkness of an aadvark is a measure of how aadvarky it is.
Aadvark(int aaness);
int get_aadvarkness();
private:
int aadvarkness;
};
bool aadvarky_enough(Aadvark aad);
int main();

View File

@ -1,88 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.6.3">
<compounddef id="aadvark_8cc" kind="file">
<compoundname>aadvark.cc</compoundname>
<includes local="no">iostream</includes>
<includes refid="aadvark_8cc" local="yes">aadvark.h</includes>
<includedby refid="aadvark_8cc" local="yes">aadvark.cc</includedby>
<incdepgraph>
<node id="0">
<label>aadvark.cc</label>
<link refid="aadvark.cc"/>
<childnode refid="1" relation="include">
</childnode>
</node>
<node id="1">
<label>iostream</label>
</node>
</incdepgraph>
<sectiondef kind="func">
<memberdef kind="function" id="aadvark_8cc_1acb52858524210ec6dddc3e16d1e52946" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type>bool</type>
<definition>bool aadvarky_enough</definition>
<argsstring>(Aadvark aad)</argsstring>
<name>aadvarky_enough</name>
<param>
<type><ref refid="classAadvark" kindref="compound">Aadvark</ref></type>
<declname>aad</declname>
</param>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" line="10" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="10" bodyend="15"/>
</memberdef>
<memberdef kind="function" id="aadvark_8cc_1ae66f6b31b5ad750f1fe042a706a4e3d4" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type>int</type>
<definition>int main</definition>
<argsstring>()</argsstring>
<name>main</name>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" line="21" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="21" bodyend="28"/>
</memberdef>
</sectiondef>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<programlisting>
<codeline lineno="1"><highlight class="preprocessor">#include<sp/>&lt;iostream&gt;</highlight><highlight class="normal"></highlight></codeline>
<codeline lineno="2"><highlight class="normal"></highlight><highlight class="preprocessor">#include<sp/>&quot;aadvark.h&quot;</highlight><highlight class="normal"></highlight></codeline>
<codeline lineno="3"><highlight class="normal"></highlight></codeline>
<codeline lineno="4"><highlight class="normal"></highlight><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/><ref refid="classAadvark_1abd061aa5f998002e72080a34f512a059" kindref="member" tooltip="Outputs the vital aadvark statistics.">Aadvark::print</ref>()<sp/>{</highlight></codeline>
<codeline lineno="5"><highlight class="normal"><sp/><sp/>std::cout<sp/>&lt;&lt;<sp/></highlight><highlight class="stringliteral">&quot;aadvark<sp/>is<sp/>&quot;</highlight><highlight class="normal"><sp/>&lt;&lt;<sp/>aadvarkness<sp/>&lt;&lt;<sp/></highlight><highlight class="stringliteral">&quot;/10<sp/>aadvarky&quot;</highlight><highlight class="normal"><sp/>&lt;&lt;<sp/>std::endl;</highlight></codeline>
<codeline lineno="6"><highlight class="normal">}</highlight></codeline>
<codeline lineno="7"><highlight class="normal"></highlight></codeline>
<codeline lineno="8"><highlight class="normal"><ref refid="classAadvark_1adf1a4b97a641411a74a04ab312484462" kindref="member">Aadvark::Aadvark</ref>(</highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>aaness):<sp/>aadvarkness(aaness)<sp/>{}</highlight></codeline>
<codeline lineno="9"><highlight class="normal"></highlight></codeline>
<codeline lineno="10"><highlight class="normal"></highlight><highlight class="keywordtype">bool</highlight><highlight class="normal"><sp/>aadvarky_enough(<ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref><sp/>aad)<sp/>{</highlight></codeline>
<codeline lineno="11"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">if</highlight><highlight class="normal"><sp/>(aad.get_aadvarkness()<sp/>&gt;<sp/>6)</highlight></codeline>
<codeline lineno="12"><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/></highlight><highlight class="keyword">true</highlight><highlight class="normal">;</highlight></codeline>
<codeline lineno="13"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">else</highlight><highlight class="normal"></highlight></codeline>
<codeline lineno="14"><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/></highlight><highlight class="keyword">false</highlight><highlight class="normal">;</highlight></codeline>
<codeline lineno="15"><highlight class="normal">}</highlight></codeline>
<codeline lineno="16"><highlight class="normal"></highlight></codeline>
<codeline lineno="17"><highlight class="normal"></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>Aadvark::get_aadvarkness()<sp/>{</highlight></codeline>
<codeline lineno="18"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/>aadvarkness;</highlight></codeline>
<codeline lineno="19"><highlight class="normal">}</highlight></codeline>
<codeline lineno="20"><highlight class="normal"></highlight></codeline>
<codeline lineno="21"><highlight class="normal"></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>main()<sp/>{</highlight></codeline>
<codeline lineno="22"><highlight class="normal"><sp/><sp/><ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref><sp/>arold<sp/>=<sp/><ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref>(6);</highlight></codeline>
<codeline lineno="23"><highlight class="normal"><sp/><sp/>arold.<ref refid="classAadvark_1abd061aa5f998002e72080a34f512a059" kindref="member" tooltip="Outputs the vital aadvark statistics.">print</ref>();</highlight></codeline>
<codeline lineno="24"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">if</highlight><highlight class="normal"><sp/>(aadvarky_enough(arold))</highlight></codeline>
<codeline lineno="25"><highlight class="normal"><sp/><sp/><sp/><sp/>std::cout<sp/>&lt;&lt;<sp/></highlight><highlight class="stringliteral">&quot;He<sp/>is<sp/>aadvarky<sp/>enough&quot;</highlight><highlight class="normal"><sp/>&lt;&lt;<sp/>std::endl;</highlight></codeline>
<codeline lineno="26"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">else</highlight><highlight class="normal"></highlight></codeline>
<codeline lineno="27"><highlight class="normal"><sp/><sp/><sp/><sp/>std::cout<sp/>&lt;&lt;<sp/></highlight><highlight class="stringliteral">&quot;He<sp/>is<sp/>not<sp/>aadvarky<sp/>enough&quot;</highlight><highlight class="normal"><sp/>&lt;&lt;<sp/>std::endl;</highlight></codeline>
<codeline lineno="28"><highlight class="normal">}</highlight></codeline>
<codeline lineno="29"><highlight class="normal"></highlight></codeline>
</programlisting>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc"/>
</compounddef>
</doxygen>

View File

@ -1,72 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.6.3">
<compounddef id="aadvark_8h" kind="file">
<compoundname>aadvark.h</compoundname>
<includes local="no">iostream</includes>
<incdepgraph>
<node id="3">
<label>aadvark.h</label>
<link refid="aadvark.h"/>
<childnode refid="4" relation="include">
</childnode>
</node>
<node id="4">
<label>iostream</label>
</node>
</incdepgraph>
<innerclass refid="classAadvark" prot="public">Aadvark</innerclass>
<sectiondef kind="func">
<memberdef kind="function" id="aadvark_8h_1acb52858524210ec6dddc3e16d1e52946" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type>bool</type>
<definition>bool aadvarky_enough</definition>
<argsstring>(Aadvark aad)</argsstring>
<name>aadvarky_enough</name>
<param>
<type><ref refid="classAadvark" kindref="compound">Aadvark</ref></type>
<declname>aad</declname>
</param>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="21" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="10" bodyend="15"/>
</memberdef>
<memberdef kind="function" id="aadvark_8h_1ae66f6b31b5ad750f1fe042a706a4e3d4" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type>int</type>
<definition>int main</definition>
<argsstring>()</argsstring>
<name>main</name>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="23" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="21" bodyend="28"/>
</memberdef>
</sectiondef>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<programlisting>
<codeline lineno="1"><highlight class="preprocessor">#include<sp/>&lt;iostream&gt;</highlight><highlight class="normal"></highlight></codeline>
<codeline lineno="2"><highlight class="normal"></highlight></codeline>
<codeline lineno="10" refid="classAadvark" refkind="compound"><highlight class="keyword">class<sp/></highlight><highlight class="normal"><ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref><sp/>{</highlight></codeline>
<codeline lineno="11"><highlight class="normal"></highlight><highlight class="keyword">public</highlight><highlight class="normal">:</highlight></codeline>
<codeline lineno="13"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/><ref refid="classAadvark_1abd061aa5f998002e72080a34f512a059" kindref="member" tooltip="Outputs the vital aadvark statistics.">print</ref>();</highlight></codeline>
<codeline lineno="15"><highlight class="normal"><sp/><sp/><ref refid="classAadvark_1adf1a4b97a641411a74a04ab312484462" kindref="member">Aadvark</ref>(</highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>aaness);</highlight></codeline>
<codeline lineno="16"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>get_aadvarkness();</highlight></codeline>
<codeline lineno="17"><highlight class="normal"></highlight><highlight class="keyword">private</highlight><highlight class="normal">:</highlight></codeline>
<codeline lineno="18"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>aadvarkness;</highlight></codeline>
<codeline lineno="19"><highlight class="normal">};</highlight></codeline>
<codeline lineno="20"><highlight class="normal"></highlight></codeline>
<codeline lineno="21"><highlight class="normal"></highlight><highlight class="keywordtype">bool</highlight><highlight class="normal"><sp/>aadvarky_enough(<ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref><sp/>aad);</highlight></codeline>
<codeline lineno="22"><highlight class="normal"></highlight></codeline>
<codeline lineno="23"><highlight class="normal"></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>main();</highlight></codeline>
</programlisting>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h"/>
</compounddef>
</doxygen>

View File

@ -1,86 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.6.3">
<compounddef id="classAadvark" kind="class" prot="public">
<compoundname>Aadvark</compoundname>
<includes refid="aadvark_8h" local="no">aadvark.h</includes>
<sectiondef kind="private-attrib">
<memberdef kind="variable" id="classAadvark_1ab79eb58d7bb9d5ddfa5d6f783836cab9" prot="private" static="no" mutable="no">
<type>int</type>
<definition>int Aadvark::aadvarkness</definition>
<argsstring></argsstring>
<name>aadvarkness</name>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="18" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" bodystart="18" bodyend="-1"/>
</memberdef>
</sectiondef>
<sectiondef kind="public-func">
<memberdef kind="function" id="classAadvark_1abd061aa5f998002e72080a34f512a059" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type>void</type>
<definition>void Aadvark::print</definition>
<argsstring>()</argsstring>
<name>print</name>
<briefdescription>
<para>Outputs the vital aadvark statistics. </para> </briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="13" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="4" bodyend="6"/>
</memberdef>
<memberdef kind="function" id="classAadvark_1adf1a4b97a641411a74a04ab312484462" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type></type>
<definition>Aadvark::Aadvark</definition>
<argsstring>(int aaness)</argsstring>
<name>Aadvark</name>
<param>
<type>int</type>
<declname>aaness</declname>
</param>
<briefdescription>
</briefdescription>
<detaileddescription>
<para><parameterlist kind="param"><parameteritem>
<parameternamelist>
<parametername>aaness</parametername>
</parameternamelist>
<parameterdescription>
<para>The aadvarkness of an aadvark is a measure of how aadvarky it is. </para></parameterdescription>
</parameteritem>
</parameterlist>
</para> </detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="15" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="8" bodyend="8"/>
</memberdef>
<memberdef kind="function" id="classAadvark_1affd2ada0a85807efcbe26615a848f53e" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type>int</type>
<definition>int Aadvark::get_aadvarkness</definition>
<argsstring>()</argsstring>
<name>get_aadvarkness</name>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="16" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="17" bodyend="19"/>
</memberdef>
</sectiondef>
<briefdescription>
<para>Models the mammal <ref refid="classAadvark" kindref="compound">Aadvark</ref>. </para> </briefdescription>
<detaileddescription>
<para>Sadly the model is incomplete and cannot capture all aspects of an aadvark yet.</para><para>This line is uninformative and is only to test line breaks in the comments. </para> </detaileddescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="10" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" bodystart="10" bodyend="19"/>
<listofallmembers>
<member refid="classAadvark_1adf1a4b97a641411a74a04ab312484462" prot="public" virt="non-virtual"><scope>Aadvark</scope><name>Aadvark</name></member>
<member refid="classAadvark_1ab79eb58d7bb9d5ddfa5d6f783836cab9" prot="private" virt="non-virtual"><scope>Aadvark</scope><name>aadvarkness</name></member>
<member refid="classAadvark_1affd2ada0a85807efcbe26615a848f53e" prot="public" virt="non-virtual"><scope>Aadvark</scope><name>get_aadvarkness</name></member>
<member refid="classAadvark_1abd061aa5f998002e72080a34f512a059" prot="public" virt="non-virtual"><scope>Aadvark</scope><name>print</name></member>
</listofallmembers>
</compounddef>
</doxygen>

View File

@ -1,15 +0,0 @@
<!-- XSLT script to combine the generated output into a single file.
If you have xsltproc you could use:
xsltproc combine.xslt index.xml >all.xml
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" indent="yes" standalone="yes" />
<xsl:template match="/">
<doxygen version="{doxygenindex/@version}">
<!-- Load all doxgen generated xml files -->
<xsl:for-each select="doxygenindex/compound">
<xsl:copy-of select="document( concat( @refid, '.xml' ) )/doxygen/*" />
</xsl:for-each>
</doxygen>
</xsl:template>
</xsl:stylesheet>

View File

@ -1,814 +0,0 @@
<?xml version='1.0' encoding='utf-8' ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="doxygen" type="DoxygenType"/>
<!-- Complex types -->
<xsd:complexType name="DoxygenType">
<xsd:sequence maxOccurs="unbounded">
<xsd:element name="compounddef" type="compounddefType" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="version" type="DoxVersionNumber" use="required" />
</xsd:complexType>
<xsd:complexType name="compounddefType">
<xsd:sequence>
<xsd:element name="compoundname" type="xsd:string"/>
<xsd:element name="title" type="xsd:string" minOccurs="0" />
<xsd:element name="basecompoundref" type="compoundRefType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="derivedcompoundref" type="compoundRefType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="includes" type="incType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="includedby" type="incType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="incdepgraph" type="graphType" minOccurs="0" />
<xsd:element name="invincdepgraph" type="graphType" minOccurs="0" />
<xsd:element name="innerdir" type="refType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="innerfile" type="refType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="innerclass" type="refType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="innernamespace" type="refType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="innerpage" type="refType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="innergroup" type="refType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="templateparamlist" type="templateparamlistType" minOccurs="0" />
<xsd:element name="sectiondef" type="sectiondefType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
<xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
<xsd:element name="inheritancegraph" type="graphType" minOccurs="0" />
<xsd:element name="collaborationgraph" type="graphType" minOccurs="0" />
<xsd:element name="programlisting" type="listingType" minOccurs="0" />
<xsd:element name="location" type="locationType" minOccurs="0" />
<xsd:element name="listofallmembers" type="listofallmembersType" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="kind" type="DoxCompoundKind" />
<xsd:attribute name="prot" type="DoxProtectionKind" />
</xsd:complexType>
<xsd:complexType name="listofallmembersType">
<xsd:sequence>
<xsd:element name="member" type="memberRefType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="memberRefType">
<xsd:sequence>
<xsd:element name="scope" />
<xsd:element name="name" />
</xsd:sequence>
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="prot" type="DoxProtectionKind" />
<xsd:attribute name="virt" type="DoxVirtualKind" />
<xsd:attribute name="ambiguityscope" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="compoundRefType" mixed="true">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="refid" type="xsd:string" use="optional" />
<xsd:attribute name="prot" type="DoxProtectionKind" />
<xsd:attribute name="virt" type="DoxVirtualKind" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="reimplementType" mixed="true">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="refid" type="xsd:string" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="incType" mixed="true">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="local" type="DoxBool" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="refType" mixed="true">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="prot" type="DoxProtectionKind" use="optional"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="refTextType" mixed="true">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="kindref" type="DoxRefKind" />
<xsd:attribute name="external" type="xsd:string" use="optional"/>
<xsd:attribute name="tooltip" type="xsd:string" use="optional"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="sectiondefType">
<xsd:sequence>
<xsd:element name="header" type="xsd:string" minOccurs="0" />
<xsd:element name="description" type="descriptionType" minOccurs="0" />
<xsd:element name="memberdef" type="memberdefType" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="kind" type="DoxSectionKind" />
</xsd:complexType>
<xsd:complexType name="memberdefType">
<xsd:sequence>
<xsd:element name="templateparamlist" type="templateparamlistType" minOccurs="0" />
<xsd:element name="type" type="linkedTextType" minOccurs="0" />
<xsd:element name="definition" minOccurs="0" />
<xsd:element name="argsstring" minOccurs="0" />
<xsd:element name="name" />
<xsd:element name="read" minOccurs="0" />
<xsd:element name="write" minOccurs="0" />
<xsd:element name="bitfield" minOccurs="0" />
<xsd:element name="reimplements" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="reimplementedby" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="enumvalue" type="enumvalueType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="initializer" type="linkedTextType" minOccurs="0" />
<xsd:element name="exceptions" type="linkedTextType" minOccurs="0" />
<xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
<xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
<xsd:element name="inbodydescription" type="descriptionType" minOccurs="0" />
<xsd:element name="location" type="locationType" />
<xsd:element name="references" type="referenceType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="referencedby" type="referenceType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="kind" type="DoxMemberKind" />
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="prot" type="DoxProtectionKind" />
<xsd:attribute name="static" type="DoxBool" />
<xsd:attribute name="const" type="DoxBool" />
<xsd:attribute name="explicit" type="DoxBool" />
<xsd:attribute name="inline" type="DoxBool" />
<xsd:attribute name="virt" type="DoxVirtualKind" />
<xsd:attribute name="volatile" type="DoxBool" />
<xsd:attribute name="mutable" type="DoxBool" />
<!-- Qt property -->
<xsd:attribute name="readable" type="DoxBool" use="optional"/>
<xsd:attribute name="writable" type="DoxBool" use="optional"/>
<!-- C++/CLI variable -->
<xsd:attribute name="initonly" type="DoxBool" use="optional"/>
<!-- C++/CLI and C# property -->
<xsd:attribute name="settable" type="DoxBool" use="optional"/>
<xsd:attribute name="gettable" type="DoxBool" use="optional"/>
<!-- C++/CLI function -->
<xsd:attribute name="final" type="DoxBool" use="optional"/>
<xsd:attribute name="sealed" type="DoxBool" use="optional"/>
<xsd:attribute name="new" type="DoxBool" use="optional"/>
<!-- C++/CLI event -->
<xsd:attribute name="add" type="DoxBool" use="optional"/>
<xsd:attribute name="remove" type="DoxBool" use="optional"/>
<xsd:attribute name="raise" type="DoxBool" use="optional"/>
<!-- Objective-C 2.0 protocol method -->
<xsd:attribute name="optional" type="DoxBool" use="optional"/>
<xsd:attribute name="required" type="DoxBool" use="optional"/>
<!-- Objective-C 2.0 property accessor -->
<xsd:attribute name="accessor" type="DoxAccessor" use="optional"/>
</xsd:complexType>
<xsd:complexType name="descriptionType" mixed="true">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" minOccurs="0"/>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="internal" type="docInternalType" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="enumvalueType" mixed="true">
<xsd:sequence>
<xsd:element name="name" />
<xsd:element name="initializer" type="linkedTextType" minOccurs="0" />
<xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
<xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="prot" type="DoxProtectionKind" />
</xsd:complexType>
<xsd:complexType name="templateparamlistType">
<xsd:sequence>
<xsd:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="paramType">
<xsd:sequence>
<xsd:element name="type" type="linkedTextType" minOccurs="0" />
<xsd:element name="declname" minOccurs="0" />
<xsd:element name="defname" minOccurs="0" />
<xsd:element name="array" minOccurs="0" />
<xsd:element name="defval" type="linkedTextType" minOccurs="0" />
<xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="linkedTextType" mixed="true">
<xsd:sequence>
<xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="graphType">
<xsd:sequence>
<xsd:element name="node" type="nodeType" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="nodeType">
<xsd:sequence>
<xsd:element name="label" />
<xsd:element name="link" type="linkType" minOccurs="0" />
<xsd:element name="childnode" type="childnodeType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="childnodeType">
<xsd:sequence>
<xsd:element name="edgelabel" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="relation" type="DoxGraphRelation" />
</xsd:complexType>
<xsd:complexType name="linkType">
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="external" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:complexType name="listingType">
<xsd:sequence>
<xsd:element name="codeline" type="codelineType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="codelineType">
<xsd:sequence>
<xsd:element name="highlight" type="highlightType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="lineno" type="xsd:integer" />
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="refkind" type="DoxRefKind" />
<xsd:attribute name="external" type="DoxBool" />
</xsd:complexType>
<xsd:complexType name="highlightType" mixed="true">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="sp" />
<xsd:element name="ref" type="refTextType" />
</xsd:choice>
<xsd:attribute name="class" type="DoxHighlightClass" />
</xsd:complexType>
<xsd:complexType name="referenceType" mixed="true">
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="compoundref" type="xsd:string" use="optional" />
<xsd:attribute name="startline" type="xsd:integer" />
<xsd:attribute name="endline" type="xsd:integer" />
</xsd:complexType>
<xsd:complexType name="locationType">
<xsd:attribute name="file" type="xsd:string" />
<xsd:attribute name="line" type="xsd:integer" />
<xsd:attribute name="bodyfile" type="xsd:string" />
<xsd:attribute name="bodystart" type="xsd:integer" />
<xsd:attribute name="bodyend" type="xsd:integer" />
</xsd:complexType>
<xsd:complexType name="docSect1Type" mixed="true">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" />
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="internal" type="docInternalS1Type" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docSect2Type" mixed="true">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" />
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="internal" type="docInternalS2Type" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docSect3Type" mixed="true">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" />
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect4" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="internal" type="docInternalS3Type" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docSect4Type" mixed="true">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" />
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="internal" type="docInternalS4Type" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docInternalType" mixed="true">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docInternalS1Type" mixed="true">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docInternalS2Type" mixed="true">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docInternalS3Type" mixed="true">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect3" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docInternalS4Type" mixed="true">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:group name="docTitleCmdGroup">
<xsd:choice>
<xsd:element name="ulink" type="docURLLink" />
<xsd:element name="bold" type="docMarkupType" />
<xsd:element name="emphasis" type="docMarkupType" />
<xsd:element name="computeroutput" type="docMarkupType" />
<xsd:element name="subscript" type="docMarkupType" />
<xsd:element name="superscript" type="docMarkupType" />
<xsd:element name="center" type="docMarkupType" />
<xsd:element name="small" type="docMarkupType" />
<xsd:element name="htmlonly" type="xsd:string" />
<xsd:element name="latexonly" type="xsd:string" />
<xsd:element name="dot" type="xsd:string" />
<xsd:element name="anchor" type="docAnchorType" />
<xsd:element name="formula" type="docFormulaType" />
<xsd:element name="ref" type="docRefTextType" />
<xsd:element name="copy" type="docEmptyType" />
<xsd:element name="trademark" type="docEmptyType" />
<xsd:element name="registered" type="docEmptyType" />
<xsd:element name="lsquo" type="docEmptyType" />
<xsd:element name="rsquo" type="docEmptyType" />
<xsd:element name="ldquo" type="docEmptyType" />
<xsd:element name="rdquo" type="docEmptyType" />
<xsd:element name="ndash" type="docEmptyType" />
<xsd:element name="mdash" type="docEmptyType" />
<xsd:element name="umlaut" type="docCharType" />
<xsd:element name="acute" type="docCharType" />
<xsd:element name="grave" type="docCharType" />
<xsd:element name="circ" type="docCharType" />
<xsd:element name="slash" type="docCharType" />
<xsd:element name="tilde" type="docCharType" />
<xsd:element name="cedil" type="docCharType" />
<xsd:element name="ring" type="docCharType" />
<xsd:element name="szlig" type="docEmptyType" />
<xsd:element name="nonbreakablespace" type="docEmptyType" />
</xsd:choice>
</xsd:group>
<xsd:complexType name="docTitleType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
</xsd:complexType>
<xsd:group name="docCmdGroup">
<xsd:choice>
<xsd:group ref="docTitleCmdGroup"/>
<xsd:element name="linebreak" type="docEmptyType" />
<xsd:element name="hruler" type="docEmptyType" />
<xsd:element name="preformatted" type="docMarkupType" />
<xsd:element name="programlisting" type="listingType" />
<xsd:element name="verbatim" type="xsd:string" />
<xsd:element name="indexentry" type="docIndexEntryType" />
<xsd:element name="orderedlist" type="docListType" />
<xsd:element name="itemizedlist" type="docListType" />
<xsd:element name="simplesect" type="docSimpleSectType" />
<xsd:element name="title" type="docTitleType" />
<xsd:element name="variablelist" type="docVariableListType" />
<xsd:element name="table" type="docTableType" />
<xsd:element name="heading" type="docHeadingType" />
<xsd:element name="image" type="docImageType" />
<xsd:element name="dotfile" type="docDotFileType" />
<xsd:element name="toclist" type="docTocListType" />
<xsd:element name="language" type="docLanguageType" />
<xsd:element name="parameterlist" type="docParamListType" />
<xsd:element name="xrefsect" type="docXRefSectType" />
<xsd:element name="copydoc" type="docCopyType" />
</xsd:choice>
</xsd:group>
<xsd:complexType name="docParaType" mixed="true">
<xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" />
</xsd:complexType>
<xsd:complexType name="docMarkupType" mixed="true">
<xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" />
</xsd:complexType>
<xsd:complexType name="docURLLink" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="url" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docAnchorType" mixed="true">
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docFormulaType" mixed="true">
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docIndexEntryType">
<xsd:sequence>
<xsd:element name="primaryie" type="xsd:string" />
<xsd:element name="secondaryie" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docListType">
<xsd:sequence>
<xsd:element name="listitem" type="docListItemType" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docListItemType">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docSimpleSectType">
<xsd:sequence>
<xsd:element name="title" type="docTitleType" minOccurs="0" />
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="para" type="docParaType" minOccurs="1" maxOccurs="unbounded" />
<xsd:element name="simplesectsep" type="docEmptyType" minOccurs="0"/>
</xsd:sequence>
</xsd:sequence>
<xsd:attribute name="kind" type="DoxSimpleSectKind" />
</xsd:complexType>
<xsd:complexType name="docVarListEntryType">
<xsd:sequence>
<xsd:element name="term" type="docTitleType" />
</xsd:sequence>
</xsd:complexType>
<xsd:group name="docVariableListGroup">
<xsd:sequence>
<xsd:element name="varlistentry" type="docVarListEntryType" />
<xsd:element name="listitem" type="docListItemType" />
</xsd:sequence>
</xsd:group>
<xsd:complexType name="docVariableListType">
<xsd:sequence>
<xsd:group ref="docVariableListGroup" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docRefTextType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="kindref" type="DoxRefKind" />
<xsd:attribute name="external" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docTableType">
<xsd:sequence>
<xsd:element name="row" type="docRowType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="caption" type="docCaptionType" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="rows" type="xsd:integer" />
<xsd:attribute name="cols" type="xsd:integer" />
</xsd:complexType>
<xsd:complexType name="docRowType">
<xsd:sequence>
<xsd:element name="entry" type="docEntryType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docEntryType">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="thead" type="DoxBool" />
</xsd:complexType>
<xsd:complexType name="docCaptionType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
</xsd:complexType>
<xsd:complexType name="docHeadingType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="level" type="xsd:integer" /> <!-- todo: range 1-6 -->
</xsd:complexType>
<xsd:complexType name="docImageType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="type" type="DoxImageKind" />
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="width" type="xsd:string" />
<xsd:attribute name="height" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docDotFileType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docTocItemType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docTocListType">
<xsd:sequence>
<xsd:element name="tocitem" type="docTocItemType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docLanguageType">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="langid" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docParamListType">
<xsd:sequence>
<xsd:element name="parameteritem" type="docParamListItem" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="kind" type="DoxParamListKind" />
</xsd:complexType>
<xsd:complexType name="docParamListItem">
<xsd:sequence>
<xsd:element name="parameternamelist" type="docParamNameList" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="parameterdescription" type="descriptionType" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docParamNameList">
<xsd:sequence>
<xsd:element name="parametername" type="docParamName" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docParamName" mixed="true">
<xsd:sequence>
<xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="direction" type="DoxParamDir" use="optional" />
</xsd:complexType>
<xsd:complexType name="docXRefSectType">
<xsd:sequence>
<xsd:element name="xreftitle" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="xrefdescription" type="descriptionType" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docCopyType">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="internal" type="docInternalType" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="link" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docCharType">
<xsd:attribute name="char" type="DoxCharRange"/>
</xsd:complexType>
<xsd:complexType name="docEmptyType"/>
<!-- Simple types -->
<xsd:simpleType name="DoxBool">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="yes" />
<xsd:enumeration value="no" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxGraphRelation">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="include" />
<xsd:enumeration value="usage" />
<xsd:enumeration value="template-instance" />
<xsd:enumeration value="public-inheritance" />
<xsd:enumeration value="protected-inheritance" />
<xsd:enumeration value="private-inheritance" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxRefKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="compound" />
<xsd:enumeration value="member" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxMemberKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="define" />
<xsd:enumeration value="property" />
<xsd:enumeration value="event" />
<xsd:enumeration value="variable" />
<xsd:enumeration value="typedef" />
<xsd:enumeration value="enum" />
<xsd:enumeration value="function" />
<xsd:enumeration value="signal" />
<xsd:enumeration value="prototype" />
<xsd:enumeration value="friend" />
<xsd:enumeration value="dcop" />
<xsd:enumeration value="slot" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxProtectionKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="public" />
<xsd:enumeration value="protected" />
<xsd:enumeration value="private" />
<xsd:enumeration value="package" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxVirtualKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="non-virtual" />
<xsd:enumeration value="virtual" />
<xsd:enumeration value="pure-virtual" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxCompoundKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="class" />
<xsd:enumeration value="struct" />
<xsd:enumeration value="union" />
<xsd:enumeration value="interface" />
<xsd:enumeration value="protocol" />
<xsd:enumeration value="category" />
<xsd:enumeration value="exception" />
<xsd:enumeration value="file" />
<xsd:enumeration value="namespace" />
<xsd:enumeration value="group" />
<xsd:enumeration value="page" />
<xsd:enumeration value="example" />
<xsd:enumeration value="dir" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxSectionKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="user-defined" />
<xsd:enumeration value="public-type" />
<xsd:enumeration value="public-func" />
<xsd:enumeration value="public-attrib" />
<xsd:enumeration value="public-slot" />
<xsd:enumeration value="signal" />
<xsd:enumeration value="dcop-func" />
<xsd:enumeration value="property" />
<xsd:enumeration value="event" />
<xsd:enumeration value="public-static-func" />
<xsd:enumeration value="public-static-attrib" />
<xsd:enumeration value="protected-type" />
<xsd:enumeration value="protected-func" />
<xsd:enumeration value="protected-attrib" />
<xsd:enumeration value="protected-slot" />
<xsd:enumeration value="protected-static-func" />
<xsd:enumeration value="protected-static-attrib" />
<xsd:enumeration value="package-type" />
<xsd:enumeration value="package-func" />
<xsd:enumeration value="package-attrib" />
<xsd:enumeration value="package-static-func" />
<xsd:enumeration value="package-static-attrib" />
<xsd:enumeration value="private-type" />
<xsd:enumeration value="private-func" />
<xsd:enumeration value="private-attrib" />
<xsd:enumeration value="private-slot" />
<xsd:enumeration value="private-static-func" />
<xsd:enumeration value="private-static-attrib" />
<xsd:enumeration value="friend" />
<xsd:enumeration value="related" />
<xsd:enumeration value="define" />
<xsd:enumeration value="prototype" />
<xsd:enumeration value="typedef" />
<xsd:enumeration value="enum" />
<xsd:enumeration value="func" />
<xsd:enumeration value="var" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxHighlightClass">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="comment" />
<xsd:enumeration value="normal" />
<xsd:enumeration value="preprocessor" />
<xsd:enumeration value="keyword" />
<xsd:enumeration value="keywordtype" />
<xsd:enumeration value="keywordflow" />
<xsd:enumeration value="stringliteral" />
<xsd:enumeration value="charliteral" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxSimpleSectKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="see" />
<xsd:enumeration value="return" />
<xsd:enumeration value="author" />
<xsd:enumeration value="authors" />
<xsd:enumeration value="version" />
<xsd:enumeration value="since" />
<xsd:enumeration value="date" />
<xsd:enumeration value="note" />
<xsd:enumeration value="warning" />
<xsd:enumeration value="pre" />
<xsd:enumeration value="post" />
<xsd:enumeration value="invariant" />
<xsd:enumeration value="remark" />
<xsd:enumeration value="attention" />
<xsd:enumeration value="par" />
<xsd:enumeration value="rcs" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxVersionNumber">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d+\.\d+.*" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxImageKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="html" />
<xsd:enumeration value="latex" />
<xsd:enumeration value="rtf" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxParamListKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="param" />
<xsd:enumeration value="retval" />
<xsd:enumeration value="exception" />
<xsd:enumeration value="templateparam" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxCharRange">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[aeiouncAEIOUNC]" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxParamDir">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="in"/>
<xsd:enumeration value="out"/>
<xsd:enumeration value="inout"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxAccessor">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="retain"/>
<xsd:enumeration value="copy"/>
<xsd:enumeration value="assign"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@ -1,17 +0,0 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygenindex xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="index.xsd" version="1.6.3">
<compound refid="classAadvark" kind="class"><name>Aadvark</name>
<member refid="classAadvark_1ab79eb58d7bb9d5ddfa5d6f783836cab9" kind="variable"><name>aadvarkness</name></member>
<member refid="classAadvark_1abd061aa5f998002e72080a34f512a059" kind="function"><name>print</name></member>
<member refid="classAadvark_1adf1a4b97a641411a74a04ab312484462" kind="function"><name>Aadvark</name></member>
<member refid="classAadvark_1affd2ada0a85807efcbe26615a848f53e" kind="function"><name>get_aadvarkness</name></member>
</compound>
<compound refid="aadvark_8cc" kind="file"><name>aadvark.cc</name>
<member refid="aadvark_8cc_1acb52858524210ec6dddc3e16d1e52946" kind="function"><name>aadvarky_enough</name></member>
<member refid="aadvark_8cc_1ae66f6b31b5ad750f1fe042a706a4e3d4" kind="function"><name>main</name></member>
</compound>
<compound refid="aadvark_8h" kind="file"><name>aadvark.h</name>
<member refid="aadvark_8h_1acb52858524210ec6dddc3e16d1e52946" kind="function"><name>aadvarky_enough</name></member>
<member refid="aadvark_8h_1ae66f6b31b5ad750f1fe042a706a4e3d4" kind="function"><name>main</name></member>
</compound>
</doxygenindex>

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