Audioino?

Can anyone look at the bootloader and tell me what they think? I know on the chAudioBoot.c file it says atmega168 but it looks like it should work on the atmega328p also. Any help would be greatly appreciated since this is a really cool bootloader and I would love to get it to work.

OK, what chip do you have? You have made repeated references to the Atmega168, so I assumed you were using it. Or are you?

I am using the atmega328p. The bootloader looks like it was written only for the atmega8 and the atmega168 but it looks like it should port over just fine since the 168 and 328 are pretty much the same.

Apart from the program memory size.

were you able to flash the bootloader successfully? if so, can you upload code through audio?

The bootloader in the Flash is at the end of the Flash. Due to the size of the Atmega328 the address of the bootloader section differs from the Atmega168.

After developing the first version of the bootloader I found a major bug. Some sound cards have an inverted output which would not work with the bootloader. I made a second java program which corrects this issue. Please use the program version which fits to your computer.

I've been using the AudioBoot_v2_0.zip so I think that should solve the inverse audio problem correct? I am running java program on my mac and I guess i could try another machine.

Also do you know how to properly address the bootloader on the atmega328p so that it gets burnt in the right location?

sdinnu:
However that also changes the start address to 3E00 rather than 3C00 which is mentioned in the bootloader's README. When i try to flash the bootloader with the bolded fuses, it only works if I bootload at address 3C00, and even after that I have the same problem of although it boots, any attempt to upload code results in that error flash. Maybe the bootloader doesnt work with the atmega328p?

Wait, wait. You have an Atmega328P, right? So that has 32 Kb of Program Memory.

Valid bootloader addresses are:

  • No bootloader: start at address 0x0000
  • Small bootloader (512 bytes): start at address 0x7E00
  • Larger bootloader (1024 bytes): start at address 0x7C00
  • Even larger bootloader (2048 bytes): start at address 0x7800
  • Largest bootloader (4096 bytes): start at address 0x7000

These are byte addresses not word addresses. The fuse calculator talks in word addresses. So if you have a 1024 byte bootloader it starts at byte 0x7C00 or word 0x3E00. So it should be compiled to start at (byte) 0x7C00, and the high fuse should be 0xDC (512 word, 1024 byte, bootloader).

I tried using Nick's Atmega programmer and changing the address on where the bootloader is placed and I cannot even get the chip to boot anymore. It only boots when I change the address to 0x3C00

Here is what I did:

    else if (subcommand == 'A')  // use internal 8 MHz clock
      {
      Serial.println (F("Using Audioino 8 MHz loader."));
      bootloader = chAudioBoot_ATMEGA168_IN_PD1_LED_PB5_hex;
      newlFuse = 0xE2;  // internal 8 MHz oscillator
      newhFuse = 0xDC;  //  1024 byte bootloader, SPI enabled
      newextFuse = 0xFF; 
      addr = 0x7C00;
      len = sizeof chAudioBoot_ATMEGA168_IN_PD1_LED_PB5_hex;
      }  // end of using the 8 MHz clock

And here is the output of your program:

Atmega chip programmer.
Written by Nick Gammon.
Entered programming mode OK.
Signature = 0x1E 0x95 0x0F
Processor = ATmega328P
Flash memory size = 32768 bytes.
LFuse = 0xE2
HFuse = 0xDC
EFuse = 0xFF
Lock byte = 0xEF
Clock calibration = 0x8D
Bootloader address = 0x7E00
Bootloader length = 512 bytes.
Type 'L' to use Lilypad (8 MHz) loader, 'A' for Audioino (8 MHz), or 'U' for Uno (16 MHz) loader ...
Using Audioino 8 MHz loader.
Type 'V' to verify, or 'G' to program the chip with the bootloader ...
Erasing chip ...
Writing bootloader ...
Committing page starting at 0x7C00
Committing page starting at 0x7C80
Committing page starting at 0x7D00
Committing page starting at 0x7D80
Committing page starting at 0x7E00
Committing page starting at 0x7E80
Committing page starting at 0x7F00
Committing page starting at 0x7F80
Written.
Verifying ...
No errors found.
Writing fuses ...
LFuse = 0xE2
HFuse = 0xDC
EFuse = 0xFF
Lock byte = 0xEF
Clock calibration = 0x8D
Done.
Type 'C' when ready to continue with another chip ...

Since this doesnt even boot properly, does the bootloader need to be recompiled for the atmega328p? How would I go about doing that?

sdinnu:
Since this doesnt even boot properly, does the bootloader need to be recompiled for the atmega328p?

Absolutely. The code is compiled to run at a certain address, and the bootloader has to be at certain limited addresses. You can't just stick them where you feel like it.

How would I go about doing that?

I'm not sure exactly how to recompile bootloaders (depends on your platform a bit) but there should be a makefile there. I've recompiled Optiboot on the Mac by ignoring the makefile and doing my own thing.

So this bootloader doenst come with any makefile so I installed AVR studio and tried to see if I can recompile the bootloader there but I am pretty lost. I have a mac and windows so environment should not be a problem. It seems like this bootloader would work if I just changed the address but I have no clue how to do that and recompile a hex.

You can't recompile a hex. You need to find the source and recompile that. Where did you get this file? Perhaps there is a clue there.

You can get all the files from the website

or I made a quick link to download them
http://cl.ly/222H0K3j0f3j

There is a AudioBoot.c file which I think is the source file that can be rebuilt. I googled around but I could not find a good tutorial on how to do such a thing.

Perhaps I am missing something, but this doesn't look like a bootloader to me (excerpted code):

//***************************************************************************************
//** the data transmition was developed on the arduino plattform
//***************************************************************************************
#ifdef ARDUINO_PLATFORM

	#define ARDUINO_DEBUG
	
	const int ledPin =  13;    // LED connected to digital pin 13

	// The setup() method runs once, when the sketch starts

	void setup()   {                
	  // initialize the digital pin as an output:
	  pinMode(ledPin, OUTPUT);     
	  Serial.begin(9600); 
          Serial.println("AudioBoot starting");
	}
	void loop()                     
	{
	  a_main();
	  while(1); // stop
	}
	
	#define LEDON  { digitalWrite(ledPin, HIGH );   }
	#define LEDOFF { digitalWrite(ledPin, LOW  );   }
    #define TOGGLELED { digitalWrite(ledPin, !digitalRead(ledPin));} 


	#define INPUTAUDIOPIN (1<<PB4)
	#define PINVALUE (PINB&INPUTAUDIOPIN)

	#define PINLOW (PINVALUE==0)
	#define PINHIGH (!PINLOW)

#endif

There is nothing there about a start compilation address, for one thing.

For example, in the Optiboot makefile I see this:

atmega328: TARGET = atmega328
atmega328: MCU_TARGET = atmega328p
atmega328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
atmega328: AVR_FREQ = 16000000L
atmega328: LDSECTION  = --section-start=.text=0x7e00
atmega328: $(PROGRAM)_atmega328.hex
atmega328: $(PROGRAM)_atmega328.lst

Note the start address (0x7e00). The file in that download doesn't even have a makefile.

It looks like he did it in Visual Studio. The file chAudioBoot.aps has this in it:

<LINKEROPTIONS> -Wl,--section-start=.text=0x3c00 </LINKEROPTIONS>

I suggest writing to the author. Perhaps he has an easy way of making a 328-compatible version.

#ifdef ARDUINO_PLATFORM

There seems to be a misunderstanding: The compilation for "ARDUINO_PLATFORM" is meant for debugging purpose. If you complile it with this option, you can use an Arduino to make the received values visible, it is not meant to be used for "bootloading".
If you want to compile a bootloader you should use one of the "microcontroller" definitions.

OK, fair enough. I got it to compile at the command line on my Mac using this shell script:

avr-gcc -mmcu=atmega328p \
    -D__AVR_ATmega328P__ \
    -DF_CPU=16000000L \
    -Os \
    -gdwarf-2 \
    -fno-inline-small-functions \
    -fno-split-wide-types \
    -fno-tree-scev-cprop  \
    -fno-exceptions -ffunction-sections -fdata-sections \
    -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -mno-tablejump  \
    -fno-keep-inline-functions -fno-common \
    -std=gnu99 \
    -Wl,--section-start=.text=7C00 \
    -Wl,--relax -nostartfiles \
    -Wl,--gc-sections \
    -oaudioboot.elf chAudioBoot.c 
rm audioboot.hex
avr-objcopy -O ihex --set-section-flags=.eeprom=alloc,load \
    --no-change-warnings \
    --change-section-lma \
    .eeprom=0 \
    -R .eeprom audioboot.elf audioboot.hex

avr-objdump -j .sec1 -d -m avr5 audioboot.hex > audioboot.lst

I modified the source file slightly to get it to compile. The diffs are:

*** chAudioBoot.c	2012-12-25 18:08:02.000000000 +1100
--- /Users/nick/Documents/AudioBoot/chaudioboot.c	2012-12-30 07:57:42.000000000 +1100
***************
*** 124,134 ****
  // here starts the code for the stand alone microcontroller
  //***************************************************************************************
  
  #ifdef UNSPECIFIED_PLATTFORM
  
  	#include <avr/io.h>
  	#include <avr/interrupt.h>
- 	#include <avr/signal.h>
  	#include <stdlib.h>
  	#include <avr/boot.h>
  
--- 124,136 ----
  // here starts the code for the stand alone microcontroller
  //***************************************************************************************
  
+ void a_main();
+ int main(void) __attribute__ ((naked)) __attribute__ ((section (".init9")));
+ 
  #ifdef UNSPECIFIED_PLATTFORM
  
  	#include <avr/io.h>
  	#include <avr/interrupt.h>
  	#include <stdlib.h>
  	#include <avr/boot.h>
  
***************
*** 177,183 ****
  	#define PINVALUE (PIND&INPUTAUDIOPIN)
  	
  	//turn on pull up and set Poti GND
! 	#define INITPORT {	PORTD|=INPUTAUDIOPIN;\	
  						DDRD|=(1<<PD2);}		
  
  	#define PINLOW (PINVALUE==0)
--- 179,185 ----
  	#define PINVALUE (PIND&INPUTAUDIOPIN)
  	
  	//turn on pull up and set Poti GND
! 	#define INITPORT {	PORTD|=INPUTAUDIOPIN;\
  						DDRD|=(1<<PD2);}		
  
  	#define PINLOW (PINVALUE==0)

Basically:

  • Removed an obsolete include for signal.h
  • Did a function prototype for a_main
  • Did a prototype for main which put it in .init9 section and made it naked
  • Got rid of a space after a backslash

The amended file is attached (as well as the build script).

Compile by using the shell script:

$ ./build.sh

Resulting files:

$ ls -l
total 104
-rwxr-xr-x  1 nick  staff   5714 30 Dec 08:05 audioboot.elf
-rw-r--r--  1 nick  staff   2055 30 Dec 08:05 audioboot.hex
-rw-r--r--  1 nick  staff  13306 30 Dec 08:05 audioboot.lst
-rwxr-xr-x@ 1 nick  staff    805 30 Dec 07:44 build.sh
-rwxr-xr-x@ 1 nick  staff  16992 30 Dec 07:57 chAudioBoot.c

The resulting file indeed seems to start at 0x7C00:

audioboot.hex:     file format ihex


Disassembly of section .sec1:

00007c00 <.sec1>:
    7c00:	11 e0       	ldi	r17, 0x01	; 1
    7c02:	a0 e0       	ldi	r26, 0x00	; 0
    7c04:	b1 e0       	ldi	r27, 0x01	; 1
    7c06:	01 c0       	rjmp	.+2      	;  0x7c0a
    7c08:	1d 92       	st	X+, r1
    7c0a:	a5 38       	cpi	r26, 0x85	; 133
    7c0c:	b1 07       	cpc	r27, r17
    7c0e:	e1 f7       	brne	.-8      	;  0x7c08
    7c10:	25 9a       	sbi	0x04, 5	; 4
    7c12:	59 9a       	sbi	0x0b, 1	; 11
    7c14:	fa d0       	rcall	.+500    	;  0x7e0a

I haven't tested it - I don't have the audio hardware set up - but this is closer to what you want. Now you want the fuses for a 1024 byte (512 word) bootloader (high fuse = 0xDC, I think).

I attach the .hex file as well just in case you don't plan to modify the bootloader. But I can't guarantee it works, as I said.

chAudioBoot.c (16.6 KB)

build.sh (805 Bytes)

audioboot.hex (2.01 KB)

Looking at the bootloader code a bit more it seems to use interrupts, a bit. You might want to omit the "naked" part. I'm not absolutely sure how well interrupts are going to work with it. Possibly it will work unchanged. Possibly not.

I was able to successfully bootload the hex file that you provided but I dont think the programming through the bootloader is working. I was also trying to compile your bootloader again after removing the naked main script and I also wanted to change the clock speed to 8mhz rather than 16 but I keep getting an error while trying to build it.

here is what i get when i run ./build.sh

http://cl.ly/image/211E2U35070R

You can copy and paste those messages you know, you don't need to take screen shots of them.

Let's see what version of avr-gcc you have. I have:

$ avr-gcc --version

avr-gcc (GCC) 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.
~ $ avr-gcc --version
avr-gcc (GCC) 4.6.2
Copyright (C) 2011 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.