diff --git a/embedded8266/common/http.c b/embedded8266/common/http.c index 08545af..1cd79d0 100644 --- a/embedded8266/common/http.c +++ b/embedded8266/common/http.c @@ -23,8 +23,12 @@ ICACHE_FLASH_ATTR void HTTPHandleInternalCallback( ); ICACHE_FLASH_ATTR void HTTPClose( ) { - curhttp->state = HTTP_STATE_NONE; - espconn_disconnect( curhttp->socket ); + //This is dead code, but it is a testament to Charles. + //Do not do this here. Wait for the ESP to tell us the + //socket is successfully closed. + //curhttp->state = HTTP_STATE_NONE; + curhttp->state = HTTP_WAIT_CLOSE; + espconn_disconnect( curhttp->socket ); } @@ -32,7 +36,6 @@ void ICACHE_FLASH_ATTR HTTPGotData( ) { uint8 c; curhttp->timeout = 0; - while( curlen-- ) { c = HTTPPOP; @@ -109,7 +112,6 @@ void ICACHE_FLASH_ATTR HTTPGotData( ) } else { - //printf( "__HTTPCLose1\n" ); HTTPClose( ); } break; @@ -149,7 +151,6 @@ static void DoHTTP( uint8_t timed ) } else { - //printf( "HTTPCLose2\n"); HTTPClose( ); } } @@ -165,7 +166,6 @@ static void DoHTTP( uint8_t timed ) { if( curhttp->timeout++ > HTTP_SERVER_TIMEOUT ) { - //printf( "HTTPClose3\n" ); HTTPClose( ); } } @@ -177,8 +177,10 @@ void HTTPTick( uint8_t timed ) uint8_t i; for( i = 0; i < HTTP_CONNECTIONS; i++ ) { + if( curhttp ) { printf( "Unexpected Race Condition\n" );} curhttp = &HTTPConnections[i]; DoHTTP( timed ); + curhttp = 0; } } @@ -266,7 +268,7 @@ void ICACHE_FLASH_ATTR HTTPHandleInternalCallback( ) curhttp->isdone = 1; } -void InternalStartHTTP( ) +void ICACHE_FLASH_ATTR InternalStartHTTP( ) { int32_t clusterno; int8_t i; @@ -322,19 +324,24 @@ void InternalStartHTTP( ) LOCAL void ICACHE_FLASH_ATTR http_disconnetcb(void *arg) { struct espconn *pespconn = (struct espconn *) arg; - curhttp = (struct HTTPConnection * )pespconn->reverse; - curhttp->state = 0; + ((struct HTTPConnection * )pespconn->reverse)->state = 0; } -LOCAL void ICACHE_FLASH_ATTR -http_recvcb(void *arg, char *pusrdata, unsigned short length) +LOCAL void http_recvcb(void *arg, char *pusrdata, unsigned short length) { struct espconn *pespconn = (struct espconn *) arg; + //Though it might be possible for this to interrupt the other + //tick task, I don't know if this is actually a probelem. + //I'm adding this back-up-the-register just in case. + if( curhttp ) { printf( "Unexpected Race Condition\n" );} + curhttp = (struct HTTPConnection * )pespconn->reverse; curdata = (uint8*)pusrdata; curlen = length; HTTPGotData(); + curhttp = 0 ; + } void ICACHE_FLASH_ATTR diff --git a/embedded8266/image.elf b/embedded8266/image.elf index 9d72368..76d2887 100755 Binary files a/embedded8266/image.elf and b/embedded8266/image.elf differ diff --git a/embedded8266/user/user_main.c b/embedded8266/user/user_main.c index b04fa21..1d4b705 100644 --- a/embedded8266/user/user_main.c +++ b/embedded8266/user/user_main.c @@ -83,8 +83,6 @@ static void procTask(os_event_t *events) hpa_running = 0; } - CSTick( 0 ); - //For profiling so we can see how much CPU is spent in this loop. #ifdef PROFILE WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(0), 1 ); @@ -109,6 +107,8 @@ static void procTask(os_event_t *events) if( events->sig == 0 && events->par == 0 ) { + CSTick( 0 ); + //Idle Event. struct station_config wcfg; char stret[256]; diff --git a/embedded8266/user/ws2812_i2s.c b/embedded8266/user/ws2812_i2s.c index 88f8eb7..2953eea 100644 --- a/embedded8266/user/ws2812_i2s.c +++ b/embedded8266/user/ws2812_i2s.c @@ -45,8 +45,16 @@ Extra copyright info: //Creates an I2S SR of 93,750 Hz, or 3 MHz Bitclock (.333us/sample) // 12000000L/(div*bestbck*2) //It is likely you could speed this up a little. -#define WS_I2S_BCK 16 + +#ifdef WS2812_THREE_SAMPLE +#define WS_I2S_BCK 22 //Seems to work as low as 19, but is shakey at 18. #define WS_I2S_DIV 4 +#elif defined( WS2812_FOUR_SAMPLE ) +#define WS_I2S_BCK 17 //Seems to work as low as 14, shoddy at 13. +#define WS_I2S_DIV 4 +#else +#error You need to either define WS2812_THREE_SAMPLE or WS2812_FOUR_SAMPLE +#endif #ifndef i2c_bbpll #define i2c_bbpll 0x67 @@ -400,7 +408,16 @@ void ICACHE_FLASH_ATTR ws2812_init() //All functions below this line are Public Domain 2015 Charles Lohr. //this code may be used by anyone in any way without restriction or limitation. +#ifdef WS2812_THREE_SAMPLE +static const uint16_t bitpatterns[16] = { + 0b100100100100, 0b100100100110, 0b100100110100, 0b100100110110, + 0b100110100100, 0b100110100110, 0b100110110100, 0b100110110110, + 0b110100100100, 0b110100100110, 0b110100110100, 0b110100110110, + 0b110110100100, 0b110110100110, 0b110110110100, 0b110110110110, +}; + +#elif defined(WS2812_FOUR_SAMPLE) //Tricky, send out WS2812 bits with coded pulses, one nibble, then the other. static const uint16_t bitpatterns[16] = { 0b1000100010001000, 0b1000100010001110, 0b1000100011101000, 0b1000100011101110, @@ -408,14 +425,67 @@ static const uint16_t bitpatterns[16] = { 0b1110100010001000, 0b1110100010001110, 0b1110100011101000, 0b1110100011101110, 0b1110111010001000, 0b1110111010001110, 0b1110111011101000, 0b1110111011101110, }; +#endif void ws2812_push( uint8_t * buffer, uint16_t buffersize ) { - uint16_t * bufferpl = (uint16_t*)&i2sBlock[0]; uint16_t place; // while( !ws2812_dma_complete ); +#ifdef WS2812_THREE_SAMPLE + uint8_t * bufferpl = (uint8_t*)&i2sBlock[0]; + +// buffersize += 3; +// if( buffersize * 4 + 1 > WS_BLOCKSIZE ) return; + + int pl = 0; + int quit = 0; + + //Once for each led. + for( place = 0; !quit; place++ ) + { + uint8_t b; + b = buffer[pl++]; uint16_t c1a = bitpatterns[(b&0x0f)]; uint16_t c1b = bitpatterns[(b>>4)]; + b = buffer[pl++]; uint16_t c2a = bitpatterns[(b&0x0f)]; uint16_t c2b = bitpatterns[(b>>4)]; + b = buffer[pl++]; uint16_t c3a = bitpatterns[(b&0x0f)]; uint16_t c3b = bitpatterns[(b>>4)]; + b = buffer[pl++]; uint16_t c4a = bitpatterns[(b&0x0f)]; uint16_t c4b = bitpatterns[(b>>4)]; + + if( pl >= buffersize ) + { + quit = 1; + if( pl-1 >= buffersize ) c4a = c4b = 0; + if( pl-2 >= buffersize ) c3a = c3b = 0; + if( pl-3 >= buffersize ) c2a = c2b = 0; + if( pl-4 >= buffersize ) c1a = c1b = 0; + } + + //Order of bits on wire: Reverse from how they appear here. +#define STEP1(x) (c##x##b >> 4 ) +#define STEP2(x) ((c##x##b << 4 ) | ( c##x##a>>8 )) +#define STEP3(x) (c##x##a & 0xff ) + + *(bufferpl++) = STEP1(2); + *(bufferpl++) = STEP3(1); + *(bufferpl++) = STEP2(1); + *(bufferpl++) = STEP1(1); + + *(bufferpl++) = STEP2(3); + *(bufferpl++) = STEP1(3); + *(bufferpl++) = STEP3(2); + *(bufferpl++) = STEP2(2); + + *(bufferpl++) = STEP3(4); + *(bufferpl++) = STEP2(4); + *(bufferpl++) = STEP1(4); + *(bufferpl++) = STEP3(3); + } + + while( bufferpl < &((uint8_t*)i2sBlock)[WS_BLOCKSIZE] ) *(bufferpl++) = 0; + +#elif defined(WS2812_FOUR_SAMPLE) + uint16_t * bufferpl = (uint16_t*)&i2sBlock[0]; + if( buffersize * 4 > WS_BLOCKSIZE ) return; for( place = 0; place < buffersize; place++ ) @@ -424,6 +494,7 @@ void ws2812_push( uint8_t * buffer, uint16_t buffersize ) *(bufferpl++) = bitpatterns[(btosend&0x0f)]; *(bufferpl++) = bitpatterns[(btosend>>4)&0x0f]; } +#endif #ifdef USE_2812_INTERRUPTS diff --git a/embedded8266/user/ws2812_i2s.h b/embedded8266/user/ws2812_i2s.h index fff35cc..85609d7 100644 --- a/embedded8266/user/ws2812_i2s.h +++ b/embedded8266/user/ws2812_i2s.h @@ -13,9 +13,19 @@ //#define I2SDMABUFLEN (32*2) //Length of one buffer, in 32-bit words. //NOTE: Blocksize MUST be divisible by 4. Cannot exceed 4092 -//Each LED takes up 12 block bytes. +//Each LED takes up 12 block bytes in WS2812_FOUR_SAMPLE +//Or 9 block bytes in WS2812_THREE_SAMPLE #define WS_BLOCKSIZE 4000 +//You can either have 3 or 4 samples per bit for WS2812s. +//3 sample can't go quite as fast as 4. +//3 sample uses more processing when updating than 4. +//4 takes up more RAM per LED than 3. +//3 has slightly more restrictve timing requirements. +//4 has more DMA load when running. +#define WS2812_THREE_SAMPLE +//#define WS2812_FOUR_SAMPLE + void ICACHE_FLASH_ATTR ws2812_init(); void ws2812_push( uint8_t * buffer, uint16_t buffersize ); //Buffersize = Nr LEDs * 3 diff --git a/embedded8266/web/page/index.html b/embedded8266/web/page/index.html index 567515c..b0be515 100644 --- a/embedded8266/web/page/index.html +++ b/embedded8266/web/page/index.html @@ -1,7 +1,10 @@ +
- |
-
-
| |
@@ -33,52 +32,6 @@ td { vertical-align: top; }
For more information about ColorChord, visit it on github, here: https://github.com/cnlohr/colorchord |
-Current Configuration: (May deviate from default configuration, reset here if in doubt) -Scanned Stations: - - - |
-Command:
- - - |
0 | -1 | -2 | -3 | -4 | -5 | -... | -12 | -13 | -14 | -15 | -
Copyright (C) 2015 <>< Charles Lohr, See LICENSE file for more info.
+Messages: " + msg + "
RSSI: " + evt.data.substr(2) + "
"; - } - - - 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. - - - - - - +window.addEventListener("load", maininit, false); @@ -258,11 +83,6 @@ function ReceiveParameters(req,data) { - - - - - is_oscilloscope_running = false; pause_oscilloscope = false; @@ -585,203 +405,6 @@ function NotesTicker() - - -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; - - ClickOpmode( 1 ); - return false; -} - -function ClickOpmode( i ) -{ - if( i == 1 ) - { - document.wifisection.wificurname.disabled = false; - document.wifisection.wificurpassword.disabled = false; - document.wifisection.wifimac.disabled = false; - document.wifisection.wificurchannel.disabled = true; - } - else - { - document.wifisection.wificurname.disabled = false; - document.wifisection.wificurpassword.disabled = true; - document.wifisection.wificurpassword.value = ""; - document.wifisection.wifimac.disabled = true; - document.wifisection.wificurchannel.disabled = 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" ); - - var opmode = Number( params[0].substr(2) ); - document.wifisection.wifitype.value = opmode; - 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] ); - - ClickOpmode( opmode ); - 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 = "SSID | MAC | RS | Ch | Enc |
---|---|---|---|---|
" + tlines[0].substr(1) + " | " + bssidval + " | " + tlines[2] + " | " + tlines[3] + " | " + tlines[4] + " |
\
+ \n |
\ + Current Configuration: (May deviate from default configuration, reset here if in doubt) \ + Scanned Stations: \ + \ + \ + |
\
+ Command: \
+ \ + \ + |
0 | \ +1 | \ +2 | \ +3 | \ +4 | \ +5 | \ +... | \ +12 | \ +13 | \ +14 | \ +15 | \ +
Messages: " + msg + "
RSSI: " + evt.data.substr(2) + "
"; + } + + + 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 ); } ); +} + + + + + + + +did_wifi_get_config = false; +is_data_ticker_running = false; +is_waiting_on_stations = false; + +function ScanForWifi() +{ + QueueOperation('WS', null); + is_waiting_on_stations=true; + IssueSystemMessage( "Scanning for Wifi..." ); +} + +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; + + ClickOpmode( 1 ); + return false; +} + +function ClickOpmode( i ) +{ + if( i == 1 ) + { + document.wifisection.wificurname.disabled = false; + document.wifisection.wificurpassword.disabled = false; + document.wifisection.wifimac.disabled = false; + document.wifisection.wificurchannel.disabled = true; + } + else + { + document.wifisection.wificurname.disabled = false; + document.wifisection.wificurpassword.disabled = true; + document.wifisection.wificurpassword.value = ""; + document.wifisection.wifimac.disabled = true; + document.wifisection.wificurchannel.disabled = 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" ); + + var opmode = Number( params[0].substr(2) ); + document.wifisection.wifitype.value = opmode; + 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] ); + + ClickOpmode( opmode ); + 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?"; + if( is_waiting_on_stations ) + { + IssueSystemMessage( "No APs found." ); + is_waiting_on_stations = false; + } + } + else + { + if( is_waiting_on_stations ) + { + IssueSystemMessage( "Scan Complete." ); + is_waiting_on_stations = false; + } + + innerhtml = "SSID | MAC | RS | Ch | Enc |
---|---|---|---|---|
" + tlines[0].substr(1) + " | " + bssidval + " | " + tlines[2] + " | " + tlines[3] + " | " + tlines[4] + " |