5
\$\begingroup\$

I see a lot of projects for AVR-based audio players that use an SD card to store the audio data.

In fact, I am currently doing the very same thing on an Arduino and its Wave Shield, which has an SD card reader.

However, I'd like to develop a device that stores the sound on onboard EEPROM or Flash memory rather than a removable medium.

The current files are 16-bit mono 22Khz PCM WAV's and altogether require 620 kilobytes.

I'm not sure what to look for in memory chips. I know I'll need sufficient storage per the above requirements. The device won't record nor alter the data, so additional capacity is unnecessary. Obviously I want to select the lowest-cost solution that will still meet the requirements:

  • Must store at least 620 KB
  • Will need to be fast enough to support 16-bit 22Khz 1-channel playback
  • Compatible with AVR microcontrollers
  • Can be write-once
  • Must retain data without power
  • Preferably SMD package but through-hole is acceptable

Some general tips on adding and using flash (or other types) of memory would be greatly appreciated!

\$\endgroup\$
6
\$\begingroup\$

I would recommend that you look at the modern SPI FLASH type parts. Winbond is one manufacturer that makes a nice range of parts that would be perfect for deployment in the SPI hardware interface on your AVR.

enter image description here

Digikey stocks the Winbond parts that are available in capacities as follows:

1 MByte for 0.50$ USD http://www.digikey.com/product-detail/en/W25Q80BVSSIG/W25Q80BVSSIG-ND/2202664

2 MByte for 0.74$ USD http://www.digikey.com/product-detail/en/W25Q16BVSSIG/W25Q16BVSSIG-ND/2208449

8 MByte for 3.01$ USD http://www.digikey.com/product-detail/en/W25Q64DWSSIG/W25Q64DWSSIG-ND/3008691

Other sizes are made but not currently in stock.

These parts are very easy to add into a circuit. The SPI port pins SPI_CLK, SPI_MOSI and SPI_MISO connect directly to three pins on the SPI Flash. +3.3V and GND are suitable power for the part and make sure to add a 0.1uF bypass capacitor across the chip power pins. The remaining pins /HOLD and /WP can be simply pulled up to 3.3V via 10K resistors. For SPI FLASH parts such as these you also have to support a /CS pin to the part. You cannot just tie this to GND as the part is designed to reset the command state machine when you drive the /CS pin high so as to get ready for the next command.

SPI FLASH parts such as these are accessed in blocks of data. The types I linked to here support block sizes of 4K bytes which are initially addressed in the read/write commands via a multi-byte address included in the commands. In your application it would not be necessary to have a RAM buffer to load a whole read block into. You could start the read of a SPI FLASH block and then read out a few bytes at a time and feed those to your audio player hardware. Each time you cross the 4K boundary you can send the command again to address to the next block. It is however possible to send a command to start at some particular block and then as long as you hold the /CS pin low and continue to supply clocks it is possible to sequentially read out the whole memory part if need be.

Note that these parts support reading and writing in the single bit wide legacy modes which is presumably the way you would use them with the AVR. They also support reading and writing in 2-bit and 4-bit modes for super high speed data transfer modes but those modes require a SPI controller capable of dealing with the wider dual and quad serial data modes.

\$\endgroup\$
7
\$\begingroup\$

I could transcribe the contents of the many tutorials on this subject here, but I'd rather point you to a very good one that explains the theory and implementation quite well: http://www.nerdkits.com/videos/halloween_huffman_audio/.

In a nutshell, you use PWM to drive the speaker, and you can store the audio samples in a rudimentary compressed format (e.g. huffman coded) in flash (program) memory or eeprom in a symbol table. What I'm saying is, you don't need an external memory chip necessarily depending on the fidelity of the audio and the duration you want to store. Many AVRs have plenty of non-volatile memory for this kind of thing.

If you really need more space than you can get on the AVR itself, you could use an external SPI EEPROM, since just about every AVR has a SPI interface. Just search digikey for "serial memory", go into the "Memory" category, filter down to the serial interface of your choice (e.g. SPI), exclude "RAM" from the "Format - Memory" category and you will still have over 700 devices to choose from. Just pick the cheapest one that is large enough to store what you need, that comes in a package that you are prepared to deal with (I recommend SO-8 for surface mount beginners).

These all basically work the same way, just read the datasheet to understand the command format. SPI works by dedicating a GPIO pin to the target device to tell it you want to communicate with it (creatively called "chip select" or "/CS"). You just ground that pin and use the AVR's SPI hardware to talk to it per the device datasheets. Browse the web / avrfreaks / github for devices with library support if you want to take a shortcut on software, but honestly we're talking about some pretty simple interface code here.

\$\endgroup\$

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.