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.

Microcontroller Programming » no such file error 1

December 22, 2012
by keith712
keith712's Avatar

i searched the forums but so far i haven't found anything about my latest problem

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:rtACSxLCD-upload

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

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

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

here's my source:

//
//
//  repeated transorbital Alernating Current Stimulation (rtAc)
//  square wave pulse with both + and - polarity and duty cycle generator
//  November2012
//  keithmac@maui.net
//
// modified December2012 to use LCD to communicate with user
//
// ACS output signal needs to be run through a 100Kohm potentiomenter
// to reduce voltage to treatment levels (threshold voltage)
//
//  ACS will need to be split into separate leads for each eye
//
//  ACS polarity inversion accomplished by having two output channels wired opposite
// of each other and using 2N7000 (npn) transistors to switch ground and signal leads
//
// hardware:
//      ATmega168 at 14.7456MHz, +5V
//      LCD uses HD44780 protocol
//
// ATmega168 pins:
//      PC0 unused
//      PC1     "
//      PC2     "
//      PC3     "
//      PC4 (pin 27) signal output pin 
//      PC5 (pin 28) signal output pin
//      PC6 RESET
//
//      PD2-5 (pins 4,5,6,11) = LCD DB4-7 (pins 11,12,13,14) lcd data input
//      PD6 (pin 12) = LCD E (pin 6) low nibble or high nibble data switch
//      PD7 (pin 13) = LCD RS (pin 4) command or data switch
//
//
// delay.h needs to know clock frequency
//
#define F_CPU 14745600UL    // 14.7456MHz
//
// std c library
//
#include <stdlib.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
//#include <util/delay.h>
#include <inttypes.h>
//
// nerdkits c library
//
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
//
// notes to myself:
// use these values to calculate tCnt and time of treatment
//  0.5281s/1cycle/1pulse  1cycle=(5.7,8.0,11.3,16.0,22.6,32.0)
// 1min rest between blocks of cycles
//  
//
// functions to be called by main():
//      lcd_clear_all()
//      pulse()
//
void lcd_clear_all() {
  //
  // 20 columns x 4 lines
  //
  lcd_goto_position(0,0);
  lcd_write_string(PSTR("                    "));
  lcd_goto_position(1,0);
  lcd_write_string(PSTR("                    "));
  lcd_goto_position(2,0);
  lcd_write_string(PSTR("                    "));
  lcd_goto_position(3,0);
  lcd_write_string(PSTR("                    "));
  lcd_goto_position(0,0);
  }
//
void pulse(uint8_t cMx) {
  //
  // loop counter
  //
  uint8_t c;
  //
  // signal output pins
  //
  DDRC |= (1<<PC4);
  DDRC |= (1<<PC5);
  //
  // pulse loops
  //
  c=cMx;
  while(c > 0) {
    PORTC |= (1<<PC4);
    delay_us(44194);
    delay_us(44194);
    PORTC &= ~(1<<PC4);
    PORTC |= (1<<PC5);
    delay_us(44194);
    delay_us(44194);
    PORTC &= ~(1<<PC5);
    c--;
    }
  c=cMx;
  while(c>0) {
    PORTC |= (1<<PC4);
    delay_us(62500);
    PORTC &= ~(1<<PC4);
    PORTC |= (1<<PC5);
    delay_us(62500);
    PORTC &= ~(1<<PC5);
    c--;
    }
  c=cMx;
   while(c>0) {
    PORTC |= (1<<PC4);
    delay_us(44194);
    PORTC &= ~(1<<PC4);
    PORTC |= (1<<PC5);
    delay_us(44194);
    PORTC &= ~(1<<PC5);
    c--;
    }
  c=cMx;
  while(c>0) {
    PORTC |= (1<<PC4);
    delay_us(31250);
    PORTC &= ~(1<<PC4);
    PORTC |= (1<<PC5);
    delay_us(31250);
    PORTC &= ~(1<<PC5);
    c--;
    }
  c=cMx;
  while(c>0) {
    PORTC |= (1<<PC4);
    delay_us(22097);
    PORTC &= ~(1<<PC4);
    PORTC |= (1<<PC5);
    delay_us(22097);
    PORTC &= ~(1<<PC5);
    c--;
    }
  c=cMx;
  while(c>0) {
    PORTC |= (1<<PC4);
    delay_us(15625);
    PORTC &= ~(1<<PC4);
    PORTC |= (1<<PC5);
    delay_us(15625);
    PORTC &= ~(1<<PC5);
    c--;
    }
  }
int main() {
  //
  // internal RC oscillator calibration for 8MHz
  // the RC oscillator is the clock for read/write to flash memory
  // 8.8MHz is maximum rate; read/writes may fail at higher clock rates
  // ATmega168 data sheet p38 and table 28-1 on p308 have data on internal RC clock
  // 176 = 10110000 = 8MHz (this value comes from musicbox.c)
  // 160 = 10100000
  // 144 = 10010000
  // 128 = 10000000 = lowest value in upper range
  //                              (which is less than the highest value in the lower range = 00001111)
  //
  OSCCAL = 176;
  //
  // initialize lcd
  //
  lcd_init();
  //
  // display duration -- edit for each change in treatment protocol
  //
  lcd_write_string(PSTR("treatment will take"));
  lcd_goto_position(1,0);
  lcd_write_string(PSTR("about 16 minutes")); // edit this time depending on pulse number
  delay_ms(8000);
  //
  //
  //
  lcd_clear_all();
  lcd_goto_position(0,0);
  lcd_write_string(PSTR("adj thrshld volts"));
  lcd_goto_position(1,0);
  lcd_write_string(PSTR("start 10sec of"));
  lcd_goto_position(2,0);
  lcd_write_string(PSTR("pulses at 6Hz"));
  delay_ms(5000);
  //
  // signal output pins
  //
  DDRC |= (1<<PC4);
  DDRC |= (1<<PC5);
  //
  // pulses for threshold voltage adjust
  //
  uint8_t c=64;;
  while(c > 0) {
    PORTC |= (1<<PC4);
    delay_us(44194);
    delay_us(44194);
    PORTC &= ~(1<<PC4);
    PORTC |= (1<<PC5);
    delay_us(44194);
    delay_us(44194);
    PORTC &= ~(1<<PC5);
    c--;
    }
  //
  // end voltage adjust
  //
  lcd_clear_all();
  lcd_goto_position(0,0);
  lcd_write_string(PSTR("end thrshld adj"));
  lcd_goto_position(1,0);
  lcd_write_string(PSTR("16min treatment")); // edit time depending on pulse number
  lcd_goto_position(2,0);
  lcd_write_string(PSTR("starts in 10sec"));
  lcd_goto_position(3,0);
  lcd_write_string(PSTR(""));
  delay_ms(10000);
  //
  // initialize loop counters
  //
  int16_t sCnt=256;
  int16_t tCnt=948; //edit depending on pulse count
  //
  // start treatment loop
  //
  while (sCnt>0) {
    //
    // display time left
    //
    lcd_clear_all();
    lcd_goto_position(1,1);
    lcd_write_string(PSTR("about "));
    lcd_write_int16(tCnt/60);
    lcd_write_string(PSTR(" min left"));
    //
    // left & right eye pulsed at the same time
    //
    pulse(2);
    //
    // one second rest between sets
    //
    delay_ms(1000);
    //
    // decrement loop counter
    //
    sCnt--;
    //
    //
    // one minute rest between blocks of sets
    //
    if(sCnt%32==0 && sCnt>0) {
      tCnt-=126;
      lcd_goto_position(2,2);
      lcd_write_string(PSTR("1 minute rest"));
      delay_ms(60000);
      }
    }
//
// end treatment loop
//
lcd_clear_all();
lcd_goto_position(3,1);
lcd_write_string(PSTR("treatment complete"));
return 0;
}

and here's the error message i get when i compile:

k712:rtACS k712$ make

make -C ../libnerdkits

make[1]: Nothing to be done for `all'.

avr-gcc -g -Os -Wall -mmcu=atmega168  -Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt -lm -o rtACSxLCD.o rtACSxLCD.c ../libnerdkits/delay.o ../libnerdkits/lcd.o ../libnerdkits/uart.o

avr-objcopy -O ihex rtACSxLCD.hex

avr-objcopy: 'rtACSxLCD.hex': No such file

make: *** [rtACSxLCD.hex] Error 1

i can't see why the hex file is not being made or saved... pls help me again!!!

k

December 22, 2012
by pcbolt
pcbolt's Avatar

Keith -

From line 11 in you makefile:

avr-objcopy -O ihex rtACSxLCD.hex

Change this to:

avr-objcopy -j .text -O ihex rtACSxLCD.o rtACSxLCD.hex
December 23, 2012
by keith712
keith712's Avatar

thanks... i put '-j .text' back in and the code compiled... YAY

but now my LCD display is back to the crazy stuff described in support>>atmega168 and atmega328p projects... BOO

i originally removed the '-j .text' on a suggestion given to me by Rick_S to look at a thread called Ubuntu LCD problems...

anyway i've been experimenting with various combinations of -Os and -O0 in the first line of the makefile and adding or deleting -j .text in the avr-objcopy line and i finally got a compiled version that displays as expected on the LCD by using -O0 on line one and deleting -j .text from the avr-objcopy line... the .hex file not found error 1 message has mysteriously disappeared!!!

of course, now i'm worried about the difference -Os and -O0 make in the hex code and what's happening to the code if i don't include the -j .text in avr-objcopy...

i haven't done too much digging around for references on makefiles because i'm still busy learning c, studying the datasheet and wiring up projects...

thanks again for all your help... it's much much much appreciated... Merry Christmas... k

December 23, 2012
by Rick_S
Rick_S's Avatar

The -Ox is the compiler optimization setting. -Os compiles for the smallest output file size where -O0 turns off optimizations. You can reference This document for a better description. Essentially some versions of the compiler (seems most prevalent on unix/Linux versions) get a bit too aggressive with small size optimization and some code gets cut that shouldn't.

At least that's my understanding if it... ;)

Rick

December 23, 2012
by Noter
Noter's Avatar

The LCD problem is caused by a bug in the optimization process in the older versions avr-gcc. Don't know why the nerdkits guys don't update the links on their download page but the newer versions have many fixes and improvements.

Atmel AVR Toolchain 3.4.1 for Linux

Atmel AVR Toolchain 3.4.1 for Windows

December 23, 2012
by keith712
keith712's Avatar

thank you both... it's interesting that i was having no problem compiling both nerdkits' and my own projects with the -Os and the -j .text options until after i ran make on a version of makefile that i'd modified in /libnerdkits as an experiment (otherwise known as a BIG MISTAKE)...

i'm going to go check out those links right now... all the best to you both... k

Post a Reply

Please log in to post a reply.

Did you know that interrupts can be used to trigger pieces of code when events happen? Learn more...