Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

PIC18F452 FLASH Read/Write (BootLoader)
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=512
Страница 1 от 1

Автор:  Predator_MF [ Чет Мар 24, 2005 6:57 pm ]
Заглавие:  PIC18F452 FLASH Read/Write (BootLoader)

Реших да си пренапиша BootLoader-а да работи и с 18-ки...Да, ама много сериозни проблеми...Първо, проблем с четенето на HEX файла. Някой преди време спомена че бил HEX32 (за 18F), всъщост си е HEX8 със много интересни записи за адреси, по-големи от FFFF...Както и да е, там се справих.
По-основния проблем е че програмата ми зацикля на 16% (някъде между 0x930 и 0x950) всеки път, като до там всичко във FLASH-а се пише както трябва, а в един момент решава да спре, PIC-чето съвсем умира. Във Errata има много интересни приказки за Program FLASH Read/Write - трябвало да се изключват всички прекъсвания поотделно преди всяко четене/запис (намразих PIC-овете). Съобразих се и с това, ама г*за...някой да знае решение на тоя проблем?

EDIT:
Да не би да има някаква "критична" при писането във FLASH-а?

Автор:  [ Чет Мар 24, 2005 7:55 pm ]
Заглавие: 

...

Автор:  bateAz [ Чет Мар 24, 2005 11:17 pm ]
Заглавие: 

Провери къде се е заредил BootLoader-а. Да не би на 16% да записваш точно върху него.

Автор:  gnm_soft [ Пет Мар 25, 2005 12:12 am ]
Заглавие: 

Sy6to taka nqma da e nikak zle da se ubedi6 100% w towa 4e ti zawiswa PIC-a (respektiwno hardware) a ne host-a (PC-to ili kakwoto polzwa6 tam ot drugata strana na UART-a)

Автор:  Gogo [ Пет Мар 25, 2005 12:44 am ]
Заглавие: 

Predator_MF dai malko intifa! Na kakuv ezik go pishesh - asm ili C ? Az si napisah edin predi godina i polovina i nemam nikakkav problem - 1320,452, 458, 8520, 8525... E, ima malko razliki pri razli4nite prfesori de. Daje biah varzal edin 458 po RS232 kum PC-to i prez nego po I2C flashvah 452...
Sega kato zapochna da pisha niakoi soft za PIC, purvata mi rabota e da mu kacha bootloadera (vse sushtiya) s niakoi programmer i posle po RS-a. Ne sam koi-znae kakuv programist, ama tova pone sam go probval na niakolko 18-ki i nema problem. Moga da butna edno ramo (mislia).

Sorry za shliokavicata, ama sam v proces na preinstalirane na windowsa.

Автор:  Цецо [ Пет Мар 25, 2005 10:58 am ]
Заглавие: 

Ами аз кат писах моя първия, прекъсванията ми играеха най-големи номера. Забрани ги глобално в момента на записа. Локално май не беше достатъчно. Иначе не виждам логика да спира на 16%. Разбра ли са що ти е да имаш ICD? Щото като спре, щеше да видиш къде точно е спрял и защо.
Иначе аз първо го бях започнал на асемблер, ама после ми писна и го измаах на С. Ама кво ми пука, Флаш има.

Автор:  Predator_MF [ Пет Мар 25, 2005 12:04 pm ]
Заглавие: 

Да бе...ей тука при мене има едно ICD2, за да го закача към процесора трябвало да откача всико от RB5,RB6 и RB7 (FLASH карта, 6 TTL-ки, 40 светодиода и 40 бутона)...как се дебъгва...Както и да е...
Значи BootLoader-а ми е между 0x7D00 и 0x7FFF, пускал съм го без да пише (не изпълнява писане, а само ACK), стига си до 100%. Проблем с писане в EEPROM-а няма, пише се OK, във FLASH-а също се пише, но при достигане на "критичния" адрес, контролера умира...По точно, стига до 0x1C40, затрива следващите 8 думи, но не записва нищо...Пусках и кучето, ама не помогна...Ето ми го най простия BootLoader:
Код:
struct
{byte       DAT_LNG;
byte       buffer[128];
}rx_buffer;
#define CMD rx_buffer.buffer[0]
...
...
#ROM 0x7D00,0x7FFF
void Bootloader()
{int8 i,cnt1,cnt2,cnt3,bltmp1,bltmp2;
int16 wrdata;
int32 fladr;
Disable_Interrupts(GLOBAL);
Disable_Interrupts(INT_RDA);
Disable_Interrupts(INT_RTCC);
Disable_Interrupts(LOW_VOLT);
Disable_Interrupts(INT_TIMER2);
// restart_wdt();
INTCON = 0x00;   // Колкото и тъпо да звучи,
INTCON2 = 0x80; // тия 5 реда помагат с 4-5 %
INTCON3 = 0;
PIE_1 = 0;
PIE_2 = 0;
cnt1  = 0;
cnt2  = 0;
rx_stat = 0;
If (CON_BTLDR == True) // Тия редове ми пращат ID на FIRMWARE-а
{printf("K");putc(0x09);printf("My Recent Device    1.1");}
else printf("RE");
CON_BTLDR = False;
boot_check:
if (!kbhit())  goto poll_boot_end;
  if (!ch1)
   {
   fladr = (int32)getc()<<24;
   ch1 = True;       // Set ID_H reception
   }else
   if (!ch2)
   {fladr+= (int32)getc()<<16;
    ch2 = True;      // Set ID_L reception
   }else
   if (!ch3)
   {fladr+= (int16)getc()<<8;
    ch3 = True;
   }else
   if (!ch4)
   {fladr+= getc();
    ch4 = True;
   }else
   if (!ch5)
   {rx_buffer.DAT_LNG = getc();        // Retrieve Data Length in rx_buffer
   if (rx_buffer.DAT_LNG > 0)
          {ch5 = True;
          bltmp1 = 0;
          bltmp2 = 0;} else rx_stat = 0;   // If Data Length is 0 (ERROR) then reset connection
   }else
   if (!ch6)
       {rx_buffer.buffer[bltmp1] = getc();
      bltmp2 = bltmp2 + rx_buffer.buffer[bltmp1];           // Update checksum
      bltmp1 ++;
      if (bltmp1 > rx_buffer.DAT_LNG ) {
         bltmp2 = bltmp2 - rx_buffer.buffer[bltmp1-1];      // Substract last byte from checksum
         ch6 = True;
         if (bltmp2 == rx_buffer.buffer[bltmp1-1])           // Verify last byte with checksum
         {rx_stat = 0;
          cnt1 = 0;
          cnt2 = 0;
BootSector:
         i = 0;
         if (fladr<0xF00000)
         {//do {erase_program_eeprom(fladr+l);l++;} while (l<rx_buffer.DAT_LNG);
            INTCON = 0x00;   // Аха, много е тъпо...
            INTCON2 = 0x80;
            INTCON3 = 0;
            PIE_1 = 0;
            PIE_2 = 0;
            //SETUP_WDT(WDT_ON);
            write_program_memory(fladr,rx_buffer.buffer,rx_buffer.DAT_LNG);
         }
          else
           do
            {write_eeprom(fladr,rx_buffer.buffer[i]);
             fladr++;
             i=i+2;
             #ASM
             write_wait:
               btfsc   EECON1,1
             goto   write_wait
             #ENDASM
            }
          while (i<rx_buffer.DAT_LNG);
         printf("OK");
         }};
      };

poll_boot_end:
//    restart_wdt();
#use rs232(baud=500000,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,enable=PIN_D0)
#ASM
decfsz cnt1,f
goto   boot_check
decfsz cnt2,f
goto   boot_check
decfsz cnt3,f
goto   boot_check
#ENDASM
reset_cpu();//Restart
}


Пробвах и на по-ниски скорости, проблема не е оттам...Самия протокол за сериината връзка си работи безотказно в няколко процесора...А сега де :wink:

Забележка:
Във "Device Editor>18F452,Errata" съм включил "FFFF (nop) after TBLRD, NOP after GIE=0". Тия двете помагат с още 4-5 процента :?

Автор:  Цецо [ Пет Мар 25, 2005 12:19 pm ]
Заглавие: 

AAAA, уби ме. Подобрявало с 4,5 %. Бе това да не е КПД. Или работи или не.

Нямам време да го прегледам сега, ако не се оправиш, ще го гледам по подробно по-късно.

По принцип темата е интересна. Какъв принцип си избрал - слагаш го в края и пренасочваш ресет вектора или го бухаш в началото. Мен първото ми се струва по нормално, ама е малко по особенно за писане на С. Директно hex файла (като символи) ли му мяташ или го правиш като бинарен отпечатък? За кучето и разните му там други FAULT ресети зимаш ли грижи? А как го активираш?

Автор:  Predator_MF [ Пет Мар 25, 2005 12:34 pm ]
Заглавие: 

Цецо написа:
AAAA, уби ме. Подобрявало с 4,5 %...

Ти не вярваш...трябва да го видиш...като изключа Errata, стига до 16%, като я включа, 54%!!! Протокола за връзката е малко особен, не въртя кръгов буфер защото е RS485, със кабел около 200м и покрай него доста други кабели и машини. Скороста достига до 20KB/s @500Kbps ако някой го интересува, ще го предоставя...
Лоудера се извиква със команда през RS485, (switch (CMD)...), в момента в който се извика, всички прекъсвания спират и в следващите 5 секунди се чака пакет от PC. Пакетите (само за лоудера) са: Offset | Data Length | Data | Checksum (ползвам и 2 байта preamble). При успешно приемане, се сравняват приетата checksum-а и сметнатата, ако съвпадат, командата се изпълнява, ако не съвпадат се чака приемане на нов пакет. PC програмата не зацикля; ако не се отговори на даден пакет, съответния се препраща до получаване на отговор "OK" или до изтичане на даден TIMEOUT. За RESET FAULT съм се погрижил, както обясних и със WDT експериметирах, все тая. Същия код съм го вкарвал и в PIC16F877A, там работи абсолютно безотказно.
PC Bootlader написа:
BAD ANSWER: LINE 430 Offset: 0x00001C40

Автор:  Цецо [ Пет Мар 25, 2005 5:11 pm ]
Заглавие: 

Един малко тъп въпрос, ама как ти е захранването. Да не се ебава по време на записа. Или пък ресета да ти мърда нещо... Абе аз го направих както си пише в
http://ww1.microchip.com/downloads/en/DeviceDoc/39576b.pdf
Код:
unsigned char WriteFlash(unsigned char *UserBuffer, unsigned char AddrH){

   unsigned char i,j;
   unsigned int n;

   Store[0]=TBLPTRU; Store[1]=TBLPTRH;   Store[2]=TBLPTRL; Store[3]=TABLAT;
   TBLPTRU = 0; TBLPTRH = AddrH;

   for (i=0;i<4;i++){
      TBLPTRL = i*64;
      EECON1 = 0b10010100;
      EECON2 = 0x55;
      EECON2 = 0xAA;
      EECON1bits.WR = 1;
   }
   TBLPTRL=0;TBLPTRH = AddrH;
   for(i=0;i<32;i++) {
      for(j=0;j<8;j++) {
         TABLAT=UserBuffer[i*8+j];
         _asm TBLWTPOSTINC _endasm
      }
      _asm TBLRDPOSTDEC _endasm
      EECON1 = 0b10000100;
      EECON2 = 0x55;
      EECON2 = 0xAA;
      EECON1bits.WR = 1;
      Nop();
      _asm TBLRDPOSTINC _endasm         
   }
   EECON1=0;

   TBLPTRL=0;TBLPTRH = AddrH;
   for(n=0;n<256;n++) {
      _asm TBLRDPOSTINC _endasm
      if(TABLAT != UserBuffer[n]) {
         TBLPTRU = Store[0]; TBLPTRH = Store[1];   TBLPTRL = Store[2]; TABLAT = Store[3];
         return FLASH_WRITE_ERROR;
      }
   }   
   TBLPTRU=Store[0]; TBLPTRH=Store[1];   TBLPTRL=Store[2]; TABLAT=Store[3];
   return 0;
}


ей така го правя аз. Преди това имам

Код:
INTCON=0;INTCON3=0;PIE1=0;PIE2=0;


И работи. [/code]

Автор:  Predator_MF [ Пет Мар 25, 2005 5:26 pm ]
Заглавие: 

Евентуалния проблем се появява, когато лоудера стигне до
Код:
#use RS232...
...Много тъпо звучи, ама някой има ли идея как да поставя #use RS232, където аз поискам?

Автор:  Predator_MF [ Съб Мар 26, 2005 5:13 pm ]
Заглавие: 

Ето го решението на проблема:
http://www.ccsinfo.com/forum/viewtopic.php?p=41906#41906...АБЕ КОЙ ДА СЕ СЕТИ ДА НАПИШЕ В Help-a

Автор:  [ Съб Мар 26, 2005 6:31 pm ]
Заглавие: 

...

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/