[Description]

Info = " Автор модуля: fomalex@tut.by";
Buffer1 = "FLASH",65536;
UART = 1;
Voltage = 5.0;

[Menu]

InitBoot = "&Инициализация загрузчика",ModuleInfoButton,"Инициализация загрузчика";
d1 = "-";
Write = "&Загрузить",WriteButton,"Загрузить прошивку";
Read = "&Прочитать FLASH",ReadButton,"Прочитать FLASH";
d2 = "-";
GetLock = "Прочитать &биты защиты",ChipInfoButton,"Прочитать биты защиты";
EraseLock = "Очистить биты защиты",EraseButton,"Очистить биты защиты";

[Interface]

ComboBox(Speed,"Скорость",10,10,90,"4800","9600","19200","19200",2);
CheckBox(TwoLine,"RX и TX раздельно",180,10,1);

[Host]

define FLASH_SIZE  65536
define FLASH_BEGIN 0x00100000

Proc Write {
    
    var Error,Address,EndAddress,Temp;
    PBPos = 0;
    Address = 65535;
    // определяем количество байт, которое нужно будет запрограммировать
    while
    {
        if(Address = 0) { break; }
        Temp = FBUF[Address];
        if(Temp != 255) { break; }
        Address--;
    }
    if(Address < 0x300)
    {
        print("");
        print(" Пустой буфер!");
        return;
    }

    //EndAddress = Address - 0x400;
    EndAddress = Address / 128;
    EndAddress++;
    PBMax = EndAddress - 8;
    EndAddress = EndAddress * 128;

    print("   Будет программироваться %i байт",EndAddress);

    Address = 0x400;
    while 
    {
        Error = WritePage(Address);
        if(Error != 'O')
        {
            print("");
            print("   Ошибка записи. Адрес %i. Код ошибки %i (%c)",Address,Error,Error);
            break;
        }
        else { print("\; OK."); }
        Address = Address + 128;
        PBPos++;
        if(Address = EndAddress) { break; }
    }
    if(Error = 'O')
    {
        if(ForceCloseAfterWrite != 0) { return(0x7FFFFFFF);}
        print("");
        print("   Запись завершена.");
    }
}

Proc InitBoot
{
    var Value,State;
    if(Speed = 0) {
        print("  Скорость 4800");
        SetupUART(4800,8,0,0);
    }
    if(Speed = 1) {
        print("  Скорость 9600");
        SetupUART(9600,8,0,0);
    }
    if(Speed = 2) {
        print("  Скорость 19200");
        SetupUART(19200,8,0,0);
    }
    if(Speed = 3) {
        print("  Скорость 28800");
        SetupUART(28800,8,0,0);
    }
    DTR = 1; RTS = 1;
    while
    {
        Value = UART;
        if(Value = 0x8000) { break;}
    }
    print("   Включите аппарат... ");
    State = 0;
    while
    {
        Value = UART;
        if(Value != 0x8000)
        {
            if(Value > 31) { print("\;%c",Value); }
            if(State = 9)
            {
                if(Value = 10) { State = 10; }
                else           { State = 0; }
            }
            if(State = 8)
            {
                if(Value = 13) { State = 9; }
                else           { State = 0; }
            }
            if(State = 7)
            {
                if(Value = '.') { State = 8; }
                else            { State = 0; }
            }
            if(State = 6)
            {
                if(Value = '.') { State = 7; }
                else            { State = 0; }
            }
            if(State = 5)
            {
                if(Value = '.') { State = 6; }
                else            { State = 0; }
            }
            if(State = 4)
            {
                if(Value = 'y') { State = 5; }
                else            { State = 0; }
            }
            if(State = 3)
            {
                if(Value = 'd') { State = 4; }
                else            { State = 0; }
            }
            if(State = 2)
            {
                if(Value = 'a') { State = 3; }
                else            { State = 0; }
            }
            if(State = 1)
            {
                if(Value = 'e') { State = 2; }
                else            { State = 0; }
            }
            if(State = 0)
            {
                if(Value = 'R') { State = 10; }
                else            { State = 0; }
            }
        }
        else
        {
            State = 0;
        }
        if(State = 10)
        {
            print("   Аппарат найден...");
            UART = 'B';
            if(TwoLine = 0) { Value = UART; }
            Value = UART;
            if(Value = 'b')
            {
                print("   Загрузчик активирован...");
                return(0x7FFFFFFF);
            }
            else {State = 0;}
        }
    }
}

Proc WritePage(Address)
{
    var PageAddress,Temp,Value;
    // отправляем номер страницы
    UART = 'W';
    if(TwoLine = 0) { Temp = UART; }
    PageAddress = Address | FLASH_BEGIN;
    TxDWORD(PageAddress);
    Value = RXDword();
    print("   Страница: %d",Value);
    Temp = 32;
    while(Temp != 0)
    {
        Address = Address + 3;
        Value = FBUF[Address];
        UART = Value;
    if(TwoLine = 0) { Temp = UART; }
        //Value = UART;
        Address--;
        Value = FBUF[Address];
        UART = Value;
    if(TwoLine = 0) { Temp = UART; }
        //Value = UART;
        Address--;
        Value = FBUF[Address];
        UART = Value;
    if(TwoLine = 0) { Temp = UART; }
        //Value = UART;
        Address--;
        Value = FBUF[Address];
        UART = Value;
    if(TwoLine = 0) { Temp = UART; }
        //Value = UART;
        Address = Address + 4;
        Temp--;      
    }
    //Value = RXDword();
    //print("   Команда: %d",Value);
    Temp = UART;
    return(Temp);
}


Proc Read
{
    var Address;
    print("  Чтение FLASH");
    PBMax = 16384 / 128;
    PBPos = 0;
    Address = 0;
    while
    {
        //print("Адрес: %i",Address);
        ReadPage(Address);
        PBPos++;
        Address = Address + 128;
        if(Address > 16384) { break; }    
    }
    return(0x7FFFFFFF);
}

Proc ReadPage(Address)
{
    var Temp,PageAddress,Value;
    UART = 'R';
    if(TwoLine = 0) {  Temp = UART;  }
    PageAddress = Address | FLASH_BEGIN;
    //print("PageAddress: %d",PageAddress);
    TxDWORD(PageAddress);
    //Value = RXDword();
    //print("\; Возврат адреса: %d",Value);
    Temp = 32;
    while(Temp != 0)
    {
        Address = Address + 3;
        Value = UART;
        FBUF[Address] = Value;
        Address--;
        Value = UART;
        FBUF[Address] = Value;
        Address--;
        Value = UART;
        FBUF[Address] = Value;
        Address--;
        Value = UART;
        FBUF[Address] = Value;
        Address = Address + 4;
        Temp--;    
    }
}

Proc TxDword(Value)
{
    var Temp;

    Temp = Value >> 24;
    UART = Temp; 
    if(TwoLine = 0) { Temp = UART; }
    Temp = Value >> 16;
    UART = Temp;
    if(TwoLine = 0) { Temp = UART; }
    Temp = Value >> 8;
    UART = Temp;
    if(TwoLine = 0) { Temp = UART; }
    Temp = Value & 255;
    UART = Temp;
    if(TwoLine = 0) { Temp = UART; }
}

Proc RXDword
{
    var Value,Temp;
    Value = UART;
    Value = Value << 8;
    Temp = UART;
    Value = Value | Temp;
    Value = Value << 8;
    Temp = UART;
    Value = Value | Temp;
    Value = Value << 8;
    Temp = UART;
    Value = Value | Temp;
    return(Value);
}

Proc GetLock
{
    var Value;
    print("   Чтение битов защиты...");
    UART = 'L';
    if(TwoLine = 0) { Value = UART; }
    Value = RXDword();
    print("   Значение битов защиты: %d",Value);
}

Proc EraseLock
{
    var Address,Value;
    print("   Сброс битов защиты...");
    Address = 0;
    PBMax = 16;
    PBPos = 0;
    while(Address != 16)
    {
        UART = 'U';
        if(TwoLine = 0) { Value = UART; }
        UART = Address;
        if(TwoLine = 0) { Value = UART; }
        Value = RXDword();
        print("%d",Value);
        Value = UART;
        if(Value != 'O')
        {
            print("   Ошибка!");
            return;
        }   
        PBPos++;
        Address++;
    }
    GetLock();
}

