[Description]
Location = "Atmel\AVR\AVR Detector";
Info = "Module to define AVR controllers via signature.",
    " ------------------------------------------------------------------------",
    " Bus: SPI.",
    "---------------------------------------------",
    " Author: ETL (c) 2005";
Buffer1 = "FLASH",2048;
Picture = "AVR ICP.BMP";
VCC = 8;
GND = 4;
Voltage = 5.0;

[Menu]

ReadSignature = "Detect AVR",ChipInfoButton,"Read signature bytes";


[Host]


//***********************************************************************
//*             ReadSignature                                          **
//***********************************************************************
Proc ReadSignature {

    var B1,B2,B3,Signature,Error;
    print("");
    print("   Reading signature bytes...");

    //--------------------------------------------
    // Try read signature for old AVR
    //--------------------------------------------
    Run(ReadSignatureOld);
    B1 = USB;
    B2 = USB;
    B3 = USB;
    //print("   Next signature bytes were readed: %b %b %b",B1,B2,B3);
    Error = B2 & 0xF0;
    if(Error != 0x90)
    {
        B1 = 255;
        B2 = 255;
        B3 = 255;
        // ---------------------------------------
        // Read signature for new AVR
        // ---------------------------------------
        Run(ReadSignature);
        Error = USB;
        if(Error = 0x53)
        {
            B1 = USB;
            B2 = USB;
            B3 = USB;
        }
    }
    print("");
    print("   Next signature bytes were readed: %b %b %b",B1,B2,B3);
    Signature = B1 << 16;
    B2 = B2 << 8;
    Signature = Signature | B2 ;
    B2 = B2 >> 8;
    Signature = Signature | B3;
    Error = 0;
    if(Signature = 0) { Error++; }
    if(Signature = 0x00FFFFFF) { Error++;}
    if(Error != 0)
    {
        print("");
        print("    Error signature detected: %b%b%b",B1,B2,B3);
        return;
    }    
    else
    {
        Error = FindSignature(Signature);
        if(Error = 0)
        {
          print("");  
          print("   Signature detected: %b%b%b, but not found in signature database",B1,B2,B3);
          return;
        }
        else 
        {
            Close(Signature);
        }
    }
}

Proc ModuleInfo {

    print("");
    print("    ***********************************************");
    print("                    AVR detector");
    print("    ***********************************************");
    print("                 Author: ETL (c) 2006");
}



[Device]

define      RESET       POUT.0
define      SCK         POUT.6
define      MISO_OUT    POUT.5
define      MISO        PIN.5
define      MOSI        POUT.4

define      PROG_ENABLE             0b1010110001010011
define      READ_DEVICE_CODE        0b0011000000000000

var Counter,InstructionW,InstructionB,SPIWord,Byte,Echo,InitCounter;

Proc ReadSignature
{
    InitSPI;
    

    if(Echo != 0x53)
    {
        USB = 0xFF;
        return;
    }
    USB = Echo;
    InstructionW = READ_DEVICE_CODE;
    InstructionB = 0;
    InstructionIn;
    USB = SPIWord;
    InstructionB = InstructionB + 0x0100;
    InstructionIn;
    USB = SPIWord;
    InstructionB = InstructionB + 0x0100;
    InstructionIn;
    USB = SPIWord;
    POUT = 0b00100000;
}

// ------------------------------------------------------------
//   read signature sequence for old AVR
// -----------------------------------------------------------
Proc ReadSignatureOld
{
    POUT = 0b00100000;
    BusInit(6,5,4,1,1,1);
    BUSDELAY = 200;
    Delay(50000);
    RESET = 1;
    Delay(50000);
    RESET = 0;
    Delay(21000);

    InstructionW = PROG_ENABLE;
    InstructionB = 0xFFFF;
    InstructionOut;

    InstructionW = READ_DEVICE_CODE;
    InstructionB = 0x00FF;
    InstructionIn;
    USB = SPIWord;
    InstructionB = InstructionB + 0x0100;
    InstructionIn;
    USB = SPIWord;
    InstructionB = InstructionB + 0x0100;
    InstructionIn;
    USB = SPIWord;

}

Proc SendWordToSPI
{
    SCK = 0;
    Counter = SPIWord >> 8;
    BUSDATA = Counter;
    BUSDATA = SPIWord;
}

Proc InitSPI
{
    POUT = 0b00100000;
    Delay(50000);
    RESET = 1;
    Delay(50000);
    RESET = 0;
    Delay(51000);
    BusInit(6,5,4,1,1);
    BUSDELAY = 200;
    InitCounter = 33;
    while
    {
        SPIWord = PROG_ENABLE;SendWordToSPI;

        // check echo
        Echo = BUSDATA;
        BUSDATA = 0xFF;
        if(Echo = 0x53) { break; }
        SCK = 0;
        RESET = 1; 
        Delay(20000);
        RESET = 0;
        InitCounter--;
        if(InitCounter = 0) { break; }
    }
    SCK = 0;
}

Proc InstructionIn
{
    Counter = InstructionW >> 8;
    SCK = 0;
    BUSDATA = Counter;
    BUSDATA = InstructionW;
    Counter = InstructionB >> 8;
    BUSDATA = Counter;
    SCK = 1;
    SPIWord = BUSDATA;
    SCK = 0;
}

Proc InstructionOUT
{
    SPIWord = InstructionW>>8;    
    SCK = 0;
    BUSDATA = SPIWord;
    BUSDATA = InstructionW;
    SPIWord = InstructionB>>8;    
    BUSDATA = SPIWord;
    BUSDATA = InstructionB;
}

