diff --git a/ld/eagle.app.v6.ld b/ld/eagle.app.v6.ld index 6a67879..b976739 100644 --- a/ld/eagle.app.v6.ld +++ b/ld/eagle.app.v6.ld @@ -5,7 +5,7 @@ MEMORY dport0_0_seg : org = 0x3FF00000, len = 0x10 dram0_0_seg : org = 0x3FFE8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 - irom0_0_seg : org = 0x402A0000, len = 0x72000 + irom0_0_seg : org = 0x402A0000, len = 0x1e2000 } PHDRS diff --git a/lib/libfreertos.a b/lib/libfreertos.a index 755ead8..bfdaa1f 100644 Binary files a/lib/libfreertos.a and b/lib/libfreertos.a differ diff --git a/lib/libjson.a b/lib/libjson.a index 439fb35..e8e364b 100644 Binary files a/lib/libjson.a and b/lib/libjson.a differ diff --git a/lib/liblwip.a b/lib/liblwip.a index d9c188d..ccaa710 100644 Binary files a/lib/liblwip.a and b/lib/liblwip.a differ diff --git a/lib/libmain.a b/lib/libmain.a index 7a8062f..101ee3f 100644 Binary files a/lib/libmain.a and b/lib/libmain.a differ diff --git a/lib/libnet80211.a b/lib/libnet80211.a index 4087316..2338717 100644 Binary files a/lib/libnet80211.a and b/lib/libnet80211.a differ diff --git a/lib/libphy.a b/lib/libphy.a index 99e0e90..b9b0f5e 100644 Binary files a/lib/libphy.a and b/lib/libphy.a differ diff --git a/lib/libpp.a b/lib/libpp.a index e0e7803..8908133 100644 Binary files a/lib/libpp.a and b/lib/libpp.a differ diff --git a/lib/libssl.a b/lib/libssl.a index 85187cb..26a0ddb 100644 Binary files a/lib/libssl.a and b/lib/libssl.a differ diff --git a/lib/libudhcp.a b/lib/libudhcp.a index 358a800..97278d0 100644 Binary files a/lib/libudhcp.a and b/lib/libudhcp.a differ diff --git a/lib/libwpa.a b/lib/libwpa.a index 8c98f6c..fe7f728 100644 Binary files a/lib/libwpa.a and b/lib/libwpa.a differ diff --git a/mp3/mad/decoder.c b/mp3/mad/decoder.c index 64b2b5c..79e0f13 100644 --- a/mp3/mad/decoder.c +++ b/mp3/mad/decoder.c @@ -324,7 +324,7 @@ int ICACHE_FLASH_ATTR run_sync(struct mad_decoder *decoder) int result = 0; int r; - printf("run_sync\n"); +// printf("run_sync\n"); if (decoder->input_func == 0) return 0; diff --git a/mp3/make.sh b/mp3/make.sh index 32f23ef..02397cb 100755 --- a/mp3/make.sh +++ b/mp3/make.sh @@ -1,5 +1,5 @@ #!/bin/bash -e -make COMPILE=gcc BOOT=none APP=0 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE=512 +make COMPILE=gcc BOOT=none APP=0 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE=1024 #xtensa-lx106-elf-size ${ESPTOOL} --port ${ESPPORT} --baud ${ESPBAUD} write_flash 0x00000 ../bin/eagle.flash.bin 0xA0000 ../bin/eagle.irom0text.bin diff --git a/mp3/user/user_main.c b/mp3/user/user_main.c index 9251260..a10ec8c 100644 --- a/mp3/user/user_main.c +++ b/mp3/user/user_main.c @@ -20,43 +20,88 @@ #include "mad.h" +/* +Mem usage: +layer3: 744 bytes rodata +*/ + + #define server_ip "192.168.40.115" //#define server_ip "192.168.1.5" //#define server_ip "192.168.4.100" #define server_port 1234 +#define READER_THREAD +//#define UART_AUDIO +//#define FROMFLASH + + + + +#ifdef FROMFLASH +char ICACHE_RODATA_ATTR mp3data[]={ +#include "mp3.dat" +}; +#endif + struct madPrivateData { int fd; xSemaphoreHandle muxBufferBusy; xSemaphoreHandle semNeedRead; +#ifdef READER_THREAD char buff[2016]; int buffPos; +#endif +#ifdef FROMFLASH + char *fpos; +#endif }; -//#define printf(a, ...) while(0) +#ifdef UART_AUDIO +#define printf(a, ...) while(0) +#endif struct madPrivateData madParms; void render_sample_block(short *short_sample_buff, int no_samples) { int i, s; -// char samp[]={0x00, 0x01, 0x11, 0x15, 0x55, 0x75, 0x77, 0xf7, 0xff}; + static int err=0; + char samp[]={0x00, 0x01, 0x11, 0x15, 0x55, 0x75, 0x77, 0xf7, 0xff}; +#ifdef UART_AUDIO for (i=0; i> 0) & 0xff); -// putchar((s >> 8) & 0xff); -// uart_tx_one_char(0, (s >> 8) & 0xff); -// uart_tx_one_char(0, (s >> 0) & 0xff); -// printf("%04X", s); + s+=err; + if (s>32867) s=32767; + if (s<-32768) s=-32768; + uart_tx_one_char(0, samp[(s >> 14)+4]); + err=s-((s>>14)<<14); } - printf("render_sample_block %04x %04x\n", short_sample_buff[0], short_sample_buff[1]); +#endif + printf("rsb %04x %04x\n", short_sample_buff[0], short_sample_buff[1]); } void set_dac_sample_rate(int rate) { - printf("set_dac_sample_rate %d\n", rate); + printf("sr %d\n", rate); } +//The mp3 read buffer. 2106 bytes should be enough for up to 48KHz mp3s according to the sox sources. Used by libmad. #define READBUFSZ 2016 -static char readBuf[READBUFSZ]; //The mp3 read buffer. 2106 bytes should be enough for up to 48KHz mp3s according to the sox sources. Used by libmad. +static char readBuf[READBUFSZ]; + +void ICACHE_FLASH_ATTR memcpyAligned(char *dst, char *src, int len) { + int x; + int w, b; + for (x=0; x>0); + if (b==1) *dst=(w>>8); + if (b==2) *dst=(w>>16); + if (b==3) *dst=(w>>24); + dst++; src++; + } +} + static enum mad_flow ICACHE_FLASH_ATTR input(void *data, struct mad_stream *stream) { int n, i; @@ -66,14 +111,15 @@ static enum mad_flow ICACHE_FLASH_ATTR input(void *data, struct mad_stream *str rem=stream->bufend-stream->next_frame; memmove(readBuf, stream->next_frame, rem); +#ifdef READER_THREAD //Wait until there is enough data in the buffer. This only happens when the data feed rate is too low, and shouldn't normally be needed! do { xSemaphoreTake(p->muxBufferBusy, portMAX_DELAY); canRead=(p->buffPos>=(sizeof(readBuf)-rem)); xSemaphoreGive(p->muxBufferBusy); if (!canRead) { - printf("Out of mp3 data! Waiting for more...\n"); - vTaskDelay(300/portTICK_RATE_MS); + printf("Buf uflow\n"); + vTaskDelay(500/portTICK_RATE_MS); } } while (!canRead); @@ -91,6 +137,20 @@ static enum mad_flow ICACHE_FLASH_ATTR input(void *data, struct mad_stream *str //Let reader thread read more data. xSemaphoreGive(p->semNeedRead); +#elif defined(FROMFLASH) + //Copy from flash + n=sizeof(readBuf)-i; + printf("Copy %p, %d bytes\n", p->fpos, n); + memcpyAligned(&readBuf[i], p->fpos, n); + printf("Flashbuf: %02x %02x %02x %02x %02x\n", readBuf[i], readBuf[i+1], readBuf[i+2], readBuf[i+3], readBuf[i+4]); + p->fpos+=(sizeof(readBuf)-i); +#else + i=rem; + while (ifd, &readBuf[i], sizeof(readBuf)-i); + i+=n; + } +#endif mad_stream_buffer(stream, readBuf, sizeof(readBuf)); return MAD_FLOW_CONTINUE; } @@ -102,115 +162,90 @@ static enum mad_flow ICACHE_FLASH_ATTR output(void *data, struct mad_header cons static enum mad_flow ICACHE_FLASH_ATTR error(void *data, struct mad_stream *stream, struct mad_frame *frame) { // struct madPrivateData *p = (struct madPrivateData*)data; - printf("decoding error 0x%04x (%s)\n", stream->error, mad_stream_errorstr(stream)); + printf("dec err 0x%04x (%s)\n", stream->error, mad_stream_errorstr(stream)); return MAD_FLOW_CONTINUE; } -//#define FAKE_MAD -#ifndef FAKE_MAD - -void ICACHE_FLASH_ATTR tskmad(void *pvParameters){ - struct mad_decoder decoder; - struct madPrivateData *p=&madParms; //pvParameters; - printf("MAD: Decoder init.\n"); - mad_decoder_init(&decoder, p, input, 0, 0 , output, error, 0); - mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC); - mad_decoder_finish(&decoder); - printf("MAD: Decode done.\n"); -} - -#else -void ICACHE_FLASH_ATTR tskmad(void *pvParameters){ - int n, i=0; - int rem, canRead; - struct madPrivateData *p = &madParms; - while(1) { - //Wait until there is enough data in the buffer. This only happens when the data feed rate is too low, and shouldn't normally be needed! - do { - xSemaphoreTake(p->muxBufferBusy, portMAX_DELAY); - canRead=(p->buffPos>=(sizeof(readBuf))); - xSemaphoreGive(p->muxBufferBusy); - if (!canRead) { - printf("Out of mp3 data! Waiting for more...\n"); - vTaskDelay(300/portTICK_RATE_MS); - } - } while (!canRead); - //Read in bytes from buffer - xSemaphoreTake(p->muxBufferBusy, portMAX_DELAY); - p->buffPos=0; - xSemaphoreGive(p->muxBufferBusy); - - //Let reader thread read more data. - xSemaphoreGive(p->semNeedRead); - - - vTaskDelay(100/portTICK_RATE_MS); - } -} -#endif - -/* -THIS IS TOO SLOW! Incoming packets arrive, but with big hickups. -Things that don't help: -- AP/STA -- More free memory -- Killing muxes -- Doing a write before the select -*/ - -void ICACHE_FLASH_ATTR tskreader(void *pvParameters) { - struct madPrivateData *p=&madParms;//pvParameters; +int openConn() { while(1) { int n, i; struct sockaddr_in remote_ip; - fd_set fdsRead; int sock=socket(PF_INET, SOCK_STREAM, 0); if (sock==-1) { - printf("Client socket create error\n"); +// printf("Client socket create error\n"); continue; } n=1; setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &n, sizeof(n)); - n=1024; - setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)); +// n=1024; +// setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)); bzero(&remote_ip, sizeof(struct sockaddr_in)); remote_ip.sin_family = AF_INET; remote_ip.sin_addr.s_addr = inet_addr(server_ip); remote_ip.sin_port = htons(server_port); - printf("Connecting to client...\n"); +// printf("Connecting to client...\n"); if (connect(sock, (struct sockaddr *)(&remote_ip), sizeof(struct sockaddr))!=00) { close(sock); - printf("Client connect fail.\n"); + printf("Conn err.\n"); vTaskDelay(1000/portTICK_RATE_MS); continue; } - - while(1) { - while (p->buffPos!=sizeof(p->buff)) { - //Wait for more data - printf("Doing select...\n"); - FD_ZERO(&fdsRead); - FD_SET(p->fd, &fdsRead); - lwip_select(p->fd+1, &fdsRead, NULL, NULL, NULL); - //Take buffer mux and read data. - xSemaphoreTake(p->muxBufferBusy, portMAX_DELAY); - n=read(p->fd, &p->buff[p->buffPos], sizeof(p->buff)-p->buffPos); - p->buffPos+=n; - xSemaphoreGive(p->muxBufferBusy); - printf("%d bytes of data read from socket.\n", n); - if (n==0) break; //ToDo: handle eof better + return sock; + } +} + + +void ICACHE_FLASH_ATTR tskmad(void *pvParameters){ + struct mad_decoder decoder; + struct madPrivateData *p=&madParms; //pvParameters; +#if !defined(READER_THREAD) && !defined(FROMFLASH) + p->fd=openConn(); +#endif +// printf("MAD: Decoder init.\n"); + mad_decoder_init(&decoder, p, input, 0, 0 , output, error, 0); + mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC); + mad_decoder_finish(&decoder); +// printf("MAD: Decode done.\n"); +} + +#ifdef READER_THREAD +void ICACHE_FLASH_ATTR tskreader(void *pvParameters) { + struct madPrivateData *p=&madParms;//pvParameters; + fd_set fdsRead; + int n; + p->fd=-1; + while(1) { + if (p->fd==-1) p->fd=openConn(); + while (p->buffPos!=sizeof(p->buff)) { + //Wait for more data +// printf("Doing select...\n"); + FD_ZERO(&fdsRead); + FD_SET(p->fd, &fdsRead); + lwip_select(p->fd+1, &fdsRead, NULL, NULL, NULL); + //Take buffer mux and read data. + xSemaphoreTake(p->muxBufferBusy, portMAX_DELAY); + n=read(p->fd, &p->buff[p->buffPos], sizeof(p->buff)-p->buffPos); + if (n<=0) { + close(p->fd); + p->fd=-1; + break; } - printf("Buffer full. Waiting for mad to empty it.\n"); - //Try to take the semaphore. This will wait until the mad task signals it needs more data. - xSemaphoreTake(p->semNeedRead, portMAX_DELAY); + p->buffPos+=n; + xSemaphoreGive(p->muxBufferBusy); + printf("Sock: %d bytes.\n", n); + if (n==0) break; //ToDo: handle eof better } + printf("Read done.\n"); + //Try to take the semaphore. This will wait until the mad task signals it needs more data. + xSemaphoreTake(p->semNeedRead, portMAX_DELAY); } } +#endif void ICACHE_FLASH_ATTR tskconnect(void *pvParameters) { vTaskDelay(3000/portTICK_RATE_MS); - printf("Connecting to AP...\n"); +// printf("Connecting to AP...\n"); wifi_station_disconnect(); // wifi_set_opmode(STATIONAP_MODE); if (wifi_get_opmode() != STATION_MODE) { @@ -227,10 +262,13 @@ void ICACHE_FLASH_ATTR tskconnect(void *pvParameters) { wifi_station_set_config(config); wifi_station_connect(); free(config); - printf("Connection thread done.\n"); +// printf("Connection thread done.\n"); - xTaskCreate(tskreader, "tskreader", 250, NULL, 11, NULL); - xTaskCreate(tskmad, "tskmad", 2200, NULL, 3, NULL); + //tskMad seems to need at least 2450 bytes of RAM. + if (xTaskCreate(tskmad, "tskmad", 2450, NULL, 3, NULL)!=pdPASS) printf("ERROR! Couldn't create MAD task!\n"); +#ifdef READER_THREAD + if (xTaskCreate(tskreader, "tskreader", 230, NULL, 11, NULL)!=pdPASS) printf("ERROR! Couldn't create reader task!\n"); +#endif vTaskDelete(NULL); } @@ -239,13 +277,18 @@ void ICACHE_FLASH_ATTR tskconnect(void *pvParameters) { void ICACHE_FLASH_ATTR user_init(void) { +#ifdef UART_AUDIO + UART_SetBaudrate(0, 441000); +#else UART_SetBaudrate(0, 115200); -// UART_SetBaudrate(0, 441000); - printf("SDK version:%s\n", system_get_sdk_version()); +#endif +#ifdef FROMFLASH + madParms.fpos=mp3data; +#endif madParms.muxBufferBusy=xSemaphoreCreateMutex(); vSemaphoreCreateBinary(madParms.semNeedRead); - printf("Starting tasks...\n"); +// printf("Starting tasks...\n"); xTaskCreate(tskconnect, "tskconnect", 200, NULL, 3, NULL); }