Pages Menu
TwitterRssFacebook
Categories Menu

Posted by on Jun 12, 2011 in Atmel AVR, Microcontrollers | 117 comments

Using AVR Studio 5

Using AVR Studio 5

AS6 Tutorial

Embedded C welcomes you!

Hello folks! Now that you are aware of the different port operations in AVR, we can move forward to actually code our way right through it! Since we will be using C (in fact Embedded C), the best software is the AVR Studio 5 by Atmel. The latest version is 5.1 which was updated in February 2012. The best part is that it is very interactive, user friendly, has awesome UI and unlike other compilers, it is totally free of cost. You can download it from here.

For those who do not want to register in order to download, I am posting the direct download links of the images here. Please report to me if the links are not proper, I will update them in that case.

Those of you who like to learn how to use the AVR Simulator, you would prefer to skip this post and move on to the next.

You have been familiar with C (I presume). You have been working with normal data types and have been writing codes that run on a computer. But now, we will be using the same C (with some modifications) to run our microcontroller (MCU). The C used in embedded systems design is called Embedded C. Here, you will come across the same if, for, while, do while, case, switch, etc, but you will be introduced to newer data types (actually a modification of the existing ones), newer libraries, newer built-in functions and newer registers!

What do we need?

The following software will assist you in your work. You can download them from the links provided. We will discuss them one by one here.

Apart from FreeISP, there are many more GUI for avrdude, like the AVRDude-GUI, AVR8 Burn-O-Mat, etc. They all are simple to use, but I have discussed only FreeISP and eXtreme Burner here. But unlike FreeISP or eXtreme Burner, AVRDude-GUI supports all kinds of programmers supported by avrdude.

Installation

Installation of these software is pretty straightforward. You should not face any trouble in it. During the installation of AVR Studio 5, it might need to install some other stuffs before the actual installation begins. If you face any trouble in installation, you are free to drop a comment below.

AVR Studio 5

AVR Studio 5

Let’s have a look at the features of AVR Studio before we proceed.

  • It is an Integrated Development Environment (IDE) for AVR Software.
  • It allows chip simulation and in-circuit emulation.
  • It supports the whole AVR family of Microcontrollers (MCUs).
  • It has easy to use User Interface (UI) and gives complete overview.
  • It uses same UI for simulation and emulation.

Creating your first AVR Project

Here is a step-by-step guide regarding how to create your first AVR Project using AVR Studio 5.

  • After installation, open AVR Studio 5 from StartAll Programs → Atmel AVR Tools → AVR Studio 5.0
  • After opening, you will see a Start Page like this. Click on “New Project…“.

    AVR Studio 5 Start Page

    AVR Studio 5 Start Page

  • Then, you will see the following dialog box. Choose AVR GCC from the ‘Installed Templates’ pane, and then choose Empty Executable Project. Now, you can give any name to it, say MyFirstProject and choose an appropriate location in your hard drive. Check Create directory for solution. Click on OK.
AVR Studio New Project

AVR Studio New Project

  • Now, you will see the Device Selection dialog box. As you can see, AVR Studio supports all the AVR MCUs! The list is huge! Choose your device from this list. We choose ATmega32. Click OK.

    AVR Studio Device Selection

    AVR Studio Device Selection

  • Now, you will see the following screen. Note that the basic program structure is already prepared for you. You simply need to initialize your variables and place your code inside the while(1) loop.

    AVR Studio New Project Start Screen

    AVR Studio New Project Start Screen

  • Congratulations! You have successfully created your first AVR Project! Now to further proceed with it, we need to write a code, which is discussed in the next part.
  • Have a look at the awesome AVR Studio IDE. Feel free to explore the software. We will discuss some of the required components as and when necessary.

Writing the code

LED Blinking Schematic

LED Blinking Schematic

Now that you have successfully created your new project, we need to write a code in the AVR Studio Code Window. Let’s write the code for the problem statement discussed in this post. We will write the code for blinking an LED. The schematic for physical connection is given below. Please note that it’s just a schematic of the region of interest. For full schematic, view the circuit diagram of your development board.

Now most of you will copy and paste the code. But I suggest you to type the whole code. This will introduce you to a whole new feature! While typing any keyword or inbuilt function, AVR Studio 5 automatically displays a list of possible functions/keywords that you wish to type. You can select it and hit enter key. This increases your typing speed also (somehow!). Plus it also gives you greater confidence in writing the code.

#include <avr/io.h>
#include <util/delay.h>                // for _delay_ms()
 
int main(void)
{
    DDRC = 0x01;                       // initialize port C
    while(1)
    {
        // LED on
        PORTC = 0b00000001;            // PC0 = High = Vcc
        _delay_ms(500);                // wait 500 milliseconds
 
        //LED off
        PORTC = 0b00000000;            // PC0 = Low = 0v
        _delay_ms(500);                // wait 500 milliseconds
    }
}

Code Explained:

  • #include <avr/io.h> is a header files which provides you with various i/o operations like DDRx, PINx, PORTx, etc.
  • #include <util/delay.h> is a header file which provides you with inbuilt delay functions like _delay_loop_1(), _delay_loop_2(), _delay_ms(), _delay_us(), etc.
  • Rest of the code is simple and straightforward. For details regarding how to use DDRx and PORTx, view this post.
  • _delay_ms(xxx) provides a delay xxx milliseconds whereas _delay_us(xxx) provides a delay of xxx microseconds. There are two more types of delays which are used commonly, _delay_loop_1() and _delay_loop_2(), but to understand their concept, you need to be familiarized with timers, which we will discuss later.

Configuring AVR Studio 5

There are two things that you must configure in order to make your code run in your MCU in a better way.

  • Setting up your clock frequency F_CPU
  • Choosing Optimization Level

Setting up Clock Frequency F_CPU

This is a very essential step. This is because if you don’t set your clock frequency, the whole timing would go wrong. _delay_ms(500) will wait for 500ms, but it counts with respect to your clock frequency. If your F_CPU setting is wrong, it won’t wait for 500ms. It will either wait longer or for lesser time. By default, delay.h defines F_CPU=1000000UL (1MHz). UL stands for unsigned long. But this isn’t always the case. Check your development board if any crystal oscillator is present or not (across the XTAL pins). If it is present, note down the exact value of the frequency. If no, then choose either 1MHz, 2MHz, 4MHz or 8MHz depending upon the fuses set in your MCU (I expect that correct fuses must have been written. We will discuss about fuses later).

Note: You must set fuse bits for a new AVR microcontroller. These fuse bits will specify the correct clock frequency (whether to follow internal clock or external clock) and many other settings. They are set only once, and hence MUST be set correctly, or else you will render your MCU useless. To learn about fuses, view this.

Now, how to put? Well, the simplest way is to add the following code before including the header files.

#ifndef F_CPU
#define F_CPU 16000000UL // or whatever may be your frequency
#endif
// remember to put it before delay.h

// now include the header files
#include <avr/io.h>
#include <util/delay.h>

// rest code goes here

You need to add it before every code you write. Or else, you can go to Project menu → MyFirstProject Properties (Alt+F7)ToolchainAVR/GNU C CompilerSymbols → Add F_CPU=16000000UL to Defined Symbols.

Always check this out before compiling your code.

Optimizing your Code

You need to choose an appropriate optimization level for your code. Choosing the right optimization level will result in smaller hex file and faster compilation time. You can do it so by going to Project menu → MyFirstProject Properties (Alt+F7)ToolchainAVR/GNU C CompilerOptimization → Choose -O2 as Optimization Level.

To know what optimization is, view this. For more details regarding optimization of code in AVR, visit this page. For details regarding the meanings of different optimization levels, view the GCC-GNU User Manual.

Building your code

After writing the code and configuring it, we proceed to build it. To do so, go to Build menu → Build Solution (F7). Now, it builds your AVR-GCC project. After the build process has finished, you will see the details in the Output window (below the source code window). There, you can check your memory usage and the build log. In the end, it shows Build Succeeded. If it doesn’t show, check you code once again and check whether you have configured your project properly. If still it shows Build Unsuccessful, then post your queries here, I will look into the matter.

Now, once you have built your code, a .hex file has been generated for your .c file. You can find it in the following directory

...path to your folder/MyFirstProject/MyFirstProject/Debug/MyFirstProject.hex

The next step is to burn this hex file into your  MCU. For this, we will use avrdude. AVR Programming can also take place from within AVR Studio 5, but at present, AVR Studio 5 has support only for the current Atmel Programmers. But most of the programmers available are AVRISP, AVRISP mkII, USBtinyISP, USBasp, etc. So, we will be using avrdude.

If you use AVRISP and USBtinyISP, or want to learn how to use avrdude GUI, proceed to the next section. If you use USBasp, then skip the next section and jump over to the topic eXtreme Burner – AVR.

Attention: AVR Studio 4 Users

There will be many who have previously worked with AVR Studio 4. The interface of AVR Studio 5 is a lot different than its earlier editions. Also, the AS4 project is not supported by AS5. For that, you can open AS5, go to File menu → Import → Import AVR Studio 4 Project. This converts AS4 project into AS5 solution and then opens in AS5.

Using AVRDude with FreeISP

AVRDude stands for AVR Downloader Uploader. It is a free software that comes with WinAVR package. It’s an executable program which can be run using the command prompt. To have a detailed idea of how avrdude works and how to run it using command prompt, view this page. But if you have an AVRISP programmer, we have a GUI for you! Its called FreeISP. The download link is provided at the top.

Please Note: Apart from FreeISP, there are many more GUI for avrdude, like the AVRDude-GUIAVR8 Burn-O-Mat, etc. They all are simple to use, but I have discussed only FreeISP and eXtreme Burner here. But unlike FreeISP or eXtreme Burner, AVRDude-GUI supports all kinds of programmers supported by avrdude.

  • Open FreeISP by clicking it’s icon. If an error like Error reading application settings pops up, simply click OK.
FreeISP Interface

FreeISP Interface

  • In the window that opens, choose the paths of your avrdude.exe file and MyFirstProject.hex file. If you have an EEPROM file, choose the path, or else leave it blank. (For the above code, leave it blank).
  • Choose you device and the COM port.
  • Choose AVRISP as the programming hardware.
  • Make sure that only ‘Program Flash’ is checked.
  • IMPORTANT: Make sure that you program only flash (and EEPROM wherever necessary). DO NOT PROGRAM FUSE BITS AND LOCK BITS without any prior knowledge, or else you might end up damaging your AVR permanently.
  • Click Program.

After you click program, FreeISP invokes avrdude and passes the required comments to it as per your inputs. Then avrdude reads your device and verifies your device ID and your chip signature. After that, it erases the flash and then writes the new hex file specified by you into the flash. Then it once again reads the flash in order to verify the data. And thus after all this, your code is burnt into the MCU and your MCU is ready to use! It might have already started to respond to your code… check that the LEDs must be blinking!

If programmed correctly, you should see something like this.

avrdude.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude.exe: Device signature = 0x1e9502
avrdude.exe: NOTE: FLASH memory has been specified, an erase cycle will be performed
             To disable this feature, specify the -D option.
avrdude.exe: erasing chip
avrdude.exe: reading input file "C:\Users\Mayank\Simulations\AVRStudio\AVR Studio 5\MyFirstProject\MyFirstProject\Debug\MyFirstProject.hex"
avrdude.exe: writing flash (206 bytes):

Writing | ################################################## | 100% 0.13s

avrdude.exe: 206 bytes of flash written
avrdude.exe: verifying flash memory against C:\Users\Mayank\Simulations\AVRStudio\AVR Studio 5\MyFirstProject\MyFirstProject\Debug\MyFirstProject.hex:
avrdude.exe: load data flash data from input file C:\Users\Mayank\Simulations\AVRStudio\AVR Studio 5\MyFirstProject\MyFirstProject\Debug\MyFirstProject.hex:
avrdude.exe: input file C:\Users\Mayank\Simulations\AVRStudio\AVR Studio 5\MyFirstProject\MyFirstProject\Debug\MyFirstProject.hex contains 206 bytes
avrdude.exe: reading on-chip flash data:

Reading | ################################################## | 100% 0.11s

avrdude.exe: verifying ...
avrdude.exe: 206 bytes of flash verified

avrdude.exe: safemode: Fuses OK

avrdude.exe done.  Thank you.

Now, if you use USBasp programmer, we have another awesome GUI for you, eXtreme Burner – AVR !

Using eXtreme Burner – AVR

Now for those who use USBasp programmer, the best GUI that I could find is the eXtreme Burner – AVR. This GUI has been developed by Avinash Gupta of eXtreme Electronics, India. You can find his tutorial here. It is available for Windows XP, Windows Vista/7 (32/64 bit), Linux (Fedora 10, Ubuntu 10.10). A few screen shots (Windows) are shown below.

eXtreme Burner - AVR

GUI Software for USBasp

GUI Software for USBasp - Burn Progress

GUI Software for USBasp – Burn Progress

GUI Software for USBasp - Task Complete!

GUI Software for USBasp – Task Complete!

So, I guess we are done regarding how to use AVR Studio 5. In the next post, we will learn to use the AVR Simulator and Debugger. Till then, you can try out various stuffs. You can connect more than one LED and create different blinking patterns! You can do whatever you want! And you can also post comments down here to let me know! ;)

Video

This is a simple demonstration of the traditional Hello World of microcontrollers – LED Blinking. The video is made by Lavin Khandelwal for maxEmbedded. He has used the low cost 28 pin AVR Development Board and the USBasp AVR Programmer by eXtreme Electronics. He used the eXtreme Burner for burning the code.

If you have any kind of suggestions, clarifications, constructive criticism etc, you can post your comments below! :) I will be glad to see them! Also you can grab the RSS Feeds or subscribe to my website to stay updated!

Thank You

Related Posts

117 Comments

  1. Hi!

    I have some problems building the project. This is what I get in the output:

    —— Build started: Project: Leds, Configuration: Debug AVR ——
    Build started.
    Project “Leds.cproj” (default targets):
    Target “PreBuildEvent” skipped, due to false condition; (‘$(PreBuildEvent)’!=”) was evaluated as (”!=”).
    Target “CoreBuild” in file “C:Program FilesAtmelAVR Studio 5.1VsCompiler.targets” from project “\psfHomeDocumentsAVRStudio 5.1LedsLedsLeds.cproj” (target “Build” depends on it):
    Using “RunCompilerTask” task from assembly “C:Program FilesAtmelAVR Studio 5.1VsCompiler.Task.dll”.
    Task “RunCompilerTask”
    C:Program FilesAtmelAVR Studio 5.1makemake.exe all
    ‘\psfHomeDocumentsAVRStudio 5.1LedsLedsDebug’
    CMD.EXE was started with the above path as the current directory.
    UNC paths are not supported. Defaulting to Windows directory.
    Leds.c
    ‘\psfHomeDocumentsAVRStudio 5.1LedsLedsDebug’
    CMD.EXE was started with the above path as the current directory.
    UNC paths are not supported. Defaulting to Windows directory.
    Invoking: AVR/GNU C Compiler
    ‘\psfHomeDocumentsAVRStudio 5.1LedsLedsDebug’
    CMD.EXE was started with the above path as the current directory.
    UNC paths are not supported. Defaulting to Windows directory.
    “C:Program FilesAtmelAVR Studio 5.1extensionsAtmelAVRGCC3.3.1.27AVRToolchainbinavr-gcc.exe” -funsigned-char -funsigned-bitfields -O1 -fpack-struct -fshort-enums -g2 -Wall -c -std=gnu99 -MD -MP -MF “Leds.d” -MT”Leds.d” -mmcu=atmega32 -o”Leds.o” “.././Leds.c”
    avr-gcc.exe: .././Leds.c: No such file or directory
    avr-gcc.exe: no input files
    make: *** [Leds.o] Error 1
    Done executing task “RunCompilerTask” — FAILED.
    Done building target “CoreBuild” in project “Leds.cproj” — FAILED.
    Done building project “Leds.cproj” — FAILED.

    Build FAILED.
    ========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========

    Is the problem in the UNC pathing? (I’m using Parallels)
    Hope you find some time to look at this problem.

    Thanks!

    Fred

    PS: your tuts are perfect!

    • AVR Studio doesn’t accept UNC paths, which is a non-Windows path structure (usually used in UNIX OS). Create another project in some other directory, like My Documents (or anywhere having path starting with a drive letter like C:…… instead of UNC path like \CompNameHome….) and make sure you check “Create directory for solution” while creating your project.

      • Thx. You’re the man! :-)

  2. Hi, I was thinking how to send messages inside the “Messages List” of AVR Studio. I mean, it could be very useful to write messages during the code compilation, so you can have a look about something like this:
    #ifdef _EXTERNAL_CLK
    #message External CLK has been defined
    #endif

    The Preprocessor Message Directive doesn’t work in Atmel AVR Studio 5. Any idea to implement something like that in AVR Studio 5?

    Thank you in advance.

      • Thanks a lot for your answer ;)

  3. hello sir !!
    thanks for such a nyc tutorial…
    actually i am using atmega644 micro controller and have build the hex code using avr studio5…can u suggest me which burner should i use and the proper fuse configuration…

    • Hello Nitish
      Most of the burners like USBasp, AVRISP, USBtinyISP, etc support ATmega644. You can use any of them.
      As far as fuses are concerned, I would suggest you to have a look at http://www.engbedded.com/fusecalc
      The fuses for ATmega16 are LOW 0xC9, HIGH 0xFF. Similarly back-calculate the fuses for ATmega644. But be very careful while setting the fuses since they cannot be altered that easily once programmed.

      • thnks for da reply sir…i was able to burn my controller successfully…
        i have one more query… i m using Max233cpp in my circuit…bt when i give supplies,it heats up very fast..i have checked the circuit over and over again bt can’t figure out why ?
        Can u suggest any particular reason why ths s happening ??

        • Hi Nitish
          See, with the information you have given me, its impossible for me to detect the error. I suggest you take the multimeter, check for the input/output voltages, check for continuity, etc etc.

  4. I haven’t any development board…..!!
    Tell me please which one should I purchase??

    • Hello
      I would suggest you to purchase a cheap one, since you can make one yourself too! eXtreme Electronics offers such boards at an affordable rate. Check it out here. You can get the USBasp programmer from here.
      This was just a suggestion. However, you are free to surf different online stores.

  5. xin cảm ơn! thank!

    • niềm vui của tôi! :)

      • Hi, how can i get only one .hex file from 3 different .c files ? Is there any feature like add or merge in avr studio 5.1 ?

        • Hi Mohit,
          I am afraid, but as far as my knowledge is concerned, there isn’t any such feature in AS5.1. You need to merge them on your own and then build the solution.

  6. is there a software to detect the particular microcontroller we are using , extreme burner is saying power on failed though my green led is lighting and red is blinking, what might be the reason

    • Hi Amruth,
      Seems like you haven’t powered up your microcontroller board. You need to power up your board separately, the USBasp doesn’t supply power to the board.

  7. Hi
    There are no errors when i compile the code but I have problem in building my code for driving LCD display I get following errors Please help
    Error 1 undefined reference to `Check_IF_LCD_isBusy’
    Error 2 undefined reference to `Send_A_String’
    Error 3 undefined reference to `Check_IF_LCD_isBusy’
    Error 4 undefined reference to `Send_A_Character’
    Code is written for atmega 8 and using avr studio5

    • Hey Ronald,

      This is a very vague. You have simply thrown some errors at me, without explaining what you did, how you did, where did you get it, which library you used, and the code itself! I am sorry, but I need more details regarding it before I can try out anything.

      BTW, such errors usually pop up when you haven’t added external libraries to your project. Try adding them. You can also refer to my LCD tutorial, however it will be quite different from yours.

  8. I have a problem in AVR studio 6. When it starts building a project , it takes almost 5 minutes to build. What can be th epossible issues with it.
    Thanks in advance.

    • Hi Ravindra,
      There can be several issues. What is the length of your code. What type of code have you written? What are your processor specs? Did AS6 get installed properly?

      • Hi Mayank.
        Thanx for the reply.
        AS6 was installed properly. Below is the code for testing purpose which is very small :

        Code can be found here.

        This project is building properly but its taking almost 5 minutes. May be some settings is required before building project but don't have any idea what needs to be done. May be some of the things which are not required are processing.

        • Did you optimize your code? Once your code is built (even after 5 minutes), is it working the same way as expected in hardware?

        • I would suggest to go for a fresh installation of AS6. Then follow this tutorial and see if you are able to do it or not.

  9. hello,
    i try to write a code for led blinking instead of using predefined delay function ,used a for loop bt it’s nt working and how to find the path of all these predefined function.. pls help

    • Hi Ritesh,
      It would be helpful if you could provide me with some more details regarding your error.
      And what kind of path are you searching for?

  10. hello
    i have installed avr 5 but can not bulid any project even the examples…!!
    — Build started: Project: AVRGCC6, Configuration: Debug AVR ——
    ========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========
    please guide me

    • Hi Abm

      Please mention the steps that you are following to build a project in AVR 5.

  11. This is much better websught for beginers and also designed in beautigully….

    • Thanks. All the best for your learning process! :)

  12. How to add header fike and source file in AVRSTUDIO5

  13. Hi Mayank, pl. also inform (as I use AVR Studio 4 only) & can’t risk disturbing it. If I download AVR Studio 5, will it upgrade AVR4 ? Or will AVR5 remain separate, so that I cn use either one of these as the need be…??

  14. hi
    thanks for educate……
    i have a problem to use studio6???
    my boards name is evk1100 and i first choose it in the studio6 then whrite my program but my program has many errors.because there arent library in it.can you help me please???
    you can send email for me…
    sorry i am from iran and can not speak english very good…..

    • Hello Neda,
      Thanks for visiting maxEmbedded! Could you please share your code and errors via pastebin.com?
      Thanks!

  15. hi
    thanks for response…..
    i read your educate and you choose microcontroler(atmega32) at the first in studio but i want choos my board in the studio and there are many errors.this is my problem.
    can you explan about choose board not microcontroler an explan me by use many example???
    about my problem :
    at the first i choose my board(evk1100-At32UC3A0512) in studio6.after than i write my code in the below :
    http://pastebin.com/JKniLmSx
    but there are eroors that i write them for you below :
    http://pastebin.com/NxDQQ9Hm
    thanks a lot

    • This means that your compiler toolchain is missing. Try uninstalling and then reinstalling Atmel Studio. And yes, there’s something called translate.google.com for your help!

      • thanks

  16. i need LCD libraray(LCD.h) for studio6 but can not download it from http://www.jump.to/fleury
    please help me ……..
    can you send it to my email?
    or say me another page for download it please.

  17. hi Max…
    excuseme i need lcd libraray(lcd.h and lcd.c) for at32uc3a0512 not atmega32.can you help me please ?
    already i danlowd lcd library from below link :
    http://homepage.hispeed.ch/peterfleury/avr-software.html
    But it was useful for atmega32 not at32uc3a0512.
    when i use that libraray for microcontroler at32uc3a0512 it had below errors :
    Error 6 ‘PORTA’ undeclared (first use in this function)

    Error 2 avr/pgmspace.h: No such file or directory 27 26 ss
    Error 1 avr/io.h: No such file or directory 26 20 ss
    and another errors………

    i need it .please help me!!! can you write libraray lcd(lcd.h )at32uc3a0512 for me please ???
    thanka olot

  18. hello
    excuseme i need lcd libraray(lcd.h and lcd.c) for at32uc3a0512 not atmega32.can you help me please ?
    already i danlowd lcd library from below link :
    http://homepage.hispeed.ch/peterfleury/avr-software.html
    But it was useful for atmega32 not at32uc3a0512.
    when i use that libraray for microcontroler at32uc3a0512 it had below errors :
    Error 6 ‘PORTA’ undeclared (first use in this function)

    Error 2 avr/pgmspace.h: No such file or directory
    Error 1 avr/io.h: No such file or directory
    and another errors………

    i need it .please help me!!! can you write libraray lcd(lcd.h )at32uc3a0512 for me please ???
    thanks alot

    • The problem is not with the library, but with your avr-gcc compiler. For some reason it’s not able to find the avr/io.h file. And you are using an AVR32 controller. First try blinking LEDs rather than jumping head on to LCDs.

      • this means you say can i use that libraray for atmega32 and at32uc3a0512 too ?

        • With necessary modifications, yes.

Trackbacks/Pingbacks

  1. How to: Step by step guide to setting up Atmel Studio (AVR Studio 6) for Arduino | aSensar - […] Using AVR Studio 5 – http://maxembedded.com/2011/06/12/using-avr-studio-5/ […]
  2. Step by step guide to setting up Atmel Studio for Arduino development - Inspired by Nature - […] Using AVR Studio 5 – http://maxembedded.com/2011/06/12/using-avr-studio-5/ […]

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: