NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Support Forum » putting atmega168 and atmega328p projects in different folders/directories

December 15, 2012
by keith712
keith712's Avatar

i have two NerdKits, one with the ATmega168 and the other with the ATmega328. i program my kits with my macBook air running 10.8.2. i keep my files in the following paths:

Desktop/gcc4/168/atmega168 project folders, libnerdkits, bootloader168

Desktop/gcc4/328/atmega328 project folders, libnerdkits with io_328p.h, bootloader328p

i came up with this arrangement a couple days ago and now i'm getting a lot of "device type not defined" and "undefined reference to '__heap_end'" errors and also the compiler is telling me that constants like PC4 and PORTC are being referenced before being defined even though i have all the #include <stdio.h> and <avr/io.h> etc statements at the head of the source code.

could it be that the preprocessor/linker/compiler is getting confused by my having multiple copies of the libnerdkits folder?

December 17, 2012
by keith712
keith712's Avatar

i'm still having this problem with the warning: device type not defined. it's stopping all my programs that use constants and functions from avr/io.h from compiling.

here's my program:

// initialload.c
// for NerdKits with ATmega168
// mrobbins@mit.edu
//
// modified dec2012 keithmac@maui.net
//
// definitions and includes
#define F_CPU 14745600 //tells delay.h the clock speed
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"

// includes not needed
//#include <stdlib.h>
//#include <avr/interrupt.h>
//#include <util/delay.h>
//#include <inttypes.h>

int main() {

  // initialize LCD
  lcd_init();

  // print message to LCD
  lcd_goto_position(0,0);
  lcd_write_string(PSTR("  Congratulations!  "));
  lcd_goto_position(1,0);
  lcd_write_string(PSTR("       Keith       "));
  lcd_goto_position(2,0);
  lcd_write_string(PSTR("  Your USB NerdKit  "));
  lcd_goto_position(3,0);
  lcd_write_string(PSTR("is alive and works!"));

  // set Pxn bit of DDRx register for output from Pxn pin of PORTx register to
  // LED anode; LED cathode to GND
  DDRC |= (1<<PC4);

  // infinite loop to prevent undefined termination of main() and
  // demontrate user defined io
  while(1) {

    // turn on LED
    PORTC |= (1<<PC4);
    delay_ms(500);

    // turn off that LED
    PORTC &= ~(1<<PC4);
    delay_ms(500);

  }

  return 0;

}

and here's the Terminal messages i get after i enter the make command:

make -C ../libnerdkits
make[1]: Nothing to be done for `all'.
avr-gcc   -o initialload.o initialload.c ../libnerdkits/delay.o ../libnerdkits/lcd.o ../libnerdkits/uart.o
In file included from initialload.c:9:0:
/usr/local/CrossPack-AVR-20121207/lib/gcc/avr/4.6.2/../../../../avr/include/avr/io.h:607:6: warning: #warning "device type not defined" [-Wcpp]
initialload.c: In function 'main':
initialload.c:36:3: error: 'DDRC' undeclared (first use in this function)
initialload.c:36:3: note: each undeclared identifier is reported only once for each function it appears in
initialload.c:36:15: error: 'PC4' undeclared (first use in this function)
initialload.c:43:5: error: 'PORTC' undeclared (first use in this function)
make: *** [initialload.hex] Error 1

what device type is undefined? i assume that once avr/io.h gets the device type defined the undeclared constants (DDRC, PC4 and PORTC) error will be fixed.

please help... k

December 17, 2012
by pcbolt
pcbolt's Avatar

Keith -

I'm not a Mac guy so I may not be the best help. There may be a few different causes to the problem, so we may need more info. I know the ATmega328 had a problem with the "io.h" files but it should work for your ATmega168. You should post your "makefile" for this project as well...something in there might be wonky. I think you are right about "avr/io.h", once that gets worked out, it should compile.

December 17, 2012
by keith712
keith712's Avatar

hi pcbolt. here's my makefile:

GCCFLAGS=-g -Os -Wall -mmcu=atmega168
LINKFLAGS=-Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt -lm
AVRDUDEFLAGS=-c avr109 -p m168 -b 115200 -P /dev/cu.usbserial
LINKOBJECTS=../libnerdkits/delay.o ../libnerdkits/lcd.o ../libnerdkits/uart.o

all:    initialload-upload

initialload.hex:    initialload.c
    make -C ../libnerdkits
    avr-gcc ${GCCFLAGS\} ${LINKFLAGS\} -o initialload.o initialload.c ${LINKOBJECTS}
    avr-objcopy -j .text -O ihex initialload.o initialload.hex

initialload.ass:    initialload.hex
    avr-objdump -S -d initialload.o > initialload.ass

initialload-upload: initialload.hex
    avrdude ${AVRDUDEFLAGS} -e
    sleep 1.0
    avrdude ${AVRDUDEFLAGS} -D -U flash:w:initialload.hex:a

i did download the io_328p.h file for my 328 projects. at first i was thinking that that was causing the problem but now i don't think so. i'm lost. i appreciate any help... k

December 17, 2012
by pcbolt
pcbolt's Avatar

Keith -

Looks OK. It's set up to use the ATmega168 (line 1 in make file) so I'm assuming this is the MCU you are programming. The one thing I did notice was you commented out the "include <inttypes.h>". That is about the only difference I can see from a project file I compiled. Your directory structure is similar to what I use as well except I'm using a Windows box. I don't think the compiler is getting confused by your directory structure, but try going back to your original setup and just make incremental changes until you see the errors again.

December 17, 2012
by pcbolt
pcbolt's Avatar

Keith -

One other thing to check. If you are programming for the ATmega328, line 1 of the make file should be...

GCCFLAGS=-g -Os -Wall -mmcu=atmega328p
December 18, 2012
by keith712
keith712's Avatar

thanks again... i'm stumped, too, but i'm going to try to backtrack like you suggest... i should have kept a log of my downloads, folder creation, file moves, etc but i wasn't expecting anything like this... wish me luck... k

December 18, 2012
by keith712
keith712's Avatar

i forgot... thanks for the reminders about the makefile changes and to double check that i haven't mixed up my kits... i did mix up the kits once so i mounted both breadboards to squares of heavy cardboard that're labeled with '168' or '328'... i'm going to strip a copy of initialload.c to just comments and start adding lines of code a few at a time to try to catch where the problem starts... hi ho hi ho, off to work i go... k

December 18, 2012
by keith712
keith712's Avatar

after about an hour of trying different versions of initial load all with no compilation due to an assortment of warnings and errors i did some more forum searches and learned a little bit about the directory usr and all the hidden files. in my usr/local directory i have the following items:

k712:local k712$ ls
AVRMacPack      CrossPack-AVR       bin
AVRMacPack-20080721 CrossPack-AVR-20121207  share

could it be that the multiple versions of macPack and crossPack are causing the problem. how do i rm or uninstall the unneeded directories or files?

December 18, 2012
by pcbolt
pcbolt's Avatar

Keith -

It could be a multiple version problem. I wish I knew more about the Mac to help. What is odd is the correct "io.h" file is being called, but the "-mmcu=atmega168" switch isn't being recognized, can't figure out why. Good luck and happy hunting.

December 18, 2012
by Noter
Noter's Avatar

There is no need to have different versions of the nerdkit for the 168 and 328. Everything is the same except in your makefile, change the mmcu for gcc and the -p m168 for avrdude for the target you are going to program and go. Get the latest toolchain from ATmel and you don't even have to worry about PB? definitions for the atmega328p, it's fixed.

December 18, 2012
by keith712
keith712's Avatar

hi Noter... i think i understand... the makefile tells the preprosser/compiler/linker what to do so if the makefile is correct there should be no confusion which library files to use. here are two of my typical makefiles for my 168 and 328 kits:

GCCFLAGS=-g -Os -Wall -mmcu=atmega168 
LINKFLAGS=-Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt -lm
AVRDUDEFLAGS=-c avr109 -p m168 -b 115200 -P /cu.usbserial
LINKOBJECTS=../libnerdkits/delay.o ../libnerdkits/lcd.o ../libnerdkits/uart.o

all:    led_blink-upload

led_blink.hex:  led_blink.c
    make -C ../libnerdkits
    avr-gcc ${GCCFLAGS} ${LINKFLAGS} -o led_blink.o led_blink.c ${LINKOBJECTS}
    avr-objcopy -j .text -O ihex led_blink.o led_blink.hex

led_blink.ass:  led_blink.hex
    avr-objdump -S -d led_blink.o > led_blink.ass

led_blink-upload:   led_blink.hex
    avrdude ${AVRDUDEFLAGS} -e
    sleep 1.0
    avrdude ${AVRDUDEFLAGS} -D -U flash:w:led_blink.hex:a

and

GCCFLAGS=-g -Os -Wall -mmcu=atmega328p 
LINKFLAGS=-Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt -lm
AVRDUDEFLAGS=-c avr109 -p m328p -b 115200 -P /dev/cu.usbserial
LINKOBJECTS=../libnerdkits/delay.o ../libnerdkits/lcd.o ../libnerdkits/uart.o

all:    led_blink-upload

led_blink.hex:  led_blink.c
    make -C ../libnerdkits
    avr-gcc ${GCCFLAGS} ${LINKFLAGS} -o led_blink.o led_blink.c ${LINKOBJECTS}
    avr-objcopy -j .text -O ihex led_blink.o led_blink.hex

led_blink.ass:  led_blink.hex
    avr-objdump -S -d led_blink.o > led_blink.ass

led_blink-upload:   led_blink.hex
    avrdude ${AVRDUDEFLAGS} -e
    sleep 1.0
    avrdude ${AVRDUDEFLAGS} -D -U flash:w:led_blink.hex:a

did i get it right? both the programs that these makefiles refer to compiled and ran last week before i started rearranging my folders to keep my 168 and 328 projects more organized.

i'm going to put all my projects in a single folder again with only one copy of libnerdkits that includes the io_328p.h file to see if that fixes my problem.

i think the other possible issue is that in my /usr/local directory are AVRMacPack, AVRMacPack-20080721, CrossPack-AVR and CrossPack-AVR-20121207 directories. could the problem be having all these different toolchains available? i'm not sure if i'm saying that right... hopefully you understand what i mean.

any comments or questions are welcome!!! thanks for taking the time to help... k

December 18, 2012
by keith712
keith712's Avatar

i just put all my projects back into one folder and i just remembered why i separated them in the first place. there is a different makefile for libnerdkits for the 168 processor vs the 328. the only differences are -mmcu=ATmega168 vs -mmcu=ATmega328p and the inclusion of io_328p.h directives in only the 328p makefile.

do i need to run the libnerdkits 168 makefile before i try to compile a 168 project and the libnerdkits 328 makefile before compiling 328 projects? i thought if i put the two different versions of libnerdkits in different folders and ran the matching makefile in their separate folders i wouldn't have to remake the library each time i changed from a 168 to a 328 project.

could this be the problem?

December 18, 2012
by Noter
Noter's Avatar

There's really no difference in the compiled code between the 168 and 328 so either copy of the library object files will work fine There is no need to remake the library when changing mcu's.

I'm not so sure on you crosspack stuff because I'm running Ubuntu and prior to that I was on windows. Don't know that much about macs. But I can tell you that on linux and windows all that matters is where the needed files are found first when going down the list of directories in the PATH variable. Currently I have an old copy of the toolchain somewhere in usr/lib (I think) but I put the latest version in my home directory and added it to the PATH ahead of all the other directories so it is found first and used. I imagine the mac is the same in one way or another.

In my makefiles I've added the makefile itself as a dependent for the gcc compile. This is so when I change the mcu or something like that but not the source program, the program will get a fresh compile anyway. Just a convenience thing so I don't have to remember to edit the c source or clean the directory first after changes to the makefile. For example the initialload makefile will have a line like this:

initialload.hex:    initialload.c Makefile

It's so fast to change the make file and compile/download the code that I don't keep different versions of a program around for different chips.

If at some point you start changing mcu clock speeds, baud rates, or pinouts for the ldc, you will have to deal with recompiling the libnerdkits code at that point but until then it will work as is for both the 168 and 328.

December 19, 2012
by keith712
keith712's Avatar

i'm learning slowly but surely... from what you've told me i decided to re-download all the source code from nerdkits and start from scratch...

i modified the makefile for initialload as follows:

GCCFLAGS=-g -Os -Wall -mmcu=atmega168 
LINKFLAGS=-Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt -lm
AVRDUDEFLAGS=-c avr109 -p m168 -b 115200 -P /dev/cu.usbserial
LINKOBJECTS=../libnerdkits/delay.o ../libnerdkits/lcd.o ../libnerdkits/uart.o

all:    initialload-upload

initialload.hex:    initialload.c
    make -C ../libnerdkits
    avr-gcc ${GCCFLAGS} ${LINKFLAGS} -o initialload.o initialload.c ${LINKOBJECTS}
    avr-objcopy -j .text -O ihex initialload.o initialload.hex

initialload.ass:    initialload.hex
    avr-objdump -S -d initialload.o > initialload.ass

initialload-upload: initialload.hex
    avrdude ${AVRDUDEFLAGS} -e
    sleep 1.0
    avrdude ${AVRDUDEFLAGS} -D -U flash:w:initialload.hex:a

i only added a few lines of comments to initialload.c as follows:

// initialload.c
// for NerdKits with ATmega168
// mrobbins@mit.edu
//
// downloaded from nerdkits 19dec12
//

#define F_CPU 14745600

#include <stdio.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"

// PIN DEFINITIONS:
//
// PC4 -- LED anode

int main() {
  // LED as output
  DDRC |= (1<<PC4);

  // turn on LED
  PORTC |= (1<<PC4);

  // fire up the LCD
  lcd_init();
  lcd_home();

  // print message to screen
  //             20 columns wide:
  //                     01234567890123456789
  lcd_line_one();
  lcd_write_string(PSTR("  Congratulations!  "));
  lcd_line_two();
  lcd_write_string(PSTR("********************"));
  lcd_line_three();
  lcd_write_string(PSTR("  Your USB NerdKit  "));
  lcd_line_four();
  lcd_write_string(PSTR("      is alive!     "));

  // turn off that LED
  PORTC &= ~(1<<PC4);

  // busy loop
  while(1) {
    // do nothing
  }

  return 0;
}

the good news: it compiles and writes to the chip... yay!!!

the bad news: when i run it the LCD flashes and then displays ' is alive! ' on line 0 of the LCD with no display on lines 1-3 and the LED turns on but never turns off

this is not the output of initialload when i first ran it a few months ago

any ideas? thanks in advance... k

December 19, 2012
by Ralphxyz
Ralphxyz's Avatar

k, can you see/use the unmodified initiaload (you did keep a copy :-)?

Once you can run initialload then try to make your modifications ONE LINE AT A TIME!!

Ralph

December 20, 2012
by keith712
keith712's Avatar

thanks Ralph... i've been busy with my 'day' job (day in quotes because i work evening and night shifts)... there's lots of overtime this time of year...

i've backed up to the point where i'm going to recheck how i've wired the lcd to the mcu... i think i can get to that later this morning... if the wiring checks out then i'm going to do what you say, i'm going to comment out the code of a copy of my original, unmodified initialload.c, outline step by step which lines of code to uncomment and then after each line of code is added back to initialload.c, compile and document either the compiler errors or if it compiles run and document the lcd/led output... i should have a table of results sometime this weekend... cross your fingers... Merry Christmas... k

December 22, 2012
by keith712
keith712's Avatar

well, i'm still stuck... my wiring all checked out... i downloaded a fresh initialload project... i minimally edited the Makefile... the new initialload compiled and downloaded to the kit with no warnings or errors... when i ran the kit the LED flashed on time as expected but this output on the LCD was:

row 0: " is alive! " row 1,2,3: empty

i then commented out all the code (except for the #define and #include statements) and uncommented:

int main(){
lcd_init();
lcd_goto_position(0,0); // lcd_goto_position() is more flexible for testing/debugging than lcd_line_one()
lcd_write_string(("  Congratulations!  "));
return 0;
}

cutting to the chase:

given: lcd_goto_position(r,c);

compiled code ignores the value of r, it always writes to row 0

if the value of c causes the string in lcd_write_string() to overflow row 0, the overflow is written to row 2 (not row 1)

if c causes the string to overflow two whole rows, rows 0 and 2 are full and overflow goes to row 1

if c causes the string to overflow three whole rows, rows 0,2,1 are full and overflow is in row 4

if i write to more then one row (no overflow) each write displays on row 0 with its first character missing and it overwrites any previous displays on row 0

does anybody know why my code can no longer access any row but 0 and why the order of the rows has been changed?

December 22, 2012
by Rick_S
Rick_S's Avatar

Have you tried THIS?? It sounds like you may have the same optimization issues going on.

Rick

December 22, 2012
by keith712
keith712's Avatar

thanks Rick... changing '-Os' to '-O0' and cutting '-j .text' from both my project's and the libnerdkits' makefiles, trashing all the .o and .hex files and then recompiling fixed the problem...

when i searched the forums before starting this thread i'm pretty sure i saw the 'ubuntu lcd problems' on the results page but because i'm using a mac osx to write code and download to my kit i didn't look at the page... dumb, dumb, dumb...

thanks again to you all and Merry Christmas... k

December 22, 2012
by Rick_S
Rick_S's Avatar

No problem, and Merry Christmas to you and yours as well!

Rick

December 25, 2012
by keith712
keith712's Avatar

i continued an on and off search through the forums the last few days and found this thread:

Microcontroller Programming ยป LCD library error? Only Line 4 and on line1 ???

on 21Aug12 in the thread (the last entry) thinalrart suggests a change to lcd_goto_position() in libnerdkits/lcd.c that fixed a similar (maybe exactly the same) problem i was having... i'm going to give it a try... not today, it's Christmas day, but soon...

December 25, 2012
by Noter
Noter's Avatar

Are you using the latest version of the toolchain? Might take care of your problem.

Atmel AVR Toolchain 3.4.1 for Linux

December 26, 2012
by keith712
keith712's Avatar

thanks Noter... you told me about the new toolchain in another thread... i've been running two different threads on this because i originally thought i had two different problems... very confusing...

anyway... i did look at that page and i should have asked you about it... i'm uploading to my nerdkit from a mac osx 10.8.2... is it ok to download and install a Linux toolchain? which version of 3.4.1 should i download? my mac has a core i7 chip so i'm pretty sure it's a 64 bit system...

hard to believe i'm saying that... i remember when 64 bit buses and registers only existed in mainfram systems that took up the middle of an air conditioned room with three 10Mb (10 whole Mb each!!!!) drives in four foot high cabinets lined up against a wall, a punch card reader the size of the xerox machines you see at kinkos and a terminal with a CRT that was 24 inches deep with s 13 inch orange on black display in one corner and if you raised the floor plates all you could see was a rat's nest of cables in a rainbow assortment of colors)...

sorry... i should have given you a garrulous old-man alert... later, k

December 26, 2012
by Noter
Noter's Avatar

I don't know much about the mac so can't help a lot but I don't think the linux distribution is compatible with osx. I found this page on CrossPack that looks to have the latest toolchain package for the mac which will definitely be a great improvement over the old version referenced by nerdkits download links.

I remember when the big machine on site was a 36 bit mainframe. I was mostly programming the mini's in those days and the first time ever I did a utility sort on the big box it finished so fast I didn't think it worked, but it did. Wow, 36 bit words, that was real power back in those days.

December 26, 2012
by keith712
keith712's Avatar

i downloaded this version of crosspack: CrossPack-AVR-20121128.dmg at the end of Nov and i downloaded CrossPack-AVR-20121207 a couple weeks later... both my nerdkits programmed and run AOK until my lcd stopped working (it would display only two bars no matter which mode my chip was in) and then when i received a new lcd it would only display in rows 0,2,1,3 in that order or if i wrote to all four rows it would only display the row four string in row 0 with the other rows empty... with yours everyone else's help i've now got my second kit and lcd back to running AOK...

i've now got my first kit back from my friend so i'm going to start to 'debug' it, too... maybe i'll even be able to get my original 'broken' lcd running again... that's why i'm still perusing the forums for similar problems... wish me luck and thanks again for all your help...

December 26, 2012
by Noter
Noter's Avatar

What was it that got it running ok again? New crosspack? Wiring?

December 26, 2012
by keith712
keith712's Avatar

when i changed makefile as follows:

optimization changed from '-Os' to '-O3' on the first line of makefile (line starting with 'GCCFLAGS=')

'-j .text' deleted from line starting with 'avr-objcopy'

actually i like using the -O3 option even though my code is one or two kb longer than with the -Os option...

i still don't know what the -j option does but i'm looking for a fix that allows me to put it back in since the nerdkits people thought it was important enough to put it in in the first place...

who made the 36 bit system... my 64 bit system was a Burroughs (7800 i think)...

December 26, 2012
by Noter
Noter's Avatar

The -j option tells avr-objcopy to copy only the .text section from the object file to the hex file. Without it I think all sections are copied. The .text section contains all your program code and the .data section contains the initialization values for variables. I copy both sections in my make file by using two -j options:

 avr-objcopy -j .text -j .data -O ihex whatever.o whatever.hex

So with only -j .text your program variables are not initialized at runtime.

Another file I like to have on hand is a memory map which can be created by adding a -map to the the link options:

LINKFLAGS=-Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt -lm -Map=whatever.map

I've experienced the optimization bug that affects the lcd position routine but that problem went away when I upgraded to a newer version of the toolchain. Before I upgraded I changed the lcd.c source to use if statements instead of a case statement and that also solved the problem but after the upgrade I put it back to case statements.

That old 36 bit machine was a Dec System 10 made by Digital Equip. Corp. It was primarily a batch processing system but had a couple of hundred terminals wired in for user inquiries/data entry and a herd of programmers hacking away.

December 27, 2012
by keith712
keith712's Avatar

aaah, memories...

thank you for the mini makefile tutorial... every bit (byte?) helps... i keep a document in my avrProjects folder with all my notes about makefiles and the dates and changes i've made to my makefiles... it's already come in handy a couple times...

i just got done pasting your note into it so i can start to incorporate your suggestions into my projects... thanks for sharing...

December 27, 2012
by Noter
Noter's Avatar

I forgot part of the option for the map file. It has to have the -Wl in front of it to let gcc know it's a linker option.

-Wl,-Map=$@.map

Here's the whole story on make.

Yep, memories. Remember the shelves of reference manuals? And patches took weeks to get. Sure is different now because everything you could ever want is instantly available on the internet.

December 27, 2012
by keith712
keith712's Avatar

thanks for getting back to me so quick... i haven't used my new makefiles yet so i'll get the '-Wl,' inserted right away...

i'd forgotten about the manuals but when you mention it i remember the bookshelves full of the biggest three ring binders ever made and they were all overstuffed with hand made tabs sticking out every which way... i was just a user trying not to fumble my stacks of punch cards with FORTRAN code using the hollerith commands to handle string output formatting... you've made my day!!!

thanks for the link to the gnu make manual... it's exactly what i've been looking for... it's amazing how much material has been converted to digital format in the last three decades and the even more amazing amount of new stuff added everyday!!!

now i just have to figure out how to squeeze an extra hour or two of study into my only-a-little-overbooked schedule...

Post a Reply

Please log in to post a reply.

Did you know that a piezoelectric buzzer can be used in reverse as a microphone? Learn more...