Wednesday, June 19, 2013

Parent-Child Relationship in OOP C++

The C++ source code below:


#include <cstdio>
#include <iostream>

using namespace std;

class CParent {
public:
 CParent() {
  ref++;
  cout <<  "class CParent: constructor ref=" << ref << endl;
  Function();
 };
 virtual ~CParent() {
  ref--;
  cout << "class CParent: destructor ref=" << ref << endl;
 }
 virtual int Function() {
  cout << "\tA::Function()" << endl;
  return ref;
 }
 static unsigned int ref;
};


class CChild : public CParent {
public:
 CChild() {
  ref++;
  cout << "\tclass CChild: constructor ref=" << ref << endl;
  m_a = new CParent();
 };
 virtual ~CChild() {
  ref--;
  cout << "\tclass CChild: destructor ref=" << ref << endl;
  delete m_a;
 }

 static unsigned int ref;
private:
 CParent *m_a;
};


unsigned int CParent::ref = 0;
unsigned int CChild::ref = 0;

int main()
{
 int i;
 int n = 2;

 CChild *c = new CChild[n];
 for(i=0; i(&c[i]);
  printf("p[%d].Function()=%d\n", i, p->Function());
 }
 cout << "CChild::Ref=" << CChild::ref << endl;
 delete [] c;
}

SPI on Arduino Nano v3.0

IC Package: 32 pin MLF



Arduino
Pin #
ATMEL 328P
 (MLF) pin#
ATMEL 328P
(PDIP) pin#
Label Function
D10 14 16 PB2 SS*
D11 15 17 PB3 MOSI
D12 16 18 PB4 MISO
D13 17 19 PB5 SCK


The problem is, according to Arduino Nano schematic, pin 13 is connected to LED through 330 ohm resistor in series.
To be able to use SPI correctly, we need to disconnect the LED.

Tuesday, June 18, 2013

Arduino Nano v3.0 with avr-dude



My order of two Arduino Nano-compatible v3.0 from eBay (shipped from China) just arrived. Also bought the USBASP USBISP AVR Programmer from eBay (about $3.0, from China too, see the picture on the left).


The good thing about this USBISP AVR programmer, besides the unbelievable price, I was told that it is  also compatible with avrdude, even Atmel AVR Studio (never tried it, thought)

But when I tried to program it with avr-dude, it always failed with various errors, such as:






avrdude: ser_recv(): programmer is not responding
avrdude: stk500v2_ReceiveMessage(): timeout

avrdude: stk500v2_getsync(): timeout communicating with programmer
or:
...
         Using Port                    : /dev/ttyUSB2
         Using Programmer              : avrisp
         Overriding Baud Rate          : 57600
avrdude: ser_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding
...



I tried "-c arduino" without setting the baud-rate, I also tried different programmer type (stk500v2, etc.), nothing worked.  Turned out, the parameters combination I used was wrong.
In this case, the programmer should be "arduino" but the baudrate must be set to something (in this case, 57600).

The following is the correct one:


bash-4.2$ avrdude -c arduino -b 57600 -P /dev/ttyUSB2 -p atmega328p -vv -U flash:w:blink.hex

avrdude: Version 5.11, compiled on Sep  9 2011 at 16:00:41
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is "/usr/local/etc/avrdude.conf"
         User configuration file is "/home/mlutfi/.avrduderc"

         Using Port                    : /dev/ttyUSB2
         Using Programmer              : arduino
         Overriding Baud Rate          : 57600
         AVR Part                      : ATMEGA328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65     5     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : Arduino
         Description     : Arduino
         Hardware Version: 2
         Firmware Version: 1.16
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f
avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "blink.hex"
avrdude: input file blink.hex auto detected as Intel Hex
avrdude: writing flash (1468 bytes):

Writing | ################################################## | 100% 0.41s

avrdude: 1468 bytes of flash written
avrdude: verifying flash memory against blink.hex:
avrdude: load data flash data from input file blink.hex:
avrdude: input file blink.hex auto detected as Intel Hex
avrdude: input file blink.hex contains 1468 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.30s

avrdude: verifying ...
avrdude: 1468 bytes of flash verified

avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: safemode: Fuses OK

avrdude done.  Thank you.

Monday, May 27, 2013

MSP430 or PIC?

After sometime using LaunchPad, I was ready to buid my own board utilizing some msp430g2211 on breakout boards laying around on my workbench.  I was going to use the JTAG pins available to program them, but bumped with the overpriced USB-based JTAG programmers/debuggers available in the market.  Yes, I could use the LaunchPad to program these separate microcontrollers, but it's not a good and decent way.

I got a  msp430 BSL usb-to-serial programmer from eBay.  After reading the datasheet for msp430g2211, I realized these type of low-cost microcontrollers don't support BSL, either.  So the only way (other than wiring LauchPad to my protoboard) to in-circuit program the chips is to use a JTAG programmer.  That's a lame, as with PIC microcontrollers, I still could used my PicKit2 to program 44-pin 18Fxx chips.  Even AVR from Atmel could do the similar way using cheap programmer available on eBay or even BusPirate.

Well, sorry msp430, for now I am back to PIC as it has so many features I need (wide availability of PDIP footprints, wide I/O voltage (2 - 5 volt) and cheap programmer).  I am aware there are some open-source efforts to build this kind of programmer for msp430 (GoodFet is one of them, the pre-assembled board is sold at https://www.adafruit.com/products/1279#Technical%20Details)

Sunday, April 21, 2013

DIY Arduino Uno on Breadboard and programmed with BusPirate

This is based on the blog on Programming AVR with AVR-GCC and AVR Programming with BusPirate

Instead of pin 13 (PB5) for LED blinking test, I use pin 8 (PB0) because PB5 is shared with SCK which we're going to use for ICSP (connected to BusPirate's SCK)

To test whether avrdude and BusPirate can communicate as well as to see if the chip is readable (so the connections are correct):

bash-4.2$ avrdude -c buspirate -P /dev/ttyUSB0 -p atmega328p -v

avrdude: Version 5.10, compiled on Mar  2 2011 at 21:55:09
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is "/etc/avrdude/avrdude.conf"
         User configuration file is "/home/mlutfi/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/ttyUSB0
         Using Programmer              : buspirate
         AVR Part                      : ATMEGA328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65     5     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : BusPirate
         Description     : The Bus Pirate

Detecting BusPirate...
avrdude: buspirate_readline(): #
avrdude: buspirate_readline(): RESET
avrdude: buspirate_readline():
** 
avrdude: buspirate_readline(): Bus Pirate v3a
**  Bus Pirate v3a
avrdude: buspirate_readline(): Firmware v5.10 (r559)  Bootloader v4.4
**  Firmware v5.10 (r559)  Bootloader v4.4
avrdude: buspirate_readline(): DEVID:0x0447 REVID:0x3046 (24FJ64GA002 B8)
**  DEVID:0x0447 REVID:0x3046 (24FJ64GA002 B8)
avrdude: buspirate_readline(): http://dangerousprototypes.com
**  http://dangerousprototypes.com
avrdude: buspirate_readline(): HiZ>
**
BusPirate: using BINARY mode
BusPirate binmode version: 1
BusPirate SPI version: 1
avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e950f
avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as 7

avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as 7
avrdude: safemode: Fuses OK
BusPirate is back in the text mode

avrdude done.  Thank you.

bash-4.2$




Now we can deploy this command into Makefile I have posted before.
For example, the following lines can be inserted at the very bottom of Makefie:


install: $(PRG).hex
    avrdude -c buspirate -P /dev/ttyUSB0 -p $(MCU_TARGET) -v -U flash:w:$(PRG).hex

To compile:

bash-4.2$ make
avr-objdump -h -S blink.elf > blink.lst
avr-objcopy -j .text -j .data -O binary blink.elf blink.bin
avr-objcopy -j .text -j .data -O srec blink.elf blink.srec
avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O ihex blink.elf blink_eeprom.hex \
|| { echo empty blink_eeprom.hex not generated; exit 0; }
avr-objcopy: --change-section-lma .eeprom=0x0000000000000000 never used
avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O binary blink.elf blink_eeprom.bin \
|| { echo empty blink_eeprom.bin not generated; exit 0; }
avr-objcopy: --change-section-lma .eeprom=0x0000000000000000 never used
avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O srec blink.elf blink_eeprom.srec \
|| { echo empty blink_eeprom.srec not generated; exit 0; }
avr-objcopy: --change-section-lma .eeprom=0x0000000000000000 never used
bash-4.2$


To install/program it to the target (ATMega328P on the breadboard):

bash-4.2$ make install
avr-c++ -c -g -Wall -O2 -mmcu=atmega328p -D__AVR_ATmega328P__ -DF_CPU=16000000UL -I /home/mlutfi/src/arduino/include -I /home/mlutfi/src/arduino/include/arduino -I /home/mlutfi/src/arduino/include/variants -I /home/mlutfi/src/arduino/include/variants/standard -I /opt/arduino-1.0.4/libraries/LiquidCrystal  blink.cpp -o blink.o
***********************************************************
Compiling blink.o
***********************************************************
avr-c++ -g -Wall -O2 -mmcu=atmega328p -D__AVR_ATmega328P__ -DF_CPU=16000000UL -I /home/mlutfi/src/arduino/include -I /home/mlutfi/src/arduino/include/arduino -I /home/mlutfi/src/arduino/include/variants -I /home/mlutfi/src/arduino/include/variants/standard -I /opt/arduino-1.0.4/libraries/LiquidCrystal  -Wl,-Map,blink.map -o blink.elf -L /home/mlutfi/src/arduino/include -lm -lc  blink.o /home/mlutfi/src/arduino/include/libatmega328p.a
avr-objcopy -j .text -j .data -O ihex blink.elf blink.hex
avrdude -c buspirate -P /dev/ttyUSB0 -p atmega328p -v -U flash:w:blink.hex

avrdude: Version 5.11, compiled on Sep  9 2011 at 16:00:41
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is "/usr/local/etc/avrdude.conf"
         User configuration file is "/home/mlutfi/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/ttyUSB0
         Using Programmer              : buspirate
         AVR Part                      : ATMEGA328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65     5     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : BusPirate
         Description     : The Bus Pirate

Detecting BusPirate...
avrdude: buspirate_readline(): #
avrdude: buspirate_readline(): RESET
avrdude: buspirate_readline():
** 
avrdude: buspirate_readline(): Bus Pirate v3a
**  Bus Pirate v3a
avrdude: buspirate_readline(): Firmware v5.10 (r559)  Bootloader v4.4
**  Firmware v5.10 (r559)  Bootloader v4.4
avrdude: buspirate_readline(): DEVID:0x0447 REVID:0x3046 (24FJ64GA002 B8)
**  DEVID:0x0447 REVID:0x3046 (24FJ64GA002 B8)
avrdude: buspirate_readline(): http://dangerousprototypes.com
**  http://dangerousprototypes.com
avrdude: buspirate_readline(): HiZ>
**
BusPirate: using BINARY mode
BusPirate binmode version: 1
BusPirate SPI version: 1
avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e950f
avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as 7
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "blink.hex"
avrdude: input file blink.hex auto detected as Intel Hex
avrdude: writing flash (1444 bytes):

Writing | ################################################## | 100% 4.46s

avrdude: 1444 bytes of flash written
avrdude: verifying flash memory against blink.hex:
avrdude: load data flash data from input file blink.hex:
avrdude: input file blink.hex auto detected as Intel Hex
avrdude: input file blink.hex contains 1444 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 4.37s

avrdude: verifying ...
avrdude: 1444 bytes of flash verified

avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as 7
avrdude: safemode: Fuses OK
BusPirate is back in the text mode

avrdude done.  Thank you.

bash-4.2$

The code "blink.cpp" itself as below:

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.

  This example code is in the public domain.


  According to UNO schematic:
    pin 13 = PB5 (19)
    pin 12 = PB4 (18)
    pin 11 = PB3 (17)
    pin 10 = PB2 (16)
    pin 9 = PB1 (15)
    pin 8 = PB0 (14)
    pin 7 = PD7 (13)
    pin 6 = PD6 (12)
    pin 5 = PD5 (11)
    pin 4 = PD4 (6)
    pin 3 = PD3 (5)
    pin 2 = PD2 (4)
    pin 1 = PD1 (3)
    pin 0 = PD0 (2)
 */
#include <arduino/Arduino.h>

#define LED     8

void setup() {               
  // initialize the digital pin as an output.
  // Pin 13 (has an LED connected on most Arduino boards:
  // but myproto on breadboand uses PB0 (14) = pin 8 as LED output
  pinMode(LED, OUTPUT);    
}

void loop() {
  digitalWrite(LED, HIGH);   // set the LED on
  delay(25);              // wait for a second
  digitalWrite(LED, LOW);    // set the LED off
  delay(25);              // wait for a second
}

Compiling Arduino program using Standard GNU toolchains

Arduino IDE has simplified our life when developing firmware for Atmel-based MCU, but for more advanced programmers, it's not a quick-and-fast way to compile.  A code developed using "Processing", a thin layer between C++ and Arduino code cannot be compiled using avr-gcc toolchains straightforward.

The following steps are needed to make the compilation becomes standard compilation as other open-source code compilation.

  1. Copy the folder <arduino root>/arduino/hardware/arduino/cores/* and <arduino root>/arduino/hardware/arduino/variants/* to a new folder, e.g. /home/myname/src/arduino/include
  2. Run the Makefile below to build a library.  In my case, I tried to build a lib for my AtMega328p-based Arduino Uno.  Goto the folder and do "make"
  3. Once the library is built, we can link it to our program (we need to rename our program's extension from *.ino to *.cpp).  See the second Makefile for an example how to build and link with the newly created lib file.
  4. To upload the program to the target (Arduino Uno), we need an ICSP programmer (available for cheap on eBay) and use "avrdude" command to do the programming.

The Makefile to build atmega328p

#MCU_TARGET     = at90s2313
#MCU_TARGET     = at90s2333
#MCU_TARGET     = at90s4414
#MCU_TARGET     = at90s4433
#MCU_TARGET     = at90s4434
#MCU_TARGET     = at90s8515
#MCU_TARGET     = at90s8535
#MCU_TARGET     = atmega128
#MCU_TARGET     = atmega1280
#MCU_TARGET     = atmega1281
#MCU_TARGET     = atmega1284p
#MCU_TARGET     = atmega16
#MCU_TARGET     = atmega163
#MCU_TARGET     = atmega164p
#MCU_TARGET     = atmega165
#MCU_TARGET     = atmega165p
#MCU_TARGET     = atmega168
#MCU_TARGET     = atmega169
#MCU_TARGET     = atmega169p
#MCU_TARGET     = atmega2560
#MCU_TARGET     = atmega2561
#MCU_TARGET     = atmega32
#MCU_TARGET     = atmega324p
#MCU_TARGET     = atmega325
#MCU_TARGET     = atmega3250
#MCU_TARGET     = atmega329
#MCU_TARGET     = atmega3290
MCU_TARGET      = atmega328p
#MCU_TARGET     = atmega48
#MCU_TARGET     = atmega64
#MCU_TARGET     = atmega640
#MCU_TARGET     = atmega644
#MCU_TARGET     = atmega644p
#MCU_TARGET     = atmega645
#MCU_TARGET     = atmega6450
#MCU_TARGET     = atmega649
#MCU_TARGET     = atmega6490
#MCU_TARGET     = atmega8
#MCU_TARGET     = atmega8515
#MCU_TARGET     = atmega8535
#MCU_TARGET     = atmega88
#MCU_TARGET     = attiny2313
#MCU_TARGET     = attiny24
#MCU_TARGET     = attiny25
#MCU_TARGET     = attiny26
#MCU_TARGET     = attiny261
#MCU_TARGET     = attiny44
#MCU_TARGET     = attiny45
#MCU_TARGET     = attiny461
#MCU_TARGET     = attiny84
#MCU_TARGET     = attiny85
#MCU_TARGET     = attiny861

#DEFS           = -DF_CPU=16000000UL
DEFS           = -D__AVR_ATmega328P__ -DF_CPU=16000000UL
ARDUINO           = /opt/arduino-1.0.4
MYARDUINO       = .
INCS           = -I $(MYARDUINO)/ \
                 -I $(MYARDUINO)/arduino \
                 -I $(MYARDUINO)/variants \
                 -I $(MYARDUINO)/variants/standard

LIBS           = -lm -lc

OPTIMIZE       = -O2 -finline-small-functions

# You should not have to change anything below here.

CC             = avr-gcc
CXX               = avr-c++
AR               = avr-ar

# Override is only needed by avr-lib build system.

override CFLAGS        = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS) $(INCS)
override CXXFLAGS      = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS) $(INCS)
override LDFLAGS       = -Wl,-Map,$(PRG).map

OBJCOPY        = avr-objcopy
OBJDUMP        = avr-objdump


PRG            = libatmega328p
SRCS           = \
                 $(MYARDUINO)/arduino/Print.cpp \
                 $(MYARDUINO)/arduino/WString.cpp \
                 $(MYARDUINO)/arduino/Stream.cpp \
                 $(MYARDUINO)/arduino/CDC.cpp \
                 $(MYARDUINO)/arduino/HardwareSerial.cpp \
                 $(MYARDUINO)/arduino/HID.cpp \
                 $(MYARDUINO)/arduino/IPAddress.cpp \
                 $(MYARDUINO)/arduino/main.cpp \
                 $(MYARDUINO)/arduino/new.cpp \
                 $(MYARDUINO)/arduino/Tone.cpp \
                 $(MYARDUINO)/arduino/USBCore.cpp \
                 $(MYARDUINO)/arduino/WMath.cpp \
                 $(MYARDUINO)/arduino/malloc.c \
                 $(MYARDUINO)/arduino/WInterrupts.c \
                 $(MYARDUINO)/arduino/wiring_analog.c \
                 $(MYARDUINO)/arduino/wiring_digital.c \
                 $(MYARDUINO)/arduino/wiring_pulse.c \
                 $(MYARDUINO)/arduino/wiring_shift.c \
                 $(MYARDUINO)/arduino/wiring.c

BUILDDIR = ./build

all: $(PRG).a $(OBJS)

#OBJS := $(patsubst %.cpp, obj/%.o, $(SRCS))
#OBJS := $(patsubst %.c, obj/%.o, $(SRCS))

OBJS := $(notdir $(SRCS))
OBJS := $(OBJS:.cpp=.o)
OBJS := $(OBJS:.c=.o)
OBJS := $(patsubst %.o, $(BUILDDIR)/%.o, $(OBJS))

#----------------------------- dependency:

$(OBJS): | $(BUILDDIR)

$(BUILDDIR):
      @mkdir -p $@

$(BUILDDIR)/%.o: $(MYARDUINO)/arduino/%.c
    @echo $<
    $(CC) -c $(CFLAGS) $< -o $@

$(BUILDDIR)/%.o: $(MYARDUINO)/arduino/%.cpp
    @echo $<
    $(CXX) -c $(CXXFLAGS) $< -o $@

#$(OBJS): $(SRCS)
#    @echo "Compiling $< to $@"
#    $(CXX) -S $(CXXFLAGS) $< -o $@


$(PRG).a: $(OBJS)
    @echo "***********************************************************"
    @echo OBJS=$(OBJS)
    @echo "***********************************************************"
    @echo "Building LIB=$(PRG).a from $?"
    @echo "-----------------------------------------------------------"
    $(AR) qusv $@ $?


clean:
    rm -rf *.o $(PRG).a *.eps *.png *.pdf *.bak $(OBJS)
    rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)

lst:  $(PRG).lst

%.lst: %.a
    $(OBJDUMP) -h -S $< > $@

# Rules for building the .text rom images

text: hex bin srec

hex:  $(PRG).hex
bin:  $(PRG).bin
srec: $(PRG).srec

%.hex: %.elf
    $(OBJCOPY) -j .text -j .data -O ihex $< $@

%.srec: %.elf
    $(OBJCOPY) -j .text -j .data -O srec $< $@

%.bin: %.elf
    $(OBJCOPY) -j .text -j .data -O binary $< $@

# Rules for building the .eeprom rom images

eeprom: ehex ebin esrec

ehex:  $(PRG)_eeprom.hex
ebin:  $(PRG)_eeprom.bin
esrec: $(PRG)_eeprom.srec

%_eeprom.hex: %.elf
    $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ \
    || { echo empty $@ not generated; exit 0; }

%_eeprom.srec: %.elf
    $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@ \
    || { echo empty $@ not generated; exit 0; }

%_eeprom.bin: %.elf
    $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@ \
    || { echo empty $@ not generated; exit 0; }

# Every thing below here is used by avr-libc's build system and can be ignored
# by the casual user.

FIG2DEV                 = fig2dev
EXTRA_CLEAN_FILES       = *.hex *.bin *.srec

dox: eps png pdf

eps: $(PRG).eps
png: $(PRG).png
pdf: $(PRG).pdf

%.eps: %.fig
    $(FIG2DEV) -L eps $< $@

%.pdf: %.fig
    $(FIG2DEV) -L pdf $< $@

%.png: %.fig
    $(FIG2DEV) -L png $< $@



A Makefile to build our application:

#MCU_TARGET     = at90s2313
#MCU_TARGET     = at90s2333
#MCU_TARGET     = at90s4414
#MCU_TARGET     = at90s4433
#MCU_TARGET     = at90s4434
#MCU_TARGET     = at90s8515
#MCU_TARGET     = at90s8535
#MCU_TARGET     = atmega128
#MCU_TARGET     = atmega1280
#MCU_TARGET     = atmega1281
#MCU_TARGET     = atmega1284p
#MCU_TARGET     = atmega16
#MCU_TARGET     = atmega163
#MCU_TARGET     = atmega164p
#MCU_TARGET     = atmega165
#MCU_TARGET     = atmega165p
#MCU_TARGET     = atmega168
#MCU_TARGET     = atmega169
#MCU_TARGET     = atmega169p
#MCU_TARGET     = atmega2560
#MCU_TARGET     = atmega2561
#MCU_TARGET     = atmega32
#MCU_TARGET     = atmega324p
#MCU_TARGET     = atmega325
#MCU_TARGET     = atmega3250
#MCU_TARGET     = atmega329
#MCU_TARGET     = atmega3290
MCU_TARGET      = atmega328p
#MCU_TARGET     = atmega48
#MCU_TARGET     = atmega64
#MCU_TARGET     = atmega640
#MCU_TARGET     = atmega644
#MCU_TARGET     = atmega644p
#MCU_TARGET     = atmega645
#MCU_TARGET     = atmega6450
#MCU_TARGET     = atmega649
#MCU_TARGET     = atmega6490
#MCU_TARGET     = atmega8
#MCU_TARGET     = atmega8515
#MCU_TARGET     = atmega8535
#MCU_TARGET     = atmega88
#MCU_TARGET     = attiny2313
#MCU_TARGET     = attiny24
#MCU_TARGET     = attiny25
#MCU_TARGET     = attiny26
#MCU_TARGET     = attiny261
#MCU_TARGET     = attiny44
#MCU_TARGET     = attiny45
#MCU_TARGET     = attiny461
#MCU_TARGET     = attiny84
#MCU_TARGET     = attiny85
#MCU_TARGET     = attiny861
OPTIMIZE       = -O2

DEFS           = -D__AVR_ATmega328P__ -DF_CPU=16000000UL
ARDUINO           = /opt/arduino-1.0.4
MYARDUINO       = /home/myname/src/arduino

INCS           = -I $(MYARDUINO)/include \
                 -I $(MYARDUINO)/include/arduino \
                 -I $(MYARDUINO)/include/variants \
                 -I $(MYARDUINO)/include/variants/standard \
                 -I /opt/arduino-1.0.4/libraries/LiquidCrystal

LIBS           = -L $(MYARDUINO)/include -lm -lc

# You should not have to change anything below here.

CC             = avr-gcc
CXX               = avr-c++

# Override is only needed by avr-lib build system.

CFLAGS        = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS) $(INCS)
override LDFLAGS       = -Wl,-Map,$(PRG).map

OBJCOPY        = avr-objcopy
OBJDUMP        = avr-objdump


PRG            = HelloWorld
SRCS           = \
                 HelloWorld.cpp \
                 /opt/arduino-1.0.4/libraries/LiquidCrystal/LiquidCrystal.cpp


all: $(PRG).elf lst text eeprom

OBJS := $(SRCS:.cpp=.o)
OBJS := $(OBJS:.c=.o)

%.o: %.c
    $(CC) -c $(CFLAGS) $? -o $@

%.o: %.cpp
    $(CXX) -c $(CFLAGS) $? -o $@

$(PRG).elf: $(OBJS)
    @echo "***********************************************************"
    @echo OBJS=$(OBJS)
    @echo "***********************************************************"
    @echo "Compiling $?"
    @echo "-----------------------------------------------------------"
    $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(LIBS) $? ./include/libatmega328p.a

# dependency:


clean:
    rm -rf *.o $(PRG).elf *.eps *.png *.pdf *.bak
    rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)

lst:  $(PRG).lst

%.lst: %.elf
    $(OBJDUMP) -h -S $< > $@

# Rules for building the .text rom images

text: hex bin srec

hex:  $(PRG).hex
bin:  $(PRG).bin
srec: $(PRG).srec

%.hex: %.elf
    $(OBJCOPY) -j .text -j .data -O ihex $< $@

%.srec: %.elf
    $(OBJCOPY) -j .text -j .data -O srec $< $@

%.bin: %.elf
    $(OBJCOPY) -j .text -j .data -O binary $< $@

# Rules for building the .eeprom rom images

eeprom: ehex ebin esrec

ehex:  $(PRG)_eeprom.hex
ebin:  $(PRG)_eeprom.bin
esrec: $(PRG)_eeprom.srec

%_eeprom.hex: %.elf
    $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ \
    || { echo empty $@ not generated; exit 0; }

%_eeprom.srec: %.elf
    $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@ \
    || { echo empty $@ not generated; exit 0; }

%_eeprom.bin: %.elf
    $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@ \
    || { echo empty $@ not generated; exit 0; }

# Every thing below here is used by avr-libc's build system and can be ignored
# by the casual user.

FIG2DEV                 = fig2dev
EXTRA_CLEAN_FILES       = *.hex *.bin *.srec

dox: eps png pdf

eps: $(PRG).eps
png: $(PRG).png
pdf: $(PRG).pdf

%.eps: %.fig
    $(FIG2DEV) -L eps $< $@

%.pdf: %.fig
    $(FIG2DEV) -L pdf $< $@

%.png: %.fig
    $(FIG2DEV) -L png $< $@