Major changes to enable much more wifi information

This commit is contained in:
cnlohr 2015-08-06 23:55:53 -04:00
parent 8e67b46173
commit 577a0e2d36
19 changed files with 1337 additions and 726 deletions

View file

@ -21,6 +21,7 @@ static struct espconn *pHTTPServer;
struct espconn *pespconn;
uint16_t g_gpiooutputmask = 0;
int ets_str2macaddr(void *, void *);
static int need_to_switch_back_to_soft_ap = 0; //0 = no, 1 = will need to. 2 = do it now.
#define MAX_STATIONS 20
@ -156,12 +157,49 @@ int ICACHE_FLASH_ATTR issue_command(char * buffer, int retsize, char *pusrdata,
flashchip->chip_size = 0x00080000;
return buffend - buffer;
}
case 'i': case 'I': //Respond with device info.
{
buffend += ets_sprintf(buffend, "I" );
int i;
for( i = 0; i < 2 ;i++ )
{
struct ip_info ipi;
wifi_get_ip_info( i, &ipi );
buffend += ets_sprintf(buffend, "\t"IPSTR, IP2STR(&ipi.ip) );
}
buffend += ets_sprintf(buffend, "\r\n" );
return buffend - buffer;
}
case 'w': case 'W': // (W1:SSID:PASSWORD) (To connect) or (W2) to be own base station. ...or WI, to get info... or WS to scan.
{
char * colon = (char *) ets_strstr( (char*)&pusrdata[2], ":" );
char * colon2 = (colon)?((char *)ets_strstr( (char*)(colon+1), ":" )):0;
int c1l = 0;
int c2l = 0;
char * colon = (char *) ets_strstr( (char*)&pusrdata[2], "\t" );
char * colon2 = (colon)?((char *)ets_strstr( (char*)(colon+1), "\t" )):0;
char * colon3 = (colon2)?((char *)ets_strstr( (char*)(colon2+1), "\t" )):0;
char * colon4 = (colon3)?((char *)ets_strstr( (char*)(colon3+1), "\t" )):0;
char * extra = colon2;
char mac[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
int bssid_set = 0;
if( colon ) { *colon = 0; colon++; }
if( colon2 ) { *colon2 = 0; colon2++; }
if( colon3 ) { *colon3 = 0; colon3++; }
if( colon4 ) { *colon4 = 0; colon4++; }
if( colon ) { c1l = ets_strlen( colon ); }
if( colon2 ) { c2l = ets_strlen( colon2 ); }
if( colon3 )
{
bssid_set = ets_str2macaddr( mac, colon3 )?1:0;
if( ( mac[0] == 0x00 || mac[0] == 0xff ) &&
( mac[1] == 0x00 || mac[1] == 0xff ) &&
( mac[2] == 0x00 || mac[2] == 0xff ) &&
( mac[3] == 0x00 || mac[3] == 0xff ) &&
( mac[4] == 0x00 || mac[4] == 0xff ) &&
( mac[5] == 0x00 || mac[5] == 0xff ) ) bssid_set = 0;
}
if( extra )
{
for( ; *extra; extra++ )
@ -178,79 +216,139 @@ int ICACHE_FLASH_ATTR issue_command(char * buffer, int retsize, char *pusrdata,
{
case '1': //Station mode
case '2': //AP Mode
if( colon && colon2 )
if( colon && colon2 && ets_strlen( colon ) > 1 )
{
int c1l = 0;
int c2l = 0;
*colon = 0; colon++;
*colon2 = 0; colon2++;
c1l = ets_strlen( colon );
c2l = ets_strlen( colon2 );
if( c1l > 32 ) c1l = 32;
if( c2l > 32 ) c2l = 32;
if( c1l > 31 ) c1l = 31;
if( c2l > 63 ) c2l = 63;
printf( "Switching to: \"%s\"/\"%s\".\n", colon, colon2 );
printf( "Switching to: \"%s\"/\"%s\" (%d/%d). BSSID_SET: %d [%c]\n", colon, colon2, c1l, c2l, bssid_set, pusrdata[1] );
if( pusrdata[1] == '1' )
{
struct station_config stationConf;
os_bzero( &stationConf, sizeof( stationConf ) );
wifi_station_get_config(&stationConf);
os_memcpy(&stationConf.ssid, colon, c1l);
os_memcpy(&stationConf.password, colon2, c2l);
stationConf.ssid[c1l] = 0;
stationConf.password[c2l] = 0;
stationConf.bssid_set = bssid_set;
os_memcpy( stationConf.bssid, mac, 6 );
printf( "-->'%s'\n",stationConf.ssid);
printf( "-->'%s'\n",stationConf.password);
EnterCritical();
// wifi_station_set_config(&stationConf);
wifi_set_opmode( 1 );
wifi_station_set_config(&stationConf);
wifi_station_connect();
ExitCritical();
// wifi_station_get_config( &stationConf );
buffend += ets_sprintf( buffend, "W1\r\n" );
printf( "Switching.\n" );
}
else
{
wifi_set_opmode_current( 1 );
struct softap_config config;
char macaddr[6];
wifi_softap_get_config( &config );
wifi_get_macaddr(SOFTAP_IF, macaddr);
os_memcpy( &config.ssid, colon, c1l );
os_memcpy( &config.password, colon2, c2l );
config.ssid_len = c1l;
#if 0 //We don't support encryption.
config.ssid[c1l] = 0;
config.password[c2l] = 0;
config.authmode = 0;
if( colon3 )
{
int k;
for( k = 0; enctypes[k]; k++ )
{
if( strcmp( colon3, enctypes[k] ) == 0 )
config.authmode = k;
}
}
#endif
int chan = (colon4)?my_atoi(colon4):config.channel;
if( chan == 0 || chan > 13 ) chan = 1;
config.channel = chan;
// printf( "Mode now. %s %s %d %d %d %d %d\n", config.ssid, config.password, config.ssid_len, config.channel, config.authmode, config.max_connection );
// printf( "Mode Set. %d\n", wifi_get_opmode() );
EnterCritical();
wifi_softap_set_config(&config);
wifi_set_opmode( 2 );
ExitCritical();
printf( "Switching SoftAP: %d %d.\n", chan, config.authmode );
buffend += ets_sprintf( buffend, "W2\r\n" );
}
}
break;
case 'I':
{
char macmap[15];
int mode = wifi_get_opmode();
buffend += ets_sprintf( buffend, "WI%d", mode );
if( mode == 2 )
{
uint8_t mac[6];
struct softap_config ap;
wifi_softap_get_config( &ap );
buffend += ets_sprintf( buffend, "\t%s\t%s\t%s\t%d", ap.ssid, ap.password, enctypes[ap.authmode], ap.channel );
wifi_get_macaddr( 1, mac );
ets_sprintf( macmap, MACSTR, MAC2STR( mac ) );
buffend += ets_sprintf( buffend, "\t%s\t%s\t%s\t%d", ap.ssid, ap.password, macmap, ap.channel );
}
else
{
struct station_config sc;
wifi_station_get_config( &sc );
buffend += ets_sprintf( buffend, "\t%s\t%s\tna\t%d", sc.ssid, sc.password, wifi_get_channel() );
if( sc.bssid_set )
ets_sprintf( macmap, MACSTR, MAC2STR( sc.bssid ) );
else
macmap[0] = 0;
buffend += ets_sprintf( buffend, "\t%s\t%s\t%s\t%d", sc.ssid, sc.password, macmap, wifi_get_channel() );
}
}
break;
case 'X': case 'x':
buffend += ets_sprintf( buffend, "WX%d", wifi_station_get_rssi() );
break;
case 'S': case 's':
{
int i, r;
struct scan_config sc;
scanplace = 0;
sc.ssid = 0;
sc.bssid = 0;
sc.channel = 0;
sc.show_hidden = 1;
EnterCritical();
if( wifi_get_opmode() == SOFTAP_MODE )
{
wifi_set_opmode_current( STATION_MODE );
need_to_switch_back_to_soft_ap = 1;
r = wifi_station_scan(0, scandone );
}
else
{
r = wifi_station_scan(0, scandone );
}
r = wifi_station_scan(&sc, scandone );
ExitCritical();
buffend += ets_sprintf( buffend, "WS%d\n", r );
uart0_sendStr(buffer);
@ -386,7 +484,9 @@ void CSTick( int slowtick )
if( need_to_switch_back_to_soft_ap == 2 )
{
need_to_switch_back_to_soft_ap = 0;
EnterCritical();
wifi_set_opmode_current( SOFTAP_MODE );
ExitCritical();
}
HTTPTick(0);

View file

@ -7,6 +7,9 @@
#define HTDEBUG( x... ) printf( x )
//#define ISKEEPALIVE "keep-alive"
#define ISKEEPALIVE "close"
struct HTTPConnection HTTPConnections[HTTP_CONNECTIONS];
struct HTTPConnection * curhttp;
uint8 * curdata;
@ -208,7 +211,7 @@ void ICACHE_FLASH_ATTR HTTPHandleInternalCallback( )
if( curhttp->bytesleft < 0xfffffffe )
{
PushString("Connection: keep-alive\r\nContent-Length: ");
PushString("Connection: "ISKEEPALIVE"\r\nContent-Length: ");
Uint32To10Str( stto, curhttp->bytesleft );
PushBlob( stto, os_strlen( stto ) );
curhttp->keep_alive = 1;

View file

@ -145,7 +145,7 @@ void ICACHE_FLASH_ATTR NewWebSocket()
curhttp->rcb = 0;
curhttp->rcbDat = (void*)&WSEvalData;
}
else if( strcmp( (const char*)curhttp->pathbuffer, "/d/ws/issue" ) == 0 )
else if( strncmp( (const char*)curhttp->pathbuffer, "/d/ws/issue", 11 ) == 0 )
{
curhttp->rcb = 0;
curhttp->rcbDat = (void*)&WSCommandData;

View file

@ -4,7 +4,7 @@
#include "mystuff.h"
const char * enctypes[6] = { "open", "wep", "wpa", "wpa2", "wpa_wpa2", "max" };
const char * enctypes[6] = { "open", "wep", "wpa", "wpa2", "wpa_wpa2", 0 };
char generic_print_buffer[384];
char generic_buffer[1500];

View file

@ -13,7 +13,7 @@
extern char generic_print_buffer[384];
extern const char * enctypes[6];// = { "open", "wep", "wpa", "wpa2", "wpa_wpa2", "max" };
extern const char * enctypes[6];// = { "open", "wep", "wpa", "wpa2", "wpa_wpa2", 0 };
#define printf( ... ) ets_sprintf( generic_print_buffer, __VA_ARGS__ ); uart0_sendStr( generic_print_buffer );

Binary file not shown.

View file

@ -2,6 +2,7 @@
#include <gpio.h>
#include <ccconfig.h>
#include <eagle_soc.h>
#include "mystuff.h"
#include <DFT32.h>
#include <embeddednf.h>
#include <embeddedout.h>
@ -10,6 +11,8 @@ extern volatile uint8_t sounddata[];
extern volatile uint16_t soundhead;
#define CONFIGURABLES 16 //(plus1)
extern uint8_t RootNoteOffset; //Set to define what the root note is. 0 = A.
uint8_t gDFTIIR = 6;
uint8_t gFUZZ_IIR_BITS = 1;
@ -24,17 +27,37 @@ 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 gCOLORCHORD_ACTIVE = 1;
struct SaveLoad
{
uint8_t configs[CONFIGURABLES];
} settings;
uint8_t * gConfigurables[] = { &RootNoteOffset, &gDFTIIR, &gFUZZ_IIR_BITS, &gFILTER_BLUR_PASSES,
uint8_t gConfigDefaults[CONFIGURABLES] = { 0, 6, 1, 2, 3, 4, 7, 4, 2, 80, 64, 12, 15, NUM_LIN_LEDS, 1, 0 };
uint8_t * gConfigurables[CONFIGURABLES] = { &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 };
&gNERF_NOTE_PORP, &gUSE_NUM_LIN_LEDS, &gCOLORCHORD_ACTIVE, 0 };
char * gConfigurableNames[] = { "gROOT_NOTE_OFFSET", "gDFTIIR", "gFUZZ_IIR_BITS", "gFILTER_BLUR_PASSES",
char * gConfigurableNames[CONFIGURABLES] = { "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 };
"gNERF_NOTE_PORP", "gUSE_NUM_LIN_LEDS", "gCOLORCHORD_ACTIVE", 0 };
void ICACHE_FLASH_ATTR CustomStart( )
{
int i;
spi_flash_read( 0x3D000, (uint32*)&settings, sizeof( settings ) );
for( i = 0; i < CONFIGURABLES; i++ )
{
if( gConfigurables[i] )
{
*gConfigurables[i] = settings.configs[i];
}
}
}
int ICACHE_FLASH_ATTR CustomCommand(char * buffer, int retsize, char *pusrdata, unsigned short len)
{
@ -50,6 +73,7 @@ int ICACHE_FLASH_ATTR CustomCommand(char * buffer, int retsize, char *pusrdata,
int whichSel = my_atoi( &pusrdata[2] );
uint16_t * which = 0;
uint16_t qty = FIXBINS;
switch( whichSel )
{
case 0:
@ -57,13 +81,14 @@ int ICACHE_FLASH_ATTR CustomCommand(char * buffer, int retsize, char *pusrdata,
case 1:
which = fuzzed_bins; break;
case 2:
qty = FIXBPERO;
which = folded_bins; break;
default:
buffend += ets_sprintf( buffend, "!CB" );
return buffend-buffer;
}
buffend += ets_sprintf( buffend, "CB%d:%d:", whichSel, FIXBINS );
buffend += ets_sprintf( buffend, "CB%d:%d:", whichSel, qty );
for( i = 0; i < FIXBINS; i++ )
{
uint16_t samp = which[i];
@ -76,6 +101,22 @@ int ICACHE_FLASH_ATTR CustomCommand(char * buffer, int retsize, char *pusrdata,
}
case 'l': case 'L': //LEDs
{
int i, it = 0;
buffend += ets_sprintf( buffend, "CL:%d:", gUSE_NUM_LIN_LEDS );
uint16_t toledsvals = gUSE_NUM_LIN_LEDS*3;
if( toledsvals > 600 ) toledsvals = 600;
for( i = 0; i < toledsvals; i++ )
{
uint8_t samp = ledOut[it++];
*(buffend++) = tohex1( samp>>4 );
*(buffend++) = tohex1( samp&0x0f );
}
return buffend-buffer;
}
case 'm': case 'M': //Oscilloscope
{
int i, it = soundhead;
@ -118,6 +159,61 @@ int ICACHE_FLASH_ATTR CustomCommand(char * buffer, int retsize, char *pusrdata,
}
case 's': case 'S':
{
switch (pusrdata[2] )
{
case 'd': case 'D':
{
int i;
for( i = 0; i < CONFIGURABLES-1; i++ )
{
if( gConfigurables[i] )
*gConfigurables[i] = gConfigDefaults[i];
}
buffend += ets_sprintf( buffend, "CD" );
return buffend-buffer;
}
case 'r': case 'R':
{
int i;
for( i = 0; i < CONFIGURABLES-1; i++ )
{
if( gConfigurables[i] )
*gConfigurables[i] = settings.configs[i];
}
buffend += ets_sprintf( buffend, "CSR" );
return buffend-buffer;
}
case 's': case 'S':
{
int i;
for( i = 0; i < CONFIGURABLES-1; i++ )
{
if( gConfigurables[i] )
settings.configs[i] = *gConfigurables[i];
}
EnterCritical();
ets_intr_lock();
spi_flash_erase_sector( 0x3D000/4096 );
spi_flash_write( 0x3D000, (uint32*)&settings, ((sizeof( settings )-1)&(~0xf))+0x10 );
ets_intr_unlock();
ExitCritical();
buffend += ets_sprintf( buffend, "CS" );
return buffend-buffer;
}
}
buffend += ets_sprintf( buffend, "!CS" );
return buffend-buffer;
}
case 'v': case 'V': //ColorChord Values
{
@ -125,10 +221,7 @@ int ICACHE_FLASH_ATTR CustomCommand(char * buffer, int retsize, char *pusrdata,
{
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 );
buffend += ets_sprintf( buffend, "CVR:" );
i = 0;
while( gConfigurableNames[i] )
@ -137,6 +230,11 @@ int ICACHE_FLASH_ATTR CustomCommand(char * buffer, int retsize, char *pusrdata,
i++;
}
buffend += ets_sprintf( buffend, "rBASE_FREQ=%d:rDFREQ=%d:rOCTAVES=%d:rFIXBPERO=%d:rNOTERANGE=%d:rSORT_NOTES=%d:",
(int)BASE_FREQ, (int)DFREQ, (int)OCTAVES, (int)FIXBPERO, (int)(NOTERANGE),(int)SORT_NOTES );
buffend += ets_sprintf( buffend, "rMAXNOTES=%d:rNUM_LIN_LEDS=%d:rLIN_WRAPAROUND=%d:rLIN_WRAPAROUND=%d:",
(int)MAXNOTES, (int)NUM_LIN_LEDS, (int)LIN_WRAPAROUND, (int)LIN_WRAPAROUND );
return buffend-buffer;
}
else if( pusrdata[2] == 'W' || pusrdata[2] == 'w' )

View file

@ -31,10 +31,16 @@
static volatile os_timer_t some_timer;
static struct espconn *pUdpServer;
void EnterCritical();
void ExitCritical();
extern volatile uint8_t sounddata[HPABUFFSIZE];
extern volatile uint16_t soundhead;
uint16_t soundtail;
extern uint8_t gCOLORCHORD_ACTIVE;
static uint8_t hpa_running = 0;
void ICACHE_FLASH_ATTR CustomStart( );
void user_rf_pre_init()
{
@ -43,6 +49,8 @@ void user_rf_pre_init()
//Call this once we've stacked together one full colorchord frame.
static void NewFrame()
{
if( !gCOLORCHORD_ACTIVE ) return;
//uint8_t led_outs[NUM_LIN_LEDS*3];
int i;
HandleFrameInfo();
@ -63,6 +71,18 @@ static void procTask(os_event_t *events)
{
system_os_post(procTaskPrio, 0, 0 );
if( gCOLORCHORD_ACTIVE && !hpa_running )
{
ExitCritical();
hpa_running = 1;
}
if( !gCOLORCHORD_ACTIVE && hpa_running )
{
EnterCritical();
hpa_running = 0;
}
CSTick( 0 );
//For profiling so we can see how much CPU is spent in this loop.
@ -97,7 +117,7 @@ static void procTask(os_event_t *events)
int stat = wifi_station_get_connect_status();
// printf( "STAT: %d\n", stat );
//printf( "STAT: %d %d\n", stat, wifi_get_opmode() );
if( stat == STATION_WRONG_PASSWORD || stat == STATION_NO_AP_FOUND || stat == STATION_CONNECT_FAIL )
{
@ -142,7 +162,7 @@ static void udpserver_recv(void *arg, char *pusrdata, unsigned short len)
// uint8_t ledout[] = { 0x00, 0xff, 0xaa, 0x00, 0xff, 0xaa, };
uart0_sendStr("X");
ws2812_push( pusrdata, len );
ws2812_push( pusrdata+3, len );
}
void ICACHE_FLASH_ATTR charrx( uint8_t c )
@ -158,11 +178,37 @@ void ICACHE_FLASH_ATTR user_init(void)
uart0_sendStr("\r\nCustom Server\r\n");
// system_restore();
CustomStart();
#ifdef PROFILE
GPIO_OUTPUT_SET(GPIO_ID_PIN(0), 0);
#endif
int opmode = wifi_get_opmode();
printf( "Opmode: %d\n", opmode );
if( opmode == 1 )
{
struct station_config sc;
wifi_station_get_config(&sc);
printf( "Station mode: \"%s\":\"%s\" (bssid_set:%d)\n", sc.ssid, sc.password, sc.bssid_set );
if( sc.ssid[0] == 0 && !sc.bssid_set )
{
wifi_set_opmode( 2 );
opmode = 2;
}
else
{
wifi_station_connect();
}
}
if( opmode == 2 )
{
struct softap_config sc;
wifi_softap_get_config(&sc);
printf( "SoftAP mode: \"%s\":\"%s\"\n", sc.ssid, sc.password );
}
wifi_set_opmode( 2 ); //We broadcast our ESSID, wait for peopel to join.
// wifi_set_opmode( 2 ); //We broadcast our ESSID, wait for peopel to join.
/*
struct station_config stationConf;
@ -202,6 +248,7 @@ void ICACHE_FLASH_ATTR user_init(void)
InitColorChord(); //Init colorchord
StartHPATimer(); //Init the high speed ADC timer.
hpa_running = 1;
ws2812_init();

View file

@ -1,9 +1,12 @@
all : execute_reflash page.dat push
IP?=192.168.4.1
mfsmaker : mfsmaker.c
gcc -o $@ $^
page.dat : mfsmaker page
# cat to_compress/*.js | gzip -9 > page/compressed.js.gz
./mfsmaker page page.dat
pushtodev : pushtodev.c
@ -13,7 +16,7 @@ execute_reflash : execute_reflash.c md5.c
gcc -o $@ $^
push : pushtodev page.dat
./pushtodev 192.168.4.1 1048576 page.dat
./pushtodev $(IP) 1048576 page.dat
clean :
rm -rf mfsmaker page.dat pushtodev execute_reflash

View file

@ -127,6 +127,7 @@ uint32_t Push( uint32_t offset, const char * file )
fprintf( stderr, "Error: Timeout in communications.\n" );
exit( -6 );
}
if( reads != 0 )
devo += sendsize;
}

View file

@ -1,103 +0,0 @@
<html>
<head>
<title>ColorChord Control Panel</title>
<script language="javascript" type="text/javascript" src=jquery-2.1.4.min.js.gz></script>
<script language="javascript" type="text/javascript" src=colorchord.js></script>
<meta charset="UTF-8">
<style>
table { width: 100%; }
td { vertical-align: top; }
.collapsible { display:none; }
.inbutton { background-color:blue; }
</style>
</head>
<body>
<h2>ColorChord: Embedded</h2>
<hr>
<table>
<tr><td width=1>
<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>
</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
</div></td></tr></table></td></tr>
<tr><td width=1>
<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();">
<table border=1 width=1%>
<tr><td width=1>Type:</td><td><input type="radio" name="wifitype" value=1>Station (Connect to infrastructure)<br><input type="radio" name="wifitype" value=2>AP (Broadcast a new AP)</td></tr>
<tr><td>SSID:</td><td><input type="text" id="wificurname"></td></tr>
<tr><td>PASS:</td><td><input type="text" id="wificurpassword"></td></tr>
<tr><td>Enc:</td><td><input type="radio" name="wificurenctype" value="open">Open<br><input type="radio" name="wificurenctype" value="wpa-wpa2">WPA2-PSK (Ignored in Station mode)</td></tr>
<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></div></td></tr>
<tr><td width=1>
<input type=submit onclick="ShowHideEvent( 'CustomCommand' );" value="Custom Command"></td><td>
<div id=CustomCommand class="collapsible">
<table width=100% border=1><tr><td>
Command: <input type=text id=custom_command>
<input type=submit value="Submit" onclick="IssueCustomCommand()"><br>
<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>
</body>
</html>

View file

@ -1,477 +0,0 @@
var wsUri = "ws://" + location.host + "/d/ws/issue";
var output;
var websocket;
var commsup = 0;
//Push objects that have:
// .request
// .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;
workqueue.push( vp );
}
function init()
{
$( ".collapsible" ).each(function( index ) {
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();
KickWifiTicker();
GPIODataTickerStart();
KickOscilloscope();
KickDFT();
}
function StartWebSocket()
{
output.innerHTML = "Connecting...";
if( websocket ) websocket.close();
workqueue = [];
lastitem = null;
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
function onOpen(evt)
{
doSend('e' );
}
function onClose(evt)
{
$('#SystemStatusClicker').css("color", "red" );
commsup = 0;
}
var msg = 0;
var tickmessage = 0;
var lasthz = 0;
function Ticker()
{
lasthz = (msg - tickmessage);
tickmessage = msg;
if( lasthz == 0 )
{
$('#SystemStatusClicker').css("color", "red" );
commsup = 0;
StartWebSocket();
}
setTimeout( Ticker, 1000 );
}
function onMessage(evt)
{
msg++;
output.innerHTML = "<p>Messages: " + msg + "</p><p>Hz:" + lasthz + "</p>";
if( commsup != 1 )
{
commsup = 1;
$('#SystemStatusClicker').css("color", "green" );
}
if( lastitem && lastitem.callback )
{
lastitem.callback( lastitem, evt.data );
lastitem = null;
}
if( workqueue.length )
{
var elem = workqueue.shift();
delete workarray[elem.request];
if( elem.request )
{
doSend( elem.request );
lastitem = elem;
return;
}
}
doSend('e');
}
function onError(evt)
{
$('#SystemStatusClicker').css("color", "red" );
commsup = 0;
}
function doSend(message)
{
websocket.send(message);
}
function IsTabOpen( objname )
{
var obj = $( "#" + objname );
var opened = obj.is( '.opened' );
return opened != 0;
}
function ShowHideEvent( objname )
{
var obj = $( "#" + objname );
obj.slideToggle( 'fast' ).toggleClass( 'opened' );
var opened = obj.is( '.opened' );
localStorage["sh" + objname] = opened?1:0;
return opened!=0;
}
function IssueCustomCommand()
{
QueueOperation( $("#custom_command").val(), function( req,data) { $("#custom_command_response").val( data ); } );
}
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( IsTabOpen('WifiSettings') )
{
is_data_ticker_running = true;
if( !did_wifi_get_config )
{
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] );
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()
{
var st = "W";
st += document.wifisection.wifitype.value;
st += ":" + document.wifisection.wificurname.value;
st += ":" + document.wifisection.wificurpassword.value;
QueueOperation( st );
did_wifi_get_config = false;
}
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();
}

View file

@ -1,8 +1,132 @@
<HTML>
<BODY>
Hello! This is a test page.<BR>
<html>
<head>
<title>ColorChord Control Panel</title>
<script language="javascript" type="text/javascript" src=jquery-2.1.4.min.js.gz></script>
<script language="javascript" type="text/javascript" src=main.js></script>
<meta charset="UTF-8">
<style>
table { width: 100%; }
td { vertical-align: top; }
.collapsible { display:none; }
.inbutton { background-color:blue; }
</style>
</head>
<body>
<h2>ColorChord: Embedded</h2>
<hr>
<table>
<tr><td width=1>
<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>
</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>
<p>Welcome to the ColorChord: Embedded ESP8266 Web-based GUI.</p>
<p>This GUI uses WebSockets, and has only been tested under the newest (as of August, 2015) Chrome and Firefox browsers.</p>
<p>For more information about ColorChord, visit it on github, here: <a href=https://github.com/cnlohr/colorchord>https://github.com/cnlohr/colorchord</a></p>
</div></td></tr></table></td></tr>
<tr><td width=1>
<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: (May deviate from default configuration, reset here if in doubt)<form name="wifisection" action="javascript:ChangeWifiConfig();">
<table border=1 width=1%>
<tr><td width=1>Type:</td><td><input type="radio" name="wifitype" value=1>Station (Connect to infrastructure)<br><input type="radio" name="wifitype" value=2 onclick="document.wifisection.wificurname.value = 'ESP'">AP (Broadcast a new AP)</td></tr>
<tr><td>SSID:</td><td><input type="text" id="wificurname"></td></tr>
<tr><td>PASS:</td><td><input type="text" id="wificurpassword"></td></tr>
<tr><td>MAC:</td><td><input type="text" id="wifimac"> (Ignored in softAP mode)</td></tr>
<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"> (Automatically saves to flash)</td></tr>
</table></form>
Scanned Stations:
<div id=WifiStations></div>
<input type=submit onclick="QueueOperation('WS', null);" value="Scan For Stations (Will disconnect!)">
</td></tr></table></div></td></tr>
<tr><td width=1>
<input type=submit onclick="ShowHideEvent( 'CustomCommand' );" value="Custom Command"></td><td>
<div id=CustomCommand class="collapsible">
<table width=100% border=1><tr><td>
Command: <input type=text id=custom_command>
<input type=submit value="Submit" onclick="IssueCustomCommand()"><br>
<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=10%>
<CANVAS id=DFTCanvas width=512></CANVAS>
</td><td><select id=WhichCanvas><option value=0>DFT</option><option value=1>Fuzzed</option><option value=2>Folded</option></select>
<br><input type=button onclick="ToggleDFTPause();" id=DFTPauseButton value="|| / >"></td></tr></table></div></td></tr>
<tr><td width=1>
<input type=submit onclick="ShowHideEvent( 'LEDs' ); KickLEDs();" value="LEDs"></td><td>
<div id=LEDs class="collapsible">
<table width=100% border=1><tr><td id=LEDCanvasHolder><CANVAS id=LEDCanvas width=512 height=100></CANVAS></td>
<td><input type=button onclick="ToggleLEDPause();" id=LEDPauseButton value="|| / >"></td></tr></table>
</div></td></tr>
<tr><td width=1>
<input type=submit onclick="ShowHideEvent( 'Notes' ); KickNotes();" value="Notes"></td><td>
<div id=Notes class="collapsible">
<table width=1 border=1><tr><td><CANVAS id=NotesCanvas width=512 height=100></CANVAS></td>
<td width=100%><input type=button onclick="ToggleNotesPause();" id=NotesPauseButton value="|| / >"></td></tr></table>
</div></td></tr>
<tr><td width=1>
<input type=submit onclick="ShowHideEvent( 'Parameters' );" value="Parameters"></td><td>
<div id=Parameters class="collapsible">
<div id=InnerParameters></div>
<input type=button value="Save" onclick='QueueOperation( "CSS" )'> <input type=button value="Revert" onclick='QueueOperation( "CSR" )'> <input type=button value="Restore" onclick='QueueOperation( "CSD" )'>
</div>
</td></tr>
</table>
</body>
</html>
<IMG SRC=dsc.jpg>
</BODY>
</HTML>

View file

@ -0,0 +1,884 @@
var wsUri = "ws://" + location.host + "/d/ws/issue";
var output;
var websocket;
var commsup = 0;
globalParams = {};
//Push objects that have:
// .request
// .callback = function( ref (this object), data );
var workqueue = [];
var wifilines = [];
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;
workqueue.push( vp );
}
function init()
{
$( ".collapsible" ).each(function( index ) {
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();
KickWifiTicker();
GPIODataTickerStart();
KickOscilloscope();
KickDFT();
KickNotes();
KickLEDs();
}
function StartWebSocket()
{
output.innerHTML = "Connecting...";
if( websocket ) websocket.close();
workarray = {};
workqueue = [];
lastitem = null;
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
function onOpen(evt)
{
doSend('e' );
}
function onClose(evt)
{
$('#SystemStatusClicker').css("color", "red" );
commsup = 0;
}
var msg = 0;
var tickmessage = 0;
var lasthz = 0;
function Ticker()
{
setTimeout( Ticker, 1000 );
lasthz = (msg - tickmessage);
tickmessage = msg;
if( lasthz == 0 )
{
$('#SystemStatusClicker').css("color", "red" );
$('#SystemStatusClicker').prop( "value", "System Offline" );
commsup = 0;
StartWebSocket();
}
else
{
$('#SystemStatusClicker').prop( "value", "System " + lasthz + "Hz" );
}
QueueOperation( "CVR", ReceiveParameters );
}
function onMessage(evt)
{
msg++;
if( commsup != 1 )
{
commsup = 1;
$('#SystemStatusClicker').css("color", "green" );
}
if( lastitem )
{
if( lastitem.callback )
{
lastitem.callback( lastitem, evt.data );
lastitem = null;
}
}
else
{
output.innerHTML = "<p>Messages: " + msg + "</p><p>RSSI: " + evt.data.substr(2) + "</p>";
}
if( workqueue.length )
{
var elem = workqueue.shift();
delete workarray[elem.request];
if( elem.request )
{
doSend( elem.request );
lastitem = elem;
return;
}
}
doSend('wx'); //Request RSSI.
}
function onError(evt)
{
$('#SystemStatusClicker').css("color", "red" );
commsup = 0;
}
function doSend(message)
{
websocket.send(message);
}
function IsTabOpen( objname )
{
var obj = $( "#" + objname );
var opened = obj.is( '.opened' );
return opened != 0;
}
function ShowHideEvent( objname )
{
var obj = $( "#" + objname );
obj.slideToggle( 'fast' ).toggleClass( 'opened' );
var opened = obj.is( '.opened' );
localStorage["sh" + objname] = opened?1:0;
return opened!=0;
}
function IssueCustomCommand()
{
QueueOperation( $("#custom_command").val(), function( req,data) { $("#custom_command_response").val( data ); } );
}
window.addEventListener("load", init, false);
///////// Various functions that are not core appear down here.
function ChangeParam( p )
{
var num = Number( p.value );
var elem = p.id.substr( 5 );
QueueOperation( "CVW:" + elem + ":" + num );
}
var hasCreateParams = false;
function ReceiveParameters(req,data) {
var elems = data.split( ":" );
for( var v = 0; v < elems.length; v++ )
{
var pair = elems[v].split( "=" );
if( pair.length == 2 )
{
globalParams[pair[0]] = Number( pair[1] );
}
}
if( !hasCreateParams )
{
hasCreateParams = true;
var htv = "<table border=1><tr><th>Value</th><th width=100%>Parameter</th></tr>";
for( var v in globalParams )
{
var vp = globalParams[v];
htv += "<tr><td><INPUT TYPE=TEXT ID=param" + v + " VALUE=" + vp + " onchange=ChangeParam(this)></td><td>" + v + "</td></tr>";
}
$("#InnerParameters").html( htv + "</table>" );
for( var v in globalParams )
{
if( v.substr(0,1) == 'r' )
{
$("#param" + v).prop( "disabled", true );
}
}
}
for( var v in globalParams )
{
var vp = globalParams[v];
var p = $("#param"+v);
if( !p.is(":focus" ) )
p.val(vp);
}
}
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;
pause_dft = false;
function KickDFT()
{
$( "#DFTPauseButton" ).css( "background-color", (is_dft_running&&!pause_dft)?"green":"red" );
if( !is_dft_running && !pause_dft )
DFTDataTicker();
}
function ToggleDFTPause()
{
pause_dft = !pause_dft;
KickDFT();
}
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( ":" );
$( "#DFTPauseButton" ).css( "background-color", "green" );
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 * canvas.clientWidth / samps;
var samp = parseInt( data.substr(i*4,4),16 );
var y2 = ( 1.-samp / 2047 ) * canvas.clientHeight;
ctx.fillStyle = CCColor( i % globalParams["rFIXBPERO"] );
ctx.fillRect( x2, y2, canvas.clientWidth / samps, canvas.clientHeight-y2 );
ctx.strokeStyle = "#000000";
ctx.strokeRect( x2, y2, canvas.clientWidth / samps, canvas.clientHeight-y2 );
}
ctx.stroke();
var samp = parseInt( data.substr(i*2,2),16 );
DFTDataTicker();
}
function DFTDataTicker()
{
if( IsTabOpen('DFT') && !pause_dft )
{
is_dft_running = true;
QueueOperation( "CB" + $("#WhichCanvas").val(), GotDFT );
}
else
{
is_dft_running = 0;
}
$( "#DFTPauseButton" ).css( "background-color", (is_dft_running&&!pause_dft)?"green":"red" );
}
is_leds_running = false;
pause_led = false;
function KickLEDs()
{
$( "#LEDPauseButton" ).css( "background-color", (is_leds_running&&!pause_led)?"green":"red" );
if( !is_leds_running && !pause_led )
LEDDataTicker();
}
function ToggleLEDPause()
{
pause_led = !pause_led;
KickLEDs();
}
function GotLED(req,data)
{
var ls = document.getElementById('LEDCanvasHolder');
var canvas = document.getElementById('LEDCanvas');
var ctx = canvas.getContext('2d');
var h = ls.height;
var w = ls.width;
if( canvas.width != ls.clientWidth-10 ) canvas.width = ls.clientWidth-10;
if( ctx.canvas.width != canvas.clientWidth ) ctx.canvas.width = canvas.clientWidth;
var secs = data.split( ":" );
$( "#LEDPauseButton" ).css( "background-color", "green" );
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 );
for( var i = 0; i < samps; i++ )
{
var x2 = i * canvas.clientWidth / samps;
var samp = data.substr(i*6,6);
var y2 = ( 1.-samp / 2047 ) * canvas.clientHeight;
ctx.fillStyle = "#" + samp.substr( 2, 2 ) + samp.substr( 0, 2 ) + samp.substr( 4, 2 );
ctx.lineWidth = 0;
ctx.fillRect( x2, 0, canvas.clientWidth / samps+1, canvas.clientHeight );
}
var samp = parseInt( data.substr(i*2,2),16 );
LEDDataTicker();
}
function LEDDataTicker()
{
if( IsTabOpen('LEDs') && !pause_led )
{
is_leds_running = true;
QueueOperation( "CL", GotLED );
}
else
{
is_leds_running = 0;
}
$( "#LEDPauseButton" ).css( "background-color", (is_leds_running&&!pause_led)?"green":"red" );
}
is_notes_running = false;
pause_notes = false;
function KickNotes()
{
$( "#NotesPauseButton" ).css( "background-color", (is_notes_running&&!pause_notes)?"green":"red" );
if( !is_notes_running && !pause_notes )
NotesTicker();
}
function ToggleNotesPause()
{
pause_notes = !pause_notes;
KickNotes();
}
function GotNotes(req,data)
{
var canvas = document.getElementById('NotesCanvas');
var ctx = canvas.getContext('2d');
var secs = data.split( ":" );
var elems = Number(secs[1] );
ctx.canvas.width = 400;
ctx.canvas.height = elems*25;
$( "#NotesPauseButton" ).css( "background-color", "green" );
var data = secs[2];
ctx.fillStyle = "#000000";
ctx.font = "18px serif"
ctx.fillRect( 0, 0, canvas.width, canvas.height );
for( var i = 0; i < elems; i++ )
{
var peak = parseInt( data.substr(i*12+0,2),16 );
var amped = parseInt( data.substr(i*12+2,4),16 );
var amped2 = parseInt( data.substr(i*12+6,4),16 );
var jump = parseInt( data.substr(i*12+10,2),16 );
if( peak == 255 )
{
ctx.fillStyle = "#ffffff";
ctx.fillText( jump, 10, i*25 + 20 );
continue;
}
ctx.fillStyle = CCColorDetail( peak );
ctx.lineWidth = 0;
ctx.fillRect( 0, i*25, 100,25);
ctx.fillRect( 101, i*25, amped/200,25);
ctx.fillRect( 229, i*25, amped2/200,25);
ctx.fillStyle = "#000000";
ctx.fillText( peak, 10, i*25 + 20 );
ctx.fillStyle = "#ffffff";
ctx.fillText( amped, 121, i*25 + 20 );
ctx.fillText( amped2, 240, i*25 + 20 );
}
var samp = parseInt( data.substr(i*2,2),16 );
NotesTicker();
}
function NotesTicker()
{
if( IsTabOpen('Notes')&& !pause_notes )
{
is_notes_running = true;
QueueOperation( "CN", GotNotes );
}
else
{
is_notes_running = 0;
}
$( "#NotesPauseButton" ).css( "background-color", (is_notes_running&&!pause_notes)?"green":"red" );
}
did_wifi_get_config = false;
is_data_ticker_running = false;
function KickWifiTicker()
{
if( !is_data_ticker_running )
WifiDataTicker();
}
function BSSIDClick( i )
{
var tlines = wifilines[i];
document.wifisection.wifitype.value = 1;
document.wifisection.wificurname.value = tlines[0].substr(1);
document.wifisection.wificurpassword.value = "";
document.wifisection.wifimac.value = tlines[1];
document.wifisection.wificurchannel.value = 0;
return false;
}
function WifiDataTicker()
{
if( IsTabOpen('WifiSettings') )
{
is_data_ticker_running = true;
if( !did_wifi_get_config )
{
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.wifimac.value = params[3];
document.wifisection.wificurchannel.value = Number( params[4] );
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>"
wifilines = [];
for( i = 1; i < lines.length-1; i++ )
{
tlines = lines[i].split( "\t" );
wifilines.push(tlines);
var bssidval = "<a href='javascript:void(0);' onclick='return BSSIDClick(" + (i -1 )+ ")'>" + tlines[1];
innerhtml += "<TR><TD>" + tlines[0].substr(1) + "</TD><TD>" + bssidval + "</TD><TD>" + tlines[2] + "</TD><TD>" + tlines[3] + "</TD><TD>" + tlines[4] + "</TD></TR>";
}
}
innerhtml += "</TABLE>";
document.getElementById("WifiStations").innerHTML = innerhtml;
} );
setTimeout( WifiDataTicker, 500 );
}
else
{
is_data_ticker_running = 0;
}
}
function ChangeWifiConfig()
{
var st = "W";
st += document.wifisection.wifitype.value;
st += "\t" + document.wifisection.wificurname.value;
st += "\t" + document.wifisection.wificurpassword.value;
st += "\t" + document.wifisection.wifimac.value;
st += "\t" + document.wifisection.wificurchannel.value;
QueueOperation( st );
did_wifi_get_config = false;
}
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();
}
function CCColor( note )
{
return ECCtoHEX( (note * globalParams["rNOTERANGE"] / globalParams["rFIXBPERO"] + globalParams["gROOT_NOTE_OFFSET"] + globalParams["rNOTERANGE"] )%globalParams["rNOTERANGE"], 255, 255 );
}
function CCColorDetail( note )
{
return ECCtoHEX( (note + globalParams["gROOT_NOTE_OFFSET"] + globalParams["rNOTERANGE"] )%globalParams["rNOTERANGE"], 255, 255 );
}
function ECCtoHEX( note, sat, val )
{
var hue = 0;
var third = 65535/3;
var scalednote = note;
var renote = note * 65536 / globalParams["rNOTERANGE"];
//Note is expected to be a vale from 0..(NOTERANGE-1)
//renote goes from 0 to the next one under 65536.
if( renote < third )
{
//Yellow to Red.
hue = (third - renote) >> 1;
}
else if( renote < (third<<1) )
{
//Red to Blue
hue = (third-renote);
}
else
{
//hue = ((((65535-renote)>>8) * (uint32_t)(third>>8)) >> 1) + (third<<1);
hue = (((65536-renote)<<16) / (third<<1)) + (third>>1); // ((((65535-renote)>>8) * (uint32_t)(third>>8)) >> 1) + (third<<1);
}
hue >>= 8;
return EHSVtoHEX( hue, sat, val );
}
function EHSVtoHEX( hue, sat, val ) //0..255 for all
{
var SIXTH1 = 43;
var SIXTH2 = 85;
var SIXTH3 = 128;
var SIXTH4 = 171;
var SIXTH5 = 213;
var or = 0, og = 0, ob = 0;
hue -= SIXTH1; //Off by 60 degrees.
hue = (hue+256)%256;
//TODO: There are colors that overlap here, consider
//tweaking this to make the best use of the colorspace.
if( hue < SIXTH1 ) //Ok: Yellow->Red.
{
or = 255;
og = 255 - (hue * 255) / (SIXTH1);
}
else if( hue < SIXTH2 ) //Ok: Red->Purple
{
or = 255;
ob = hue*255 / SIXTH1 - 255;
}
else if( hue < SIXTH3 ) //Ok: Purple->Blue
{
ob = 255;
or = ((SIXTH3-hue) * 255) / (SIXTH1);
}
else if( hue < SIXTH4 ) //Ok: Blue->Cyan
{
ob = 255;
og = (hue - SIXTH3)*255 / SIXTH1;
}
else if( hue < SIXTH5 ) //Ok: Cyan->Green.
{
og = 255;
ob = ((SIXTH5-hue)*255) / SIXTH1;
}
else //Green->Yellow
{
og = 255;
or = (hue - SIXTH5) * 255 / SIXTH1;
}
var rv = val;
if( rv > 128 ) rv++;
var rs = sat;
if( rs > 128 ) rs++;
//or, og, ob range from 0...255 now.
//Need to apply saturation and value.
or = (or * val)>>8;
og = (og * val)>>8;
ob = (ob * val)>>8;
//OR..OB == 0..65025
or = or * rs + 255 * (256-rs);
og = og * rs + 255 * (256-rs);
ob = ob * rs + 255 * (256-rs);
//printf( "__%d %d %d =-> %d\n", or, og, ob, rs );
or >>= 8;
og >>= 8;
ob >>= 8;
if( or > 255 ) or = 255;
if( og > 255 ) og = 255;
if( ob > 255 ) ob = 255;
return "#" + tohex8(og) + tohex8(or) + tohex8(ob);
}
function tohex8( c )
{
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}

View file

@ -1 +0,0 @@
test

View file

@ -1,10 +0,0 @@
<HTML>
<HEAD>
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript" src=wstest.js></script>
</HEAD>
<BODY>
<h2>WebSocket Test</h2>
<div id="output"></div>
</BODY>
</HTML>

View file

@ -1,86 +0,0 @@
var wsUri = "ws://" + location.host + "/d/ws/echo";
var output;
function init()
{
output = document.getElementById("output");
console.log( wsUri );
testWebSocket();
}
function testWebSocket()
{
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
function repeatsend()
{
doSend('Hello!' );
setTimeout( repeatsend, 1000 );
}
function onOpen(evt)
{
writeToScreen("CONNECTED");
doSend('Hello.' );
//repeatsend();
// doSend('{"args": ["entity", 1000], "kwargs": {}, "op": "ClientUpdater__requestUpdates", "seq": 1, "context": ["ClientUpdater", 0]}');
}
function onClose(evt)
{
writeToScreen("DISCONNECTED");
}
var msg = 0;
var tickmessage = 0;
var lasthz = 0;
function Ticker()
{
lasthz = msg - tickmessage;
tickmessage = msg;
setTimeout( Ticker, 1000 );
}
function onMessage(evt)
{
// eval( evt.data );
output.innerHTML = msg++ + " " + lasthz;
doSend('x' );
// obj = JSON.parse(evt.data);
// console.log( obj );
// writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
// websocket.close();
}
function onError(evt)
{
writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}
function doSend(message)
{
writeToScreen("SENT: " + message);
websocket.send(message);
}
function writeToScreen(message)
{
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
window.addEventListener("load", init, false);
Ticker();

View file

@ -84,7 +84,7 @@ int main(int argc, char**argv)
servaddr.sin_port=htons(7878);
int devo = 0;
int lastsector = -1;
int lastsector_block = -1;
int resend_times = 0;
int r;
while( !feof( f ) )
@ -96,9 +96,10 @@ int main(int argc, char**argv)
int reads = fread( buffer, 1, 1024, f );
int sendplace = offset + devo;
int sendsize = reads;
int sector = sendplace / sector_SIZE;
if( sector != lastsector )
#ifdef SECTOR
int sector = sendplace / sector_SIZE;
if( sector != lastsector_block )
{
char se[64];
int sel = sprintf( se, "FE%d\r\n", sector );
@ -120,9 +121,36 @@ int main(int argc, char**argv)
exit( -6 );
}
lastsector = sector;
lastsector_block = sector;
}
#else //block
int block = sendplace / 65536;
if( block != lastsector_block )
{
char se[64];
int sel = sprintf( se, "FB%d\r\n", block );
thissuccess = 0;
for( tries = 0; tries < 10; tries++ )
{
char match[75];
printf( "Erase: %d\n", block );
sendto( sockfd, se, sel, MSG_NOSIGNAL, (struct sockaddr *)&servaddr,sizeof(servaddr));
sprintf( match, "FB%d", block );
if( PushMatch(match) == 0 ) { thissuccess = 1; break; }
printf( "Retry.\n" );
}
if( !thissuccess )
{
fprintf( stderr, "Error: Timeout in communications.\n" );
exit( -6 );
}
lastsector_block = block;
}
#endif
resend_times = 0;
resend:
r = sprintf( bufferout, "FW%d:%d:", sendplace, sendsize );