I am on my way with this, but it's going slowly.
This commit is contained in:
parent
202a67326a
commit
518d69c0aa
18 changed files with 998 additions and 0 deletions
150
embedded8266/user/colorchord.c
Normal file
150
embedded8266/user/colorchord.c
Normal file
|
@ -0,0 +1,150 @@
|
|||
#include "colorchord.h"
|
||||
|
||||
static uint8_t donefirstrun;
|
||||
static int8_t sintable[512]; //Actually [sin][cos] pairs.
|
||||
|
||||
//LDD instruction on AVR can read with constant offset. We can set Y to be the place in the buffer, and read with offset.
|
||||
static uint16_t datspace[bins*4]; //(advances,places,isses,icses)
|
||||
|
||||
//
|
||||
void HandleProgressiveInt( int8_t sample1, int8_t sample2 )
|
||||
{
|
||||
int i;
|
||||
uint16_t startpl = 0;
|
||||
int16_t ts, tc;
|
||||
int16_t tmp1;
|
||||
int8_t s1, c1;
|
||||
uint16_t ipl, localipl, adv;
|
||||
|
||||
|
||||
//startpl maps to 'Y'
|
||||
//
|
||||
|
||||
|
||||
//Estimated 68 minimum instructions... So for two pairs each... just under 5ksps, theoretical.
|
||||
//Running overall at ~2kHz.
|
||||
for( i = 0; i < bins; i++ ) //Loop, fixed size = 3 + 2 cycles 5
|
||||
{
|
||||
//12 cycles MIN
|
||||
adv = datspace[startpl++]; //Read, indirect from RAM (and increment) 2+2 cycles 4
|
||||
ipl = datspace[startpl++]; //Read, indirect from RAM (and increment) 2+2 cycles 4
|
||||
|
||||
//13 cycles MIN
|
||||
ipl += adv; //Advance, 16bit += 16bit, 1 + 1 cycles 2
|
||||
localipl = (ipl>>8)<<1; //Select upper 8 bits 1 cycles 1
|
||||
|
||||
// need to load Z with 'sintable' and add localipl 2
|
||||
s1 = sintable[localipl++]; //Read s1 component out of table. 2+2 cycles 2
|
||||
c1 = sintable[localipl++]; //Read c1 component out of table. 2 cycles 2
|
||||
|
||||
ts = (s1 * sample1); // 8 x 8 multiply signed + copy R1 out. zero MSB ts 2
|
||||
tc = (c1 * sample1); // 8 x 8 multiply signed + copy R1 out. zero MSB tc 2
|
||||
|
||||
|
||||
//15 cycles MIN
|
||||
ipl += adv; //Advance, 16bit += 16bit, 1 + 1 cycles 2
|
||||
localipl = (ipl>>8)<<1; //Select upper 8 bits 1 cycles 1
|
||||
|
||||
// need to load Z with 'sintable' and add localipl 2
|
||||
s1 = sintable[localipl++]; //Read s1 component out of table. 2 cycles 2
|
||||
c1 = sintable[localipl++]; //Read c1 component out of table. 2 cycles 2
|
||||
|
||||
ts += (s1 * sample2); // 8 x 8 multiply signed + add R1 out. 3
|
||||
tc += (c1 * sample2); // 8 x 8 multiply signed + add R1 out. 3
|
||||
|
||||
|
||||
//Add TS and TC to the datspace stuff. (24 instructions)
|
||||
tmp1 = datspace[startpl]; //Read out, sin component. 4
|
||||
tmp1 -= tmp1>>6; //Subtract from the MSB (with carry) 2
|
||||
tmp1 += ts>>6; //Add MSBs with carry 2
|
||||
|
||||
datspace[startpl++] = tmp1; //Store values back 4
|
||||
|
||||
tmp1 = datspace[startpl]; //Read out, sin component. 4
|
||||
tmp1 -= tmp1>>6; //Subtract from the MSB (with carry) 2
|
||||
tmp1 += tc>>6; //Add MSBs with carry 2
|
||||
|
||||
datspace[startpl++] = tmp1; //Store values back 4
|
||||
|
||||
datspace[startpl-3] = ipl; //Store values back 4
|
||||
}
|
||||
}
|
||||
|
||||
void SetupConstants()
|
||||
{
|
||||
int i;
|
||||
static int last_place;
|
||||
|
||||
if( !donefirstrun )
|
||||
{
|
||||
donefirstrun = 1;
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
sintable[i*2+0] = i;//(int8_t)((sin( i / 256.0 * 6.283 ) * 127.0));
|
||||
sintable[i*2+1] = i+1;//(int8_t)((cos( i / 256.0 * 6.283 ) * 127.0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for( i = 0; i < bins; i++ )
|
||||
{
|
||||
float freq = i;//frequencies[i];
|
||||
datspace[i*4] = 65536.0/freq;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
void DoDFTProgressiveInteger( float * outbins, float * frequencies, int bins, const float * databuffer, int place_in_data_buffer, int size_of_data_buffer, float q, float speedup )
|
||||
{
|
||||
int i;
|
||||
static int last_place;
|
||||
|
||||
if( !donefirstrun )
|
||||
{
|
||||
donefirstrun = 1;
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
sintable[i*2+0] = (int8_t)((sinf( i / 256.0 * 6.283 ) * 127.0));
|
||||
sintable[i*2+1] = (int8_t)((cosf( i / 256.0 * 6.283 ) * 127.0));
|
||||
}
|
||||
}
|
||||
|
||||
if( gbins != bins )
|
||||
{
|
||||
gbins = bins;
|
||||
if( datspace ) free( datspace );
|
||||
datspace = malloc( bins * 2 * 4 );
|
||||
}
|
||||
|
||||
|
||||
for( i = 0; i < bins; i++ )
|
||||
{
|
||||
float freq = frequencies[i];
|
||||
datspace[i*4] = 65536.0/freq;
|
||||
}
|
||||
|
||||
|
||||
for( i = last_place; i != ( place_in_data_buffer&0xffffe ); i = (i+2)%size_of_data_buffer )
|
||||
{
|
||||
int8_t ifr1 = (int8_t)( ((databuffer[i+0]) ) * 127 );
|
||||
int8_t ifr2 = (int8_t)( ((databuffer[i+1]) ) * 127 );
|
||||
// printf( "%d %d\n", i, place_in_data_buffer&0xffffe );
|
||||
HandleProgressiveInt( ifr1, ifr2 );
|
||||
}
|
||||
|
||||
last_place = place_in_data_buffer&0xfffe;
|
||||
|
||||
//Extract bins.
|
||||
for( i = 0; i < bins; i++ )
|
||||
{
|
||||
int16_t isps = datspace[i*4+2];
|
||||
int16_t ispc = datspace[i*4+3];
|
||||
int16_t mux = ( (isps/256) * (isps/256)) + ((ispc/256) * (ispc/256));
|
||||
// printf( "%d (%d %d)\n", mux, isps, ispc );
|
||||
outbins[i] = sqrt( mux )/100.0;
|
||||
}
|
||||
// printf( "\n");
|
||||
}
|
||||
|
||||
*/
|
17
embedded8266/user/colorchord.h
Normal file
17
embedded8266/user/colorchord.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef _COLORCHORD_H
|
||||
#define _COLORCHORD_H
|
||||
|
||||
#include "mem.h"
|
||||
#include "c_types.h"
|
||||
#include "user_interface.h"
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
|
||||
#define bins 120
|
||||
|
||||
void HandleProgressiveInt( int8_t sample1, int8_t sample2 );
|
||||
void SetupConstants();
|
||||
|
||||
#endif
|
||||
|
||||
|
3
embedded8266/user/mystuff.c
Normal file
3
embedded8266/user/mystuff.c
Normal file
|
@ -0,0 +1,3 @@
|
|||
#include "mystuff.h"
|
||||
|
||||
char generic_print_buffer[384];
|
8
embedded8266/user/mystuff.h
Normal file
8
embedded8266/user/mystuff.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef _MYSTUFF_H
|
||||
#define _MYSTUFF_H
|
||||
|
||||
extern char generic_print_buffer[384];
|
||||
|
||||
#define printf( ... ) os_sprintf( generic_print_buffer, __VA_ARGS__ ); uart0_sendStr( generic_print_buffer );
|
||||
|
||||
#endif
|
143
embedded8266/user/user_main.c
Normal file
143
embedded8266/user/user_main.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
#include "mem.h"
|
||||
#include "c_types.h"
|
||||
#include "user_interface.h"
|
||||
#include "ets_sys.h"
|
||||
#include "driver/uart.h"
|
||||
#include "osapi.h"
|
||||
#include "espconn.h"
|
||||
#include "mystuff.h"
|
||||
#include "ws2812.h"
|
||||
|
||||
#define PORT 7777
|
||||
#define SERVER_TIMEOUT 1000
|
||||
#define MAX_CONNS 5
|
||||
#define MAX_FRAME 2000
|
||||
|
||||
#define procTaskPrio 0
|
||||
#define procTaskQueueLen 1
|
||||
|
||||
|
||||
static volatile os_timer_t some_timer;
|
||||
static struct espconn *pUdpServer;
|
||||
|
||||
|
||||
|
||||
//Note to self. In future consider looking at this: http://pastebin.com/6eLxSrNz
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Tasks that happen all the time.
|
||||
|
||||
os_event_t procTaskQueue[procTaskQueueLen];
|
||||
static void ICACHE_FLASH_ATTR
|
||||
procTask(os_event_t *events)
|
||||
{
|
||||
system_os_post(procTaskPrio, 0, 0 );
|
||||
if( events->sig == 0 && events->par == 0 )
|
||||
{
|
||||
//Idle Event.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Timer event.
|
||||
static void ICACHE_FLASH_ATTR
|
||||
myTimer(void *arg)
|
||||
{
|
||||
int i;
|
||||
uart0_sendStr(".");
|
||||
SetupConstants();
|
||||
|
||||
#define GPIO_OUTPUT_SET(gpio_no, bit_value) \
|
||||
gpio_output_set(bit_value<<gpio_no, ((~bit_value)&0x01)<<gpio_no, 1<<gpio_no,0)
|
||||
GPIO_OUTPUT_SET(GPIO_ID_PIN(WSGPIO), 0);
|
||||
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
|
||||
|
||||
//XXX LOOK HERE!!!
|
||||
//Right now, I am not actually using real data from the inputs, but rather doing this to test performance of my algorithm.
|
||||
//The next step is to take real ADC inpts.
|
||||
for( i = 0; i < 4000; i++ )
|
||||
{
|
||||
HandleProgressiveInt( 0xaa, 0xbb );
|
||||
}
|
||||
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 0 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Called when new packet comes in.
|
||||
static void ICACHE_FLASH_ATTR
|
||||
udpserver_recv(void *arg, char *pusrdata, unsigned short len)
|
||||
{
|
||||
int i = 0;
|
||||
struct espconn *pespconn = (struct espconn *)arg;
|
||||
uint8_t buffer[MAX_FRAME];
|
||||
|
||||
//Make sure watchdog is disabled. WS2812's take a while and can mess it up.
|
||||
ets_wdt_disable();
|
||||
os_intr_lock();
|
||||
WS2812OutBuffer( pusrdata, len );
|
||||
os_intr_unlock();
|
||||
ets_sprintf( buffer, "%d\r\n", len );
|
||||
uart0_sendStr(buffer);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR at_recvTask()
|
||||
{
|
||||
//Called from UART.
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
uart_init(BIT_RATE_115200, BIT_RATE_115200);
|
||||
int wifiMode = wifi_get_opmode();
|
||||
|
||||
uart0_sendStr("\r\nCustom Server\r\n");
|
||||
|
||||
wifi_set_opmode( 2 ); //We broadcast our ESSID, wait for peopel to join.
|
||||
|
||||
pUdpServer = (struct espconn *)os_zalloc(sizeof(struct espconn));
|
||||
ets_memset( pUdpServer, 0, sizeof( struct espconn ) );
|
||||
espconn_create( pUdpServer );
|
||||
pUdpServer->type = ESPCONN_UDP;
|
||||
pUdpServer->proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp));
|
||||
pUdpServer->proto.udp->local_port = 7777;
|
||||
espconn_regist_recvcb(pUdpServer, udpserver_recv);
|
||||
|
||||
wifi_station_dhcpc_start();
|
||||
|
||||
if( espconn_create( pUdpServer ) )
|
||||
{
|
||||
while(1) { uart0_sendStr( "\r\nFAULT\r\n" ); }
|
||||
}
|
||||
|
||||
//XXX TODO figure out how to safely re-allow this.
|
||||
ets_wdt_disable();
|
||||
|
||||
char outbuffer[] = { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,0xff,0xff, 0x00,0xff,0x00 };
|
||||
WS2812OutBuffer( outbuffer, 1 ); //Initialize the output.
|
||||
|
||||
//Add a process
|
||||
system_os_task(procTask, procTaskPrio, procTaskQueue, procTaskQueueLen);
|
||||
|
||||
uart0_sendStr("\r\nCustom Server\r\n");
|
||||
WS2812OutBuffer( outbuffer, sizeof(outbuffer) );
|
||||
|
||||
|
||||
//Timer example
|
||||
os_timer_disarm(&some_timer);
|
||||
os_timer_setfn(&some_timer, (os_timer_func_t *)myTimer, NULL);
|
||||
os_timer_arm(&some_timer, 1000, 1);
|
||||
|
||||
system_os_post(procTaskPrio, 0, 0 );
|
||||
}
|
||||
|
||||
|
61
embedded8266/user/ws2812.c
Normal file
61
embedded8266/user/ws2812.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
#include "ws2812.h"
|
||||
#include "ets_sys.h"
|
||||
#include "mystuff.h"
|
||||
#include "osapi.h"
|
||||
|
||||
#define GPIO_OUTPUT_SET(gpio_no, bit_value) \
|
||||
gpio_output_set(bit_value<<gpio_no, ((~bit_value)&0x01)<<gpio_no, 1<<gpio_no,0)
|
||||
|
||||
|
||||
//I just used a scope to figure out the right time periods.
|
||||
|
||||
void SEND_WS_0()
|
||||
{
|
||||
uint8_t time = 8;
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
|
||||
while(time--)
|
||||
{
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 0 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SEND_WS_1()
|
||||
{
|
||||
uint8_t time = 9;
|
||||
while(time--)
|
||||
{
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
|
||||
}
|
||||
time = 3;
|
||||
while(time--)
|
||||
{
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 0 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void WS2812OutBuffer( uint8_t * buffer, uint16_t length )
|
||||
{
|
||||
uint16_t i;
|
||||
GPIO_OUTPUT_SET(GPIO_ID_PIN(WSGPIO), 0);
|
||||
for( i = 0; i < length; i++ )
|
||||
{
|
||||
uint8_t byte = buffer[i];
|
||||
if( byte & 0x80 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x40 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x20 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x10 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x08 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x04 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x02 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x01 ) SEND_WS_1(); else SEND_WS_0();
|
||||
}
|
||||
//reset will happen when it's low long enough.
|
||||
//(don't call this function twice within 10us)
|
||||
}
|
||||
|
||||
|
||||
|
16
embedded8266/user/ws2812.h
Normal file
16
embedded8266/user/ws2812.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef _WS2812_H
|
||||
#define _WS2812_H
|
||||
|
||||
#define WSGPIO 0
|
||||
|
||||
#include "c_types.h"
|
||||
#include "user_interface.h"
|
||||
#include "ets_sys.h"
|
||||
#include "gpio.h"
|
||||
|
||||
//You will have to os_intr_lock(); os_intr_unlock();
|
||||
|
||||
void WS2812OutBuffer( uint8_t * buffer, uint16_t length );
|
||||
|
||||
#endif
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue