Dual mode working

This commit is contained in:
cnlohr
2024-10-09 01:05:35 -07:00
parent 4c84e5e538
commit 933a3d4347
3 changed files with 114 additions and 73 deletions
+66 -59
View File
@@ -69,7 +69,12 @@ SOFTWARE.
// For I2C, output will be on PB8/PB9 SCL/SDA // For I2C, output will be on PB8/PB9 SCL/SDA
//#define ENABLE_OLED //#define ENABLE_OLED
//#define PWM_OUTPUT //#define PWM_OUTPUT
int g_volume_pwm = 127; // 0 - 127 (100%) (but you can go over 100) (For when using PWM)
#define ENABLE_OLED_SCOPE #define ENABLE_OLED_SCOPE
//#define PROFILING_PIN PC8
#define SAMPLETIME 1 // 0: 1.5 cycles; 1: 7.5 cycles; 2: 13.5 cycles; (0 would go fastest and is important in single-ADC mode, but 1 seems slightly better in 2-ADC mode)
#ifdef ENABLE_OLED_SCOPE #ifdef ENABLE_OLED_SCOPE
#define SH1107_128x128 #define SH1107_128x128
@@ -92,7 +97,7 @@ SOFTWARE.
#endif #endif
#if defined( ENABLE_OLED ) && defined( ENABLE_OLED_SCOPE ) #if defined( ENABLE_OLED ) && defined( ENABLE_OLED_SCOPE )
#error Can't be SPI and I2C OLED #error Cant be SPI and I2C OLED
#endif #endif
@@ -104,22 +109,20 @@ SOFTWARE.
volatile uint16_t adc_buffer[ADC_BUFFSIZE]; volatile uint16_t adc_buffer[ADC_BUFFSIZE];
int g_volume_pwm = 127; // 0 - 127 (100%) (but you can go over 100)
int32_t g_goertzel_phasor_r = 32768; int32_t g_goertzel_phasor_r = 32768;
int32_t g_goertzel_phasor_i = 0; int32_t g_goertzel_phasor_i = 0;
int32_t g_goertzel_advance_r = 32768;
int32_t g_goertzel_advance_i = 0;
#if 1 #if 1
int g_pwm_period = (30-1); // Very basic setup, for tuning to 880AM
int g_goertzel_buffer = (180); int g_pwm_period = (60-1);
int g_exactcompute = (0); int g_exactcompute = (1);
int32_t g_goertzel_omega_per_sample = 5509657063; // 0.816667 of whole per step / 0.880000MHz int g_goertzel_buffer = (1024);
int32_t g_goertzel_omega_per_sample = 873460290; // 0.183333 of whole per step / -8.720000MHz
int32_t g_goertzel_coefficient = 873460290; int32_t g_goertzel_coefficient = 873460290;
int32_t g_goertzel_coefficient_s = -1961823932; int32_t g_goertzel_coefficient_s = 1961823932;
int32_t g_goertzel_advance_r = -3425;
int32_t g_goertzel_advance_i = 32588;
#endif #endif
int intensity_average = 1; int intensity_average = 1;
@@ -139,44 +142,53 @@ void SetupADC()
// ADC CLK is chained off of APB2. // ADC CLK is chained off of APB2.
// Reset the ADC to init all regs // Reset the ADC to init all regs
RCC->APB2PRSTR |= RCC_APB2Periph_ADC1; RCC->APB2PRSTR |= RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2;
RCC->APB2PRSTR &= ~RCC_APB2Periph_ADC1; RCC->APB2PRSTR &= ~( RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 );
// ADCCLK = 12 MHz => RCC_ADCPRE divide by 4 // ADCCLK = 12 MHz => RCC_ADCPRE divide by 4
RCC->CFGR0 &= ~RCC_ADCPRE; // Clear out the bis in case they were set RCC->CFGR0 &= ~RCC_ADCPRE; // Clear out the bis in case they were set
RCC->CFGR0 |= RCC_ADCPRE_DIV2; // Fastest possible (divide-by-2) NOTE: This is OUTSIDE the specified value in the datasheet. RCC->CFGR0 |= RCC_ADCPRE_DIV2; // Fastest possible (divide-by-2) NOTE: This is OUTSIDE the specified value in the datasheet.
// Set up single conversion on chl 7 // Set up single conversion on chl 7
ADC1->RSQR1 = 0;
ADC1->RSQR2 = 0;
ADC1->RSQR3 = CHANNEL; // 0-9 for 8 ext inputs and two internals Set to 7 for PA7 ADC1->RSQR3 = CHANNEL; // 0-9 for 8 ext inputs and two internals Set to 7 for PA7
ADC2->RSQR3 = CHANNEL; // 0-9 for 8 ext inputs and two internals Set to 7 for PA7
ADC1->ISQR = CHANNEL; // Mirror in case we switch to injection mode.
ADC2->ISQR = CHANNEL;
// Not using injection group. // Not using injection group.
// Sampling time for channels. Careful: This has PID tuning implications. // Sampling time for channels. Careful: This has PID tuning implications.
// Note that with 3 and 3,the full loop (and injection) runs at 138kHz. // Note that with 3 and 3,the full loop (and injection) runs at 138kHz.
ADC1->SAMPTR2 = (0<<(3*CHANNEL)); // (3*channel) ADC1->SAMPTR2 = (SAMPLETIME<<(3*CHANNEL)); // (3*channel)
ADC2->SAMPTR2 = (SAMPLETIME<<(3*CHANNEL)); // (3*channel)
// Turn on ADC and set rule group to sw trig // Turn on ADC and set rule group to sw trig
// 0 = Use TRGO event for Timer 1 to fire ADC rule. // 0 = Use TRGO event for Timer 1 to fire ADC rule.
ADC1->CTLR2 = ADC_ADON | ADC_EXTTRIG | ADC_DMA; ADC1->CTLR2 = ADC_ADON | ADC_EXTTRIG | ADC_DMA;
ADC2->CTLR2 = ADC_ADON | ADC_EXTTRIG | ADC_EXTSEL_1;// | ADC_DMA;
// For EXTTRIG, EXTSEL (none) = 0 = TIM1CC1 /
// For JEXTTRIG, EXTSEL = 0 = TIM1 TRGO (Or ADC_JEXTSEL_0 => CH4)
// Reset calibration // Reset calibration
ADC1->CTLR2 |= ADC_RSTCAL; ADC1->CTLR2 |= ADC_RSTCAL;
ADC2->CTLR2 |= ADC_RSTCAL;
while(ADC1->CTLR2 & ADC_RSTCAL); while(ADC1->CTLR2 & ADC_RSTCAL);
while(ADC2->CTLR2 & ADC_RSTCAL);
// Calibrate ADC // Calibrate ADC
ADC1->CTLR2 |= ADC_CAL; ADC1->CTLR2 |= ADC_CAL;
ADC2->CTLR2 |= ADC_CAL;
while(ADC1->CTLR2 & ADC_CAL); while(ADC1->CTLR2 & ADC_CAL);
while(ADC2->CTLR2 & ADC_CAL);
// ADC_SCAN: Allow scanning. // ADC_SCAN: Allow scanning.
ADC2->CTLR1 = ADC_SCAN;
ADC1->CTLR1 = ADC1->CTLR1 =
//ADC_SCAN; //ADC_DUALMOD_0 | ADC_DUALMOD_3 | // Alternate Trigger Mode (Can't use with DMA)
ADC_SCAN ; ADC_SCAN;
//| ADC_BUFEN ; //ADC_Pga_16 | ADC_BUFEN ;
//ADC_Pga_16 | ADC_SCAN | ADC_BUFEN ; //ADC_Pga_64 | ADC_BUFEN;
//ADC_Pga_64 | ADC_SCAN;
// Turn on DMA // Turn on DMA
RCC->AHBPCENR |= RCC_AHBPeriph_DMA1; RCC->AHBPCENR |= RCC_AHBPeriph_DMA1;
@@ -184,17 +196,16 @@ void SetupADC()
//DMA1_Channel1 is for ADC //DMA1_Channel1 is for ADC
DMA1_Channel1->PADDR = (uint32_t)&ADC1->RDATAR; DMA1_Channel1->PADDR = (uint32_t)&ADC1->RDATAR;
DMA1_Channel1->MADDR = (uint32_t)adc_buffer; DMA1_Channel1->MADDR = (uint32_t)adc_buffer;
DMA1_Channel1->CNTR = ADC_BUFFSIZE; DMA1_Channel1->CNTR = ADC_BUFFSIZE/2;
DMA1_Channel1->CFGR = DMA1_Channel1->CFGR =
DMA_M2M_Disable | DMA_M2M_Disable |
DMA_Priority_VeryHigh | DMA_Priority_VeryHigh |
DMA_MemoryDataSize_HalfWord | DMA_MemoryDataSize_Word |
DMA_PeripheralDataSize_HalfWord | DMA_PeripheralDataSize_Word |
DMA_MemoryInc_Enable | DMA_MemoryInc_Enable |
DMA_Mode_Circular | DMA_Mode_Circular |
DMA_DIR_PeripheralSRC; DMA_DIR_PeripheralSRC;
// NVIC_SetPriority( DMA1_Channel1_IRQn, 0<<4 ); //We don't need to tweak priority.
NVIC_EnableIRQ( DMA1_Channel1_IRQn ); NVIC_EnableIRQ( DMA1_Channel1_IRQn );
DMA1_Channel1->CFGR |= DMA_CFGR1_EN | DMA_IT_TC | DMA_IT_HT; // Transmission Complete + Half Empty Interrupts. DMA1_Channel1->CFGR |= DMA_CFGR1_EN | DMA_IT_TC | DMA_IT_HT; // Transmission Complete + Half Empty Interrupts.
@@ -223,12 +234,15 @@ static void SetupTimer1()
TIM1->BDTR |= 0xc000;//TIM_MOE; TIM1->BDTR |= 0xc000;//TIM_MOE;
#endif #endif
TIM1->CCER |= TIM_CC1E; TIM1->CCER |= TIM_CC1E | TIM_CC4E | TIM_CC3E;
TIM1->CHCTLR1 |= TIM_OC1M_2 | TIM_OC1M_1; TIM1->CHCTLR1 |= TIM_OC1M_2 | TIM_OC1M_1;
TIM1->CH1CVR = 1; TIM1->CHCTLR2 |= TIM_OC3M_2 | TIM_OC3M_1 | TIM_OC4M_2 | TIM_OC4M_1;
TIM1->CH1CVR = 1; // In case we are using rule triggering
TIM1->CH3CVR = 1; // In case we are using rule (alternate) triggering
TIM1->CH4CVR = 1; // In case we are using injection triggering
// Setup TRGO to trigger for ADC (NOTE: Not on the 203! TIM1_TRGO is only connected to injection) // Setup TRGO to trigger for ADC injection group
//TIM1->CTLR2 = TIM_MMS_1; TIM1->CTLR2 = TIM_MMS_1;
// Enable TIM1 outputs // Enable TIM1 outputs
TIM1->BDTR = TIM_MOE; TIM1->BDTR = TIM_MOE;
@@ -237,6 +251,8 @@ static void SetupTimer1()
#ifdef ENABLE_OLED_SCOPE #ifdef ENABLE_OLED_SCOPE
// Command-mode, Set X, Disable Timer, Set Y, Enable Timer
// Done this way to prevent streaking.
uint8_t cmdxy[] = { 0x00, 0xd3, 0x30, 0xd5, 0xff, 0x00, 0xdc, 0x30, 0xd5, 0xf0 }; uint8_t cmdxy[] = { 0x00, 0xd3, 0x30, 0xd5, 0xff, 0x00, 0xdc, 0x30, 0xd5, 0xf0 };
void config_turbo_scope() void config_turbo_scope()
@@ -281,24 +297,15 @@ void ssd1306_send_turbo(uint8_t *data, uint8_t sz)
while(SPI1->STATR & SPI_STATR_BSY); while(SPI1->STATR & SPI_STATR_BSY);
funDigitalWrite( SSD1306_CS_PIN, FUN_HIGH ); funDigitalWrite( SSD1306_CS_PIN, FUN_HIGH );
// we're happy
} }
static void PlotPoint( int x, int y ) static void PlotPoint( int x, int y )
{ {
// Set X, Pause, Set Y, Start
funDigitalWrite( SSD1306_CS_PIN, FUN_HIGH ); funDigitalWrite( SSD1306_CS_PIN, FUN_HIGH );
cmdxy[2] = x; cmdxy[7] = y; cmdxy[2] = x; cmdxy[7] = y;
DMA1_Channel3->CNTR = sizeof(cmdxy); DMA1_Channel3->CNTR = sizeof(cmdxy);
funDigitalWrite( SSD1306_CS_PIN, FUN_LOW ); funDigitalWrite( SSD1306_CS_PIN, FUN_LOW );
DMA1_Channel3->CFGR |= DMA_CFGR1_EN; DMA1_Channel3->CFGR |= DMA_CFGR1_EN;
// Set X, Set Y
// uint8_t cmdxy[16] = { 0x00, 0xd3, 0x30, 0x00, 0x00, 0xdc, 0x30 };
// cmdxy[2] = x; cmdxy[6] = y;
//ssd1306_i2c_send(SSD1306_I2C_ADDR, cmdxy+1, sizeof(cmdxy)-1);
//ssd1306_send_turbo(cmdxy, sizeof(cmdxy));
} }
#endif #endif
@@ -347,7 +354,9 @@ void DMA1_Channel1_IRQHandler( void )
// Clear all possible flags. // Clear all possible flags.
DMA1->INTFCR = DMA1_IT_GL1; DMA1->INTFCR = DMA1_IT_GL1;
int tpl = ADC_BUFFSIZE - DMA1_Channel1->CNTR; // Warning, sometimes this is == to the base, or == 0 (i.e. might be 256, if top is 255) int tpl = ADC_BUFFSIZE - DMA1_Channel1->CNTR*2;
// Warning, sometimes this is DMA1_Channel1->CNTR == to the base, or == 0 (i.e. might be 256, if top is 255)
tpl += ADC_BUFFSIZE; tpl += ADC_BUFFSIZE;
tpl = (tpl & (ADC_BUFFSIZE-1)); tpl = (tpl & (ADC_BUFFSIZE-1));
if( tpl == ADC_BUFFSIZE ) tpl = 0; if( tpl == ADC_BUFFSIZE ) tpl = 0;
@@ -366,6 +375,9 @@ void DMA1_Channel1_IRQHandler( void )
// Here is where the magic happens. // Here is where the magic happens.
#if 1 #if 1
// Also, this is the current limiting factor for the maximum samplerate.
// We can't go above 7.2MSPS and keep up here when main CPU is @ 144MHz.
#define XSTR(x) #x #define XSTR(x) #x
#define GOERTZELLOOP(idx) \ #define GOERTZELLOOP(idx) \
asm volatile("\n\ asm volatile("\n\
@@ -548,15 +560,12 @@ void InnerLoop()
} }
#endif #endif
int pxa = 0;
// Only display half of the list so the other half could // Only display half of the list so the other half could
// be updated by the ISR. // be updated by the ISR.
int glread = qibaselogs_head;
int intensity = 0;
#ifdef ENABLE_OLED #ifdef ENABLE_OLED
int pxa = 0;
int glread = qibaselogs_head;
for( pxa = 0; pxa < LOG_GOERTZEL_LIST; pxa++ ) for( pxa = 0; pxa < LOG_GOERTZEL_LIST; pxa++ )
{ {
@@ -589,16 +598,10 @@ void InnerLoop()
//if( ik == sizeof(ssd1306_buffer) ) ik = 0; //if( ik == sizeof(ssd1306_buffer) ) ik = 0;
ssd1306_setbuf(0); ssd1306_setbuf(0);
#else
Delay_Ms(17);
#endif #endif
// printf( "%6d %8d %8d - %8d %8d - %8d\n", g_goertzel_outs,g_goertzelp2_store, g_goertzelp_store, rr, ri, x );
// Delay_Ms(940);
//printf( "!!!!\n ");
// Do nothing.
Delay_Ms(17);
} }
} }
@@ -828,7 +831,7 @@ void HandleHidUserReportOutComplete( struct _USBState * ctx )
uint32_t * configs = (uint32_t*)scratchpad; uint32_t * configs = (uint32_t*)scratchpad;
// Note: configs[0] == 0xac (command type) // Note: configs[0] == 0xac (command type)
printf( "Is Configure Packet %08x\n", configs[1] ); //printf( "Is Configure Packet %08x\n", configs[1] );
int numconfigs = configs[1]; int numconfigs = configs[1];
if( numconfigs > 0) g_pwm_period = configs[2]; if( numconfigs > 0) g_pwm_period = configs[2];
@@ -847,13 +850,13 @@ void HandleHidUserReportOutComplete( struct _USBState * ctx )
// Consider using PGA. // Consider using PGA.
//ADC_Pga_16 | ADC_SCAN | ADC_BUFEN ; //ADC_Pga_16 | ADC_SCAN | ADC_BUFEN ;
//ADC_Pga_64 | ADC_SCAN; //ADC_Pga_64 | ADC_SCAN;
ADC1->CTLR1 = ADC1->CTLR1 |= ADC_BUFEN;// | ADC_Pga_4; // Adding PGA causes wild oscillation.
ADC_SCAN | ADC_BUFEN; ADC1->CTLR2 |= ADC_BUFEN;// | ADC_Pga_4;
} }
else else
{ {
ADC1->CTLR1 = ADC1->CTLR1 &= (~ADC_BUFEN);
ADC_SCAN; ADC2->CTLR1 &= (~ADC_BUFEN);
} }
} }
@@ -861,6 +864,10 @@ void HandleHidUserReportOutComplete( struct _USBState * ctx )
g_goertzel_samples = 0; g_goertzel_samples = 0;
TIM1->ATRLR = g_pwm_period; TIM1->ATRLR = g_pwm_period;
TIM1->CH1CVR = 1;
TIM1->CH3CVR = TIM1->ATRLR/2+1;
g_isConfigurePacket = 0; g_isConfigurePacket = 0;
} }
return; return;
+42 -8
View File
@@ -22,6 +22,7 @@ function DrawSpan( rowspan, colspan, freq, target, docolor, extrastr = "" )
return ret; return ret;
} }
var system_rate = 288000000; // in MHz for effective ADC (note: This can be 2x normal clock if in dual ADC mode)
var lastGn; var lastGn;
var lastGmhz; var lastGmhz;
var lastGfr; var lastGfr;
@@ -62,7 +63,7 @@ function SendGoertz()
var g_exactcompute = exact_compute; var g_exactcompute = exact_compute;
textarea.value = textarea.value =
"int g_pwm_period = ("+n+"-1);\n" + "int g_pwm_period = ("+n+"-1); // " + system_rate/lastGn/1000000. + " MHz Samplerate\n" +
"int g_exactcompute = ("+exact_compute+");\n" + "int g_exactcompute = ("+exact_compute+");\n" +
"int g_goertzel_buffer = ("+brf+");\n" + "int g_goertzel_buffer = ("+brf+");\n" +
"int32_t g_goertzel_omega_per_sample = " + g_goertzel_coefficient.toFixed(0) + "; // " + ( omega / (3.1415926535*2.0)).toFixed(6) + " of whole per step / " + mhz.toFixed(6) + "MHz\n" + "int32_t g_goertzel_omega_per_sample = " + g_goertzel_coefficient.toFixed(0) + "; // " + ( omega / (3.1415926535*2.0)).toFixed(6) + " of whole per step / " + mhz.toFixed(6) + "MHz\n" +
@@ -95,7 +96,8 @@ function SendGoertz()
for( var i = 0|0; i < 10; i++ ) for( var i = 0|0; i < 10; i++ )
{ {
var tc = (tz / 1000000000.0) % 10; var tc = (tz / 1000000000.0) % 10;
document.getElementById( "mhzm" + i ).value = tc|0; if( document.getElementById( "mhzm" + i ) )
document.getElementById( "mhzm" + i ).value = tc|0;
tz *= 10; tz *= 10;
} }
} }
@@ -131,6 +133,8 @@ function mhzm( event, ths )
let goertzel2 = document.getElementById("GOERTZEL2").checked; let goertzel2 = document.getElementById("GOERTZEL2").checked;
let quanta = Math.round(Number(document.getElementById("quanta").value)); let quanta = Math.round(Number(document.getElementById("quanta").value));
let quantasearch = Math.round(Number(document.getElementById("quantasearch").value)); let quantasearch = Math.round(Number(document.getElementById("quantasearch").value));
SaveDefaults();
system_rate = xtal *1000000;
let n = lastGn; let n = lastGn;
let freq = ( xtal / n ); let freq = ( xtal / n );
@@ -167,7 +171,7 @@ function computeTable()
let goertzel2 = document.getElementById("GOERTZEL2").checked; let goertzel2 = document.getElementById("GOERTZEL2").checked;
let quanta = Math.round(Number(document.getElementById("quanta").value)); let quanta = Math.round(Number(document.getElementById("quanta").value));
let quantasearch = Math.round(Number(document.getElementById("quantasearch").value)); let quantasearch = Math.round(Number(document.getElementById("quantasearch").value));
SaveDefaults();
const max_harmonics = 28|0; const max_harmonics = 28|0;
const min_harmonics = (quadrature?1:0)|0; const min_harmonics = (quadrature?1:0)|0;
@@ -206,6 +210,7 @@ function computeTable()
if( goertzels || quadrature ) if( goertzels || quadrature )
{ {
contents += "<input type=checkbox ID=toggle_adc_buffer onchange='toggleBuffer(this)'><label for=toggle_buffer>ADC Buffer Enable</label><BR>Scroll Wheel Control:<BR>";
contents += "<TABLE BORDER=1>"; contents += "<TABLE BORDER=1>";
contents += '<TR><TH>d\\h</div></TH>'; contents += '<TR><TH>d\\h</div></TH>';
for( let h = 0|min_harmonics; h <= max_harmonics; h++ ) for( let h = 0|min_harmonics; h <= max_harmonics; h++ )
@@ -279,7 +284,7 @@ function computeTable()
if( mode == 0 ) if( mode == 0 )
{ {
contents += "<TD COLSPAN=2>" contents += "<TD COLSPAN=2>"
if( tgoertzelp == h ) contents += "<SPAN ONCLICK='Goertz(" + n + ", " + freq * (h+goertzelpoint) + ", " + (goertzelpoint) + ", " + quantaA + ", 0)'>↑" + (goertzelpoint).toFixed(6) + "</SPAN>"; if( tgoertzelp == h ) contents += "<INPUT TYPE=SUBMIT ONCLICK='Goertz(" + n + ", " + freq * (h+goertzelpoint) + ", " + (goertzelpoint) + ", " + quantaA + ", 0)' VALUE='↑" + (goertzelpoint).toFixed(6) + "'/>";
contents += "</TD>"; contents += "</TD>";
} }
else if( mode == 1 ) else if( mode == 1 )
@@ -289,7 +294,7 @@ function computeTable()
else if( mode == 2 ) else if( mode == 2 )
{ {
contents += "<TD COLSPAN=2>" contents += "<TD COLSPAN=2>"
if( tgoertzelpi == h-1 ) contents += "<SPAN ONCLICK='Goertz(" + n + ", " + freq * (h-goertzelpointinv) + ", " + goertzelpointinv + ", " + quantaINV + ", 0)'>↓" + goertzelpointinv.toFixed(6) + "</SPAN>"; if( tgoertzelpi == h-1 ) contents += "<INPUT TYPE=SUBMIT ONCLICK='Goertz(" + n + ", " + freq * (h-goertzelpointinv) + ", " + goertzelpointinv + ", " + quantaINV + ", 0)' VALUE='↓" + goertzelpointinv.toFixed(6) + "'/>";
contents += "</TD>"; contents += "</TD>";
} }
else if( mode == 3 ) else if( mode == 3 )
@@ -328,7 +333,7 @@ function computeTable()
contents += "<TH COLSPAN=1>" + h + "</TH>"; contents += "<TH COLSPAN=1>" + h + "</TH>";
} }
for( let n = 0|28; n <= 96; n++ ) for( let n = 0|28; n <= 96; n+=2 )
{ {
let freq = ( xtal / n ); let freq = ( xtal / n );
let goertzelpoint = 0; let goertzelpoint = 0;
@@ -358,7 +363,7 @@ function computeTable()
if( rid == 0 ) if( rid == 0 )
{ {
contents += "<TD COLSPAN=1 ROWSPAN=2>" contents += "<TD COLSPAN=1 ROWSPAN=2>"
contents += "<SPAN ONCLICK='Goertz(" + n + ", " + freq * (h+tgoertzelpoint) + ", " + (tgoertzelpoint) + ", " + quantaA + ", 1)'>↑" + n + "</SPAN>"; contents += "<INPUT TYPE=SUBMIT ONCLICK='Goertz(" + n + ", " + freq * (h+tgoertzelpoint) + ", " + (tgoertzelpoint) + ", " + quantaA + ", 1)' VALUE='↑" + n + "'/>";
contents += "</TD>" contents += "</TD>"
} }
} }
@@ -386,8 +391,37 @@ function computeTable()
document.getElementById( "TABLE" ).innerHTML = contents; document.getElementById( "TABLE" ).innerHTML = contents;
} }
const savedFields = ["crystalmhz", "targetmhz", "QUADRATURE", "GOERTZELS", "GOERTZELS2", "quanta", "quantasearch"];
function SaveDefaults()
{
for( i in savedFields )
{
let f = savedFields[i];
let e = document.getElementById(f);
if( e )
{
localStorage.setItem( f, e.value );
}
}
}
function LoadDefaults()
{
for( i in savedFields )
{
let f = savedFields[i];
let e = document.getElementById(f);
if( e && localStorage.getItem( f ) )
{
e.value = localStorage.getItem( f );
}
}
}
function onLoad() function onLoad()
{ {
LoadDefaults();
onLoadWebHidControl(); onLoadWebHidControl();
} }
</SCRIPT> </SCRIPT>
@@ -406,7 +440,7 @@ function onLoad()
<TR> <TR>
<TD VALIGN=TOP> <TD VALIGN=TOP>
<TABLE WIDTH=480> <TABLE WIDTH=480>
<TR><TD>Crystal MHz</TD><TD><INPUT ID=crystalmhz VALUE=144></TD></TR> <TR><TD>System Rate MHz</TD><TD><INPUT ID=crystalmhz VALUE=288></TD></TR>
<TR><TD>Target MHz</TD><TD><INPUT ID=targetmhz VALUE=27.019360></TD></TR> <TR><TD>Target MHz</TD><TD><INPUT ID=targetmhz VALUE=27.019360></TD></TR>
<TR><TD>Quanta</TD><TD><INPUT ID=quanta VALUE=1024> (Goertzel's Only)</TD></TR> <TR><TD>Quanta</TD><TD><INPUT ID=quanta VALUE=1024> (Goertzel's Only)</TD></TR>
<TR><TD>Quanta Search Range</TD><TD><INPUT ID=quantasearch VALUE=64> (Goertzel's Only)</TD></TR> <TR><TD>Quanta Search Range</TD><TD><INPUT ID=quantasearch VALUE=64> (Goertzel's Only)</TD></TR>
+6 -6
View File
@@ -110,7 +110,7 @@ async function toggleAudio()
if( n == this.rbuffertail ) \ if( n == this.rbuffertail ) \
{ \ { \
this.rbuffertail = (this.rbuffertail + (1|0))%(8192|0); \ this.rbuffertail = (this.rbuffertail + (1|0))%(8192|0); \
console.log( `Overflow` ); \ /*console.log( `Overflow` ); */ \
} \ } \
var vv = e.data[i]; \ var vv = e.data[i]; \
this.dcoffset = this.dcoffset * 0.995 + vv * 0.005; \ this.dcoffset = this.dcoffset * 0.995 + vv * 0.005; \
@@ -128,7 +128,7 @@ async function toggleAudio()
var s = Math.fround( this.sampleplace ); /*float*/ \ var s = Math.fround( this.sampleplace ); /*float*/ \
var tail = this.rbuffertail | 0; /* int*/ \ var tail = this.rbuffertail | 0; /* int*/ \
var tailnext = this.rbuffertail | 0; /* int*/ \ var tailnext = this.rbuffertail | 0; /* int*/ \
if( tail == this.rbufferhead ) { console.log( "Underflow " ); return true; }\ if( tail == this.rbufferhead ) { /*console.log( "Underflow " );*/ return true; }\
var tsamp = Math.fround( this.rbuffer[tail] ); \ var tsamp = Math.fround( this.rbuffer[tail] ); \
var nsamp = Math.fround( this.rbuffer[tailnext] ); \ var nsamp = Math.fround( this.rbuffer[tailnext] ); \
this.totalsampcount += len|0; \ this.totalsampcount += len|0; \
@@ -140,7 +140,7 @@ async function toggleAudio()
s -= excess; \ s -= excess; \
tail = ( tail + (excess|0) ) % (8192|0); \ tail = ( tail + (excess|0) ) % (8192|0); \
tailnext = ( tail + (1|0) ) % (8192|0); \ tailnext = ( tail + (1|0) ) % (8192|0); \
if( tail == this.rbufferhead ) { console.log( "Underflow" ); break; } \ if( tail == this.rbufferhead ) { /* console.log( "Underflow" ); */ break; } \
tsamp = Math.fround( this.rbuffer[tail] ); \ tsamp = Math.fround( this.rbuffer[tail] ); \
nsamp = Math.fround( this.rbuffer[tailnext] ); \ nsamp = Math.fround( this.rbuffer[tailnext] ); \
} \ } \
@@ -187,7 +187,7 @@ async function toggleAudio()
gainParam.setValueAtTime( 0, audioContext.currentTime ); gainParam.setValueAtTime( 0, audioContext.currentTime );
} }
var newVal = 0.1 - targetGain; var newVal = 0.5 - targetGain;
console.log( "Setting gain to: " + newVal ); console.log( "Setting gain to: " + newVal );
let gainParam = playingAudioProcessor.parameters.get("gain"); let gainParam = playingAudioProcessor.parameters.get("gain");
gainParam.setValueAtTime( newVal, audioContext.currentTime); gainParam.setValueAtTime( newVal, audioContext.currentTime);
@@ -356,7 +356,7 @@ async function sendLoop()
ctx.fillStyle = `rgb( 255 255 255 )`; ctx.fillStyle = `rgb( 255 255 255 )`;
let mulcoeff = 10000.0 / lastIntensity; let mulcoeff = 30000.0 / lastIntensity;
var lot = 1.2; var lot = 1.2;
var x = 253; var x = 253;
@@ -454,7 +454,7 @@ async function sendLoop()
if( audioContext != null && playingAudioProcessor != null ) if( audioContext != null && playingAudioProcessor != null )
{ {
// TODO: Use crystalmhz // TODO: Use crystalmhz
let sampleAdvance = (144000000.0/sample_divisor) / audioContext.sampleRate; let sampleAdvance = (system_rate/sample_divisor) / audioContext.sampleRate;
let sampleAdvanceParam = playingAudioProcessor.parameters.get("sampleAdvance"); let sampleAdvanceParam = playingAudioProcessor.parameters.get("sampleAdvance");
sampleAdvanceParam.setValueAtTime( sampleAdvance, audioContext.currentTime); sampleAdvanceParam.setValueAtTime( sampleAdvance, audioContext.currentTime);
playingAudioProcessor.port.postMessage( demodbuffer ); playingAudioProcessor.port.postMessage( demodbuffer );