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

PIC флаш запис проблем
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=2247
Страница 1 от 2

Автор:  backson [ Чет Апр 20, 2006 10:06 am ]
Заглавие:  PIC флаш запис проблем

Ползвам функцията

rom void * memcpyram2pgm(rom void * dest, const void * src, sizeram_t memsize ),

която копира известен брой байтове от RAM във Flash, но нещо не се получава т.е. функцията като код се изпълнява но непроменя FLASH паметта на съответния адрес или не копира нищо. Аз попринцип съм извършвал запис във FLASH, но на асемблер. FLASHa ми е отключен, проверих конфиг битовете. Използвам MCC18 и PIC18f452.

Автор:  Цецо [ Чет Апр 20, 2006 10:24 am ]
Заглавие: 

Веднъж имах проблеми със ICD то във такава ситуация. Без ICD-то програмирането си работеше. Но беше отдавна и не помня точно каква беше ситуацията.

Автор:  backson [ Чет Апр 20, 2006 10:26 am ]
Заглавие: 

Мен ICD2 ми е постоянно включено ще пробвам да го извадя

Автор:  Цецо [ Чет Апр 20, 2006 10:31 am ]
Заглавие: 

А и аз на готовите функции немам много вяра. Специално пък за тая работа съвсем. Пиша си я сам.

А и сега се сещам че имаше ядове некакви със прекъсванията. При запис във флеша трябва да са забранени. Ама незнам защо ме гложди спомена, че не беше достатъчно да се спрат глобално, ами имаше нужда и локално да ги спра. Но това са някакви бледи спомени, не ги приемай като чиста монета.

Автор:  backson [ Чет Апр 20, 2006 10:34 am ]
Заглавие: 

не ми се ще да осирам Си кода с асмеблерски изпълнения. Искам да забравя асемблера...

Автор:  Цецо [ Чет Апр 20, 2006 10:37 am ]
Заглавие: 

Асемблера не се забравя, то си е болест доживотна.

Но специално за случая можеш да си го напишеш на С. Не ти трябва асемблер.

Код:
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;
}


Това е от един мой бутлоадер. Но го няма трика с прекъсванията защото по принцип всичко е спряно. Но си спомням добре, че в друг проект имах проблем баш с прекъсванията. Нещо имаше но не помня точно какво. И май имаше ерата по въпроса.

Автор:  backson [ Чет Апр 20, 2006 10:40 am ]
Заглавие: 

Ами разрови се ако имаш възможност щото ми е спешно и се въртя тука :(

Автор:  Цецо [ Чет Апр 20, 2006 10:43 am ]
Заглавие: 

Имаме проблем със синхронизацията. Постнах кода в горния пост.

Автор:  backson [ Чет Апр 20, 2006 11:00 am ]
Заглавие: 

Ми то в ератата си пише - при 252 и 452 процесорите самозаписа във Флаш нестава както е описано. Трябва да се презарежда ръчно TABLATa . Паметта била разделена на два дискретни блока и адресирането не ставало всеки път. Аз знам копелетата защо са го напревили щот първо пуснаха 242 и 442 процесори, а после 452 с двойно повече флаш ма не са си оправили адресирането... Там пише също ако срещнете проблема ползвайте процесор от по-новата фамилия - 4520 :)

Автор:  Predator_MF [ Чет Апр 20, 2006 2:14 pm ]
Заглавие: 

Абе на 452 проблема му се появява като вдигнеш секюрити на кой да е блок от паметта, иначе проблем с bootloader-а не видях, два такива чипа имам и двата се пишат безпогрешно
Код:
#define VERSION 0x3130     //
#define VERSION_WORD 0x7B8F
#ROM VERSION_WORD = {VERSION}
//#########################################
#byte rINTCON  = 0x0FF2
#byte rINTCON2 = 0x0FF1
#byte rINTCON3 = 0x0FF0
#byte rPIE_1    = 0x0F9D
#byte rPIE_2    = 0x0FA0
#bit  rWRERR    = 0x0FA6.3
//#byte PIR1     = 0x0F9E
//#byte RCSTA    = 0x0FAB
#byte rTXREG    = 0x0FAD
#byte rTXSTA    = 0x0FAC
#bit  rTXEN     = 0xFAC.5
#bit  rTXIF     = 0x0F9E.4
#bit  rTRMT     = 0x0FAC.1     // Transmit Buffer Emty (1 = Emty)
//#bit  RCIF     = 0x0F9E.5
#bit  rCOM_EN   = 0xF8C.0      // RS485 Enable/Diable
#bit  rUART_EN  = 0x0FAB.7     // SPEN (Serial Port Enable)
#bit  rSYNC    = 0xFAC.4


#ORG 0x7B90,0x7FFF AUTO=0 DEFAULT
void Bootloader()
{#use rs232(baud=691200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,enable=PIN_D5)
int8 i,cnt1,cnt2,cnt3,bltmp1,bltmp2,version_h,version_l;
int16 wrdata;
int32 fladr;
rINTCON = 0x00;
rINTCON2 = 0x80;
rINTCON3 = 0;
rPIE_1 = 0;
rPIE_2 = 0;
cnt1  = 0;
cnt2  = 0;
rx_stat = 0;
If (CON_BTLDR == True)
{version_h = (int8)(read_program_eeprom(VERSION_WORD)>>8);
  version_l = read_program_eeprom(VERSION_WORD);
printf("K");putc(0x09);printf("My Device Bootloader %C.%C",version_h,version_l);}
else break;
CON_BTLDR = False;
boot_check:
if (!kbhit())  goto poll_boot_end;
  if (!ch1)
   {
   fladr = (int32)getc()<<24;
   ch1 = True;       // Most significant 8 bits <31:24>
   }else
   if (!ch2)
   {fladr+= (int32)getc()<<16;
    ch2 = True;      // Next 8 bits  <23:16>
   }else
   if (!ch3)
   {fladr+= (int16)getc()<<8;
    ch3 = True;      // <15:8>
   }else
   if (!ch4)
   {fladr+= getc();
    ch4 = True;      // <7:0>
   }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;goto boot_end;}   // If Data Length is 0 (ERROR) then reset
   }else
   if (!ch6)
       {rx_buffer.buffer[bltmp1] = getc();
      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;
         bltmp2+= ((int8)(fladr>>24)) + ((int8)(fladr>>16)) + ((int8)(fladr>>8)) + fladr;
         if (bltmp2 == rx_buffer.buffer[bltmp1-1])           // Verify last byte with checksum
         {rx_stat = 0;
          cnt1 = 0;
          cnt2 = 0;
          cnt3 = 0;
BootSector:
         i = 0;
         if (fladr<0xF00000)
         {  rINTCON = 0x00;
            rINTCON2 = 0x80;
            rINTCON3 = 0;
            rPIE_1 = 0;
            rPIE_2 = 0;
            write_program_memory(fladr,rx_buffer.buffer,rx_buffer.DAT_LNG);
//            delay_ms(2);
#ifdef shit
             #ASM
             fwrite_wait:
               btfsc   EECON1,1
             goto   fwrite_wait
             #ENDASM
#endif

         }
          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");
         }else printf("RE");};
      };

poll_boot_end:
#ASM
decfsz cnt1,f
goto   boot_check
decfsz cnt2,f
goto   boot_check
decfsz cnt3,f
goto   boot_check
#ENDASM
boot_end:
reset_cpu();//Restart
}
#org default


При мен работи безотказно, връзката ми е през оптрони, но и това не го бърка... През PC пращам в следната последователност:
    <Адрес> <Дължина на запис, по принцип 8><16 байта които да се запишат><CheckSum - сбор на последните 16 байта>

18F452 на тази скорост се записва за около 40 секунди
PS. Това ми е старата версия, имам и малко корегирана такава, тук само съдържанието на FLASH-а минавам с чексума, иначе в другата и адреса на който се пише също се смята в чексумата. Както и да е, надявам се да е от полза на някого :)

Автор:  TheWizard [ Чет Апр 20, 2006 2:24 pm ]
Заглавие: 

Напишете си BOOT-а на ASM - за цялата серия 18(с малки разлики) се събира под 512 байта и това + процедури като
SendChar(char X).... можете да си ги викате от МАИН часта и същевременно са в заключената област на PICа

Автор:  Predator_MF [ Чет Апр 20, 2006 2:28 pm ]
Заглавие: 

Ами тоя лоудер моя без стринговете е под 512 байта както е написан на C, но това не ме бърка особено, в момента в който вдигна кой да е бит от секюритито на 452 лоудера спира да работи, пише го и в ерата - да забравя за секюрити

Автор:  backson [ Чет Апр 20, 2006 3:13 pm ]
Заглавие: 

Predator_MF искаш да кажеш че ако си защитиш кода назевисимо дори само една банка неможеш да пишеш във FLASHа ли ? Ебаси мамата

Автор:  Predator_MF [ Чет Апр 20, 2006 3:23 pm ]
Заглавие: 

Цитат:
Ебаси мамата

И аз така казах като видях
PIC18F452 Errata написа:
Enabling code protection for any program memory
block will also enable write protection for that
block. This would prevent even legitimate selfwrite
attempts by the microcontroller, such as
those used in a bootloader, in any code-protected
block.

Автор:  Gogo [ Чет Апр 20, 2006 4:29 pm ]
Заглавие: 

Някога си написах дин бутлоадер, дето и до сега си го качвам на 18-ките. Забранено му е да чете каквото и да е, да пише в конфиг-а, ИД-то и първите 512 байта (той е там). Качвал съм го на 1320, 458, 8520, 8525 - "code protection" е ENABLED за всички области от флаша и пиковете си бачкат. Пробвал съм след програмиране с бутлоадера да го чета с програматор - не става. Ама точно на 452 не съм качвал бутлоадера, та за него незнам.

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