[LÖST]Flasha nya PIC-18?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6931
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

[LÖST]Flasha nya PIC-18?

Inlägg av Marta »

Har aldrig förr haft pronlem med att flasha någon PIC med min hembyggda enhet, men 18F46K42 tvärvägrar.

Känner någon till om det finns fel i programmeringsdatabladet eller något speciellt som kan ställa till det?

Någon som har en fungerande enhet och en logikanalysator och kan läsa av vad som verkligen skickas?
Senast redigerad av Marta 29 november 2018, 07:56:09, redigerad totalt 1 gång.
Användarvisningsbild
Klas-Kenny
Inlägg: 11328
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Flasha nya PIC-18?

Inlägg av Klas-Kenny »

Vet inte just den processorn, men har sett egenheter med att skriva konfigurationsbitar på nya modeller.
Inklusive någon bugg, som lösts ut först efter att ha kört logikanalysator på original debugger..
Då på PIC16 förvisso.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6931
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Flasha nya PIC-18?

Inlägg av Marta »

Du menar alltså att det finns tidigare exempel på felaktig dokumentatation och som inte rättats?

De tidigare pic18 använde tblwrt på något sätt för att flasha dem. Adressen ställdes in genom att injicera instruktioner for load immediate och sedan spara i olika sfr.

Hela detta härke är borta på de nya. Nu finns där kommandon i samma stil som på pic10/12/16. Även ett adresskommando som är nytt. Datadelen har längts till 24 bits och allt shiftas ut med vänstershift msb först. Förr var det åt andra hållet.

Det kan ju lätt ha blivit något fel i beskrivningen när allt är rykande färskt. Har ingen analysator och det är väl ingen chans att kunna få t.ex. pickit3 att repetera samma sekvens med sådan fart att scope med fördröjd tidbas räcker...

Hade vari mycket tacksam om någon hade kunnat göra ett förök att läsa av en verifierat fungerande enhet.

Här är en länk till dokumentationen:

http://ww1.microchip.com/downloads/en/D ... 01886B.pdf
Användarvisningsbild
Klas-Kenny
Inlägg: 11328
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Flasha nya PIC-18?

Inlägg av Klas-Kenny »

Ja, detta ser ut som väldigt likt den algoritm som gällde den processor där jag hade problem.

Kan kolla källkod på jobbet imorgon, se om jag kan se vad det var exakt.
Har för mig att det var något kommando som skulle köras innan man kunde skriva config, kan ha varit en extra row erase på just config-minnet men minns inte säkert, var något år sen.
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Flasha nya PIC-18?

Inlägg av lillahuset »

Vi använde PIC16F877 i ett projekt när den var helt ny. Tusentals i en anläggning.
Det gick inte att programmera om dem. Efter ett tag får vi besked från Microchip att enda workaround de kände till var att sänka matningen till 3V. Det var bara att göra omkonstruktion och byta till Atmel.

Fråga Microchip. Jag tror ju inte det är det felet eller liknande men man vet ju aldrig.
Användarvisningsbild
Klas-Kenny
Inlägg: 11328
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Flasha nya PIC-18?

Inlägg av Klas-Kenny »

Minnet var inte helt ute och cyklade, det var just en extra Row Erase som löste ut problemet.

Körde Bulk Erase på hela minnet först i programmeringen, men just config gick inte att skriva efter det. Utan var tvungen att sätta PC till 0x8000 där konfigurationsorden börjar på den processorn, och köra Row Erase.
Finns inget om detta i manualen, står inget annat än att det ska räcka med Bulk Erase.
Jag antar att du verifierat att device-id kan läsas ut, så att processorn verkligen kommit in i icsp-mode.

Processorn i fråga då var PIC16F15354, men dess programmeringsspecifikation är väldigt lik.
http://ww1.microchip.com/downloads/en/D ... 01838C.pdf

Prova det vettja. :)



Om det är till någon nytta, här är mitt högsta lager kod som parse'ar HEX-fil och programmerar processorn. Innan den koden körs så görs såklart vad som behövs för att sätta processorn i icsp-mode, samt en bulk erase körs.
PC-program skrivet i C#, sen pratar det USB med programmeraren.
Kanske värt att läsa kommentarerna i alla fall, om det kan vara något specifikt där som du missat.

Kod: Markera allt

        public bool doProg()
        {

            if (File.Exists(hexPath))
            {
                using (StreamReader sr = File.OpenText(hexPath))
                {
                    string thisLine = "";

                    byte addressRemainder = 0;

                    bool firstWrite = true;

                    byte[] PicData = new byte[63];
                    int CurrentPicDataPos = 0;
                    int lastAddr = 0;
                    int ContiniousBytesCount = 0;
                    int CurrentPc = 0;

                    while ((thisLine = sr.ReadLine() ) != null)
                    {
                        if(thisLine.StartsWith(":")) {
                            
                            thisLine = thisLine.TrimStart(':');
                            
                            byte[] thisLineBin = StringToByteArray(thisLine);
                            
                            // We now have one line from hex file, in binary format.

                            // First byte in line is number of data bytes in line
                            byte len = thisLineBin[0];

                            // Address is contaied in two bytes, with possible a third byte set in previous line (should be contained in addressRemainder)
                            int addr = ((addressRemainder << 16) & 0xff0000) | ((thisLineBin[1] << 8) & 0xff00) | ((thisLineBin[2]) & 0xff);

                            addr /= 2;              // Addresses in hex file are double what they are in PIC due to PIC addressing words (2B), not single bytes.
                            addressRemainder = 0;

                            


                            if (thisLineBin[3] == 0)  // Program Data
                            {
                                

                                if (((lastAddr + (len / 2)) != addr))   // Address jump in hex file...
                                {
                                    if (!firstWrite)
                                    {
                                        if (!Usb.WritePicPackage(PicData))
                                            return false;
                                        if (!Usb.BeginPicProg())
                                            return false;
                                        CurrentPicDataPos = 0;
                                        ContiniousBytesCount = 0;

                                    }

                                    if (!Usb.PicSetPc(addr))     // This must be new address, set PC to it.
                                        return false;
                                    
                                    CurrentPc = addr;
                                }

                                firstWrite = false;

                                
                                lastAddr = addr;

                                if (addr < PROGRAM_MEMORY_SIZE)
                                {
                                    if (CurrentPicDataPos == 0)
                                    {
                                        PicData[0] = 0;
                                        CurrentPicDataPos = 1;

                                    }
                                    else
                                    {
                                        //PicData[0] += len;  // Increase packet length with what is about to be added
                                    }

                                    for (int i = 0; i < len; i+=2)
                                    {
                                        PicData[CurrentPicDataPos] = thisLineBin[i + 4];
                                        CurrentPicDataPos++;
                                        PicData[CurrentPicDataPos] = thisLineBin[i + 5];
                                        CurrentPicDataPos++;
                                        
                                        PicData[0] += 2;

                                        CurrentPc++;
                                        ContiniousBytesCount++;
                                        
                                        if ((CurrentPc % 32) == 0)  // New row, write the old one by sending PicData, begin program and reset counters..
                                        {
                                            if (!Usb.WritePicPackage(PicData))
                                                return false;

                                            if (!Usb.PicSetPc(CurrentPc - 1))
                                                return false;
                                            if (!Usb.BeginPicProg())
                                                return false;
                                            if (!Usb.PicSetPc(CurrentPc))
                                                return false;
                                            PicData[0] = 0;
                                            CurrentPicDataPos = 1;

                                            ContiniousBytesCount = 0;

                                        }
                                        if (CurrentPicDataPos > (PicData.Length - 1))   // PicData full, write it and reset counters
                                        {
                                            if (!Usb.WritePicPackage(PicData))
                                                return false;
                                            PicData[0] = 0;
                                            CurrentPicDataPos = 1;

                                            ContiniousBytesCount = 0;
                                        }
                                    }

                                    
                                    
                                }
                                else if(addr >= CONFIG_MEMORY_START && addr < CONFIG_MEMORY_END)     // Config data. 
                                {
                                    form.WriteInfo("Writing Config...");
                                    for (int i = 0; i < PicData.Length; i++)
                                        PicData[i] = 0;

                                    PicData[0] = 2;

                                    CurrentPc = CONFIG_MEMORY_START;
                                    if (!Usb.PicSetPc(CurrentPc))
                                        return false;

                                    if (!Usb.ErasePicRow())     // Config data requires an extra row erase for some reason
                                        return false;

                                    CurrentPc = addr;
                                    if (!Usb.PicSetPc(CurrentPc))
                                        return false;

                                    int j = 0;
                                    while (CurrentPc < CONFIG_MEMORY_END)
                                    {
                                        
                                        PicData[1] = thisLineBin[j + 4];
                                        PicData[2] = thisLineBin[j + 5];
                                        if (!Usb.WritePicConfPackage(PicData))
                                            return false;
                                        if (!Usb.BeginPicProg())
                                            return false;

                                        Thread.Sleep(3);    // Config data takes a little longer to program...
                                        j += 2;
                                        CurrentPc++;
                                        if (CurrentPc < CONFIG_MEMORY_END)
                                            if (!Usb.IncreasePicPc())
                                                return false;
                                    }

                                    CurrentPicDataPos = 0;
                                    ContiniousBytesCount = 0;
                                }
                                
                            }
                            else if (thisLineBin[3] == 4) // Setting high part of PC
                            {
                                addressRemainder = thisLineBin[5];
                            }

                        }


                                                   
                        
                    }

                    sr.Close();
                
                }
            }
            else
            {
                MessageBox.Show("PIC Hex file not found...");
                return false;
            }

            return true;
        }
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6931
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Flasha nya PIC-18?

Inlägg av Marta »

Tackar för engagemanget.

När det gäller switch till programmeringsläge så utgår jag från att detta funkar. Använder HVP 8.5V och stigtiden är väl under 1us som är specat som max.

Däremot går det inte att läsa ut något som helst. Varken device id eller device information. PGD ligger kvar som ingång/tristate hela tiden. Har verifierat kommandona med scope och allt ser rätt ut.

Har haft egendomligheter förr med hårdvaran. Det behövdes ett motstånd i serie med PGD för att överhörning inte skulle rycka i PGC och få märkliga saker att hända. Har provat det här, men utan resultat. Skall koppla upp den med kortast möjliga trådar lödda direkt på kretsen och se om det gör skillnad. Förutsatt jag klarar det med stenhanden...

Din kod ser ut att använda något färdigt som utför den kritiska delen och viftar med PGC/PGD. Det är där jag är orolig att något är trasigt i mitt program.

Hur som helst verkar Din enhet ta kommandon på så pass låg nivå att det borde vara möjligt att repetera samma så snabbt att det kan ses på ett analogt scope. Är det en PicKit? I värsta fall får jag skaffa en sådan och sälja igen när den avlockats sina hemligheter.
Användarvisningsbild
Klas-Kenny
Inlägg: 11328
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Flasha nya PIC-18?

Inlägg av Klas-Kenny »

Å nä, här är inget färdigt. :)
Bara att den koden ligger ute i den PIC32 som utför programmeringen, och inte i PC-programmet. Men antog att det var mer övergripande metod du ville ha, för att se om det var något särskilt du missat.
Men svarar den inte alls är det ju såklart någonting annat.

Nu minns jag inte exakt (har inget schema, min utrustning är byggd på veroboard och används i produktion, har ingen lust att hämta den och skruva upp), men jag vill minnas att jag har typ 100ohm eller så i serie med dataledningarna. Inte för att det inte fungerade utan, utan bara ett litet lager skydd.

Nu använder jag inte högspänning utan LVP, så just att sätta processorn i icsp-mode kan jag inte säga så mycket om för din del. Men här kommer lite av lågnivåfunktionerna jag skrivit och använder:

Kod: Markera allt

#define ISP_CLK_TRIS        TRISDbits.TRISD1
#define ISP_CLK_LAT         LATDbits.LATD1

/*
 * Note: Isp Data pin is also hard coded in function Isp_Read_Byte() in PicIsp.c
 * Change there also, if pin is changed.
 */
#define ISP_DAT_TRIS        TRISDbits.TRISD2
#define ISP_DAT_LAT         LATDbits.LATD2
#define ISP_DAT_PORTBIT     PORTDbits.RD2
    
#define ISP_RST_TRIS        TRISDbits.TRISD3
#define ISP_RST_LAT         LATDbits.LATD3  

void Isp_Clockout() {
    ISP_CLK_LAT = 1;
    Nop();
    Nop();
    Nop();
    Nop();
    ISP_CLK_LAT = 0;
    
}


void Isp_Send_Byte(uint8_t data) {
    int i;
    for(i = 7; i>= 0; i--) {
        if(ISP_DAT_PORTBIT != (data >> i) & 0x01)
            ISP_DAT_LAT = (data >> i) & 0x01;
        else {
            Nop();
            Nop();
            Nop();
        }
        Isp_Clockout();
    }
    ISP_DAT_LAT = 0;
}


// Data pin has to be set to input before using this function
uint8_t Isp_Read_Byte() {
    int i;
    uint8_t data = 0;
    uint8_t PortdData = 0;
    for(i = 7; i>=0; i--) {
                       
        LATDbits.LATD1 = 1;
        
        Nop();          // Wait for data valid..
        Nop();
        Nop();
        Nop();
        Nop();
        Nop();
        Nop();
        Nop();
        Nop();
        Nop();
        Nop();
        Nop();
        
        PortdData = PORTD;
        LATDbits.LATD1 = 0;
        
        data = data | (((PortdData & 0x04) >> 2) << i);     // Read RD2 and shift into correct bit location in byte
        
    }
    i=0;
    return data;
}

void Tdly() {
    BSP_DelayUs(1); //Tdly
}

void Enter_Pic_ISP() {
    
    LATDbits.LATD1 = 0;
    LATDbits.LATD2 = 0;
    
    ISP_DAT_TRIS = 0;
    ISP_CLK_TRIS = 0;
    
    Isp_Send_Byte('M');
    Isp_Send_Byte('C');
    Isp_Send_Byte('H');
    Isp_Send_Byte('P');
}

void Isp_Load_Pc(uint16_t addr) {
    
    Isp_Send_Byte(0x80);
    
    Tdly();
    
    Isp_Send_Byte((addr >> 15) & 0x01);
    Isp_Send_Byte((addr >> 7) & 0xff);
    Isp_Send_Byte((addr << 1) & 0xfe);
    
}

void Isp_Bulk_Erase() {
    
    Isp_Load_Pc(0x8000);    // Set PC to address 8000 to erase all.
    Isp_Send_Byte(0x18);
    
}

void Isp_Load_Nv(uint16_t data) {
    
    Isp_Send_Byte(0x02);    // Increase PC after write...
    Tdly();
    
    Isp_Send_Byte(0x00);
    Isp_Send_Byte((data >> 7) & 0xff);
    Isp_Send_Byte((data << 1) & 0xfe);
    
    
}

void Isp_Load_Nv_Multi(uint8_t len, uint8_t* data) {
        
    int i;
    uint16_t nvData;
    for(i=0; i<len; i+=2) {
        nvData = ((data[i+1] << 8 ) & 0xff00) | ((data[i] ) & 0xff);
        Isp_Load_Nv(nvData);
        Tdly();
    }
}

void Isp_Load_Nv_NoIncrease(uint16_t data) {
    
    Isp_Send_Byte(0x00);    // Don't increase PC after write...
    Tdly();
    
    Isp_Send_Byte(0x00);
    Isp_Send_Byte((data >> 7) & 0xff);
    Isp_Send_Byte((data << 1) & 0xfe);
    
}

void Isp_Load_Nv_Multi_NoIncrease(uint8_t len, uint8_t* data) {
        
    int i;
    uint16_t nvData;
    for(i=0; i<len; i+=2) {
        nvData = ((data[i+1] << 8 ) & 0xff00) | ((data[i] ) & 0xff);
        Isp_Load_Nv_NoIncrease(nvData);
        Tdly();
    }
}

void Isp_Begin_Prog() {
     
    Isp_Send_Byte(0xe0);    // Begin Internally Timed Programming
    
    
}

void Isp_Inc_Pc() {
     
    Isp_Send_Byte(0xf8);    // Increment PC
}

void Isp_Erase_Row() {
    
    Isp_Send_Byte(0xF0);
    
}


// Note: If this function is used to read EEPROM, some returned bits has to be masked off.

int16_t Isp_Read_Nv(uint8_t incPc) {
    
    if(incPc)
        Isp_Send_Byte(0xfe);
    else
        Isp_Send_Byte(0xfc);
    
    ISP_DAT_TRIS = 1;       // Set data pin to input for reading
    Tdly();
    
    Isp_Read_Byte();        // Dummy read, wont contain data
    uint8_t data1 = Isp_Read_Byte();
    uint8_t data0 = Isp_Read_Byte();
    
    uint16_t returnData = ((data1 & 0x7f) << 7) | ((data0 & 0xfe) >> 1);
    
    ISP_DAT_TRIS = 0;       // restore data pin to output for future writing..
    
    return returnData;
    
}
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6931
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Flasha nya PIC-18?

Inlägg av Marta »

Tack för koden.

Ser en sak Du har annorlunda, PGD sätts alltid till noll efter att en byte har sänts. Dessutom kommer detta att ske två gånger mitt i när en 24-bit sekvens skickas.

Den skickar också i en rasande fart om nu Nop() är just en maskinkods-NOP. Men där är i varje fall inte satt ut någon maxtid annat än 1us stigtid på Vpp.

Först blev jag helt vimmelkantig av Din mottagningsrutin, den klipper ju de två översta bitsen, men det är ju för PIC16...
Skall skriva om min kod och rensa den från allt kladd som blivit nu under experimenterandet.

Min enhet använder en 16F1454 och har koden i assembler. Väl så enkelt till sådant här.
Användarvisningsbild
Klas-Kenny
Inlägg: 11328
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Flasha nya PIC-18?

Inlägg av Klas-Kenny »

Mycket riktigt skickar den i en rasande fart, hela proceduren tar någon sekund och då är USB-kommunikationens latenstid (raw HID, förhållandevis långsamt) den största begränsningen. :)
Hade betydligt långsammare under utveckling, sen snabbade jag upp så mycket jag kunde utan att tappa stabilitet då allt fungerade, sekunder räknas ju då den går i en produktionsmiljö.

Hoppas att det var till någon hjälp och att du får fart på det.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6931
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Flasha nya PIC-18?

Inlägg av Marta »

Just nu har det gått troll i allting. Är ganska säker på att det är hårdvarurelaterade problem. Kommer att ta en stund att lösa. Som invalid gör jag allt mellan 10 och 100 gånger långsammare än förr innan stenhanden drabbade mig.

Ett exempel. Adresserar 0x000000 och läser sedan en sträng med ff 01 ff som rådata ut från PIC, men bara om där är pull-up på PGD. Utan läses nollor. Observera att nollorna kommer mitt i, så det är inte en kapacitans som laddas upp på ingången. Det kommer sannolikt från PIC. Sker med såväl HVP som LVP aktiv, men inte när den är i reset. Vid LVP är enda skilladen att MCHP har skickats. Skopet visar rena pulser med en testrutin för detta. Aktuell data omöjlig att se på ett analogt scope.
Ren magi? Eller... Fortsättning följer.

Tillägg: Den andra byten innehåller vad som förväntas i den tredje. Det är som att den är i otakt. Kommandot för att läsa är 0xfe. Kanske även 0xff läser. Det skulle förklara pull-upens inverkan och de tappade 8 klockorna. Kommandot skickas aldrig och första byten i läsningen blir kommando. Milde vilde vad jag har virrat till det. Är nog för gammal nu...
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6931
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Flasha nya PIC-18?

Inlägg av Marta »

De magiska dimmorna har skingrats!

Är helt klart för gammal och för nollställd i skallen numera. Rutinen som skickar adressen till PIC skickade bara data. Hade utelämnat det inledande kommandot som skall vara där... Därmed kom program och PIC i otakt och adresserna blev till icke dokumenterade kommandon..

Ber Er alla och Klas-Kenny i synnerhet om ursäkt för denna senila röra.
Användarvisningsbild
Icecap
Inlägg: 26139
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: [LÖST]Flasha nya PIC-18?

Inlägg av Icecap »

Det är knappast något att ursäkta för. Vissa andra medlemmar i detta forum hade knappast än förstådd grejen ATT programmera via egna system.

Själv är jag nyfiken på vilken hårdvara & mjukvara du använder, är det ett hemmabrygg eller hur?
Användarvisningsbild
rvl
Inlägg: 5782
Blev medlem: 5 april 2016, 14:58:53
Ort: Helsingfors

Re: [LÖST]Flasha nya PIC-18?

Inlägg av rvl »

Huvudsaken är att det löste sig! Ibland är det svårt att se uppenbara problem i sin egen kod, speciellt om det är andra parter inblandade som kan vara förklaringen. Ofta räcker det redan att formulera det upplevda problemet, för att själv se lösningen.

ps. Invaliden, du kanske kan hjälpa Marta på Microchipforumet.
Användarvisningsbild
säter
Inlägg: 32547
Blev medlem: 22 februari 2009, 21:16:35
Ort: Säter

Re: [LÖST]Flasha nya PIC-18?

Inlägg av säter »

Invaliden, du kanske kan hjälpa Marta på Microchipforumet
Hur tänkte du här? :)
Skriv svar