major changes to the backend for controlling the ESP8266 ColorChord.
A new challenger has arrived. It looks like basically... any network traffic causes glitches in the ADC in. Not sure how to attack that yet.
This commit is contained in:
parent
666d8077ab
commit
c4669ce825
|
@ -13,6 +13,7 @@ SRCS:=driver/uart.c \
|
|||
common/mfs.c \
|
||||
user/ws2812_i2s.c \
|
||||
user/hpatimer.c \
|
||||
user/custom_commands.c \
|
||||
driver/adc.c \
|
||||
../embeddedcommon/DFT32.c \
|
||||
../embeddedcommon/embeddednf.c \
|
||||
|
|
|
@ -1,13 +1,63 @@
|
|||
#ifndef _CCCONFIG_H
|
||||
#define _CCCONFIG_H
|
||||
|
||||
#include "c_types.h"
|
||||
|
||||
#define HPABUFFSIZE 512
|
||||
|
||||
#define CCEMBEDDED
|
||||
#define NUM_LIN_LEDS 24
|
||||
#define USE_NUM_LIN_LEDS 24
|
||||
#define NUM_LIN_LEDS 255
|
||||
#define DFREQ 16000
|
||||
|
||||
#define memcpy ets_memcpy
|
||||
#define memset ets_memset
|
||||
|
||||
extern uint8_t gDFTIIR; //=6
|
||||
#define DFTIIR gDFTIIR
|
||||
|
||||
extern uint8_t gFUZZ_IIR_BITS; //=1
|
||||
#define FUZZ_IIR_BITS gFUZZ_IIR_BITS
|
||||
|
||||
#define MAXNOTES 12 //MAXNOTES cannot be changed dynamically.
|
||||
|
||||
extern uint8_t gFILTER_BLUR_PASSES; //=2
|
||||
#define FILTER_BLUR_PASSES gFILTER_BLUR_PASSES
|
||||
|
||||
extern uint8_t gSEMIBITSPERBIN; //=3
|
||||
#define SEMIBITSPERBIN gSEMIBITSPERBIN
|
||||
|
||||
extern uint8_t gMAX_JUMP_DISTANCE; //=4
|
||||
#define MAX_JUMP_DISTANCE gMAX_JUMP_DISTANCE
|
||||
|
||||
extern uint8_t gMAX_COMBINE_DISTANCE; //=7
|
||||
#define MAX_COMBINE_DISTANCE gMAX_COMBINE_DISTANCE
|
||||
|
||||
extern uint8_t gAMP_1_IIR_BITS; //=4
|
||||
#define AMP_1_IIR_BITS gAMP_1_IIR_BITS
|
||||
|
||||
extern uint8_t gAMP_2_IIR_BITS; //=2
|
||||
#define AMP_2_IIR_BITS gAMP_2_IIR_BITS
|
||||
|
||||
extern uint8_t gMIN_AMP_FOR_NOTE; //=80
|
||||
#define MIN_AMP_FOR_NOTE gMIN_AMP_FOR_NOTE
|
||||
|
||||
extern uint8_t gMINIMUM_AMP_FOR_NOTE_TO_DISAPPEAR; //=64
|
||||
#define MINIMUM_AMP_FOR_NOTE_TO_DISAPPEAR gMINIMUM_AMP_FOR_NOTE_TO_DISAPPEAR
|
||||
|
||||
extern uint8_t gNOTE_FINAL_AMP; //=12
|
||||
#define NOTE_FINAL_AMP gNOTE_FINAL_AMP
|
||||
|
||||
extern uint8_t gNERF_NOTE_PORP; //=15
|
||||
#define NERF_NOTE_PORP gNERF_NOTE_PORP
|
||||
|
||||
extern uint8_t gUSE_NUM_LIN_LEDS; // = NUM_LIN_LEDS
|
||||
#define USE_NUM_LIN_LEDS gUSE_NUM_LIN_LEDS
|
||||
|
||||
//We are not enabling these for the ESP8266 port.
|
||||
#define LIN_WRAPAROUND 0
|
||||
#define SORT_NOTES 0
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -13,11 +13,14 @@
|
|||
#include "http.h"
|
||||
#include "spi_flash.h"
|
||||
#include "esp8266_rom.h"
|
||||
#include <gpio.h>
|
||||
#include "flash_rewriter.h"
|
||||
|
||||
static struct espconn *pUdpServer;
|
||||
static struct espconn *pHTTPServer;
|
||||
struct espconn *pespconn;
|
||||
uint16_t g_gpiooutputmask = 0;
|
||||
|
||||
|
||||
static int need_to_switch_back_to_soft_ap = 0; //0 = no, 1 = will need to. 2 = do it now.
|
||||
#define MAX_STATIONS 20
|
||||
|
@ -64,6 +67,7 @@ static void ICACHE_FLASH_ATTR scandone(void *arg, STATUS status)
|
|||
int ICACHE_FLASH_ATTR issue_command(char * buffer, int retsize, char *pusrdata, unsigned short len)
|
||||
{
|
||||
char * buffend = buffer;
|
||||
pusrdata[len] = 0;
|
||||
|
||||
switch( pusrdata[0] )
|
||||
{
|
||||
|
@ -271,8 +275,68 @@ int ICACHE_FLASH_ATTR issue_command(char * buffer, int retsize, char *pusrdata,
|
|||
}
|
||||
return buffend - buffer;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
case 'G': case 'g':
|
||||
{
|
||||
static const uint32_t AFMapper[16] = {
|
||||
0, PERIPHS_IO_MUX_U0TXD_U, 0, PERIPHS_IO_MUX_U0RXD_U,
|
||||
0, 0, 1, 1,
|
||||
1, 1, 1, 1,
|
||||
PERIPHS_IO_MUX_MTDI_U, PERIPHS_IO_MUX_MTCK_U, PERIPHS_IO_MUX_MTMS_U, PERIPHS_IO_MUX_MTDO_U };
|
||||
|
||||
int nr = my_atoi( &pusrdata[2] );
|
||||
|
||||
|
||||
if( AFMapper[nr] == 1 )
|
||||
{
|
||||
buffend += ets_sprintf( buffend, "!G%c%d\n", pusrdata[1], nr );
|
||||
return buffend - buffer;
|
||||
}
|
||||
else if( AFMapper[nr] )
|
||||
{
|
||||
PIN_FUNC_SELECT( AFMapper[nr], 3); //Select AF pin to be GPIO.
|
||||
}
|
||||
|
||||
switch( pusrdata[1] )
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
GPIO_OUTPUT_SET(GPIO_ID_PIN(nr), pusrdata[1]-'0' );
|
||||
buffend += ets_sprintf( buffend, "G%c%d", pusrdata[1], nr );
|
||||
g_gpiooutputmask |= (1<<nr);
|
||||
break;
|
||||
case 'i': case 'I':
|
||||
GPIO_DIS_OUTPUT(GPIO_ID_PIN(nr));
|
||||
buffend += ets_sprintf( buffend, "GI%d\n", nr );
|
||||
g_gpiooutputmask &= ~(1<<nr);
|
||||
break;
|
||||
case 'f': case 'F':
|
||||
{
|
||||
int on = GPIO_INPUT_GET( GPIO_ID_PIN(nr) );
|
||||
on = !on;
|
||||
GPIO_OUTPUT_SET(GPIO_ID_PIN(nr), on );
|
||||
g_gpiooutputmask |= (1<<nr);
|
||||
buffend += ets_sprintf( buffend, "GF%d:%d\n", nr, on );
|
||||
break;
|
||||
}
|
||||
case 'g': case 'G':
|
||||
buffend += ets_sprintf( buffend, "GG%d:%d\n", nr, GPIO_INPUT_GET( GPIO_ID_PIN(nr) ) );
|
||||
break;
|
||||
case 's': case 'S':
|
||||
{
|
||||
uint32_t rmask = 0;
|
||||
int i;
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
rmask |= GPIO_INPUT_GET( GPIO_ID_PIN(i) )?(1<<i):0;
|
||||
}
|
||||
buffend += ets_sprintf( buffend, "GS:%d:%d\n", g_gpiooutputmask, rmask );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buffend - buffer;
|
||||
}
|
||||
case 'c': case 'C':
|
||||
return CustomCommand( buffer, retsize, pusrdata, len);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -307,7 +371,6 @@ void ICACHE_FLASH_ATTR CSInit()
|
|||
espconn_regist_connectcb(pHTTPServer, httpserver_connectcb);
|
||||
espconn_accept(pHTTPServer);
|
||||
espconn_regist_time(pHTTPServer, 15, 0); //timeout
|
||||
|
||||
}
|
||||
|
||||
void CSTick( int slowtick )
|
||||
|
|
|
@ -11,14 +11,19 @@
|
|||
//NOTE: It is SAFE to use pusrdata and retdata as the same buffer.
|
||||
int ICACHE_FLASH_ATTR issue_command(char * retdata, int retsize, char *pusrdata, unsigned short len);
|
||||
|
||||
|
||||
//Includes UDP Control + HTTP Interfaces
|
||||
void ICACHE_FLASH_ATTR CSInit();
|
||||
void ICACHE_FLASH_ATTR CSTick( int slowtick );
|
||||
|
||||
//You must provide:
|
||||
//Critical should not lock interrupts, just disable services that have problems
|
||||
//with double-interrupt faults. I.e. turn off/on any really fast timer interrupts.
|
||||
//These generally only get called when doing serious operations like reflashing.
|
||||
void EnterCritical();
|
||||
void ExitCritical();
|
||||
|
||||
//If we receive a command that's not F, E or W (Flash Echo Wifi)
|
||||
int ICACHE_FLASH_ATTR CustomCommand(char * buffer, int retsize, char *pusrdata, unsigned short len);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -62,6 +62,13 @@ void Uint32To10Str( char * out, uint32 dat )
|
|||
out[place] = 0;
|
||||
}
|
||||
|
||||
char tohex1( uint8_t i )
|
||||
{
|
||||
i = i&0x0f;
|
||||
return (i<10)?('0'+i):('a'-10+i);
|
||||
}
|
||||
|
||||
|
||||
void ICACHE_FLASH_ATTR EndTCPWrite( struct espconn * conn )
|
||||
{
|
||||
if(generic_ptr!=generic_buffer)
|
||||
|
|
|
@ -17,6 +17,8 @@ extern const char * enctypes[6];// = { "open", "wep", "wpa", "wpa2", "wpa_wpa2",
|
|||
|
||||
#define printf( ... ) ets_sprintf( generic_print_buffer, __VA_ARGS__ ); uart0_sendStr( generic_print_buffer );
|
||||
|
||||
char tohex1( uint8_t i );
|
||||
|
||||
int32 my_atoi( const char * in );
|
||||
void Uint32To10Str( char * out, uint32 dat );
|
||||
|
||||
|
|
Binary file not shown.
184
embedded8266/user/custom_commands.c
Normal file
184
embedded8266/user/custom_commands.c
Normal file
|
@ -0,0 +1,184 @@
|
|||
#include "commonservices.h"
|
||||
#include <gpio.h>
|
||||
#include <ccconfig.h>
|
||||
#include <eagle_soc.h>
|
||||
#include <DFT32.h>
|
||||
#include <embeddednf.h>
|
||||
#include <embeddedout.h>
|
||||
|
||||
extern volatile uint8_t sounddata[];
|
||||
extern volatile uint16_t soundhead;
|
||||
|
||||
|
||||
extern uint8_t RootNoteOffset; //Set to define what the root note is. 0 = A.
|
||||
uint8_t gDFTIIR = 6;
|
||||
uint8_t gFUZZ_IIR_BITS = 1;
|
||||
uint8_t gFILTER_BLUR_PASSES = 2;
|
||||
uint8_t gSEMIBITSPERBIN = 3;
|
||||
uint8_t gMAX_JUMP_DISTANCE = 4;
|
||||
uint8_t gMAX_COMBINE_DISTANCE = 7;
|
||||
uint8_t gAMP_1_IIR_BITS = 4;
|
||||
uint8_t gAMP_2_IIR_BITS = 2;
|
||||
uint8_t gMIN_AMP_FOR_NOTE = 80;
|
||||
uint8_t gMINIMUM_AMP_FOR_NOTE_TO_DISAPPEAR = 64;
|
||||
uint8_t gNOTE_FINAL_AMP = 12;
|
||||
uint8_t gNERF_NOTE_PORP = 15;
|
||||
uint8_t gUSE_NUM_LIN_LEDS = NUM_LIN_LEDS;
|
||||
|
||||
|
||||
uint8_t * gConfigurables[] = { &RootNoteOffset, &gDFTIIR, &gFUZZ_IIR_BITS, &gFILTER_BLUR_PASSES,
|
||||
&gSEMIBITSPERBIN, &gMAX_JUMP_DISTANCE, &gMAX_COMBINE_DISTANCE, &gAMP_1_IIR_BITS,
|
||||
&gAMP_2_IIR_BITS, &gMIN_AMP_FOR_NOTE, &gMINIMUM_AMP_FOR_NOTE_TO_DISAPPEAR, &gNOTE_FINAL_AMP,
|
||||
&gNERF_NOTE_PORP, &gUSE_NUM_LIN_LEDS, 0 };
|
||||
|
||||
char * gConfigurableNames[] = { "gROOT_NOTE_OFFSET", "gDFTIIR", "gFUZZ_IIR_BITS", "gFILTER_BLUR_PASSES",
|
||||
"gSEMIBITSPERBIN", "gMAX_JUMP_DISTANCE", "gMAX_COMBINE_DISTANCE", "gAMP_1_IIR_BITS",
|
||||
"gAMP_2_IIR_BITS", "gMIN_AMP_FOR_NOTE", "gMINIMUM_AMP_FOR_NOTE_TO_DISAPPEAR", "gNOTE_FINAL_AMP",
|
||||
"gNERF_NOTE_PORP", "gUSE_NUM_LIN_LEDS", 0 };
|
||||
|
||||
int ICACHE_FLASH_ATTR CustomCommand(char * buffer, int retsize, char *pusrdata, unsigned short len)
|
||||
{
|
||||
char * buffend = buffer;
|
||||
|
||||
switch( pusrdata[1] )
|
||||
{
|
||||
|
||||
|
||||
case 'b': case 'B': //bins
|
||||
{
|
||||
int i;
|
||||
int whichSel = my_atoi( &pusrdata[2] );
|
||||
|
||||
uint16_t * which = 0;
|
||||
switch( whichSel )
|
||||
{
|
||||
case 0:
|
||||
which = embeddedbins32; break;
|
||||
case 1:
|
||||
which = fuzzed_bins; break;
|
||||
case 2:
|
||||
which = folded_bins; break;
|
||||
default:
|
||||
buffend += ets_sprintf( buffend, "!CB" );
|
||||
return buffend-buffer;
|
||||
}
|
||||
|
||||
buffend += ets_sprintf( buffend, "CB%d:%d:", whichSel, FIXBINS );
|
||||
for( i = 0; i < FIXBINS; i++ )
|
||||
{
|
||||
uint16_t samp = which[i];
|
||||
*(buffend++) = tohex1( samp>>12 );
|
||||
*(buffend++) = tohex1( samp>>8 );
|
||||
*(buffend++) = tohex1( samp>>4 );
|
||||
*(buffend++) = tohex1( samp>>0 );
|
||||
}
|
||||
return buffend-buffer;
|
||||
}
|
||||
|
||||
|
||||
case 'm': case 'M': //Oscilloscope
|
||||
{
|
||||
int i, it = soundhead;
|
||||
buffend += ets_sprintf( buffend, "CM:512:" );
|
||||
for( i = 0; i < 512; i++ )
|
||||
{
|
||||
uint8_t samp = sounddata[it++];
|
||||
it = it & (HPABUFFSIZE-1);
|
||||
*(buffend++) = tohex1( samp>>4 );
|
||||
*(buffend++) = tohex1( samp&0x0f );
|
||||
}
|
||||
return buffend-buffer;
|
||||
}
|
||||
|
||||
case 'n': case 'N': //Notes
|
||||
{
|
||||
int i;
|
||||
buffend += ets_sprintf( buffend, "CN:%d:", MAXNOTES );
|
||||
for( i = 0; i < MAXNOTES; i++ )
|
||||
{
|
||||
uint16_t dat;
|
||||
dat = note_peak_freqs[i];
|
||||
*(buffend++) = tohex1( dat>>4 );
|
||||
*(buffend++) = tohex1( dat>>0 );
|
||||
dat = note_peak_amps[i];
|
||||
*(buffend++) = tohex1( dat>>12 );
|
||||
*(buffend++) = tohex1( dat>>8 );
|
||||
*(buffend++) = tohex1( dat>>4 );
|
||||
*(buffend++) = tohex1( dat>>0 );
|
||||
dat = note_peak_amps2[i];
|
||||
*(buffend++) = tohex1( dat>>12 );
|
||||
*(buffend++) = tohex1( dat>>8 );
|
||||
*(buffend++) = tohex1( dat>>4 );
|
||||
*(buffend++) = tohex1( dat>>0 );
|
||||
dat = note_jumped_to[i];
|
||||
*(buffend++) = tohex1( dat>>4 );
|
||||
*(buffend++) = tohex1( dat>>0 );
|
||||
}
|
||||
return buffend-buffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
case 'v': case 'V': //ColorChord Values
|
||||
{
|
||||
if( pusrdata[2] == 'R' || pusrdata[2] == 'r' )
|
||||
{
|
||||
int i;
|
||||
|
||||
buffend += ets_sprintf( buffend, "CVR:rBASE_FREQ=%d:rDFREQ=%d:rOCTAVES=%d:rFIXBPERO=%d:NOTERANGE=%d:",
|
||||
(int)BASE_FREQ, (int)DFREQ, (int)OCTAVES, (int)FIXBPERO, (int)(NOTERANGE) );
|
||||
buffend += ets_sprintf( buffend, "CVR:rMAXNOTES=%d:rNUM_LIN_LEDS=%d:rLIN_WRAPAROUND=%d:rLIN_WRAPAROUND=%d:",
|
||||
(int)MAXNOTES, (int)NUM_LIN_LEDS, (int)LIN_WRAPAROUND, (int)LIN_WRAPAROUND );
|
||||
|
||||
i = 0;
|
||||
while( gConfigurableNames[i] )
|
||||
{
|
||||
buffend += ets_sprintf( buffend, "%s=%d:", gConfigurableNames[i], *gConfigurables[i] );
|
||||
i++;
|
||||
}
|
||||
|
||||
return buffend-buffer;
|
||||
}
|
||||
else if( pusrdata[2] == 'W' || pusrdata[2] == 'w' )
|
||||
{
|
||||
char * colon = 0, * colon2 = 0;
|
||||
do
|
||||
{
|
||||
int i = 0;
|
||||
colon = (char *) ets_strstr( (char*)&pusrdata[2], ":" );
|
||||
if( !colon ) break;
|
||||
*colon = 0;
|
||||
colon++;
|
||||
colon2 = (char *) ets_strstr( (char*)colon, ":" );
|
||||
if( !colon2 ) break;
|
||||
*colon2 = 0;
|
||||
colon2++;
|
||||
|
||||
while( gConfigurableNames[i] )
|
||||
{
|
||||
if( strcmp( colon, gConfigurableNames[i] ) == 0 )
|
||||
{
|
||||
*gConfigurables[i] = my_atoi(colon2);
|
||||
buffend += ets_sprintf( buffend, "CVW" );
|
||||
return buffend-buffer;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
} while( 0 );
|
||||
|
||||
buffend += ets_sprintf( buffend, "!CV" );
|
||||
return buffend-buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffend += ets_sprintf( buffend, "!CV" );
|
||||
return buffend-buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
#include "ws2812_i2s.h"
|
||||
#include "hpatimer.h"
|
||||
#include <DFT32.h>
|
||||
#include "ccconfig.h"
|
||||
#include <embeddednf.h>
|
||||
#include <embeddedout.h>
|
||||
#include "ets_sys.h"
|
||||
|
@ -31,7 +32,6 @@ static volatile os_timer_t some_timer;
|
|||
static struct espconn *pUdpServer;
|
||||
|
||||
|
||||
#define HPABUFFSIZE 512
|
||||
extern volatile uint8_t sounddata[HPABUFFSIZE];
|
||||
extern volatile uint16_t soundhead;
|
||||
uint16_t soundtail;
|
||||
|
@ -49,7 +49,7 @@ static void NewFrame()
|
|||
UpdateLinearLEDs();
|
||||
|
||||
//SendSPI2812( ledOut, NUM_LIN_LEDS );
|
||||
ws2812_push( ledOut, NUM_LIN_LEDS * 3 );
|
||||
ws2812_push( ledOut, USE_NUM_LIN_LEDS * 3 );
|
||||
}
|
||||
|
||||
os_event_t procTaskQueue[procTaskQueueLen];
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
table { width: 100%; }
|
||||
td { vertical-align: top; }
|
||||
.collapsible { display:none; }
|
||||
.inbutton { background-color:blue; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -20,18 +21,18 @@ td { vertical-align: top; }
|
|||
<input type=submit onclick="ShowHideEvent( 'SystemStatus' );" value="System Status" id=SystemStatusClicker></td><td>
|
||||
<div id=SystemStatus class="collapsible">
|
||||
<table width=100% border=1><tr><td>
|
||||
<div id=output></div>
|
||||
</td></tr></table></td></tr>
|
||||
<div id=output>
|
||||
</td></tr></table></div></td></tr>
|
||||
|
||||
<tr><td width=1>
|
||||
<input type=submit onclick="ShowHideEvent( 'Introduction' );" value="Introduction"></td><td>
|
||||
<div id=Introduction class="collapsible">
|
||||
<table border=1><tr><td>
|
||||
System Info...<br>line2<br>line3
|
||||
</td></tr></table></td></tr>
|
||||
</div></td></tr></table></td></tr>
|
||||
|
||||
<tr><td width=1>
|
||||
<input type=submit onclick="ShowHideEvent( 'WifiSettings' );" value="Wifi Settings"></td><td>
|
||||
<input type=submit onclick="ShowHideEvent( 'WifiSettings' ); KickWifiTicker();" value="Wifi Settings"></td><td>
|
||||
<div id=WifiSettings class="collapsible">
|
||||
<table width=100% border=1><tr><td>
|
||||
Current Configuration:<form name="wifisection" action="javascript:ChangeWifiConfig();">
|
||||
|
@ -43,11 +44,10 @@ Current Configuration:<form name="wifisection" action="javascript:ChangeWifiConf
|
|||
<tr><td>Chan:</td><td><input type="text" id="wificurchannel"> (Ignored in Station mode)</td></tr></tr>
|
||||
<tr><td></td><td><input type=submit value="Change Settings"></td></tr>
|
||||
</form></table>
|
||||
|
||||
Scanned Stations:
|
||||
<div id=WifiStations></div>
|
||||
<input type=submit onclick="QueueOperation('ws', null);" value="Scan For Stations (Will disconnect!)">
|
||||
</td></tr></table></td></tr>
|
||||
</td></tr></table></div></td></tr>
|
||||
|
||||
<tr><td width=1>
|
||||
<input type=submit onclick="ShowHideEvent( 'CustomCommand' );" value="Custom Command"></td><td>
|
||||
|
@ -58,6 +58,41 @@ Command: <input type=text id=custom_command>
|
|||
<textarea id=custom_command_response readonly rows=15 cols=80></textarea>
|
||||
</td></tr></table></td></tr>
|
||||
|
||||
<tr><td width=1>
|
||||
<input type=submit onclick="ShowHideEvent( 'GPIOs' ); GPIODataTicker();" value="GPIOs"></td><td>
|
||||
<div id=GPIOs class="collapsible">
|
||||
<table width=100% border=1><tr>
|
||||
<td align=center>0<input type=button id=ButtonGPIO0 value=0 onclick="TwiddleGPIO(0);"><input type=button id=BGPIOIn0 value=In onclick="GPIOInput(0);" class="inbutton"></td>
|
||||
<td align=center>1<input type=button id=ButtonGPIO1 value=0 onclick="TwiddleGPIO(1);"><input type=button id=BGPIOIn1 value=In onclick="GPIOInput(1);" class="inbutton"></td>
|
||||
<td align=center>2<input type=button id=ButtonGPIO2 value=0 onclick="TwiddleGPIO(2);"><input type=button id=BGPIOIn2 value=In onclick="GPIOInput(2);" class="inbutton"></td>
|
||||
<td align=center>3<input type=button id=ButtonGPIO3 value=0 onclick="TwiddleGPIO(3);"><input type=button id=BGPIOIn3 value=In onclick="GPIOInput(3);" class="inbutton"></td>
|
||||
<td align=center>4<input type=button id=ButtonGPIO4 value=0 onclick="TwiddleGPIO(4);"><input type=button id=BGPIOIn4 value=In onclick="GPIOInput(4);" class="inbutton"></td>
|
||||
<td align=center>5<input type=button id=ButtonGPIO5 value=0 onclick="TwiddleGPIO(5);"><input type=button id=BGPIOIn5 value=In onclick="GPIOInput(5);" class="inbutton"></td>
|
||||
<td>...</td>
|
||||
<td align=center>12<input type=button id=ButtonGPIO12 value=0 onclick="TwiddleGPIO(12);"><input type=button id=BGPIOIn12 value=In onclick="GPIOInput(12);" class="inbutton"></td>
|
||||
<td align=center>13<input type=button id=ButtonGPIO13 value=0 onclick="TwiddleGPIO(13);"><input type=button id=BGPIOIn13 value=In onclick="GPIOInput(13);" class="inbutton"></td>
|
||||
<td align=center>14<input type=button id=ButtonGPIO14 value=0 onclick="TwiddleGPIO(14);"><input type=button id=BGPIOIn14 value=In onclick="GPIOInput(14);" class="inbutton"></td>
|
||||
<td align=center>15<input type=button id=ButtonGPIO15 value=0 onclick="TwiddleGPIO(15);"><input type=button id=BGPIOIn15 value=In onclick="GPIOInput(15);" class="inbutton"></td>
|
||||
</tr></table></div></td></tr>
|
||||
|
||||
|
||||
|
||||
<tr><td width=1>
|
||||
<input type=submit onclick="ShowHideEvent( 'OScope' ); KickOscilloscope();" value="Oscilloscope"></td><td>
|
||||
<div id=OScope class="collapsible">
|
||||
<table width=100% border=1><tr><td width=10%>
|
||||
<CANVAS id=OScopeCanvas width=512></CANVAS>
|
||||
</td><td><input type=button onclick="ToggleOScopePause();" id=OScopePauseButton value="|| / >"></td></tr></table></div></td></tr>
|
||||
|
||||
|
||||
<tr><td width=1>
|
||||
<input type=submit onclick="ShowHideEvent( 'DFT' ); KickDFT();" value="DFT"></td><td>
|
||||
<div id=DFT class="collapsible">
|
||||
<table width=100% border=1><tr><td width=100%>
|
||||
<CANVAS id=DFTCanvas width=512></CANVAS>
|
||||
</td></tr></table></div></td></tr>
|
||||
|
||||
|
||||
|
||||
</table>
|
||||
|
||||
|
|
|
@ -8,10 +8,17 @@ var commsup = 0;
|
|||
// .callback = function( ref (this object), data );
|
||||
|
||||
var workqueue = [];
|
||||
var workarray = {};
|
||||
var lastitem;
|
||||
|
||||
function QueueOperation( command, callback )
|
||||
{
|
||||
if( workarray[command] == 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
workarray[command] = 1;
|
||||
var vp = new Object();
|
||||
vp.callback = callback;
|
||||
vp.request = command;
|
||||
|
@ -25,16 +32,20 @@ function init()
|
|||
if( localStorage["sh" + this.id] > 0.5 )
|
||||
{
|
||||
$( this ).show().toggleClass( 'opened' );
|
||||
// console.log( "OPEN: " + this.id );
|
||||
}
|
||||
});
|
||||
|
||||
$("#custom_command_response").val( "" );
|
||||
|
||||
|
||||
output = document.getElementById("output");
|
||||
Ticker();
|
||||
|
||||
|
||||
WifiDataTicker();
|
||||
KickWifiTicker();
|
||||
GPIODataTickerStart();
|
||||
KickOscilloscope();
|
||||
KickDFT();
|
||||
}
|
||||
|
||||
function StartWebSocket()
|
||||
|
@ -98,6 +109,7 @@ function onMessage(evt)
|
|||
if( workqueue.length )
|
||||
{
|
||||
var elem = workqueue.shift();
|
||||
delete workarray[elem.request];
|
||||
if( elem.request )
|
||||
{
|
||||
doSend( elem.request );
|
||||
|
@ -121,7 +133,12 @@ function doSend(message)
|
|||
websocket.send(message);
|
||||
}
|
||||
|
||||
|
||||
function IsTabOpen( objname )
|
||||
{
|
||||
var obj = $( "#" + objname );
|
||||
var opened = obj.is( '.opened' );
|
||||
return opened != 0;
|
||||
}
|
||||
|
||||
function ShowHideEvent( objname )
|
||||
{
|
||||
|
@ -129,6 +146,7 @@ function ShowHideEvent( objname )
|
|||
obj.slideToggle( 'fast' ).toggleClass( 'opened' );
|
||||
var opened = obj.is( '.opened' );
|
||||
localStorage["sh" + objname] = opened?1:0;
|
||||
return opened!=0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -149,49 +167,218 @@ window.addEventListener("load", init, false);
|
|||
|
||||
///////// Various functions that are not core appear down here.
|
||||
|
||||
is_oscilloscope_running = false;
|
||||
pause_oscilloscope = false;
|
||||
|
||||
function KickOscilloscope()
|
||||
{
|
||||
$( "#OScopePauseButton" ).css( "background-color", (is_oscilloscope_running&&pause_oscilloscope)?"green":"red" );
|
||||
if( !is_oscilloscope_running && !pause_oscilloscope)
|
||||
OScopeDataTicker();
|
||||
}
|
||||
|
||||
function ToggleOScopePause()
|
||||
{
|
||||
pause_oscilloscope = !pause_oscilloscope;
|
||||
KickOscilloscope();
|
||||
}
|
||||
|
||||
function GotOScope(req,data)
|
||||
{
|
||||
var canvas = document.getElementById('OScopeCanvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
var h = canvas.height;
|
||||
var w = canvas.width;
|
||||
if( ctx.canvas.width != canvas.clientWidth ) ctx.canvas.width = canvas.clientWidth;
|
||||
if( ctx.canvas.height != canvas.clientHeight ) ctx.canvas.height = canvas.clientHeight;
|
||||
|
||||
$( "#OScopePauseButton" ).css( "background-color", "green" );
|
||||
|
||||
var secs = data.split( ":" );
|
||||
|
||||
var samps = Number( secs[1] );
|
||||
var data = secs[2];
|
||||
var lastsamp = parseInt( data.substr(0,2),16 );
|
||||
ctx.clearRect( 0, 0, canvas.width, canvas.height );
|
||||
ctx.beginPath();
|
||||
for( var i = 0; i < samps; i++ )
|
||||
{
|
||||
var x2 = (i+1) * canvas.clientWidth / samps;
|
||||
var samp = parseInt( data.substr(i*2+2,2),16 );
|
||||
var y2 = ( 1.-samp / 255 ) * canvas.clientHeight;
|
||||
|
||||
if( i == 0 )
|
||||
{
|
||||
var x1 = i * canvas.clientWidth / samps;
|
||||
var y1 = ( 1.-lastsamp / 255 ) * canvas.clientHeight;
|
||||
ctx.moveTo( x1, y1 );
|
||||
}
|
||||
|
||||
ctx.lineTo( x2, y2 );
|
||||
|
||||
lastsamp = samp;
|
||||
}
|
||||
ctx.stroke();
|
||||
|
||||
var samp = parseInt( data.substr(i*2,2),16 );
|
||||
|
||||
OScopeDataTicker();
|
||||
}
|
||||
|
||||
function OScopeDataTicker()
|
||||
{
|
||||
if( IsTabOpen('OScope') && !pause_oscilloscope )
|
||||
{
|
||||
is_oscilloscope_running = true;
|
||||
QueueOperation( "CM", GotOScope );
|
||||
}
|
||||
else
|
||||
{
|
||||
is_oscilloscope_running = 0;
|
||||
}
|
||||
$( "#OScopePauseButton" ).css( "background-color", (is_oscilloscope_running&&!pause_oscilloscope)?"green":"red" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
is_dft_running = false;
|
||||
|
||||
function KickDFT()
|
||||
{
|
||||
if( !is_dft_running )
|
||||
DFTDataTicker();
|
||||
|
||||
}
|
||||
|
||||
function GotDFT(req,data)
|
||||
{
|
||||
var canvas = document.getElementById('DFTCanvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
var h = canvas.height;
|
||||
var w = canvas.width;
|
||||
if( ctx.canvas.width != canvas.clientWidth ) ctx.canvas.width = canvas.clientWidth;
|
||||
if( ctx.canvas.height != canvas.clientHeight ) ctx.canvas.height = canvas.clientHeight;
|
||||
|
||||
var secs = data.split( ":" );
|
||||
|
||||
var samps = Number( secs[1] );
|
||||
var data = secs[2];
|
||||
var lastsamp = parseInt( data.substr(0,4),16 );
|
||||
ctx.clearRect( 0, 0, canvas.width, canvas.height );
|
||||
ctx.beginPath();
|
||||
for( var i = 0; i < samps; i++ )
|
||||
{
|
||||
var x2 = (i+1) * canvas.clientWidth / samps;
|
||||
var samp = parseInt( data.substr(i*4+4,4),16 );
|
||||
var y2 = ( 1.-samp / 2047 ) * canvas.clientHeight;
|
||||
|
||||
if( i == 0 )
|
||||
{
|
||||
var x1 = i * canvas.clientWidth / samps;
|
||||
var y1 = ( 1.-lastsamp / 2047 ) * canvas.clientHeight;
|
||||
ctx.moveTo( x1, y1 );
|
||||
}
|
||||
|
||||
ctx.lineTo( x2, y2 );
|
||||
|
||||
lastsamp = samp;
|
||||
}
|
||||
ctx.stroke();
|
||||
|
||||
var samp = parseInt( data.substr(i*2,2),16 );
|
||||
|
||||
DFTDataTicker();
|
||||
}
|
||||
|
||||
function DFTDataTicker()
|
||||
{
|
||||
if( IsTabOpen('DFT') )
|
||||
{
|
||||
is_dft_running = true;
|
||||
QueueOperation( "CB", GotDFT );
|
||||
}
|
||||
else
|
||||
{
|
||||
is_dft_running = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
did_wifi_get_config = false;
|
||||
is_data_ticker_running = false;
|
||||
|
||||
function KickWifiTicker()
|
||||
{
|
||||
if( !is_data_ticker_running )
|
||||
WifiDataTicker();
|
||||
}
|
||||
|
||||
function WifiDataTicker()
|
||||
{
|
||||
if( !did_wifi_get_config )
|
||||
if( IsTabOpen('WifiSettings') )
|
||||
{
|
||||
QueueOperation( "WI", function(req,data)
|
||||
{
|
||||
var params = data.split( "\t" );
|
||||
|
||||
document.wifisection.wifitype.value = Number( params[0].substr(2) );
|
||||
document.wifisection.wificurname.value = params[1];
|
||||
document.wifisection.wificurpassword.value = params[2];
|
||||
document.wifisection.wificurenctype.value = params[3];
|
||||
document.wifisection.wificurchannel.value = Number( params[4] );
|
||||
is_data_ticker_running = true;
|
||||
|
||||
did_wifi_get_config = true;
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
QueueOperation( "WR", function(req,data) {
|
||||
var lines = data.split( "\n" );
|
||||
var innerhtml;
|
||||
if( lines.length < 3 )
|
||||
if( !did_wifi_get_config )
|
||||
{
|
||||
innerhtml = "No APs found. Did you scan?";
|
||||
}
|
||||
else
|
||||
{
|
||||
innerhtml = "<TABLE border=1><TR><TH>SSID</TH><TH>MAC</TH><TH>RS</TH><TH>Ch</TH><TH>Enc</TH></TR>"
|
||||
for( i = 1; i < lines.length-1; i++ )
|
||||
QueueOperation( "WI", function(req,data)
|
||||
{
|
||||
var dats = lines[i].split( "\t" );
|
||||
innerhtml += "<TR><TD>" + dats[0] + "</TD><TD>" + dats[1] + "</TD><TD>" + dats[2] + "</TD><TD>" + dats[3] + "</TD><TD>" + dats[4] + "</TD></TR>";
|
||||
}
|
||||
}
|
||||
innerhtml += "</HTML>";
|
||||
document.getElementById("WifiStations").innerHTML = innerhtml;
|
||||
} );
|
||||
var params = data.split( "\t" );
|
||||
|
||||
document.wifisection.wifitype.value = Number( params[0].substr(2) );
|
||||
document.wifisection.wificurname.value = params[1];
|
||||
document.wifisection.wificurpassword.value = params[2];
|
||||
document.wifisection.wificurenctype.value = params[3];
|
||||
document.wifisection.wificurchannel.value = Number( params[4] );
|
||||
|
||||
setTimeout( WifiDataTicker, 1000 );
|
||||
did_wifi_get_config = true;
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
QueueOperation( "WR", function(req,data) {
|
||||
var lines = data.split( "\n" );
|
||||
var innerhtml;
|
||||
if( lines.length < 3 )
|
||||
{
|
||||
innerhtml = "No APs found. Did you scan?";
|
||||
}
|
||||
else
|
||||
{
|
||||
innerhtml = "<TABLE border=1><TR><TH>SSID</TH><TH>MAC</TH><TH>RS</TH><TH>Ch</TH><TH>Enc</TH></TR>"
|
||||
for( i = 1; i < lines.length-1; i++ )
|
||||
{
|
||||
var dats = lines[i].split( "\t" );
|
||||
innerhtml += "<TR><TD>" + dats[0] + "</TD><TD>" + dats[1] + "</TD><TD>" + dats[2] + "</TD><TD>" + dats[3] + "</TD><TD>" + dats[4] + "</TD></TR>";
|
||||
}
|
||||
}
|
||||
innerhtml += "</TABLE>";
|
||||
document.getElementById("WifiStations").innerHTML = innerhtml;
|
||||
} );
|
||||
setTimeout( WifiDataTicker, 500 );
|
||||
}
|
||||
else
|
||||
{
|
||||
is_data_ticker_running = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function ChangeWifiConfig()
|
||||
|
@ -206,3 +393,85 @@ function ChangeWifiConfig()
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function TwiddleGPIO( gp )
|
||||
{
|
||||
var st = "GF";
|
||||
st += gp;
|
||||
QueueOperation( st );
|
||||
}
|
||||
|
||||
function GPIOInput( gp )
|
||||
{
|
||||
var st = "GI";
|
||||
st += gp;
|
||||
QueueOperation( st );
|
||||
}
|
||||
|
||||
function GPIOUpdate(req,data) {
|
||||
var secs = data.split( ":" );
|
||||
var op = 0;
|
||||
var n = Number(secs[2]);
|
||||
var m = Number(secs[1]);
|
||||
|
||||
for( op = 0; op < 16; op++ )
|
||||
{
|
||||
var b = $( "#ButtonGPIO" + op );
|
||||
if( b )
|
||||
{
|
||||
if( 1<<op & n )
|
||||
{
|
||||
b.css("background-color","red" );
|
||||
b.css("color","black" );
|
||||
b.prop( "value", "1" );
|
||||
}
|
||||
else
|
||||
{
|
||||
b.css("background-color","black" );
|
||||
b.css("color","white" );
|
||||
b.prop( "value", "0" );
|
||||
}
|
||||
}
|
||||
|
||||
b = $( "#BGPIOIn" + op );
|
||||
if( b )
|
||||
{
|
||||
if( 1<<op & m )
|
||||
{
|
||||
b.css("background-color","blue" );
|
||||
b.css("color","white" );
|
||||
b.attr( "value", "out" );
|
||||
}
|
||||
else
|
||||
{
|
||||
b.css("background-color","green" );
|
||||
b.css("color","white" );
|
||||
b.attr( "value", "in" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if( IsTabOpen('GPIOs') )
|
||||
QueueOperation( "GS", GPIOUpdate );
|
||||
}
|
||||
|
||||
function GPIODataTicker()
|
||||
{
|
||||
if( !IsTabOpen('GPIOs') ) return;
|
||||
QueueOperation( "GS", GPIOUpdate );
|
||||
setTimeout( GPIODataTicker, 500 );
|
||||
}
|
||||
|
||||
|
||||
function GPIODataTickerStart()
|
||||
{
|
||||
if( IsTabOpen('GPIOs') )
|
||||
GPIODataTicker();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -19,20 +19,29 @@
|
|||
#define BASE_FREQ 55.0
|
||||
|
||||
//The higher the number the slackier your FFT will be come.
|
||||
#ifndef FUZZ_IIR_BITS
|
||||
#define FUZZ_IIR_BITS 1
|
||||
#endif
|
||||
|
||||
//Notes are the individually identifiable notes we receive from the sound.
|
||||
//We track up to this many at one time. Just because a note may appear to
|
||||
//vaporize in one frame doesn't mean it is annihilated immediately.
|
||||
#ifndef MAXNOTES
|
||||
#define MAXNOTES 12
|
||||
#endif
|
||||
|
||||
//We take the raw signal off of the
|
||||
#ifndef FILTER_BLUR_PASSES
|
||||
#define FILTER_BLUR_PASSES 2
|
||||
#endif
|
||||
|
||||
//Determines bit shifts for where notes lie. We represent notes with an
|
||||
//uint8_t. We have to define all of the possible locations on the note line
|
||||
//in this. note_frequency = 0..((1<<SEMIBITSPERBIN)*FIXBPERO-1)
|
||||
#ifndef SEMIBITSPERBIN
|
||||
#define SEMIBITSPERBIN 3
|
||||
#endif
|
||||
|
||||
#define NOTERANGE ((1<<SEMIBITSPERBIN)*FIXBPERO)
|
||||
|
||||
|
||||
|
@ -40,26 +49,37 @@
|
|||
//then consider this new note the same one as last time, and move the
|
||||
//established note. This is also used when combining notes. It is this
|
||||
//distance times two.
|
||||
#ifndef MAX_JUMP_DISTANCE
|
||||
#define MAX_JUMP_DISTANCE 4
|
||||
#endif
|
||||
|
||||
#ifndef MAX_COMBINE_DISTANCE
|
||||
#define MAX_COMBINE_DISTANCE 7
|
||||
|
||||
#endif
|
||||
|
||||
//These control how quickly the IIR for the note strengths respond. AMP 1 is
|
||||
//the response for the slow-response, or what we use to determine size of
|
||||
//splotches, AMP 2 is the quick response, or what we use to see the visual
|
||||
//strength of the notes.
|
||||
#ifndef AMP_1_IIR_BITS
|
||||
#define AMP_1_IIR_BITS 4
|
||||
#endif
|
||||
|
||||
#ifndef AMP_2_IIR_BITS
|
||||
#define AMP_2_IIR_BITS 2
|
||||
#endif
|
||||
|
||||
//This is the amplitude, coming from folded_bins. If the value is below this
|
||||
//it is considered a non-note.
|
||||
#ifndef MIN_AMP_FOR_NOTE
|
||||
#define MIN_AMP_FOR_NOTE 80
|
||||
#endif
|
||||
|
||||
//If the strength of a note falls below this, the note will disappear, and be
|
||||
//recycled back into the unused list of notes.
|
||||
#ifndef MINIMUM_AMP_FOR_NOTE_TO_DISAPPEAR
|
||||
#define MINIMUM_AMP_FOR_NOTE_TO_DISAPPEAR 64
|
||||
|
||||
#endif
|
||||
|
||||
//This prevents compilation of any floating-point code, but it does come with
|
||||
//an added restriction: Both DFREQ and BASE_FREQ must be #defined to be
|
||||
|
@ -68,15 +88,16 @@
|
|||
|
||||
#include "DFT32.h"
|
||||
|
||||
extern uint16_t folded_bins[]; //[FIXBPERO] <- The folded fourier output.
|
||||
extern uint16_t fuzzed_bins[]; //[FIXBINS] <- The Full DFT after IIR, Blur and Taper
|
||||
|
||||
extern uint16_t folded_bins[]; //[FIXBPERO] <- The folded fourier output.
|
||||
|
||||
//frequency of note; Note if it is == 255, then it means it is not set. It is
|
||||
//generally a value from
|
||||
extern uint8_t note_peak_freqs[];
|
||||
extern uint8_t note_peak_freqs[]; //[MAXNOTES]
|
||||
extern uint16_t note_peak_amps[]; //[MAXNOTES]
|
||||
extern uint16_t note_peak_amps2[]; //[MAXNOTES] (Responds quicker)
|
||||
extern uint8_t note_jumped_to[]; //[MAXNOTES] When a note combines into another one,
|
||||
extern uint16_t note_peak_amps2[]; //[MAXNOTES] (Responds quicker)
|
||||
extern uint8_t note_jumped_to[]; //[MAXNOTES] When a note combines into another one,
|
||||
//this records where it went. I.e. if your note just disappeared, check this flag.
|
||||
|
||||
void UpdateFreqs(); //Not user-useful on most systems.
|
||||
|
|
Loading…
Reference in a new issue