Author Topic: Writing to flash problems on atmega 16  (Read 7849 times)

0 Members and 1 Guest are viewing this topic.

Offline izuaTopic starter

  • Supreme Robot
  • *****
  • Posts: 682
  • Helpful? 0
    • izua electronics
Writing to flash problems on atmega 16
« on: May 04, 2008, 10:17:24 AM »
Hi! I've recently tried to write to flash, and after several attempts and questions on another forum, I was able to do it right (but not as in specs).

I'm using an atmega16, currently simulated in ISIS vsm.

My problem is at follows: I call a function to write to the flash buffer, from 0 to 128 (+ page offset), passing it words and addressing increments of 2 for the address. I have, of course, previously run boot_page_erase on page and waited for it to finish.

All data from address 0 to 63 is written ok. All data from 64 to 127 is not written (read later as 0xFF).

If I duplicate the routine used to write from 0 to 128, but instead set it to write offset with 64 bytes (64 to 192), without a page erase, the whole page gets written (0-127, as the original routine is intended)

As extra info, atmega16 has 16kbytes of flash, and 128 pages of 64 words. The write function is set in the bootloader section (which is defined at maximum size, 1024 bytes). boot_page_erase wants a byte address and erases the page where that byte is contained. boot_page_fill wants a byte address, but the data to be written must be a 16bit value. that's why I'm going from 0 to 128 in steps of two (and writing 007F in one pass, instead of one byte in two passes).

Here is the buggy function.
Code: [Select]
BOOTLOADER_SECTION
void flash_test()
{

    boot_spm_busy_wait();       // Wait until the memory is written.
char str[7];
uint16_t i;
//first, erase last page
uint32_t page = 128*89; // (page 90)
boot_page_erase(page);
    boot_spm_busy_wait();       // Wait until the memory is written.

uart_out("done erase 1\r\n");
//write data in flashbuffer
/**** one write should cover 0 - 128 */
page = 128*89; //page 89
    for (i=0; i<SPM_PAGESIZE; i+=2)
    {
        uint16_t w = 0x007F;
        boot_page_fill(page + i, w);
//boot_spm_busy_wait ();

//utoa(page+i, str, 10);
//uart_out(str);
//uart_out(",");
    }

    boot_page_write (page);     // Store buffer in flash page.
    boot_spm_busy_wait();       // Wait until the memory is written.
    boot_rww_enable ();
uart_out("done write\r\n");
/***** done write *******/

//write data in flashbuffer, part 2
/**** previous write covers 0-64. offseting it by 64 allows me to clear write the whole page */
/*page = 128*89+64; //page 89
    for (i=0; i<SPM_PAGESIZE; i+=2)
    {
        uint16_t w = 0x007F;
        boot_page_fill(page + i, w);
//boot_spm_busy_wait ();

//utoa(page+i, str, 10);
//uart_out(str);
//uart_out(",");
    }

    boot_page_write (page);     // Store buffer in flash page.
    boot_spm_busy_wait();       // Wait until the memory is written.
    boot_rww_enable ();
uart_out("done write\r\n");*/
/***** done write *******/



page = 128*89;
//read buffer
    for (i=0; i<SPM_PAGESIZE; i+=1)
    {
uint8_t l = pgm_read_byte(page+i);

utoa(i, str, 10);
uart_out(str);
uart_out(" = ");

utoa(l, str, 10);
uart_out(str);

//TXByte(l);
uart_outP(crlf);
    }

uart_outP(PSTR("ia pula ca am terminat\r\n"));
}

If you uncomment "write data in flashbuffer, part 2" code, you will see that the whole page gets written, instead of half. What am i doing wrong?

considering the code is ok, how big is the buffer boot_page_fill accesses ? Is it a hardware buffer, or is it implemented in RAM? I believe it should be the size of a page, but it looks like it isn't..
Check out my homepage for in depth tutorials on microcontrollers and electronics.

 


Get Your Ad Here

data_list