summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Daniel <cd@maintech.de>2013-01-10 19:10:41 +0100
committerChristian Daniel <cd@maintech.de>2013-01-10 19:10:41 +0100
commitbc917000f5ce707dc3849d31c8c1e443893ddb78 (patch)
tree2ba024831892c5e0d54dbae07ebba25aa95638d7
parentcc2fc0e5b6635b671ba1a2b0aadc8e35bf675679 (diff)
- make MCI switch transfer frequency according to needed bandwidth
- add "switch to DFU" command to USB - cleanup usb device code (comments and error handling) - add E4K register write via USB
-rw-r--r--firmware/osmosdr-radioapp/src/driver/e4k.c7
-rw-r--r--firmware/osmosdr-radioapp/src/driver/e4k.h1
-rw-r--r--firmware/osmosdr-radioapp/src/driver/mci.c22
-rw-r--r--firmware/osmosdr-radioapp/src/driver/mci.h1
-rw-r--r--firmware/osmosdr-radioapp/src/usb/usbdevice.c82
5 files changed, 72 insertions, 41 deletions
diff --git a/firmware/osmosdr-radioapp/src/driver/e4k.c b/firmware/osmosdr-radioapp/src/driver/e4k.c
index e1cc781..967bb03 100644
--- a/firmware/osmosdr-radioapp/src/driver/e4k.c
+++ b/firmware/osmosdr-radioapp/src/driver/e4k.c
@@ -1012,7 +1012,7 @@ int e4k_reInit(E4KCtx* e4k)
magic_init(e4k);
/* Set common mode voltage a bit higher for more margin */
- e4k_commonModeSet(e4k, 3);
+ e4k_commonModeSet(e4k, 7);
#if 0
/* Initialize DC offset lookup tables */
e4k_dc_offset_gen_table(e4k);
@@ -1104,6 +1104,11 @@ void e4k_dump(E4KCtx* e4k)
);
}
+int e4k_setReg(E4KCtx* e4k, u8 reg, u8 val)
+{
+ return e4k_reg_write(e4k, reg, val);
+}
+
/*! \brief High-level tuning API, just specify frquency
*
diff --git a/firmware/osmosdr-radioapp/src/driver/e4k.h b/firmware/osmosdr-radioapp/src/driver/e4k.h
index 7decd0b..0f1599e 100644
--- a/firmware/osmosdr-radioapp/src/driver/e4k.h
+++ b/firmware/osmosdr-radioapp/src/driver/e4k.h
@@ -60,6 +60,7 @@ typedef struct {
void e4k_configure(E4KCtx* ctx, const TWI* twi, u8 addr, u32 refFreq, const PinConfig* powerPins, uint numPowerPins);
void e4k_setPower(E4KCtx* ctx, Bool up);
void e4k_dump(E4KCtx* e4k);
+int e4k_setReg(E4KCtx* e4k, u8 reg, u8 val);
int e4k_tune(E4KCtx* e4k, u32 freq);
int e4k_reInit(E4KCtx* e4k);
int e4k_ifGainSet(E4KCtx* e4k, u8 stage, s8 value);
diff --git a/firmware/osmosdr-radioapp/src/driver/mci.c b/firmware/osmosdr-radioapp/src/driver/mci.c
index 29c6ed8..91a7039 100644
--- a/firmware/osmosdr-radioapp/src/driver/mci.c
+++ b/firmware/osmosdr-radioapp/src/driver/mci.c
@@ -138,6 +138,28 @@ void mci_configure(AT91S_MCI* mci, uint id)
mci->MCI_CFG = AT91C_MCI_FIFOMODE_AMOUNTDATA | AT91C_MCI_FERRCTRL_RWCMD | AT91C_MCI_HSMODE_ENABLE;
}
+void mci_setSpeed(AT91S_MCI* mci, u32 decimation)
+{
+ uint speed = MCI_INITIAL_SPEED;
+
+ /*
+ * Fs = 4MHz
+ * Dec MCI-Speed
+ * 32 1500000
+ * 16 3000000
+ * 8 6000000
+ * 4 12000000
+ * 2 24000000
+ * 1 48000000
+ */
+
+ if((decimation >= 0) && (decimation <= 7))
+ speed = 96000000 / (2 << decimation);
+
+ uint clkDiv = (BOARD_MCK / (speed * 2)) - 1;
+ mci->MCI_MR = (clkDiv | (AT91C_MCI_PWSDIV & (0x7 << 8))) | AT91C_MCI_RDPROOF_ENABLE | (512 << 16);
+}
+
void mci_startStream(AT91S_MCI* mci)
{
#if 0
diff --git a/firmware/osmosdr-radioapp/src/driver/mci.h b/firmware/osmosdr-radioapp/src/driver/mci.h
index 83ace49..8e24ae1 100644
--- a/firmware/osmosdr-radioapp/src/driver/mci.h
+++ b/firmware/osmosdr-radioapp/src/driver/mci.h
@@ -5,6 +5,7 @@
#include "../crt/types.h"
void mci_configure(AT91S_MCI* mci, uint id);
+void mci_setSpeed(AT91S_MCI* mci, u32 decimation);
void mci_startStream(AT91S_MCI* mci);
void mci_stopStream(AT91S_MCI* mci);
void mci_enableInterrupts(AT91S_MCI* mci, u32 irqs);
diff --git a/firmware/osmosdr-radioapp/src/usb/usbdevice.c b/firmware/osmosdr-radioapp/src/usb/usbdevice.c
index 86c5691..ea83c5d 100644
--- a/firmware/osmosdr-radioapp/src/usb/usbdevice.c
+++ b/firmware/osmosdr-radioapp/src/usb/usbdevice.c
@@ -31,6 +31,7 @@
#include "../driver/sdrfpga.h"
#include "../driver/e4k.h"
#include "../driver/chanfilter.h"
+#include "../driver/mci.h"
#define STR_MANUFACTURER 1
#define STR_PRODUCT 2
@@ -323,6 +324,7 @@ const static Request g_writeRequests[] = {
{ FUNC(GROUP_GENERAL, 0x00), 0, "general init" }, // init whatever
{ FUNC(GROUP_GENERAL, 0x01), 0, "general power down" }, // power down
{ FUNC(GROUP_GENERAL, 0x02), 0, "general power up" }, // power up
+ { FUNC(GROUP_GENERAL, 0x03), 0, "switch to DFU" }, // switch to DFU mode
// fpga commands
{ FUNC(GROUP_FPGA_V2, 0x00), 0, "FPGA init" }, // fpga init
@@ -340,7 +342,7 @@ const static Request g_writeRequests[] = {
// e4000 tuner commands
{ FUNC(GROUP_TUNER_E4K, 0x00), 0, "E4K init" }, // e4k_init()
- { FUNC(GROUP_TUNER_E4K, 0x01), 0, "E4K register write" }, // reg write
+ { FUNC(GROUP_TUNER_E4K, 0x01), 2, "E4K register write" }, // reg write
{ FUNC(GROUP_TUNER_E4K, 0x02), 5, "E4K set if gain" }, // e4k_if_gain_set(uint8_t stage, int8_t value)
{ FUNC(GROUP_TUNER_E4K, 0x03), 1, "E4K set mixer gain" }, // e4k_mixer_gain_set(struct e4k_state *e4k, int8_t value)
{ FUNC(GROUP_TUNER_E4K, 0x04), 1, "E4K set commonmode" }, // e4k_commonmode_set(int8_t value)
@@ -414,7 +416,7 @@ static void sourceStart(void)
static void finalizeWrite(void* arg, u8 status, uint transferred, uint remaining)
{
- int res;
+ int res = 0;
if((status != 0) ||(remaining != 0)) {
dprintf("USB request failed\n");
@@ -425,115 +427,115 @@ static void finalizeWrite(void* arg, u8 status, uint transferred, uint remaining
switch(g_writeState.func) {
// general api
case FUNC(GROUP_GENERAL, 0x00): // init all
- res = 0; // no op so far
+ // no op so far
break;
case FUNC(GROUP_GENERAL, 0x01): // power down
sdrfpga_setPower(False);
e4k_setPower(&g_e4kCtx, False);
- res = 0;
break;
case FUNC(GROUP_GENERAL, 0x02): // power up
sdrfpga_setPower(True);
e4k_setPower(&g_e4kCtx, True);
- res = 0;
break;
+ case FUNC(GROUP_GENERAL, 0x03): // switch to DFU
+ sys_reset(True);
+ break;
+
// fpga commands
case FUNC(GROUP_FPGA_V2, 0x00): // fpga init
- res = 0; // no op so far
+ // no op so far
break;
- case FUNC(GROUP_FPGA_V2, 0x01):
+ case FUNC(GROUP_FPGA_V2, 0x01): // reg write
sdrfpga_regWrite(g_writeState.data[0], read_bytewise32(g_writeState.data + 1));
- res = 0;
break;
- case FUNC(GROUP_FPGA_V2, 0x02):
+ case FUNC(GROUP_FPGA_V2, 0x02): // set decimation
sdrfpga_setDecimation(g_writeState.data[0]);
- res = 0;
+#if defined(BOARD_SAMPLE_SOURCE_MCI)
+ mci_setSpeed(AT91C_BASE_MCI0, g_writeState.data[0]);
+#endif // defined(BOARD_SAMPLE_SOURCE_MCI)
break;
- case FUNC(GROUP_FPGA_V2, 0x03):
+ case FUNC(GROUP_FPGA_V2, 0x03): // set IQ swap
sdrfpga_setIQSwap(g_writeState.data[0]);
- res = 0;
break;
- case FUNC(GROUP_FPGA_V2, 0x04):
+ case FUNC(GROUP_FPGA_V2, 0x04): // set IQ gain
sdrfpga_setIQGain(read_bytewise16(g_writeState.data), read_bytewise16(g_writeState.data + 2));
- res = 0;
break;
- case FUNC(GROUP_FPGA_V2, 0x05):
+ case FUNC(GROUP_FPGA_V2, 0x05): // set IQ offset
sdrfpga_setIQOfs(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()
res = si570_init(&g_si570Ctx);
break;
- case FUNC(GROUP_VCXO_SI570, 0x01):
+ case FUNC(GROUP_VCXO_SI570, 0x01): // reg write
res = si570_regWrite(&g_si570Ctx, g_writeState.data[0], g_writeState.data[1], g_writeState.data + 2);
break;
- case FUNC(GROUP_VCXO_SI570, 0x02):
+ case FUNC(GROUP_VCXO_SI570, 0x02): // set frequency and trim value
res = si570_setFrequencyAndTrim(&g_si570Ctx, read_bytewise32(g_writeState.data), read_bytewise32(g_writeState.data + 4));
break;
- case FUNC(GROUP_VCXO_SI570, 0x03):
+ case FUNC(GROUP_VCXO_SI570, 0x03): // set frequency
res = si570_setFrequency(&g_si570Ctx, read_bytewise32(g_writeState.data));
break;
// e4000 tuner commands
- case FUNC(GROUP_TUNER_E4K, 0x00):
+ case FUNC(GROUP_TUNER_E4K, 0x00): // e4k_reInit
res = e4k_reInit(&g_e4kCtx);
break;
case FUNC(GROUP_TUNER_E4K, 0x01): // reg write
- res = -1;
+ res = e4k_setReg(&g_e4kCtx, g_writeState.data[0], g_writeState.data[1]);
break;
- case FUNC(GROUP_TUNER_E4K, 0x02):
+ case FUNC(GROUP_TUNER_E4K, 0x02): // set IF gain
res = e4k_ifGainSet(&g_e4kCtx, g_writeState.data[0], read_bytewise32(g_writeState.data + 1));
e4k_dcOffsetCalibrate(&g_e4kCtx);
break;
- case FUNC(GROUP_TUNER_E4K, 0x03):
+ case FUNC(GROUP_TUNER_E4K, 0x03): // set mixer gain
res = e4k_mixerGainSet(&g_e4kCtx, g_writeState.data[0]);
e4k_dcOffsetCalibrate(&g_e4kCtx);
break;
- case FUNC(GROUP_TUNER_E4K, 0x04):
+ case FUNC(GROUP_TUNER_E4K, 0x04): // set common mode
res = e4k_commonModeSet(&g_e4kCtx, g_writeState.data[0]);
break;
- case FUNC(GROUP_TUNER_E4K, 0x05):
+ case FUNC(GROUP_TUNER_E4K, 0x05): // tune
res = e4k_tune(&g_e4kCtx, read_bytewise32(g_writeState.data) / 1000);
e4k_dcOffsetCalibrate(&g_e4kCtx);
break;
- case FUNC(GROUP_TUNER_E4K, 0x06):
+ case FUNC(GROUP_TUNER_E4K, 0x06): // set if filter BW
res = e4k_ifFilterBWSet(&g_e4kCtx, g_writeState.data[0], read_bytewise32(g_writeState.data + 1));
break;
- case FUNC(GROUP_TUNER_E4K, 0x07):
+ case FUNC(GROUP_TUNER_E4K, 0x07): // set channel filter
res = e4k_ifFilterChanEnable(&g_e4kCtx, g_writeState.data[0]);
break;
- case FUNC(GROUP_TUNER_E4K, 0x08):
+ case FUNC(GROUP_TUNER_E4K, 0x08): // set DC offset
res = e4k_manualDCOffsetSet(&g_e4kCtx, g_writeState.data[0], g_writeState.data[1], g_writeState.data[2], g_writeState.data[3]);
break;
- case FUNC(GROUP_TUNER_E4K, 0x09):
+ case FUNC(GROUP_TUNER_E4K, 0x09): // calibrate DC offset
res = e4k_dcOffsetCalibrate(&g_e4kCtx);
break;
- case FUNC(GROUP_TUNER_E4K, 0x0a):
+ case FUNC(GROUP_TUNER_E4K, 0x0a): // generate DC offset table
res = e4k_dcOffsetGenTable(&g_e4kCtx);
break;
- case FUNC(GROUP_TUNER_E4K, 0x0b):
- res = e4k_setLNAGain(&g_e4kCtx, read_bytewise32(g_writeState.data));
+ case FUNC(GROUP_TUNER_E4K, 0x0b): // set LNA gain
+ res = e4k_setLNAGain(&g_e4kCtx, (s32)read_bytewise32(g_writeState.data));
e4k_dcOffsetCalibrate(&g_e4kCtx);
break;
- case FUNC(GROUP_TUNER_E4K, 0x0c):
+ case FUNC(GROUP_TUNER_E4K, 0x0c): // enable manual gain control
res = e4k_enableManualGain(&g_e4kCtx, g_writeState.data[0]);
break;
- case FUNC(GROUP_TUNER_E4K, 0x0d):
+ case FUNC(GROUP_TUNER_E4K, 0x0d): // enable enhanced gain
res = e4k_setEnhGain(&g_e4kCtx, read_bytewise32(g_writeState.data));
e4k_dcOffsetCalibrate(&g_e4kCtx);
break;
// op-amp based channel filter
- case FUNC(GROUP_FILTER_V1, 0x00):
- res = 0; // no op so far
+ case FUNC(GROUP_FILTER_V1, 0x00): // init
+ // no op so far
break;
- case FUNC(GROUP_FILTER_V1, 0x01):
+ case FUNC(GROUP_FILTER_V1, 0x01): // reg write
res = chanfilter_regWrite(g_writeState.data[0], g_writeState.data[1], g_writeState.data[2]);
break;
- case FUNC(GROUP_FILTER_V1, 0x02):
+ case FUNC(GROUP_FILTER_V1, 0x02): // set all potis
res = chanfilter_setAll(g_writeState.data[0], g_writeState.data[1], g_writeState.data[2], g_writeState.data[3]);
break;
@@ -565,12 +567,12 @@ static void osmosdrWrite(const USBGenericRequest* request)
}
if(i == ARRAY_SIZE(g_writeRequests)) {
usbdhs_stall(0);
- dprintf("OsmoSDR invalid request size\n");
+ dprintf("OsmoSDR unknown request\n");
return;
}
if(len != g_writeRequests[i].len) {
usbdhs_stall(0);
- dprintf("OsmoSDR unknown request\n");
+ dprintf("OsmoSDR invalid request size\n");
return;
}