Advice on UART BootLoader for 18F26K83

Post Reply
Author
Message
Bluedog01
Posts: 25
Joined: 16 Dec 2019 05:59

Advice on UART BootLoader for 18F26K83

#1 Post by Bluedog01 » 18 Feb 2020 00:51

Hi,

I have made successful UART bootloader in MikroC for 18F66K80 by modifying the example given for 18F45K22.

I am now trying to make a bootloader for 18F26K83. This device seems to have different internal register names and configurations. It also appears that Flash_Erase_Write_64 function (as used in 18F45K22 example) cannot be used with this device.

I have looked at other example bootloaders for 18F devices (eg. boot18_64k.c) however, again, register names and configurations are very different to 18F26K83.

Can anyone offer advice as to which example (if any) is more suitable to modify for 18F26K83? I am only new to this so I don't fully understand what is required as yet. Any and all information appreciated.

Andy

Bluedog01
Posts: 25
Joined: 16 Dec 2019 05:59

Re: Advice on UART BootLoader for 18F26K83

#2 Post by Bluedog01 » 18 Feb 2020 22:54

Hi

I have made an attempt to modify example code boot18_64k.c

I think I have modified all of the register names appropriately to suit 18F26K83. The code below wont build as the compiler complains about the line:

while (j < _FLASH_ERASE/_FLASH_WRITE_LATCH) {

Undeclared identifier '_FLASH_ERASE' in expression boot18_64K_18F26k83_01a.c

Any help or advice greatly appreciated.

Andy

*****************

Code: Select all

#include "built_in.h"

/*
 * constants :
 *  _FLASH_WRITE_LATCH - flash write latch size
 *  _FLASH_ERASE       - flash erase block size
 * are related to mcu flash memory write and erase block sizes
 * and as such are defined in appropriate flash library file.
 * Be aware that these constants are MCU dependent.
 * Compiler will link them from appropriate flash library,
 * so the user does not have to take care of them.
 *
 */

static char block[64];

void Susart_Init(unsigned short brg_reg) org 65136 {
  unsigned short i;

  //RCSTA = 0x90;    // Enable serial port; Set to continuous receive
  //TXSTA = 0x26;    // Enable transmit; baud rate select = high speed
  //The UxBRG registers should only be written when ON = 0.
  U1BRGL = 103;
  U1BRGH = 0;
  U1CON0.B7 = 0;        //BRGS Baud rate Generator Speed Select bit
  U1CON1.B7 =  1;    // Serial port enabled
  U1CON0.B4 = 1;     // Receiver is enabled
  U1CON0.B5 = 1;     // Transmit is enabled

  TRISC.B7 = 1;
  TRISC.B6 = 0;
//  BAUDCON2.BRG16 = 1;

  //while (PIR1.RCIF)
  while (PIR3.B3)     // U1RXIF: UART1 Receive Interrupt Flag bit(
    //i = RCREG;
    i = U1RXB;        // UART1 Receive buffer

  //SPBRG = brg_reg;
  //BAUDCON2.BRG16 = 1;

}


void Susart_Write(unsigned short data_) org 65080 {

  //while (!TXSTA.TRMT)
  while (!U1ERRIR.B7)   // TXMTIF Transmit Shift Register Empty Interrupt Flag bit
  
    ;
  //TXREG = data_;
  U1TXB = data_;
}

unsigned short Susart_Data_Ready() org 65120 {
  //return (PIR1.RCIF);
  return (PIR3.B3);
}

unsigned short Susart_Read() org 65040 {
  unsigned short rslt;
  //rslt = RCREG;
  rslt = U1RXB;
  /*
  if (RCSTA.OERR) {
     RCSTA.CREN = 0;
     RCSTA.CREN = 1;
  }
  */
  if (U1ERRIR.B1) {      //RXFOIF
     rslt = U1RXB;
     U1ERRIR.B1 = 0;
  }
  
  
  return rslt;
}

//-------------- Empty function, this is where the start address of 'real'
//               program will be placed (by Write_Begin()). That is why
//               this function must have at least 4 bytes of ROM available
//               after its org address.
void Start_Program() org 0xFFC0 {
}

void Flash_Write_Sector(long address, char *sdata) org 64020 {
  unsigned short saveintcon, i, j;

  //saveintcon = INTCON;
  saveintcon = INTCON0;

  //--- erase memory
  TBLPTRL = Lo(address);
  TBLPTRH = Hi(address);
  TBLPTRU = Higher(address);
  //--- required erase sequence
  //EECON1.EEPGD = 1;            //  EEPGD control bit determines if the access will be a program or data EEPROM memory access
  //EECON1.CFGS = 0;             // When set, subsequent operations will operate on Configuration registers regardless of EEPGD. When clear, memory
                                 // selection access is determined by EEPGD.
  NVMCON1.B7 = 1;
  NVMCON1.B6 = 0;

  //EECON1.WREN = 1;
  NVMCON1.WREN = 1;
  
  //EECON1.FREE = 1;
  NVMCON1.FREE = 1;
  
  
  //INTCON.GIE = 0;
  INTCON0.GIE = 0;
  
  /*
  EECON2 = 0x55;
  EECON2 = 0xAA;
  EECON1.WR = 1;
  */
  
  NVMCON2 = 0x55;
  NVMCON2 = 0xAA;
  NVMCON1.WR = 1;
  
  
  //INTCON.GIE = 1;
  INTCON0.GIE = 1;
  
  asm TBLRD*- ;
  //--- write memory
  FSR0L = Lo(sdata);
  FSR0H = Hi(sdata);
  j = 0;
  while (j < _FLASH_ERASE/_FLASH_WRITE_LATCH) {
    i = 0;
    while (i < _FLASH_WRITE_LATCH) {
      TABLAT  = POSTINC0;
      asm {
        TBLWT+*
      }
      i++;
    }
    /*
    EECON1.EEPGD = 1;
    EECON1.CFGS = 0;
    EECON1.WREN = 1;
    */
    NVMCON1.B7 = 1;
    NVMCON1.B6 = 0;
    NVMCON1.WREN = 1;
    

    //INTCON.GIE = 0;
    INTCON0.GIE = 0;
    
    NVMCON2 = 0x55;
    NVMCON2 = 0xAA;
    NVMCON1.WR = 1;
    j++;
  }
  //INTCON.GIE = 1;
  INTCON0.GIE = 1;
  
  //EECON1.WREN = 0;
  NVMCON1.WREN = 0;
  //--- restore interrupt
  //INTCON = saveintcon;
  INTCON0 = saveintcon;
}

unsigned short Susart_Write_Loop(char send, char receive) org 63926 {
  unsigned short rslt = 0;

  LBL_BOOT18_64_01:
    ___Boot_Delay64k();
    Susart_Write(send);
    ___Boot_Delay64k();

    rslt++;
    if (rslt == 255u)
      return 0;
    if (Susart_Read() == receive)
      return 1;
  goto LBL_BOOT18_64_01;
}

//-------------- This void will recover the bootlocation 0x0000, 0x0001 and
//               0x0002 to point to the bootloaer's main. It will also move
//               the reset vector of the program that is uploaded to a new
//               location, in this case 0x1FA0
void Write_Begin() org 64774 {

  Flash_Write_Sector(0xFFC0, block);
  //--- goto main 64888
  block[0] = 0xBC;
  block[1] = 0xEF;
  block[2] = 0x7E;
  block[3] = 0xF0;

}

//-------------- Starts with bootload
void Start_Bootload() org 65186 {
  unsigned short i = 0, xx, yy;
  long j = 0;

  while (1) {
    if (i == 64u) {
      //--- If 32 words (64 bytes) recieved then write to flash
      if (!j)
        Write_Begin();
      Flash_Write_Sector(j, block);

      i = 0;
      j += 0x40;
    }
    //--- Ask for yy
    Susart_Write('y');
    while (!Susart_Data_Ready()) ;
    //--- Read yy
    yy = Susart_Read();
    //--- Ask for xx
    Susart_Write('x');
    while (!Susart_Data_Ready()) ;
    //--- Read xx
    xx = Susart_Read();
    //--- Save xxyy in block[i]
    block[i++] = yy;
    block[i++] = xx;
  }
}


User avatar
stefan.filipovic
mikroElektronika team
Posts: 1135
Joined: 18 Dec 2018 10:30

Re: Advice on UART BootLoader for 18F26K83

#3 Post by stefan.filipovic » 25 Feb 2020 16:56

Hi,

Could you try with the bootloader from the attachment?
I've modified the bootloader from the following path:
C:\Users\Public\Documents\Mikroelektronika\mikroC PRO for PIC\Examples\Other\Bootloader\P18F45K22

Please let me know does it works.

Kind regards,
Attachments
BootloaderK83.zip
(122.12 KiB) Downloaded 231 times
Stefan Filipović

Bluedog01
Posts: 25
Joined: 16 Dec 2019 05:59

Re: Advice on UART BootLoader for 18F26K83

#4 Post by Bluedog01 » 03 Mar 2020 21:48

Hi Stefan,

I have tried the bootloader you attached however there are some unusual problems.

I can program bootloader into MCU and then upload application via uart. This works the first time only.

If I try to program a second application via uart the application does not work as expected. If I then try to load the first application again, it no longer works as expected.

The applications I am uploading are simple blinky programs and they all work as expected if I upload them via Mikroprog programmer.

I can attach all of the files if you need them.

Andy

Post Reply

Return to “mikroBootloader”