Codevision - ATMEGA88 bootloader issue

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a nice Ethernet bootloader for the ATMEG328 that's been working for several years (manages to take advantage of DHCP) and now I'm doing a design using an ATMEGA88 via UART. I thought this would be easy to port over. So far, I can jump from the main program to the bootloader ok as well as back to the main program after the bootloader times out.
But when I try to program it, it hangs up in some funky state when it goes to erase the flash. Reset the power and it works again but nothing was erased or re-programmed. I used the same bits of code that worked in the 328 - seems like this should be safe since they are on the same data sheet. (I did change the page size and all, but I haven't gotten to where that comes into play.) I'm using Codevision - I'm self taught in C so afraid to leave the compound.
Below is what I have in my main program, it goes off when it gets to page erase:

                for(address = 0; address < 0x1800;address += 64) 
                    {
                    _WAIT_FOR_SPM();                                   
                    _PAGE_ERASE( address );
                    }

In the in the flash.h and flash.c I have the following:

#define _PAGE_ERASE(addr) __AddrToZByteToSPMCR_SPM( (void flash *) (addr), 0x03 )

 

void __AddrToZByteToSPMCR_SPM(void flash *addr, unsigned char ctrl);

 

unsigned char __AddrToZByteToSPMCR_LPM(void flash *addr, unsigned char ctrl)
{
#asm
     ldd  r30,y+1
     ldd  r31,y+2
     ld   r22,y
     WR_SPMCR_REG_R22
     lpm
     mov  r30,r0
#endasm
}

 

I know virtually nothing of assembly language, so it's a bit of black magic to me.

Any help appreciated.

This topic has a solution.
Last Edited: Fri. Feb 9, 2018 - 03:32 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You've shown __AddrToZByteToSPMCR_LPM() but what we need to see is __AddrToZByteToSPMCR_SPM().

 

From another thread:

http://www.avrfreaks.net/forum/at90can128-bootloader-spmen-not-clearing

void __AddrToZByteToSPMCR_SPM(void flash *addr, unsigned char ctrl)
{
#asm
     ldd  r30,y+1
     ldd  r31,y+2
     ld   r22,y
     WR_SPMCR_REG_R22
     spm
#endasm
}

We're also missing WR_SPMCR_REG_R22.  From that same thread:

#asm
     #define WR_SPMCR_REG_R22 sts 0x57,r22
#endasm

... but that thread was about the at90can128.  From that datasheet we see that the I/O register at SRAM address 0x57 is SPMCSR (as expected).  That register has the same address in the m88 (and m328), so one question is, I suppose, what do you have it defined as?

 

So looking at the assembler, it's clear that Z is loaded with the first function argument, addr, and r22 is loaded with the second function argument, ctrl, and then writes that to SPMCSR.  Your _PAGE_ERASE(addr) calls __AddrToZByteToSPMCR_SPM() with a ctrl of 0x03, so SPMCSR is written with the bits PGERS and SPMEN set to '1', with the remaining bits '0'.

 

Again from the same thread:

#define _WAIT_FOR_SPM() while( SPMCSR & (1<<SPMEN) )

 

All of this corresponds to the correct procedure for erasing a page, so this 'should' work.

 

As for the address you're passing (0x1800), that corresponds to a 2K bootloader.  Does this match your fuse settings, and the actual location of the bootloader?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Found the problem, I was missing this bit of magic code in the flash file:

 

// Required for compatibility with Enhanced Parameter Passing Mode 2
#pragma dstack_par+

 Whatever that means, but it's working now.

Thanks