Skip to content

Commit

Permalink
Add flash mode. Doesn't work yet somehow.
Browse files Browse the repository at this point in the history
  • Loading branch information
Spritetm committed May 15, 2015
1 parent 5d74aed commit 58820dd
Show file tree
Hide file tree
Showing 14 changed files with 144 additions and 101 deletions.
2 changes: 1 addition & 1 deletion ld/eagle.app.v6.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Binary file modified lib/libfreertos.a
Binary file not shown.
Binary file modified lib/libjson.a
Binary file not shown.
Binary file modified lib/liblwip.a
Binary file not shown.
Binary file modified lib/libmain.a
Binary file not shown.
Binary file modified lib/libnet80211.a
Binary file not shown.
Binary file modified lib/libphy.a
Binary file not shown.
Binary file modified lib/libpp.a
Binary file not shown.
Binary file modified lib/libssl.a
Binary file not shown.
Binary file modified lib/libudhcp.a
Binary file not shown.
Binary file modified lib/libwpa.a
Binary file not shown.
2 changes: 1 addition & 1 deletion mp3/mad/decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion mp3/make.sh
Original file line number Diff line number Diff line change
@@ -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

239 changes: 141 additions & 98 deletions mp3/user/user_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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<no_samples; i++) {
s=short_sample_buff[i];
// putchar((s >> 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<len; x++) {
b=((int)src&3);
w=*((int *)(src-b));
if (b==0) *dst=(w>>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;
Expand All @@ -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);

Expand All @@ -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 (i<sizeof(readBuf)) {
n=read(p->fd, &readBuf[i], sizeof(readBuf)-i);
i+=n;
}
#endif
mad_stream_buffer(stream, readBuf, sizeof(readBuf));
return MAD_FLOW_CONTINUE;
}
Expand All @@ -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) {
Expand All @@ -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);
}

Expand All @@ -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);

}
Expand Down

0 comments on commit 58820dd

Please sign in to comment.