Touchless programming of an 8051/52 microcontroller

This post just shows how to quickly set up your 8051 embedded project to boot to the Atmel built in bootloader in order to upgrade the firmware. This method requires the flash API available from Atmel here http://www.atmel.com/dyn/resources/prod_documents/7725.zip

The FLIP programmer is the de facto programmer for most Atmel parts with ISP flash. It is a free download, and easy to use as well. I’ve even succesfully used it on Phillips parts with a bit of tinkering.

http://www.atmel.com/dyn/products/tools_card.asp?category_id=163&family_id=607&subfamily_id=1723&tool_id=3886

While there is overhead from including the API, it is surprisingly small; copy pasta-ing the code from the API and putting it directly into my main C file only saves about 180 bytes. It’s easier to just include the API. As I use the ED2 or RD2 variants with 64k of flash I can afford an extra kilobyte of memory usage. As you can upgrade the firmware through the serial port without needing a jumper this is a must for boxed applications.

While most of the Atmel examples use #include "config.h" to keep all of the headers in one place I prefer to include them as needed.

So, the first step is to include the API itself

#include "flash_api.h"

Then you need to edit the flash header to reflect the 8051 variant you use. In my case, with the AT89C51ED2 or the AT89C51RD2 I use #include<AT89C51XD2.H>   

Note the use of <> brackets for the include. This lets the Keil IDE know to use the header from it’s standard library. In many cases I’ll use a custom stdio header, in which case I’ll use #include "stdio.h" and keep the edited header file in the project directory.

The following is exactly as I use it in my application

case 6:

printf("\033[2J");

printf("Enter 9 to enter ISP mode, any other key to exit\n");

scanfErrorCheck = scanf("%d", &selection);

if(scanfErrorCheck == 1)

        {

        if(selection == 9)

               {

               printf("Power cycle and then connect via Flip\n");

               DelayMs(100);

               __api_wr_SBV(0xFC);

               __api_wr_BSB(0x55);

               __api_set_BLJB();

               reset ();

              }

       }

   else

       {

       SBUF=0;

       }

       RI=0;

      break;

The important parts of the code are

               __api_wr_SBV(0xFC);

               __api_wr_BSB(0x55);

               __api_set_BLJB();

As these are the API calls themselves. The first line sets the boot vector to the Atmel bootloader, the second line sets the boot sector, and the last line sets the bootloader jump bit, which the micro-controller uses to determine which address to boot from.

You will need to power cycle your controller once these commands have been run, and if you are using an RTOS you need to block all interrupts and sleep all other tasks until the power has cycled. If you have an interrupt available you can also do a watchdog reset and avoid the power cycle stage, as I have done in the code example above. However it can be a bit flaky at times, so if you can use the power cycle method you should.

If you change your mind about the upgrade you can simply cycle power yet again to boot from the user installed code.

Notes

  1. ianspringer posted this