My own AVR ISP programmer using PIC16f877a and python!

Introduction: 

(don't skip to read the note below)
I recently purchased few AVR microcontrollers. I don't know much about AVR since I am using it for first time. Any way, I have some experience on working with PIC and MSP430. To program AVR using USB, I came to know that USBASP is the best and cheap choice. But any way, I thought of making my own ISP programmer (both PC software and burning hardware) for AVR using my fav PIC (PIC16f877A) microcontroller just for getting familiarised with the process of loading the binary into the AVR flash.
      From PC side, coding is done on python. In short words, the python script reads the hex file (intel hex format) and make some ascii conversion on it and then send it to the PIC16F877A line by line. Now by using some commands for isp programming, the PIC communicate with AVR and transfer the data to it via SPI. I have tested my programmer on atmega8, atmega16 and atmega32.

Note:
 I did this just for learning some thing about the burning process, please don't consider this seriously because this may have many bugs , I don't know and I didn't tested much.. Also I am not interested to continue this because it will be time wasting as there are already many cheap and efficient avr programmers available now. So please don't complain about bugs and don't use this for any important purpose ;-)


 Intel hex format:

Intel hex format is well explained in wikipedia. I learned about it from there. Here is the link towards the wikipedia page. An intel hex file contains the binary information about the flash address and data. It is a text file format. Each line of intel hex file consist of 6 parts. See below picture.







explanation is there on wikipedia. But I think the above two picture itself explains it...:-)

Python code for PC:

#!/usr/bin/python
import serial,time,sys,os

SERIALPORT = "/dev/ttyUSB0"
HEX = "a.hex"
BAUD = 115200
IF_FUSE_LOW = 0
IF_FUSE_HIGH = 0

if not sys.argv[1:]:
    print "usage: ./avrisp.py [hex file] [fuse bits low] [fuse bits high]"
    print "example: ./avrisp.py led.hex 225 133"
    print "note: use fuse bits only if it is necessary"
if sys.argv[1:]:
    HEX = sys.argv[1]
if sys.argv[2:]:
    FUSE_LOW = sys.argv[2]
    IF_FUSE_LOW = 1
if sys.argv[3:]:
    FUSE_HIGH = sys.argv[3]
    IF_FUSE_HIGH = 1

ser = serial.Serial(SERIALPORT,BAUD)
try:
    ser.open()
    ser.setDTR(1)
except Exception,e:
    print "error open serial port: " + str(e)
    exit()
if ser.isOpen():
    try:
        ser.flushInput()
        ser.flushOutput()
        f = open(HEX)
        hex = f.read()
        list = hex.split("\r\n")
        list = list[:-1]
        ser.write(chr(4));time.sleep(.01)
        ser.write('0');time.sleep(.01)
        ser.write('0');time.sleep(.01)
        ser.write('0');time.sleep(.01)
        ser.write('B');time.sleep(.01)
        ser.write('U');time.sleep(.01)
        ser.write('R');time.sleep(.01)
        ser.write('N');time.sleep(.01)
        time.sleep(.1)
        for line in list:
            line = line[1:-2]
            l = len(line)
            count = 0;
            while count < l:
                value = int(line[count] + line[count + 1],16)
                ser.write(chr(value))
                time.sleep(.0008)
                count = count + 2
            print line
            time.sleep(.0005)
        time.sleep(.1)
        if IF_FUSE_LOW == 1:
            ser.write(chr(1));time.sleep(.01)
            ser.write('Y');time.sleep(.01)
            ser.write('E');time.sleep(.01)
            ser.write('S');time.sleep(.01)
            ser.write(chr(int(FUSE_LOW)));time.sleep(.01)
        else:
            ser.write(chr(1));time.sleep(.01)
            ser.write('N');time.sleep(.01)
            ser.write('O');time.sleep(.01)
            ser.write('O');time.sleep(.01)
            ser.write('O');time.sleep(.01)
            time.sleep(.2)
        if IF_FUSE_HIGH == 1:
            ser.write(chr(1));time.sleep(.01)
            ser.write('Y');time.sleep(.01)
            ser.write('E');time.sleep(.01)
            ser.write('S');time.sleep(.01)
            ser.write(chr(int(FUSE_HIGH)));time.sleep(.01)
        else:
            ser.write(chr(1));time.sleep(.01)
            ser.write('N');time.sleep(.01)
            ser.write('O');time.sleep(.01)
            ser.write('O');time.sleep(.01)
            ser.write('O');time.sleep(.01)
        ser.close()
        print "BURNING IS COMPLETED"
    except Exception, e1:
        print "error communicating...: " + str(e1)
else:
    print "cannot open serial port "
Actually the hex file is in txt format. So, for example, a byte 0xff is represented as string "FF" in text file. So it takes two bytes in the text file. But I need to send the ascii ie 0xff to PIC. So I need to convert the string "FF" to byte 0xff. For that, I have used
value = int(line[count] + int[count + 1],16) 
Now in value, there will be the ascii of string 'FF' ie now value = 255 or 0xff. I just ignored the ":" and checksum and send  (via UART) the remaining part each line after converting two adjacent bytes in text to corresponding ascii byte. PIC collects the received byte until it receives a complete line of hex. Now the PIC process the received data which will be explained later. Similarly all of the bytes in hex are send to the PIC. After sending the hex file, Next is the fuse bits. We can add the fuse bits as command line argument (optional), then it checks for the existence of sys.argv[2] and sys.arg[3]. Pyserial (a python module) is used for accessing the serial port of PC. In my case, I am using USB to UART converter. So my port is /dev/ttyUSB0. Also baud rate I am using is 115200. If file name is not specified in command line argument, it uses "a.hex" as default value. Also, if no fuse bits are provided in command line argument, it doesn't modify the default fuse bits...........

  Note: 
    At first time, when I tested my programmer with random fuse bits, I got in trouble :( . The AVR clock source is changed to external clock. Then I couldn't use the ISP programmer since the AVR lacks a clock source. Later , I am forced to provide an external clock source. I used an MSP430 launchpad for providing clock to AVR. (or we can use any multi-vibrator or external frequency generator). So, it is not recommended to alter the fuse bits unless it is necessary.


PIC16F877A to burn AVR (isp):
code (for Hi Tech C compiler, MPLAB) 
#include<pic.h>
#define _XTAL_FREQ 20e6
#define RESET RC2
#define MOSI RC5
#define MISO RC4
#define SCK RC3
unsigned char x,y,z, buff[4], buffer[50];
int count;
char flag;
void usrt_init()
{
    GIE = 1;
    PEIE = 1;
    RCIE = 1;
    TRISC6=0;
    TXSTA=0b00100110;
    RCSTA=0b11010000;
    SPBRG=10;
}
void printf(const char *p)
{
    while(*p){
        TXREG=*p;
        while(TRMT==0);
        p++;
    }
}
void txd(unsigned char vv)
{
    TXREG=vv;
    while(TRMT==0);
}
void spi_init()
{
    TRISC4=1;
    RC3=0;RC5=0;
    TRISC2=TRISC3=TRISC5=0;
}
static unsigned char spi_write(unsigned char ibuf)
{
    unsigned char obuf;
    int i;
    for (obuf = 0, i = 7; i >= 0; --i)
    {
        MOSI = (ibuf >> i) & 1;
        SCK = 1;
        obuf |= (MISO << i);
        SCK = 0;
    }
    return obuf;
}
void isp(char a, char b, char c, char d)
{
    buff[0] = spi_write(a);
    buff[1] = spi_write(b);
    buff[2] = spi_write(c);
    buff[3] = spi_write(d);
}
int isp_start(void)
{
    unsigned int n;
    for (n = 0; n < 5; ++n)
    {
        RESET = 0;
        __delay_ms(25);
        isp(0xac, 0x53, 0, 0);
        if (buff[2] == 0x53)
        return 1;
        RESET = 1;
    }
    return 0;
}
void isp_close()
{
    RESET = 1;
}
unsigned char ispReadFlash(unsigned int address) {
    spi_write(0x20 | ((address & 1) << 3));
    spi_write(address >> 9);
    spi_write(address >> 1);
    return spi_write(0);
}
unsigned char ispWriteFlash(unsigned int address, unsigned char data) {
    spi_write(0x40 | ((address & 1) << 3));
    spi_write(address >> 9);
    spi_write(address >> 1);
    spi_write(data);
    return 0;
}
unsigned char ispFlushPage(unsigned int address) {
    spi_write(0x4C);
    spi_write(address >> 9);
    spi_write(address >> 1);
    spi_write(0);
    __delay_ms(4.8);
    return 0;
}
isp_erase()
{
    isp(0xac,0x80,0,0);
    __delay_ms(10);
    int i=4;
    while(i) {
        i--;
        RESET = 1;
        __delay_ms(5);
        RESET = 0;
        __delay_ms(5);
    }
    isp_start();
}
isp_burn_AVR()
{
    unsigned int mult = 1, checkpoint = 64*1 - 1;
    unsigned int address, length;
    char exit = 0;
    while(1)
    {
        if(flag == 1) {
            flag = 0;
            unsigned int temp_address;
            if(length = buffer[0]) {
                address = buffer[1];
                address <<= 8;
                address |= buffer[2];
                temp_address = address;
                char k = 4;
                while(length) {
                    ispWriteFlash(address, buffer[k]);
                    address++;
                    k++;
                    length--;
                }
                address = temp_address + 15;
            }
            else {
                exit = 1;
                ispFlushPage(64*(mult - 1));
            }
            if(address == checkpoint) {
                ispFlushPage(64*(mult-1));
                mult++;
                checkpoint = 64*mult -1;
            }
            address++;
        }
        if(exit){
            break;
        }
    }
}
void isp_write_fuse_low(char fuse_low)
{
    isp(0xac, 0xa0, 0, fuse_low);
    __delay_ms(10);
}
void isp_write_fuse_high(char fuse_high)
{
    isp(0xac, 0xa8, 0, fuse_high);
    __delay_ms(10);
}
void interrupt UART()
{
    x = RCREG;
    static char len = 16;
    if(count == 0){
        len = x;
        len+=3;
    }
    buffer[count] = x;
    if(count == len){
        count = 0;
        flag = 1;
    }
    else {
        count++;
    }
}
void main(void)
{
    TRISD=0;
    usrt_init();
    spi_init();
    while(1) {
        while(!flag);
        if(buffer[4] == 'B' && buffer[5] == 'U' && buffer[6] == 'R' && buffer[7] == 'N') {
            flag = 0;
            if(!isp_start())
            while(1);
            isp_erase();
            isp_burn_AVR();
            while(!flag);
            if(buffer[1] == 'Y' && buffer[2] == 'E' && buffer[3] == 'S' && (buffer[4]&0xf) != 0)
            isp_write_fuse_low(buffer[4]);
            while(!flag);
            if(buffer[1] == 'Y' && buffer[2] == 'E' && buffer[3] == 'S')
            isp_write_fuse_high(buffer[4]);
            RESET = 1;
        }
    }
}
At  first the PIC waits for a string "BURN" to be received via UART which tells the PIC that the python script in PC is trying to burn a code into the AVR, and thus PIC enter to the programming mode. In programming mode, the RESET PIN on AVR is made LOW by the RC2 pin of PIC. It then erases the AVR using command set {0xac, 0x80, 0, 0}. After erasing command set is send, then few +ve pulses are applied on reset pin. Now the PIC waits for the line buffer to get filled with the first line of hex code.Then it checks for the number of data bytes and if it is non zero, it means there are some data to be loaded to AVR flash. The flash address is extracted from the buffer. Then using command 40/48 (even/odd address), it sends the data byte to AVR via SPI. For example, for address 0x0000, if data byte is 0x34, then we need to send it to AVR buffer by using command 40.
ie, isp(0x40, 0x00, 0x00, 0x34). Now for odd address it is command 48. So the function ispWriteFlash(address,data) will do the task. Similarly the remaining data bytes are also loaded to AVR buffer. Then the PIC waits for next hex line to be filled in the same buffer.  Then it do the same steps as above. When the address reaches a value equal to the multiple of 64, we need to give another command (0x4c) which really burns the buffered 64 bytes to flash. Now after programming the flash, it program the fuse bits (if provided in python command line argument). There are specific commands for all operation... When the programming is completed, the reset pin is made high (RC2 pin of PIC will do it). Thus AVR starts executing the new code burned into it and the PIC waits for next burn request from python script (ie the same "BURN" string).  Thats all about PIC burner...;-)
Screenshots and photos:

44 comments :

  1. Hi Vinod, Would like your advice or suggestions on how to interface a keyboard or digitizer with a TV? My mother is hearing impaired and sometimes its very convenient to type a message and show her on cellphone or laptop. I would really like to do this on a big screen. Its very easy to connect a laptop to a TV with vga/hdmi/svideo these days but I would like something permanent (cant keep the laptop connected to TV all the time). I have software background but havent worked much with microcontrollers so dont know which to use and what the best way to do this is? Any help would be appreaciated. Thanks

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. If you’re interested in internet or phone service, you can go with one of Comcast’s double or triple play bundles.It also offers bundles of TV, broadband internet and phone service with download speeds

    ReplyDelete
  4. The thing about broken gadgets is that, regardless of how broken they will be, they presumably still make them work parts. electronic review

    ReplyDelete
  5. nown because of its variety of DJ equipment, numark ttusb review has a turntable which is directed at the domestic marketplace and is designed for digitising music

    ReplyDelete
  6. So it is imperative to deal with them appropriately in order to limit harm and glitch. have a peek at these guys

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Very Well-Written Content. I found this blog unique and what i have been looking for, many thanks. Happy Independence Day Essay in Hindi 2018

    ReplyDelete
  9. In most cities, there are recycling centers that are set up specifically to deal with these end of life electronics. They know what needs to be done when they are recycled and will dispose of them in the safest manner possible best dashcam

    ReplyDelete
  10. Now and again we go for customer back plans which think of electronic items or are reported by retailers without computing the enthusiasm, handling expenses or regularly scheduled payments. Best Websites For Building Computers

    ReplyDelete
  11. But today, with thousands of wholesalers scouring the Internet for selling products and finding suppliers, consumers and retailers are left with a wide range of options.top split ac under 30000 Rs.

    ReplyDelete
  12. Once in a while the offer of maintenance agreement is likewise added to the price tag of a thing and in this manner makes the value run higher;Robot vacuum cleaner

    ReplyDelete
  13. Along these lines, it"s nothing unexpected that miniaturized scale processors ought to be re-coordinated from the PC world and assembling world into the home. Bobsweep

    ReplyDelete
  14. An assortment of abilities are related with this sort of occupation position, which manages correspondences, control frameworks, and flag preparing. click here

    ReplyDelete
  15. These electronic components have become a major part of our daily life, whether we think so or not. Bobsweep robotic vacuum cleaner and mop

    ReplyDelete
  16. We can not move even a solitary advance without the assistance of electronic products and machines. Bobsweep

    ReplyDelete
  17. These are a portion of the shrewd network advances and abilities that will make an incentive to the framework, coming about to a more upgraded, decentralized,Bobsweep reviews

    ReplyDelete
  18. Anyone subscribing to RSS feeds or media aggregators are now able to download or instruct their RFF program to download anything new that comes out on a subject important to them comment

    ReplyDelete
  19. Videos too are important in Instagram marketing. You can create and share a video with your employees to promote the product at hand.bobsweep pro robotic vacuum cleaner and mop reviews

    ReplyDelete
  20. Do you accomplish all the more later in the day? When you know your most beneficial time, cut out a lump of it and attempt to seclude yourself from the diversions of the electronic technology. bobsweep pethair plus review

    ReplyDelete
  21. While you are tidying and clearing your home, you ought to consider utilizing these channels to do however much cleaning of individual things as could reasonably be expected.Bobsweep review

    ReplyDelete
  22. The aim behind having these fans to is overwhelm the warmth from these electronics and to help keep them cool. bobsweep pethair plus reviews

    ReplyDelete
  23. Extraordinary compared to other approaches to buy an electronic thing is to do some online research for the said item or relatively comparative thing range on the site offering them on the web. Bobsweep pethair plus robotic vacuum reviews

    ReplyDelete
  24. Keep in mind that the electrical parts of your home could cause significant issues if not legitimately introduced or fixed.domestic electrical

    ReplyDelete
  25. Mechanical information UNIVERSITY MURANGA is an essential piece of the courses that are canvassed in the establishment.

    ReplyDelete
  26. Here are some of the tips that will help you lot in getting the idea on how to look for the best deals on these electronic items.
    file management

    ReplyDelete
  27. This foundation may likewise give the way to affecting ongoing exchanges and make middle people, for example, deals representatives, stock merchants and travel specialists, whose work is to give a basic data connect among purchasers and venders, repetitive. engineering app Tech pally

    ReplyDelete
  28. This web site is my aspiration , rattling superb pattern and perfect content material . Best Chinese Projectors

    ReplyDelete
  29. The way this mark took was not controllable or recognizable, and much of the time it navigated miles of wire before achieving its goal, so how might it be viewed as a legitimate mark? Tech Waste Recycling

    ReplyDelete
  30. By influencing utilization of exceptionally specialized contraptions you to can undoubtedly anchor your home and produce some fine outcomes in a hurry. You got the chance to be exceptionally cautious while picking the correct choices in a hurry. WittySpy.com

    ReplyDelete
  31. An administration work area framework which is utilized to follow episodes, issue, changes, can't be utilized to take care of this style of issue. They are two unique standards. Techeries.com

    ReplyDelete
  32. . Interesting post. I Have Been wondering about this issue, st martin diocesan school so thanks for posting. Pretty cool post.It 's really very nice and Useful post.Thanks

    ReplyDelete
  33. It very well may be extremely hurtful in light of the fact that you can meet mishaps en route in the event that you don't have anything that will keep you conscious. local car dealerships

    ReplyDelete
  34. I have read your blog it is very helpful for me. I want to say thanks to you. public schools in east delhi I have bookmark your site for future updates

    ReplyDelete
  35. Planes have them and cars will too, and why not the Black box on planes have be literally invaluable for many years with its ability to get detail records of trips and logs of what happens to a plane in flight or when accidents occur. car dealerships near me

    ReplyDelete
  36. This comment has been removed by the author.

    ReplyDelete
  37. Interesting blog thanks for sharing While choosing your perfect ride for driving, Accord Cars comes with and the best packages for you to pick from. Car rentals for self drive in Chennai are done the easier. Just pick out your plan from hourly, daily, weekly and even monthly plans available.

    ReplyDelete
  38. The article is very useful. Thanks. hd videos

    ReplyDelete
  39. But today, with thousands of wholesalers scouring the Internet for selling products and finding suppliers, consumers and retailers are left with a wide range of options. https://bestacunder.com/best-ac-under-30000/

    ReplyDelete
  40. This comment has been removed by the author.

    ReplyDelete