Skocz do zawartości

ESP32: Wire, dźwięk i... ślamazara :(


Pomocna odpowiedź

Napisano

Taki trochę wkurzający problem...

Mam sobie ESP32.

Nie używam WiFi ani bluetootha.

Na rdzeniu 1 działa sobie cała piękna pętla loop().

Na rdzeniu 0 działa wyłącznie generator dźwięku (cały czas), w skrócie wygląda to tak:

unsigned int frameCount;
for (;;) {
  // tu pobiera parametry generowania dźwięku
  for (i=0;i<64;i++) {
    int16 sample = kolejna_faza_dzwieku();
    dac.writeSample(sample, sample);
  }
  if (frameCount++ % 64 == 0) vTaskDelay(1);
}

Pobranie parametrów to po prostu parę podstawień w obrębie locka, generowanie kolejnej fazy to po prostu pobranie kolejnego sampla z tablicy z krokiem zależnym od parametrów i przemnożenie przez głośność (razy dwa generatory).

W głównej pętli mam obsługę wyświetlacza na I2C, uproszczoną do granic możliwości.

Dopóki nie odpalę taska z dźwiękiem, wszystko działa bardzo ślicznie. Po odpaleniu dźwięku transfer kilkunastu bajtów zajmuje mniej więcej pół sekundy...

Rozumiem, że sama procedura i2c_write działa na rdzeniu 0 (aż tak głęboko w kod nie wnikałem). Czyli: proces w tasku głównym zleca komunikację i2c, czeka na wykonanie, tymczasem działający na rdzeniu 0 i2c_write nie może się dopchać do procka...

Jakieś pomysły co z tym fantem zrobić?

 

 

Nie znam szczegółów ESP32, ale z tego co wyczytałem to posiada kontroler DMA. Pytanie jak go ugryść?
Na pierwszy rzut oka to, tak wygląda, że odtwarzanie dźwięku, zajmuje większość przepustowości wewnętrznej magistrali I/O.

30 minut temu, BlackJack napisał:

Nie znam szczegółów ESP32

Zobacz, to zupełnie jak ja 😉

30 minut temu, BlackJack napisał:

z tego co wyczytałem to posiada kontroler DMA

i używa go do dźwięku (8 buforów bo 64 bajty o ile dobrze pamiętam, nie chce mi się zaglądać do źródeł).

Coś mi się nie wydaje że to kwestia przepustowości, wieczorem będę miał dostęp do tego urządzenia to jeszcze poeksperymentuję...

 

...no i jest tak jak myślałem; nie ma to nic wspólnego z DMA.

Drobna zmiana w kodzie: zakomentowana inicjalizacja DAC (tak na wszelki wypadek), wątek audio wygląda tak:

void busyLoop(uint32_t ms)
{
    uint32_t ems=millis();
    while (millis() - ems < ms);
}

void IRAM_ATTR AudioThread(void *pvParameter)
{
    
    while(1) {
        busyLoop(64);
        vTaskDelay(1);
    }
}

Zgodnie z moimi oczekiwaniami efekt jest ten sam - wolne działanie Wire.

Ergo: bajki o przepustowości pozostają bajkami, a problem pozostał.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...