2
\$\begingroup\$

I'm using an ATTINY816 (the new series AVRs) to manage a system that includes the following tasks:

  1. Simple audio "effect processing" (delay, pitch up, pitch down...) using internal ADC + DAC
  2. Storage and retrieval of audio data from external serial (SPI) RAM
  3. Display relevant data on LCD (SPI interface)
  4. Wait for commands from a WIFI modem (ESP8266) connected with UART

The top priority is to handle the audio processing glitch free as much as possible (ADC / DAC / external RAM). The next priority is to respond to commands from the ESP8266 and lastly to update the LCD.

I'm trying to figure out a strategy to tackle these tasks. I've managed to write a driver for the LCD + using a buffer management library for the LCD output. However I'm not sure how to manage everything on the existing hardware (which can't be upgraded).

Advice will be appreciated. If you are familiar with the new AVRs please try to comment on taking advantage of some peripherals like the event system or DMA which I did not to this point as I am not sure what would be the correct way to use them really.

\$\endgroup\$
  • 1
    \$\begingroup\$ Audio on an ATtiny or ATmega is dubious even without effects processing or trying to do anything else. The ESP8266 would do a better job at the audio, but perhaps not when also dealing with WiFi. You could consider the ESP32 dual core, but that may be painful to work out. An ARM part with a few DMA engines could let you decouple many of these tasks from their sample / arrival rates. \$\endgroup\$ – Chris Stratton Dec 28 '18 at 16:32
  • \$\begingroup\$ I do not have much expierence with AVR but looking at the data sheet you may want to look at "EVSYS - Event System" in chapter 14.....or you can look at the link and use preemptive multitasking. forum.43oh.com/topic/… \$\endgroup\$ – jsolarski Dec 28 '18 at 16:48
  • \$\begingroup\$ It is difficult to offer good advice right now, because it would either fill up a book or else may very well not apply and would be wasted advice. You have two MCUs. One is an ESP8266 that handles your WiFi comms and is attached to an ATtiny816 via a UART. We are provided no information about what the WiFi does for you, no information about how much data per second or if it is all outgoing, all incoming, or some mixture (with regard to the ATtiny816.) \$\endgroup\$ – jonk Dec 28 '18 at 20:04
  • \$\begingroup\$ You also have an SPI-enabled LCD display of unknown complexity tied to the ATtiny816. We are provided no information about how often, or how much data is involved in a refresh of the display, or even if it is possible to direct updates using SPI commands so that the entire display doesn't have to be updated if only one item changes. \$\endgroup\$ – jonk Dec 28 '18 at 20:04
  • \$\begingroup\$ You also have SPI-enabled external RAM and you apparently some RAM for writing and some RAM for reading. But again, it's not clear if you are using two separate SPI-enabled RAM, one for reading and one for writing, or if they are the same memory which must be used bidirectionally (with interleaved operations of unknown priority.) We have no information about the rate update except about what we might guess regarding the audio data (unspecified) from other experiences. (A slightly educated guess is all that we can achieve, at best.) \$\endgroup\$ – jonk Dec 28 '18 at 20:05
0
\$\begingroup\$

The (Potential) Bad News

Without more detail on how complex the LCD screen is (graphical, or a few lines of text), how often it's updated, what kind of data you are getting from the esp8266 (or how often), it's hard to formulate a very specific strategy, but here are some general tips. Also, I assume you are "listening" to real-time audio with the ADC, processing it based on commands (WiFi->ESP8366->USART->AVR), buffering and such with the external RAM (SPI), outputting the processed audio with the DAC, and displaying current operation info on the LCD (also SPI).

This is a lot for an 8-bit MCU to do, even maxed out at 20Mhz. This DigiKey article discusses choosing an MCU for audio-applications and mentions a minimum of 32kHz sampling rate for music. That means you have 625 clock cycles between samples to do something useful with them. Also of note, anything involving 32-bit variables (like a floating point number) will require multiple clock cycles that normally only take 1 cycle for an 8-bit operation. I imagine you'll be doing some complicated math, even with "simple" audio effects. Any sort of division (even 8-bit) will be ridiculously slow.

Also, the tiny816 has a 10-bit ADC, but an 8-bit DAC, so you will loose some precision in the processed audio quality.


Multi-Tasking Concepts

Multi-tasking on AVR microcontrollers is done using interrupts and timers. There is no multi-threading or processing available. Only one command can be executed my the core processor at once. Of course, many of the hardware peripherals can do things independently of the core. You can use a complicated strategy to time-split the operation (do one thing for so long, then give up control to another task), but this involves saving the entire state to memory in order to switch to another task. It's much simpler to let the processor handle the most time intensive tasks nonstop until it's interrupted by something else, then temporarily perform some other operation or set a flag telling the main loop to handle it on the next cycle.

Here's an application note on "Core Independent Peripherals" which focuses on the tinyAVR 1-Series (including the tiny816). Newer AVR like the tiny816 also have the Event System (see section 14 of the datasheet). To help prioritize and manage the program. I don't believe the tiny816 has true DMA, which could be used to auto-buffer the sampled data. It does have peripheral-peripheral signalling though, so that could be used to trigger data-buffering.

Also, here's an application note on recording audio with the tiny817. There's an Atmel START project for it as well: search here for AVR42777. This project just records (a very limited about) of audio (8-bit, low-ish quality) in raw format to an SD card using SPI with playback.


Example Strategy

  • When enabled, the ADC is auto-triggered to sample incoming audio at the highest frequency your MCU can manage/process.
  • Sampled data is buffered in the external RAM (SPI, don't know the baud for your RAM).
  • The "Main Loop" tries to process buffered audio data from RAM as it is available, checking status flags in between cycles. A status flag will cause a jump to some sub-routine (like handling a new command or updating the LCD).
  • USART Rx from the ESP8266 triggers an ISR. It is buffered until a complete package is received, and a status flag tells MAIN to do something with it. Otherwise, the state of the package can be stored (statically) in the ISR and handled from there, but it's best to keep the ISR as compact as possible.
  • A hardware timer triggers an ISR to prepare to update the LCD as often as deemed necessary - this rate depends on the screen and the data being shown, but you'll want to avoid it flickering. LCD data should be written from a function call in main, not the timer ISR (buffered data can be auto-transmitted from the SPI Tx ISR as well).
  • Another timer can trigger the DAC audio output (this rate is a combination of your sampling rate and the effects you want on that audio), and this must the highest priority event, or the output will sound like garbage.
\$\endgroup\$
  • \$\begingroup\$ saving state needn't be a big problem the AVR has lots of registers, it may be that some can be dedicated to some routines and not need saving. \$\endgroup\$ – Jasen Jan 13 at 4:07
  • \$\begingroup\$ @Jasen That's a valid point. I think it depends on how many different states might need to be saved at once. That's potentially a lot on the stack. \$\endgroup\$ – Kurt E. Clothier Jan 14 at 10:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.