Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 13 of 13

Thread: Help Compiling "Blinky"

  1. #1
    Junior Member
    Join Date
    Dec 2015
    Posts
    2

    Help Compiling "Blinky"

    I am attempting to compile Blinky for my USB Teensy 2. I just installed winAVR on Windows 10 x64, an when I execute make it fails.

    Code:
          0 [main] sh 4192 sync_with_child: child 5676(0x1AC) died before initialization with status code 0xC0000142
        235 [main] sh 4192 sync_with_child: *** child state waiting for longjmp
    /usr/bin/sh: fork: Resource temporarily unavailable
          0 [main] sh 3264 sync_with_child: child 2344(0x1BC) died before initialization with status code 0xC0000142
        474 [main] sh 3264 sync_with_child: *** child state waiting for longjmp
    /usr/bin/sh: fork: Resource temporarily unavailable
    
    -------- begin --------
    avr-gcc (WinAVR 20100110) 4.3.3
    Copyright (C) 2008 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
    
    Compiling C: blinky.c
    avr-gcc -c -mmcu=atmega32u4         -I. -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -ffunction-sections -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./blinky.lst  -std=gnu99 -MMD -MP -MF .dep/blinky.o.d blinky.c -o blinky.o
    blinky.c:158: fatal error: opening dependency file .dep/blinky.o.d: No such file or directory
    compilation terminated.
    make: *** [blinky.o] Error 1

  2. #2
    Junior Member
    Join Date
    Feb 2016
    Posts
    4

    A partial solution to the identical problem--Need more help

    I also have identical results as op in make output running Windows 10 pro version 1151. I have laboriously found a partial solution. Manually creating a /.dep directory in the code directory gets us much of the way through the compilation and linking. I now get this output:
    Code:
    C:_________\blinky>make
          0 [main] sh 5808 sync_with_child: child 4516(0x174) died before initialization with status code 0xC0000142
        651 [main] sh 5808 sync_with_child: *** child state waiting for longjmp
    /usr/bin/sh: fork: Resource temporarily unavailable
          0 [main] sh 4040 sync_with_child: child 5156(0x174) died before initialization with status code 0xC0000142
        244 [main] sh 4040 sync_with_child: *** child state waiting for longjmp
    /usr/bin/sh: fork: Resource temporarily unavailable
    
    -------- begin --------
    avr-gcc (WinAVR 20100110) 4.3.3
    Copyright (C) 2008 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
    
    Compiling C: blinky.c
    avr-gcc -c -mmcu=atmega32u4         -I. -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -ffunction-sections -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./blinky.lst  -std=gnu99 -MMD -MP -MF .dep/blinky.o.d blinky.c -o blinky.o
    
    Compiling C: usb_debug_only.c
    avr-gcc -c -mmcu=atmega32u4         -I. -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -ffunction-sections -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./usb_debug_only.lst  -std=gnu99 -MMD -MP -MF .dep/usb_debug_only.o.d usb_debug_only.c -o usb_debug_only.o
    
    Compiling C: print.c
    avr-gcc -c -mmcu=atmega32u4         -I. -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -ffunction-sections -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./print.lst  -std=gnu99 -MMD -MP -MF .dep/print.o.d print.c -o print.o
    
    Linking: blinky.elf
    avr-gcc -mmcu=atmega32u4         -I. -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -ffunction-sections -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=blinky.o  -std=gnu99 -MMD -MP -MF .dep/blinky.elf.d blinky.o usb_debug_only.o print.o --output blinky.elf -Wl,-Map=blinky.map,--cref -Wl,--relax -Wl,--gc-sections     -lm
    
    Creating load file for Flash: blinky.hex
    avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature blinky.elf blinky.hex
    
    Creating load file for EEPROM: blinky.eep
    avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
            --change-section-lma .eeprom=0 --no-change-warnings -O ihex blinky.elf blinky.eep || exit 0
          0 [main] sh 4480 sync_with_child: child 3504(0x178) died before initialization with status code 0xC0000142
        675 [main] sh 4480 sync_with_child: *** child state waiting for longjmp
    /usr/bin/sh: fork: Resource temporarily unavailable
    make: [blinky.eep] Error 128 (ignored)
    
    Creating Extended Listing: blinky.lss
    avr-objdump -h -S -z blinky.elf > blinky.lss
          0 [main] sh 5688 sync_with_child: child 1144(0x170) died before initialization with status code 0xC0000142
        678 [main] sh 5688 sync_with_child: *** child state waiting for longjmp
    /usr/bin/sh: fork: Resource temporarily unavailable
    make: *** [blinky.lss] Error 128
    This produces a .hex file that works, but also throws errors I do not recognize. Errors I don't recognize make me very nervous.

    Help would be greatly appreciated.

    [EDIT] The .dep folder has to be made from the command line: mkdir .dep.[/EDIT]
    Last edited by RonBurke; 02-25-2016 at 02:38 AM. Reason: Omitted information.

  3. #3
    Senior Member
    Join Date
    Nov 2015
    Location
    Wales
    Posts
    579
    Can you post your make files?

  4. #4
    Junior Member
    Join Date
    Feb 2016
    Posts
    4

    Makefile for blinky

    Thanks for your response. This is the makefile that came with the download. I haven't altered it. (I guess I'll have to relearn make; haven't used it for years.)
    Code:
    # Hey Emacs, this is a -*- makefile -*-
    #----------------------------------------------------------------------------
    # WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
    #
    # Released to the Public Domain
    #
    # Additional material for this makefile was written by:
    # Peter Fleury
    # Tim Henigan
    # Colin O'Flynn
    # Reiner Patommel
    # Markus Pfaff
    # Sander Pool
    # Frederik Rouleau
    # Carlos Lamas
    #
    #----------------------------------------------------------------------------
    # On command line:
    #
    # make all = Make software.
    #
    # make clean = Clean out built project files.
    #
    # make coff = Convert ELF to AVR COFF.
    #
    # make extcoff = Convert ELF to AVR Extended COFF.
    #
    # make program = Download the hex file to the device, using avrdude.
    #                Please customize the avrdude settings below first!
    #
    # make debug = Start either simulavr or avarice as specified for debugging, 
    #              with avr-gdb or avr-insight as the front end for debugging.
    #
    # make filename.s = Just compile filename.c into the assembler code only.
    #
    # make filename.i = Create a preprocessed source file for use in submitting
    #                   bug reports to the GCC project.
    #
    # To rebuild project do "make clean" then "make all".
    #----------------------------------------------------------------------------
    
    
    # Target file name (without extension).
    TARGET = blinky
    
    
    # List C source files here. (C dependencies are automatically generated.)
    SRC =	$(TARGET).c \
    	usb_debug_only.c \
    	print.c
    
    # MCU name, you MUST set this to match the board you are using
    # type "make clean" after changing this, so all files will be rebuilt
    #
    #MCU = at90usb162       # Teensy 1.0
    MCU = atmega32u4        # Teensy 2.0
    #MCU = at90usb646       # Teensy++ 1.0
    #MCU = at90usb1286      # Teensy++ 2.0
    
    
    # Processor frequency.
    #   Normally the first thing your program should do is set the clock prescaler,
    #   so your program will run at the correct speed.  You should also set this
    #   variable to same clock speed.  The _delay_ms() macro uses this, and many
    #   examples use this variable to calculate timings.  Do not add a "UL" here.
    F_CPU = 16000000
    
    
    # Output format. (can be srec, ihex, binary)
    FORMAT = ihex
    
    
    # Object files directory
    #     To put object files in current directory, use a dot (.), do NOT make
    #     this an empty or blank macro!
    OBJDIR = .
    
    
    # List C++ source files here. (C dependencies are automatically generated.)
    CPPSRC = 
    
    
    # List Assembler source files here.
    #     Make them always end in a capital .S.  Files ending in a lowercase .s
    #     will not be considered source files but generated files (assembler
    #     output from the compiler), and will be deleted upon "make clean"!
    #     Even though the DOS/Win* filesystem matches both .s and .S the same,
    #     it will preserve the spelling of the filenames, and gcc itself does
    #     care about how the name is spelled on its command-line.
    ASRC =
    
    
    # Optimization level, can be [0, 1, 2, 3, s]. 
    #     0 = turn off optimization. s = optimize for size.
    #     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
    OPT = s
    
    
    # Debugging format.
    #     Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
    #     AVR Studio 4.10 requires dwarf-2.
    #     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
    DEBUG = dwarf-2
    
    
    # List any extra directories to look for include files here.
    #     Each directory must be seperated by a space.
    #     Use forward slashes for directory separators.
    #     For a directory that has spaces, enclose it in quotes.
    EXTRAINCDIRS = 
    
    
    # Compiler flag to set the C Standard level.
    #     c89   = "ANSI" C
    #     gnu89 = c89 plus GCC extensions
    #     c99   = ISO C99 standard (not yet fully implemented)
    #     gnu99 = c99 plus GCC extensions
    CSTANDARD = -std=gnu99
    
    
    # Place -D or -U options here for C sources
    CDEFS = -DF_CPU=$(F_CPU)UL
    
    
    # Place -D or -U options here for ASM sources
    ADEFS = -DF_CPU=$(F_CPU)
    
    
    # Place -D or -U options here for C++ sources
    CPPDEFS = -DF_CPU=$(F_CPU)UL
    #CPPDEFS += -D__STDC_LIMIT_MACROS
    #CPPDEFS += -D__STDC_CONSTANT_MACROS
    
    
    
    #---------------- Compiler Options C ----------------
    #  -g*:          generate debugging information
    #  -O*:          optimization level
    #  -f...:        tuning, see GCC manual and avr-libc documentation
    #  -Wall...:     warning level
    #  -Wa,...:      tell GCC to pass this to the assembler.
    #    -adhlns...: create assembler listing
    CFLAGS = -g$(DEBUG)
    CFLAGS += $(CDEFS)
    CFLAGS += -O$(OPT)
    CFLAGS += -funsigned-char
    CFLAGS += -funsigned-bitfields
    CFLAGS += -ffunction-sections
    CFLAGS += -fpack-struct
    CFLAGS += -fshort-enums
    CFLAGS += -Wall
    CFLAGS += -Wstrict-prototypes
    #CFLAGS += -mshort-calls
    #CFLAGS += -fno-unit-at-a-time
    #CFLAGS += -Wundef
    #CFLAGS += -Wunreachable-code
    #CFLAGS += -Wsign-compare
    CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
    CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
    CFLAGS += $(CSTANDARD)
    
    
    #---------------- Compiler Options C++ ----------------
    #  -g*:          generate debugging information
    #  -O*:          optimization level
    #  -f...:        tuning, see GCC manual and avr-libc documentation
    #  -Wall...:     warning level
    #  -Wa,...:      tell GCC to pass this to the assembler.
    #    -adhlns...: create assembler listing
    CPPFLAGS = -g$(DEBUG)
    CPPFLAGS += $(CPPDEFS)
    CPPFLAGS += -O$(OPT)
    CPPFLAGS += -funsigned-char
    CPPFLAGS += -funsigned-bitfields
    CPPFLAGS += -fpack-struct
    CPPFLAGS += -fshort-enums
    CPPFLAGS += -fno-exceptions
    CPPFLAGS += -Wall
    CPPFLAGS += -Wundef
    #CPPFLAGS += -mshort-calls
    #CPPFLAGS += -fno-unit-at-a-time
    #CPPFLAGS += -Wstrict-prototypes
    #CPPFLAGS += -Wunreachable-code
    #CPPFLAGS += -Wsign-compare
    CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
    CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
    #CPPFLAGS += $(CSTANDARD)
    
    
    #---------------- Assembler Options ----------------
    #  -Wa,...:   tell GCC to pass this to the assembler.
    #  -adhlns:   create listing
    #  -gstabs:   have the assembler create line number information; note that
    #             for use in COFF files, additional information about filenames
    #             and function names needs to be present in the assembler source
    #             files -- see avr-libc docs [FIXME: not yet described there]
    #  -listing-cont-lines: Sets the maximum number of continuation lines of hex 
    #       dump that will be displayed for a given single line of source input.
    ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
    
    
    #---------------- Library Options ----------------
    # Minimalistic printf version
    PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
    
    # Floating point printf version (requires MATH_LIB = -lm below)
    PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
    
    # If this is left blank, then it will use the Standard printf version.
    PRINTF_LIB = 
    #PRINTF_LIB = $(PRINTF_LIB_MIN)
    #PRINTF_LIB = $(PRINTF_LIB_FLOAT)
    
    
    # Minimalistic scanf version
    SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
    
    # Floating point + %[ scanf version (requires MATH_LIB = -lm below)
    SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
    
    # If this is left blank, then it will use the Standard scanf version.
    SCANF_LIB = 
    #SCANF_LIB = $(SCANF_LIB_MIN)
    #SCANF_LIB = $(SCANF_LIB_FLOAT)
    
    
    MATH_LIB = -lm
    
    
    # List any extra directories to look for libraries here.
    #     Each directory must be seperated by a space.
    #     Use forward slashes for directory separators.
    #     For a directory that has spaces, enclose it in quotes.
    EXTRALIBDIRS = 
    
    
    
    #---------------- External Memory Options ----------------
    
    # 64 KB of external RAM, starting after internal RAM (ATmega128!),
    # used for variables (.data/.bss) and heap (malloc()).
    #EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
    
    # 64 KB of external RAM, starting after internal RAM (ATmega128!),
    # only used for heap (malloc()).
    #EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
    
    EXTMEMOPTS =
    
    
    
    #---------------- Linker Options ----------------
    #  -Wl,...:     tell GCC to pass this to linker.
    #    -Map:      create map file
    #    --cref:    add cross reference to  map file
    LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
    LDFLAGS += -Wl,--relax
    LDFLAGS += -Wl,--gc-sections
    LDFLAGS += $(EXTMEMOPTS)
    LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
    LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
    #LDFLAGS += -T linker_script.x
    
    
    
    #---------------- Programming Options (avrdude) ----------------
    
    # Programming hardware
    # Type: avrdude -c ?
    # to get a full listing.
    #
    AVRDUDE_PROGRAMMER = stk500v2
    
    # com1 = serial port. Use lpt1 to connect to parallel port.
    AVRDUDE_PORT = com1    # programmer connected to serial device
    
    AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
    #AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
    
    
    # Uncomment the following if you want avrdude's erase cycle counter.
    # Note that this counter needs to be initialized first using -Yn,
    # see avrdude manual.
    #AVRDUDE_ERASE_COUNTER = -y
    
    # Uncomment the following if you do /not/ wish a verification to be
    # performed after programming the device.
    #AVRDUDE_NO_VERIFY = -V
    
    # Increase verbosity level.  Please use this when submitting bug
    # reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> 
    # to submit bug reports.
    #AVRDUDE_VERBOSE = -v -v
    
    AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
    AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
    AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
    AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
    
    
    
    #---------------- Debugging Options ----------------
    
    # For simulavr only - target MCU frequency.
    DEBUG_MFREQ = $(F_CPU)
    
    # Set the DEBUG_UI to either gdb or insight.
    # DEBUG_UI = gdb
    DEBUG_UI = insight
    
    # Set the debugging back-end to either avarice, simulavr.
    DEBUG_BACKEND = avarice
    #DEBUG_BACKEND = simulavr
    
    # GDB Init Filename.
    GDBINIT_FILE = __avr_gdbinit
    
    # When using avarice settings for the JTAG
    JTAG_DEV = /dev/com1
    
    # Debugging port used to communicate between GDB / avarice / simulavr.
    DEBUG_PORT = 4242
    
    # Debugging host used to communicate between GDB / avarice / simulavr, normally
    #     just set to localhost unless doing some sort of crazy debugging when 
    #     avarice is running on a different computer.
    DEBUG_HOST = localhost
    
    
    
    #============================================================================
    
    
    # Define programs and commands.
    SHELL = sh
    CC = avr-gcc
    OBJCOPY = avr-objcopy
    OBJDUMP = avr-objdump
    SIZE = avr-size
    AR = avr-ar rcs
    NM = avr-nm
    AVRDUDE = avrdude
    REMOVE = rm -f
    REMOVEDIR = rm -rf
    COPY = cp
    WINSHELL = cmd
    
    
    # Define Messages
    # English
    MSG_ERRORS_NONE = Errors: none
    MSG_BEGIN = -------- begin --------
    MSG_END = --------  end  --------
    MSG_SIZE_BEFORE = Size before: 
    MSG_SIZE_AFTER = Size after:
    MSG_COFF = Converting to AVR COFF:
    MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
    MSG_FLASH = Creating load file for Flash:
    MSG_EEPROM = Creating load file for EEPROM:
    MSG_EXTENDED_LISTING = Creating Extended Listing:
    MSG_SYMBOL_TABLE = Creating Symbol Table:
    MSG_LINKING = Linking:
    MSG_COMPILING = Compiling C:
    MSG_COMPILING_CPP = Compiling C++:
    MSG_ASSEMBLING = Assembling:
    MSG_CLEANING = Cleaning project:
    MSG_CREATING_LIBRARY = Creating library:
    
    
    
    
    # Define all object files.
    OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o) 
    
    # Define all listing files.
    LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst) 
    
    
    # Compiler flags to generate dependency files.
    GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
    
    
    # Combine all necessary flags and optional flags.
    # Add target processor to flags.
    ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
    ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
    ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
    
    
    
    
    
    # Default target.
    all: begin gccversion sizebefore build sizeafter end
    
    # Change the build target to build a HEX file or a library.
    build: elf hex eep lss sym
    #build: lib
    
    
    elf: $(TARGET).elf
    hex: $(TARGET).hex
    eep: $(TARGET).eep
    lss: $(TARGET).lss
    sym: $(TARGET).sym
    LIBNAME=lib$(TARGET).a
    lib: $(LIBNAME)
    
    
    
    # Eye candy.
    # AVR Studio 3.x does not check make's exit code but relies on
    # the following magic strings to be generated by the compile job.
    begin:
    	@echo
    	@echo $(MSG_BEGIN)
    
    end:
    	@echo $(MSG_END)
    	@echo
    
    
    # Display size of file.
    HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
    #ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
    ELFSIZE = $(SIZE) $(TARGET).elf
    
    sizebefore:
    	@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
    	2>/dev/null; echo; fi
    
    sizeafter:
    	@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
    	2>/dev/null; echo; fi
    
    
    
    # Display compiler version information.
    gccversion : 
    	@$(CC) --version
    
    
    
    # Program the device.  
    program: $(TARGET).hex $(TARGET).eep
    	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
    
    
    # Generate avr-gdb config/init file which does the following:
    #     define the reset signal, load the target file, connect to target, and set 
    #     a breakpoint at main().
    gdb-config: 
    	@$(REMOVE) $(GDBINIT_FILE)
    	@echo define reset >> $(GDBINIT_FILE)
    	@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
    	@echo end >> $(GDBINIT_FILE)
    	@echo file $(TARGET).elf >> $(GDBINIT_FILE)
    	@echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)
    ifeq ($(DEBUG_BACKEND),simulavr)
    	@echo load  >> $(GDBINIT_FILE)
    endif
    	@echo break main >> $(GDBINIT_FILE)
    
    debug: gdb-config $(TARGET).elf
    ifeq ($(DEBUG_BACKEND), avarice)
    	@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
    	@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
    	$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
    	@$(WINSHELL) /c pause
    
    else
    	@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
    	$(DEBUG_MFREQ) --port $(DEBUG_PORT)
    endif
    	@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
    
    
    
    
    # Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
    COFFCONVERT = $(OBJCOPY) --debugging
    COFFCONVERT += --change-section-address .data-0x800000
    COFFCONVERT += --change-section-address .bss-0x800000
    COFFCONVERT += --change-section-address .noinit-0x800000
    COFFCONVERT += --change-section-address .eeprom-0x810000
    
    
    
    coff: $(TARGET).elf
    	@echo
    	@echo $(MSG_COFF) $(TARGET).cof
    	$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
    
    
    extcoff: $(TARGET).elf
    	@echo
    	@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
    	$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
    
    
    
    # Create final output files (.hex, .eep) from ELF output file.
    %.hex: %.elf
    	@echo
    	@echo $(MSG_FLASH) $@
    	$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@
    
    %.eep: %.elf
    	@echo
    	@echo $(MSG_EEPROM) $@
    	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
    	--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
    
    # Create extended listing file from ELF output file.
    %.lss: %.elf
    	@echo
    	@echo $(MSG_EXTENDED_LISTING) $@
    	$(OBJDUMP) -h -S -z $< > $@
    
    # Create a symbol table from ELF output file.
    %.sym: %.elf
    	@echo
    	@echo $(MSG_SYMBOL_TABLE) $@
    	$(NM) -n $< > $@
    
    
    
    # Create library from object files.
    .SECONDARY : $(TARGET).a
    .PRECIOUS : $(OBJ)
    %.a: $(OBJ)
    	@echo
    	@echo $(MSG_CREATING_LIBRARY) $@
    	$(AR) $@ $(OBJ)
    
    
    # Link: create ELF output file from object files.
    .SECONDARY : $(TARGET).elf
    .PRECIOUS : $(OBJ)
    %.elf: $(OBJ)
    	@echo
    	@echo $(MSG_LINKING) $@
    	$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
    
    
    # Compile: create object files from C source files.
    $(OBJDIR)/%.o : %.c
    	@echo
    	@echo $(MSG_COMPILING) $<
    	$(CC) -c $(ALL_CFLAGS) $< -o $@ 
    
    
    # Compile: create object files from C++ source files.
    $(OBJDIR)/%.o : %.cpp
    	@echo
    	@echo $(MSG_COMPILING_CPP) $<
    	$(CC) -c $(ALL_CPPFLAGS) $< -o $@ 
    
    
    # Compile: create assembler files from C source files.
    %.s : %.c
    	$(CC) -S $(ALL_CFLAGS) $< -o $@
    
    
    # Compile: create assembler files from C++ source files.
    %.s : %.cpp
    	$(CC) -S $(ALL_CPPFLAGS) $< -o $@
    
    
    # Assemble: create object files from assembler source files.
    $(OBJDIR)/%.o : %.S
    	@echo
    	@echo $(MSG_ASSEMBLING) $<
    	$(CC) -c $(ALL_ASFLAGS) $< -o $@
    
    
    # Create preprocessed source for use in sending a bug report.
    %.i : %.c
    	$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ 
    
    
    # Target: clean project.
    clean: begin clean_list end
    
    clean_list :
    	@echo
    	@echo $(MSG_CLEANING)
    	$(REMOVE) $(TARGET).hex
    	$(REMOVE) $(TARGET).eep
    	$(REMOVE) $(TARGET).cof
    	$(REMOVE) $(TARGET).elf
    	$(REMOVE) $(TARGET).map
    	$(REMOVE) $(TARGET).sym
    	$(REMOVE) $(TARGET).lss
    	$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
    	$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
    	$(REMOVE) $(SRC:.c=.s)
    	$(REMOVE) $(SRC:.c=.d)
    	$(REMOVE) $(SRC:.c=.i)
    	$(REMOVEDIR) .dep
    
    
    # Create object files directory
    $(shell mkdir $(OBJDIR) 2>/dev/null)
    
    
    # Include the dependency files.
    -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
    
    
    # Listing of phony targets.
    .PHONY : all begin finish end sizebefore sizeafter gccversion \
    build elf hex eep lss sym coff extcoff \
    clean clean_list program debug gdb-config

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,498
    Hmmm, looks like perhaps a problem with WinAVR. Maybe try reinstalling WinAVR first?

  6. #6
    Junior Member
    Join Date
    Feb 2016
    Posts
    4
    No luck with a WinAVR reinstall. I'm going to play with this a little more. I suspect there may be some subtle differences between Windows 10 and earlier versions that are causing the problem. WinAVR doesn't appear to have been update since 2010. If I don't have any luck I'll switch to Linux. I have Debian 8 running on a different machine. I was using Windows because that's what the device (a multi-button input for a physical therapy application for cerebral palsy) will be interacting with when it's working. If I learn anything useful I'll post again.

    Thanks for the responses.

  7. #7
    Junior Member
    Join Date
    Feb 2016
    Posts
    4
    Well, that's strange. The problem seems to have been longstanding and never fixed. The solution was in a post that refers to the 2007 version of WinAVR. MadWizard.org has a patch for msys-1.0.dll in the WinAVR/utils/bin directory. I applied the patch and the problems disappeared. Explanation and patch at http://www.madwizard.org/electronics...es/winavrvista Thanks MadWizard for leaving this up since 2007!!!

  8. #8
    Junior Member
    Join Date
    Dec 2017
    Location
    Bay Area
    Posts
    1
    Registered to say thanks to RonBurke. So strange this works, yet so great MadWizard left it up and he posted this answer. I could see some people possibly having last-mile troubles, so I'll just say it: once you download the mysys-1.0.dll from MadWizard, extract the zip, and move the dll to the WinAVR/utils/bin directory, wherever you installed it. I deleted the existing dll of the same name first. Looks like this wasn't the first time this file was patched as my install includes mysys-1.0.dll.old file. I left that alone. In any event, after following RonBurke's instructions, I ran make in my directory again and it compiled without error.

  9. #9
    Registered just to say jeeeeeeesh, what a load of crap!
    In addition to RonBurke's dll patch above, I still had to create the .dep directory in my /blink source folder before it worked.
    And even then, the .eep and .lss sections of the make seems to die...
    But it did produce the .hex file, and I could flash it to the Teensy 2 with teensy loader, and its blinking morse-code at me right now... so it seems to have worked.
    I'm using WinAVR-20100110 for what it's worth...
    Good luck people of the future!

  10. #10
    Junior Member
    Join Date
    Mar 2020
    Posts
    6
    Yes. Changing seven values in the file usb_debug_only.c allowed blinky to compile without error. Change 'device_descriptor’, ‘hid_report_descriptor’, ‘config1_descriptor’, ‘string0’, ‘string1’, ‘string2’ and ‘descriptor_list' to constant from static and makefile will run.

    The demo code blinky.zip at https://www.pjrc.com/teensy/gcc.html did not work with WinAVR on Windows 10, did not work on Ubuntu or Raspbian, did not work from CLI, Netbeans or Geany IDE.

    The error messages were all of the nature "usb_debug_only.c:96:24: error: variable ‘device_descriptor’ must be const in order to be put into read-only section". Closer inspection of usb_debug_only.c showed the values declared as static.

    Other posters on this forum said to change to const and code would compile. They were correct and makefile began working, generating a hex file and several other fascinating files such as .map and .lst.


    Now, I arrive at another matter. The example is written for Teensy's that have AVR chips and I have a Teensy LC with an ARM chip.

    When I try to upload to my board with TeensyDuino I get messages that "blinky.hex" is not compiled for this board
    Compiled for: "Teensy 2.0 (ATMEGA32U4)"
    This board is: "Teensy LC (MKL26Z64)"

    My next step will be to modify Makefile so that it calls for ARM compiler tools instead of AVR tools. The boards.txt file from my Arduino folder may show exactly which changes I need to make.

    Wish me luck.

    Click image for larger version. 

Name:	CompatibilityError.PNG 
Views:	2 
Size:	285.8 KB 
ID:	19454

  11. #11
    Junior Member
    Join Date
    Mar 2020
    Posts
    6
    Code:
    // usb_debug_only.c   modified to run by changing seven static values to constants
    /* USB Debug Channel Example for Teensy USB Development Board
     * http://www.pjrc.com/teensy/
     * Copyright (c) 2008 PJRC.COM, LLC
     * 
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     * 
     * The above copyright notice and this permission notice shall be included in
     * all copies or substantial portions of the Software.
     * 
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
    
    // Version 1.0: Initial Release
    // Version 1.1: Add support for Teensy 2.0
    // Version 1.x: Pat Fitzgerald
    // modified from original downloaded from https://www.pjrc.com/teensy/gcc.html
    // original failed to compile on Ubuntu, Raspbian and Windows error message that 
    // static values need to be changed to constants
    //   'device_descriptor’, ‘hid_report_descriptor’, ‘config1_descriptor’, 
    //   ‘string0’, ‘string1’, ‘string2’ and ‘descriptor_list' 
    //    to constant from static
    
    #define USB_SERIAL_PRIVATE_INCLUDE
    #include "usb_debug_only.h"
    
    /**************************************************************************
     *
     *  Configurable Options
     *
     **************************************************************************/
    
    // You can change these to give your code its own name.  On Windows,
    // these are only used before an INF file (driver install) is loaded.
    #define STR_MANUFACTURER    L"Your Name"
    #define STR_PRODUCT        L"Your USB Device"
    
    
    // Mac OS-X and Linux automatically load the correct drivers.  On
    // Windows, even though the driver is supplied by Microsoft, an
    // INF file is needed to load the driver.  These numbers need to
    // match the INF file.
    #define VENDOR_ID        0x16C0
    #define PRODUCT_ID        0x0479
    
    
    // USB devices are supposed to implment a halt feature, which is
    // rarely (if ever) used.  If you comment this line out, the halt
    // code will be removed, saving 102 bytes of space (gcc 4.3.0).
    // This is not strictly USB compliant, but works with all major
    // operating systems.
    #define SUPPORT_ENDPOINT_HALT
    
    
    
    /**************************************************************************
     *
     *  Endpoint Buffer Configuration
     *
     **************************************************************************/
    
    // you might want to change the buffer size, up to 64 bytes.
    // The host reserves your bandwidth because this is an interrupt
    // endpoint, so it won't be available to other interrupt or isync
    // endpoints in other devices on the bus.
    
    #define ENDPOINT0_SIZE        32
    #define DEBUG_TX_ENDPOINT    3
    #define DEBUG_TX_SIZE        32
    #define DEBUG_TX_BUFFER        EP_DOUBLE_BUFFER
    
    static const uint8_t PROGMEM endpoint_config_table[] = {
        0,
        0,
        1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER,
        0
    };
    
    
    /**************************************************************************
     *
     *  Descriptor Data
     *
     **************************************************************************/
    
    // Descriptors are the data that your computer reads when it auto-detects
    // this USB device (called "enumeration" in USB lingo).  The most commonly
    // changed items are editable at the top of this file.  Changing things
    // in here should only be done by those who've read chapter 9 of the USB
    // spec and relevant portions of any USB class specifications!
    
    
    const uint8_t PROGMEM device_descriptor[] = {
        18,                    // bLength
        1,                    // bDescriptorType
        0x00, 0x02,                // bcdUSB
        0,                    // bDeviceClass
        0,                    // bDeviceSubClass
        0,                    // bDeviceProtocol
        ENDPOINT0_SIZE,                // bMaxPacketSize0
        LSB(VENDOR_ID), MSB(VENDOR_ID),        // idVendor
        LSB(PRODUCT_ID), MSB(PRODUCT_ID),    // idProduct
        0x00, 0x01,                // bcdDevice
        1,                    // iManufacturer
        2,                    // iProduct
        0,                    // iSerialNumber
        1                    // bNumConfigurations
    };
    
    const uint8_t PROGMEM hid_report_descriptor[] = {
        0x06, 0x31, 0xFF,            // Usage Page 0xFF31 (vendor defined)
        0x09, 0x74,                // Usage 0x74
        0xA1, 0x53,                // Collection 0x53
        0x75, 0x08,                // report size = 8 bits
        0x15, 0x00,                // logical minimum = 0
        0x26, 0xFF, 0x00,            // logical maximum = 255
        0x95, DEBUG_TX_SIZE,            // report count
        0x09, 0x75,                // usage
        0x81, 0x02,                // Input (array)
        0xC0                    // end collection
    };
    
    #define CONFIG1_DESC_SIZE (9+9+9+7)
    #define HID_DESC2_OFFSET  (9+9)
    const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
        // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
        9,                     // bLength;
        2,                    // bDescriptorType;
        LSB(CONFIG1_DESC_SIZE),            // wTotalLength
        MSB(CONFIG1_DESC_SIZE),
        1,                    // bNumInterfaces
        1,                    // bConfigurationValue
        0,                    // iConfiguration
        0xC0,                    // bmAttributes
        50,                    // bMaxPower
        // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
        9,                    // bLength
        4,                    // bDescriptorType
        0,                    // bInterfaceNumber
        0,                    // bAlternateSetting
        1,                    // bNumEndpoints
        0x03,                    // bInterfaceClass (0x03 = HID)
        0x00,                    // bInterfaceSubClass
        0x00,                    // bInterfaceProtocol
        0,                    // iInterface
        // HID interface descriptor, HID 1.11 spec, section 6.2.1
        9,                    // bLength
        0x21,                    // bDescriptorType
        0x11, 0x01,                // bcdHID
        0,                    // bCountryCode
        1,                    // bNumDescriptors
        0x22,                    // bDescriptorType
        sizeof(hid_report_descriptor),        // wDescriptorLength
        0,
        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
        7,                    // bLength
        5,                    // bDescriptorType
        DEBUG_TX_ENDPOINT | 0x80,        // bEndpointAddress
        0x03,                    // bmAttributes (0x03=intr)
        DEBUG_TX_SIZE, 0,            // wMaxPacketSize
        1                    // bInterval
    };
    
    // If you're desperate for a little extra code memory, these strings
    // can be completely removed if iManufacturer, iProduct, iSerialNumber
    // in the device desciptor are changed to zeros.
    struct usb_string_descriptor_struct {
        uint8_t bLength;
        uint8_t bDescriptorType;
        int16_t wString[];
    };
    const struct usb_string_descriptor_struct PROGMEM string0 = {
        4,
        3,
        {0x0409}
    };
    const struct usb_string_descriptor_struct PROGMEM string1 = {
        sizeof(STR_MANUFACTURER),
        3,
        STR_MANUFACTURER
    };
    const struct usb_string_descriptor_struct PROGMEM string2 = {
        sizeof(STR_PRODUCT),
        3,
        STR_PRODUCT
    };
    
    // This table defines which descriptor data is sent for each specific
    // request from the host (in wValue and wIndex).
    const struct descriptor_list_struct {
        uint16_t    wValue;
        uint16_t    wIndex;
        const uint8_t    *addr;
        uint8_t        length;
    } PROGMEM descriptor_list[] = {
        {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
        {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
        {0x2200, 0x0000, hid_report_descriptor, sizeof(hid_report_descriptor)},
        {0x2100, 0x0000, config1_descriptor+HID_DESC2_OFFSET, 9},
        {0x0300, 0x0000, (const uint8_t *)&string0, 4},
        {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
        {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}
    };
    #define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
    
    
    /**************************************************************************
     *
     *  Variables - these are the only non-stack RAM usage
     *
     **************************************************************************/
    
    // zero when we are not configured, non-zero when enumerated
    static volatile uint8_t usb_configuration=0;
    
    // the time remaining before we transmit any partially full
    // packet, or send a zero length packet.
    static volatile uint8_t debug_flush_timer=0;
    
    
    /**************************************************************************
     *
     *  Public Functions - these are the API intended for the user
     *
     **************************************************************************/
    
    
    // initialize USB
    void usb_init(void)
    {
        HW_CONFIG();
        USB_FREEZE();                // enable USB
        PLL_CONFIG();                // config PLL
            while (!(PLLCSR & (1<<PLOCK))) ;    // wait for PLL lock
            USB_CONFIG();                // start USB clock
            UDCON = 0;                // enable attach resistor
        usb_configuration = 0;
            UDIEN = (1<<EORSTE)|(1<<SOFE);
        sei();
    }
    
    // return 0 if the USB is not configured, or the configuration
    // number selected by the HOST
    uint8_t usb_configured(void)
    {
        return usb_configuration;
    }
    
    // transmit a character.  0 returned on success, -1 on error
    int8_t usb_debug_putchar(uint8_t c)
    {
        static uint8_t previous_timeout=0;
        uint8_t timeout, intr_state;
    
        // if we're not online (enumerated and configured), error
        if (!usb_configuration) return -1;
        // interrupts are disabled so these functions can be
        // used from the main program or interrupt context,
        // even both in the same program!
        intr_state = SREG;
        cli();
        UENUM = DEBUG_TX_ENDPOINT;
        // if we gave up due to timeout before, don't wait again
        if (previous_timeout) {
            if (!(UEINTX & (1<<RWAL))) {
                SREG = intr_state;
                return -1;
            }
            previous_timeout = 0;
        }
        // wait for the FIFO to be ready to accept data
        timeout = UDFNUML + 4;
        while (1) {
            // are we ready to transmit?
            if (UEINTX & (1<<RWAL)) break;
            SREG = intr_state;
            // have we waited too long?
            if (UDFNUML == timeout) {
                previous_timeout = 1;
                return -1;
            }
            // has the USB gone offline?
            if (!usb_configuration) return -1;
            // get ready to try checking again
            intr_state = SREG;
            cli();
            UENUM = DEBUG_TX_ENDPOINT;
        }
        // actually write the byte into the FIFO
        UEDATX = c;
        // if this completed a packet, transmit it now!
        if (!(UEINTX & (1<<RWAL))) {
            UEINTX = 0x3A;
            debug_flush_timer = 0;
        } else {
            debug_flush_timer = 2;
        }
        SREG = intr_state;
        return 0;
    }
    
    
    // immediately transmit any buffered output.
    void usb_debug_flush_output(void)
    {
        uint8_t intr_state;
    
        intr_state = SREG;
        cli();
        if (debug_flush_timer) {
            UENUM = DEBUG_TX_ENDPOINT;
            while ((UEINTX & (1<<RWAL))) {
                UEDATX = 0;
            }
            UEINTX = 0x3A;
            debug_flush_timer = 0;
        }
        SREG = intr_state;
    }
    
    
    
    /**************************************************************************
     *
     *  Private Functions - not intended for general user consumption....
     *
     **************************************************************************/
    
    
    
    // USB Device Interrupt - handle all device-level events
    // the transmit buffer flushing is triggered by the start of frame
    //
    ISR(USB_GEN_vect)
    {
        uint8_t intbits, t;
    
            intbits = UDINT;
            UDINT = 0;
            if (intbits & (1<<EORSTI)) {
            UENUM = 0;
            UECONX = 1;
            UECFG0X = EP_TYPE_CONTROL;
            UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
            UEIENX = (1<<RXSTPE);
            usb_configuration = 0;
            }
        if (intbits & (1<<SOFI)) {
            if (usb_configuration) {
                t = debug_flush_timer;
                if (t) {
                    debug_flush_timer = -- t;
                    if (!t) {
                        UENUM = DEBUG_TX_ENDPOINT;
                        while ((UEINTX & (1<<RWAL))) {
                            UEDATX = 0;
                        }
                        UEINTX = 0x3A;
                    }
                }
            }
        }
    }
    
    
    // Misc functions to wait for ready and send/receive packets
    static inline void usb_wait_in_ready(void)
    {
        while (!(UEINTX & (1<<TXINI))) ;
    }
    static inline void usb_send_in(void)
    {
        UEINTX = ~(1<<TXINI);
    }
    static inline void usb_wait_receive_out(void)
    {
        while (!(UEINTX & (1<<RXOUTI))) ;
    }
    static inline void usb_ack_out(void)
    {
        UEINTX = ~(1<<RXOUTI);
    }
    
    
    
    // USB Endpoint Interrupt - endpoint 0 is handled here.  The
    // other endpoints are manipulated by the user-callable
    // functions, and the start-of-frame interrupt.
    //
    ISR(USB_COM_vect)
    {
            uint8_t intbits;
        const uint8_t *list;
            const uint8_t *cfg;
        uint8_t i, n, len, en;
        uint8_t bmRequestType;
        uint8_t bRequest;
        uint16_t wValue;
        uint16_t wIndex;
        uint16_t wLength;
        uint16_t desc_val;
        const uint8_t *desc_addr;
        uint8_t    desc_length;
    
            UENUM = 0;
            intbits = UEINTX;
            if (intbits & (1<<RXSTPI)) {
                    bmRequestType = UEDATX;
                    bRequest = UEDATX;
                    wValue = UEDATX;
                    wValue |= (UEDATX << 8);
                    wIndex = UEDATX;
                    wIndex |= (UEDATX << 8);
                    wLength = UEDATX;
                    wLength |= (UEDATX << 8);
                    UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
                    if (bRequest == GET_DESCRIPTOR) {
                list = (const uint8_t *)descriptor_list;
                for (i=0; ; i++) {
                    if (i >= NUM_DESC_LIST) {
                        UECONX = (1<<STALLRQ)|(1<<EPEN);  //stall
                        return;
                    }
                    desc_val = pgm_read_word(list);
                    if (desc_val != wValue) {
                        list += sizeof(struct descriptor_list_struct);
                        continue;
                    }
                    list += 2;
                    desc_val = pgm_read_word(list);
                    if (desc_val != wIndex) {
                        list += sizeof(struct descriptor_list_struct)-2;
                        continue;
                    }
                    list += 2;
                    desc_addr = (const uint8_t *)pgm_read_word(list);
                    list += 2;
                    desc_length = pgm_read_byte(list);
                    break;
                }
                len = (wLength < 256) ? wLength : 255;
                if (len > desc_length) len = desc_length;
                do {
                    // wait for host ready for IN packet
                    do {
                        i = UEINTX;
                    } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
                    if (i & (1<<RXOUTI)) return;    // abort
                    // send IN packet
                    n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
                    for (i = n; i; i--) {
                        UEDATX = pgm_read_byte(desc_addr++);
                    }
                    len -= n;
                    usb_send_in();
                } while (len || n == ENDPOINT0_SIZE);
                return;
                    }
            if (bRequest == SET_ADDRESS) {
                usb_send_in();
                usb_wait_in_ready();
                UDADDR = wValue | (1<<ADDEN);
                return;
            }
            if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
                usb_configuration = wValue;
                usb_send_in();
                cfg = endpoint_config_table;
                for (i=1; i<5; i++) {
                    UENUM = i;
                    en = pgm_read_byte(cfg++);
                    UECONX = en;
                    if (en) {
                        UECFG0X = pgm_read_byte(cfg++);
                        UECFG1X = pgm_read_byte(cfg++);
                    }
                }
                    UERST = 0x1E;
                    UERST = 0;
                return;
            }
            if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
                usb_wait_in_ready();
                UEDATX = usb_configuration;
                usb_send_in();
                return;
            }
    
            if (bRequest == GET_STATUS) {
                usb_wait_in_ready();
                i = 0;
                #ifdef SUPPORT_ENDPOINT_HALT
                if (bmRequestType == 0x82) {
                    UENUM = wIndex;
                    if (UECONX & (1<<STALLRQ)) i = 1;
                    UENUM = 0;
                }
                #endif
                UEDATX = i;
                UEDATX = 0;
                usb_send_in();
                return;
            }
            #ifdef SUPPORT_ENDPOINT_HALT
            if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
              && bmRequestType == 0x02 && wValue == 0) {
                i = wIndex & 0x7F;
                if (i >= 1 && i <= MAX_ENDPOINT) {
                    usb_send_in();
                    UENUM = i;
                    if (bRequest == SET_FEATURE) {
                        UECONX = (1<<STALLRQ)|(1<<EPEN);
                    } else {
                        UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
                        UERST = (1 << i);
                        UERST = 0;
                    }
                    return;
                }
            }
            #endif
            if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
                if (wIndex == 0) {
                    len = wLength;
                    do {
                        // wait for host ready for IN packet
                        do {
                            i = UEINTX;
                        } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
                        if (i & (1<<RXOUTI)) return;    // abort
                        // send IN packet
                        n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
                        for (i = n; i; i--) {
                            UEDATX = 0;
                        }
                        len -= n;
                        usb_send_in();
                    } while (len || n == ENDPOINT0_SIZE);
                    return;
                }
            }
            }
        UECONX = (1<<STALLRQ) | (1<<EPEN);    // stall
    }
    Last edited by Frank B; 03-22-2020 at 11:59 PM. Reason: added code tags

  12. #12
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    6,578
    @NBPat, please use the code tags. The code is unreadable without them. I've added them to previous post.

  13. #13
    Junior Member
    Join Date
    Mar 2020
    Posts
    6
    Thank you, FrankB. I appreciate you adding the required code tags. How do I do it correctly in the future? Is there a guide?
    I see an octothorpe character (#) in the toolbar and it says Wrap CODE tags around selected text. Do I just click one octothorpe at the start and one at the end?
    When I posted it looked okay. But I did not look at it after hitting the post reply button.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •