Archive for the ‘AVR’ Category

Practical STM32 differences compared to AVR

Saturday, August 28th, 2010

I’ve been playing with the STM32 header board for a while now, so today I’d like to write about some practical differences between the STM32 and AVR. At first I wanted to use Cortex-M3 instead of STM32, but that wouldn’t be correct since the Cortex-M3 is only the core, while the peripherals is where most of the practical differences lie. Also note I’m talking about programming using C/C++, not assembly.

Clock signals

On an AVR you can simply set/clear a bit in the appropriate register to make a GPIO pin high or low. Not so on the STM32. While the concept of setting a bit remains the same (there are differences such as atomic write access, but you won’t notice those during normal usage), the difference is that they won’t do anything until you enable the corresponding peripheral. Before going any further take a look at the system architecture diagram:

As you can see in this diagram the STM32 has a couple of busses; an AHB and 2 APB busses. Each peripheral is connected to one of those busses and will only do something if it gets a clock signal. After a reset all clocks are disabled, including the system clock (please look up CMSIS’ SystemInit() function for info on enabling the Embedded Flash Interface, the PLL and SystemCoreClock). Before using a peripheral look up which bus it is connected to and set the corresponding bit in the RCC register to enable its clock signal. If for example you want to use GPIOA, you need to set the IOPAEN bit in the RCC_APB2ENR register. Another GPIO difference is that you must choose between 3 speeds; 2MHz, 10MHz or 50MHz.

But that’s not all concerning clock signals. Peripherals such as USARTs and SPI are mapped to the same pins as GPIO pins. Even though you can not use both at the same time, the GPIO pins have to be initialised as usual (clock enabled, input/output, speed and mode (floating/push-pull/etc)) as used by the used peripheral. On top of that you get clocks for the alternate function and the peripheral itself. That’s 3 clock signals total which all have to be enabled.

Shift registers

Another issue I ran into was the use of shift registers. Peripherals such as USART and SPI only have a data register on the AVR. Just write a byte to it and the AVR blocks until the byte is transmitted. The STM32 takes a slightly different approach. You write data to the data register which is blocking. Next the data is moved into a shift register for transmission and execution continues.

In reality this means that your code continues and for example deactivates the chip select signal of some other IC (e.g. the audio decoder in case of the music player) while data is still being transmitted. The result is a partial reception of the data and nothing happens. The solution is to wait for a status bit to clear before deactivating any chip select signal (in case of SPI; the BSY bit in the SPI_SR register as seen in the above diagram).

That’s it for now.

Finding the limit and power saving

Monday, July 26th, 2010

Well I’m definitely going to make a 20MHz ATmega328p version just to discover where the limit lies with FLAC. Scratch that… apparently Atmel is working with ‘speed grades’ these days, or in other words “Maximum frequency is dependent on Vcc”. Reaching 20MHz requires at least 4.5V and this poses a bit of a problem since all other components require 3.3V or less. Guess this also explains why the 3.3V Arduino Pro Mini board only comes at 8MHz.

In the mean time I’ve been working on getting some basic functionality to work. Currently working are play, pause and stop playback, play next song, continues playback (instead of just 1 song for testing purposes which got a little repetitive after a while ;)), volume control (up, down and mute) and a debug function outputting decode time, samplerate, bitrate and type of file.

Atm I’m trying to get sleep modes working. Also new is card detection. When no card is inserted the AVR goes into the 0.1 uA power down mode. Insert a card and it starts playing. Not fully working yet , but it’s getting there. Also when playback is stopped it should go into idle mode until the play command is received (saving 4 mA).

A command I haven’t got a clue yet on how to implement is shuffle. If anyone has a suggestion, ¬†feel free to add a comment.

STM32F103xE vs ATmega328p quick peak

Sunday, July 25th, 2010

Now that the new controller is on its way, it’s time for a small comparison while looking at the musicplayer requirements. The difference is huge. First of all the STM32F is a 32-bit controller with more of everything. In other words it’s like comparing a pig with a chicken and pretty pointless, but well worth a quick look.

First a couple of specs. Just a small selection, I’d recommend the datasheets for a complete list. I’ve also added the LPC2106 for comparison.

ATmega328p

  • Low-power 8-bit AVR @20MHz
  • 32 kB Flash, 2 kB SRAM, 1 kB EEPROM
  • 1x SPI, 1x USART
  • Active: 0.2 mA, power-down: 0.1 uA, power-save: 0.75 uA
  • TQFP32 package

STM32F103RET

  • 32-bit ARM Cortex-M3 core @72MHz
  • 512 kB Flash, 64 kB SRAM
  • 3x SPI, 5x USART
  • SDIO
  • Active: 69 mA, sleep: 45 mA, stop: 35 uA, standby: 3.8 uA
  • LQFP64 package

LPC2106

  • 16/32-bit ARM7TDMI-S core @60MHz
  • 128 kB Flash, 64 kB SRAM
  • 1x SPI, 2x USART
  • Active: 40 mA, idle: 7 mA, power-down: 10 uA
  • Requires 1.8V and 3.3V
  • LQFP48 package

Ignoring the raw numbers, what does this mean for the musicplayer project? It has SDIO, meaning faster SD card access. Playing FLAC files results in lots of data transfers, so the more efficient this handled, the better. Combined with raw processing power this also means FatFs can be fully unleashed. It would also allow sending way more trackinfo to the remote without interrupting playback.

On the AVR I’ve been using its little brother Petit FatFs using FAT32 with 8.3 filenames, single fileaccess and read only. Using the full version means multiple files at once, probably improved shuffle/random functionality and maybe even tag reading.

Alas, having all this advanced circuitry at our disposal has a downside… double lead count and increased power consumption. It’s a subject I haven’t thought about much, but the general idea was to keep power as low as possible. One thought is to use a LiPo battery and small solar cell, so lower power consumption equals longer playtime.

Hmmm, that LPC2106 doesn’t look so bad considering the lead count and power consumption…

Let’s dance!

Friday, July 23rd, 2010

We have lift off! Reading the datasheet has once again proved to be the key. The SCI_CLOCKF register is initialised to 0×00 at power up. This means the decoder’s DSP is working at 12.288MHz with a max SPI write speed of 3.072MHz. The result is 2 fold; either the DSP hasn’t got enough decoding power and/or data transfers go out of sync. The ATmega328¬† is using it’s max SPI speed of 4MHz, roughly 1MHZ more than the decoder. You don’t have to be a rocket scientist to imagine this is a disaster waiting to happen.

(more…)

Hardware merge

Monday, July 19th, 2010

For the first time all components sit together on a breadboard (well actually 2 because the decoder board is so wide). And yes, things still work – UART, SDHC reading and decoder tests. Code wise things are also looking good. There’s still lots to do, but seeing less than 8kB FLASH and 850 byte RAM is used so far (without the FLAC patch) my current concern is speed. Doing a directory listing takes much longer than expected. Slow is normal at this stage (no 512 byte sector reading, dumping via ‘slow’ UART), but still.

The next step will be attempting to play a couple of songs, starting with a low bitrate MP3 up to a 50MB FLAC file. In the meantime, enjoy these two shots;

Something fishy

Saturday, July 10th, 2010

During the past week I’ve spend various evenings getting bluetooth communication and SPI (for the SD card/VS1053) to work, but thus far without success. Something fishy is going on and I haven’t yet been able to put my finger on it. I’ve been using avr-gcc (the one included in WinAVR and Debian testing) and results are unpredictable.

(more…)

Older is better?

Friday, July 9th, 2010

Having problems with avrdude 5.10 (included in the latest WinAVR, version string “Version 5.10, compiled on Jan 19 2010 at 10:45:23″. Also valid for the latest version in the Debian testing repository) I had to dig a little deeper and ended up with the version included in the Arduino 0018 distribution. Here’s a working commandline:

avrdude -Cavrdude.conf -v -v -v -v -patmega328p -cstk500v1 -P\\.\COM11 -b57600 -D -Uflash:w:musicplayer.hex:i

It’s an old version, but confirmed to work: “Version 5.4-arduino, compiled on Oct 11 2007″. Beats me why a 3 year old version works better, but after having unreliable results for days with the latest version, I’m not complaining.

Arduino programming woes

Tuesday, July 6th, 2010

After finally successfully programming an Arduino Pro Mini using avrdude here’s a commandline to remember:

avrdude -v -v -v -v -pm328p -carduino -b57600 -PCOM11 -D -Uflash:w:<xxx>.hex:i

The documentation only seems to mention baudrates of 19200 and 9600 baud (for really old versions) so knowing the above will save you an evening of fruitlessly hunting for answers…

Btw, way to go Sparkfun for not answering questions regarding your own product. It’s been 3 days and not a single word. No points for you this week.