Files
snapclient/components/protocol/protocol.c
Carlos 15b4baba28 - merge with original master from jorgen
- minimize RAM usage of all components
- use both IRAM and DRAM in player component so we can buffer up to 1s on modules without SPI RAM
- support fragemented pcm chunks so we can use all available RAM if there isn't a big enough block available but still enough HEAP
- reinclude all components from jorgen's master branch
- add custom i2s driver to get a precise timing of initial sync
- change wrong usage of esp_timer for latency measurement of snapcast protocol
- add player component
2021-08-19 21:57:16 +02:00

194 lines
7.2 KiB
C

// MADIF protocol handler
// Read incomming messeage from queue and do the work
// Protocol description
/*
0 Interface functions
Scan clients on i2c bus.
Get host system (ESP32, RPI, Cypress)
Select audio source (Snapcast, RTPrx, Bluetooth, Signal generator)
Enable DSP processing
1 Device communication I2C
2 GPIO manipolation
3 Audio generator
4 Telemetri subsystem
5 Test function
6 RTPrx module
7 DSP processor configuration
*/
#include "esp_types.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_system.h"
#include "esp_log.h"
#include "stdint.h"
#include "protocol.h"
//#include "MerusAudio.h"
#include "rtprx.h"
#include "i2s.h"
#include "dsp_processor.h"
extern enum dspFlows dspFlow;
// Protcol format
// Byte 0 1 2 3 4 ...
// Cont: Function length subCommand data <data> ...
enum audio_sources { SNAPCAST, RTPRX, BLUETOOTH, SIGNALGENERATOR };
static const char TAG[] = "PROT";
static uint8_t audio_source ;
extern uint8_t muteCH[4];
void protocolHandlerTask(void *pvParameter)
{ audio_source = 1;
ESP_LOGI(TAG,"Protocol handler started");
while (1)
{ uint8_t *msg;
xQueueReceive(prot_queue, &msg, portMAX_DELAY);
//ESP_LOGI(TAG,"Recieved message %d length %d",*(msg),*(msg+1));
switch (*msg) {
case 0 : // Interface functions
switch (*(msg+2)) {
case 0 : { ESP_LOGI(TAG,"Change Source to : %d\n",(int)*(msg+3));
if (audio_source != *(msg+3) )
{ if (audio_source == SNAPCAST) {
i2s_custom_zero_dma_buffer(0);
// Not implemnted do nothing
}
else if (audio_source == RTPRX)
{ ESP_LOGI(TAG,"Stop RTPrx");
rtp_rx_stop();
}
else if (audio_source == BLUETOOTH)
{ // Not implemnted do nothing
}
else if (audio_source == SIGNALGENERATOR)
{ //signalgenerator_stop();
ESP_LOGI(TAG,"Stop generator");
}
}
audio_source = *(msg+3);
switch (audio_source) {
case SNAPCAST : break;
case RTPRX : { ESP_LOGI(TAG,"Start RTPrx");
rtp_rx_start();
} break;
case BLUETOOTH : break;
//case SIGNALGENERATOR : { ESP_LOGI(TAG,"Start signal ");
// signalgenerator_start();
// }
// break;
default : break;
}
}
break;
case 1 : { ESP_LOGI(TAG,"Measure system PVDD");
}
break;
case 2 : { ESP_LOGI(TAG,"Scan i2s bus...");
}
break;
default : break;
}
break;
case 1 : // Device communication // Fuse and otp decoding
switch (*(msg+2)) {
case 0 : // Byte read
{ uint8_t value = 0; //ma_read_byte( *(msg+3), *(msg+4), (*(msg+5)<<8)+*(msg+6) ) ;
printf("Value read : %d\n", value);
// return value to sender
break;
}
case 1 : { // Byte write
//ma_write_byte(*(msg+3),*(msg+4),(*(msg+5)<<8)+*(msg+6),*(msg+7) );
printf("i2c_write : \n");
break;
}
case 3 :
{ uint8_t l = (*(msg+1)-7);
uint8_t *writebuf;
//ESP_LOGI(TAG,"I2C write block : %d\n",*(msg+7));
writebuf = malloc(l);
for (int8_t i = 0; i<l ; i++ )
writebuf[i] = *(msg+7+i);
//ma_write(*(msg+3),*(msg+4),(*(msg+5)<<8)+*(msg+6),writebuf,l);
break;
}
default : break;
}
break;
case 2 : //GPIO
break;
/*case 3 : // Signal Generator
switch (*(msg+2)) {
case 0: // Stop generator
signalgenerator_stop();
ESP_LOGI(TAG, "Stop_SignalGenerator :%d",*(msg+2));
break;
case 1: // Start generator
signalgenerator_start();
ESP_LOGI(TAG, "Start_SignalGenerator :%d",*(msg+2));
break;
case 2: // Change Mode :
signalgenerator_mode(*(msg+3)); // cont, sweep, burst
ESP_LOGI(TAG, "SignalGenerator change mode :%d",*(msg+3));
break;
case 3: // Change Oscillator Type : // Sine, tri, square, noise
signalgenerator_osctype(*(msg+3));
ESP_LOGI(TAG, "SignalGenerator change oscType :%d",*(msg+3));
break;
case 4: signalgenerator_freq(*(msg+3),*(msg+4),*(msg+5)); // freq int >> 4
break;
default : break;
}
break;
*/
case 4 : break;
case 5 : break;
case 6 : //RTPrx
switch (*(msg+2)) {
case 0: // Stop RX reciever
rtp_rx_stop();
break;
case 1: // Start Rx reciever
rtp_rx_start();
break;
default : break;
}
break;
case 7 : // DSP
switch (*(msg+2)) {
case 0: // Bypass 0 or 1 or 2
dspFlow = (int) *(msg+3);
break;
case 1: // Change Xover frequency
//dsp_set_xoverfreq(*(msg+3),*(msg+4));
break;
case 99: { uint8_t ch = *(msg+3);
uint8_t state = *(msg+4);
printf("Mute %d %d\n",ch,state);
if ( (ch<=1) & (state<=1) )
{ muteCH[ch] = state;
}
}
break;
default : break;
}
break;
default : break;
}
free(msg);
}
}