STM32F107 UART Bootloader mikroC

1

I try to adopt the UART Bootloader from mikroelektronika, written for the STM32F051r8 (https://www.st.com/resource/en/datasheet/stm32f051r8.pdf)

to a STM32F107VCT7 (https://www.mouser.de/datasheet/2/389/CD00220364-490297.pdf)

Here is the original Code:

/*
 * Project name:
     USB_UART_Bootloader
 * Copyright:
     (c) MikroElektronika, 2018.
 * Revision History:
     - initial release;
 * Description:
     MCU flash. It is used, instead of programming tools, to
     load real program code into the MCU. Real program code can
     be passed from PC to bootloader by specific PC application
     (Bootloader Tool) over numerous communication interfaces.

     This bootloader communicates with PC over UART inteface
     by using mikroE bootloader protocol. It is designed to
     work in conjuction with mikroE's 'mikroBootloader'
     PC application.

 * Test configuration:
     MCU:             STM32F051R8
                      https://www.st.com/resource/en/datasheet/stm32f051r8.pdf
     Dev.Board:       MINI-M0 for STM32
                      https://www.mikroe.com/mini-stm32f0
     Oscillator:      48.000000
     Ext. Modules:    None
     SW:              mikroC PRO for ARM v6.0.0
                      https://www.mikroe.com/mikroc-arm
 * NOTES:
     - It's recommended not to alter the start address of the main().
       Otherwise, less space in ROM will be available for the
       application being bootloaded.
*/
////////////////////////////////////////////////////////////////////////////////
#include <built_in.h>
////////////////////////////////////////////////////////////////////////////////
#pragma orgall 0xEC00
#define BOOTLOADER_START_ADDR   0xEC00
#define START_PROGRAM_ADDR      0xFC00
////////////////////////////////////////////////////////////////////////////////
static char block[1024];
////////////////////////////////////////////////////////////////////////////////
void Start_Program() org START_PROGRAM_ADDR{

}
////////////////////////////////////////////////////////////////////////////////
unsigned short UART_Write_Loop(char send, char receive){
  unsigned int rslt = 0;

  while(1){
    Delay_5ms();
    UART_Write(send);
    Delay_5ms();

    rslt++;
    if (rslt == 0x0200)
      return 0;
    if(UART_Data_Ready()) {
      if(UART_Read() == receive)
        return 1;
    }
  }
}
////////////////////////////////////////////////////////////////////////////////
void FLASH_EraseWritePage(unsigned long address) {
  unsigned int i = 0;
  unsigned int dataToWrite;

  FLASH_ErasePage(address);

  for (i = 0; i < 512; i++)
  {
    dataToWrite = block[i * 2] | (block[i * 2 + 1] << 8);
    FLASH_Write_HalfWord(address + i*2, dataToWrite);
  }
}
////////////////////////////////////////////////////////////////////////////////
void Write_Begin(){
  unsigned int i;
  unsigned long* ptr;
  unsigned char appResetVector[16];
  unsigned long arm_m0_inst;
  unsigned int dataToWrite;

  //LDR R0, PC+X
  arm_m0_inst = 0x4800 + 1;

  appResetVector[0] = arm_m0_inst;
  appResetVector[1] = arm_m0_inst >> 8;

  //MOV SP, R0
  arm_m0_inst = 0x4685;

  appResetVector[2] = arm_m0_inst;
  appResetVector[3] = arm_m0_inst >> 8;

  //LDR R0, PC+Y
  arm_m0_inst = 0x4800 + 1;

  appResetVector[4] = arm_m0_inst;
  appResetVector[5] = arm_m0_inst >> 8;

  //BX R0
  arm_m0_inst = 0x4700;
  appResetVector[6] = arm_m0_inst;
  appResetVector[7] = arm_m0_inst >> 8;

  //SP
  appResetVector[8] = block[0];
  appResetVector[9] = block[1];
  appResetVector[10] = block[2];
  appResetVector[11] = block[3];

  //PC
  appResetVector[12] = block[4];
  appResetVector[13] = block[5];
  appResetVector[14] = block[6];
  appResetVector[15] = block[7];

  FLASH_ErasePage(START_PROGRAM_ADDR);

  for (i = 0; i < 8; i++)
  {
    dataToWrite = appResetVector[i * 2] | (appResetVector[i * 2 + 1] << 8);
    FLASH_Write_HalfWord(START_PROGRAM_ADDR + i*2, dataToWrite);
  }

  ptr = (unsigned long*)0x00000000;
  block[0] = LoWord(*ptr);
  block[1] = LoWord(*ptr) >> 8;
  block[2] = HiWord(*ptr);
  block[3] = HiWord(*ptr) >> 8;

  ptr++;

  block[4] = LoWord(*ptr);
  block[5] = LoWord(*ptr) >> 8;
  block[6] = HiWord(*ptr);
  block[7] = HiWord(*ptr) >> 8;
}
////////////////////////////////////////////////////////////////////////////////
void Start_Bootload(){
  unsigned int i = 0;
  char xx, yy;
  long j = 0;

  while (1) {
    if (i == 1024) {
      //--- If 256 words (1024 bytes) recieved then write to flash
      if (!j)
        Write_Begin();
      if (j < BOOTLOADER_START_ADDR) {
        FLASH_EraseWritePage(j);
      }

      i = 0;
      j += 0x400;
    }
    //--- Ask for yy
    UART_Write('y');
    while (!UART_Data_Ready()) ;
    //--- Read yy
    yy = UART_Read();
    //--- Ask for xx
    UART_Write('x');
    while (!UART_Data_Ready()) ;
    //--- Read xx
    xx = UART_Read();
    //--- Save xxyy in block[i]
    block[i++] = yy;
    block[i++] = xx;
  }
}
////////////////////////////////////////////////////////////////////////////////
void main() org BOOTLOADER_START_ADDR{
// Main program
 // UART1_Init_Advanced(115200, _UART_8_BIT_DATA, _UART_NOPARITY, _UART_ONE_STOPBIT, &_GPIO_MODULE_USART1_PA9_10);   // Display
    // Delay_ms(1000);

    UART2_Init_Advanced(115200, _UART_8_BIT_DATA, _UART_NOPARITY, _UART_ONE_STOPBIT, &_GPIO_MODULE_USART2_PD56);              // USB Serial
    Delay_ms(1000);


  Delay_100ms();

  if (UART_Write_Loop('g','r')) {     // Send 'g' for ~5 sec, if 'r'
    Start_Bootload();                 //   received start bootload
  }
  else {
    Start_Program();                  //   else start program
  }
}
////////////////////////////////////////////////////////////////////////////////

I think the only thing I need to modify are these lines:

#pragma orgall 0xEC00
#define BOOTLOADER_START_ADDR   0xEC00
#define START_PROGRAM_ADDR      0xFC00

I study the STM32F051r8 Datasheet and can't fiund any reference for 0xEC00 as start of Flash Memory.

Which values do I need for the STM32F107VCT7?

When i use the values on top and compile it to the 107, it works but while uploading MCU stocks.

arm
stm32
uart
bootloader
mikroc
asked on Stack Overflow Jun 14, 2019 by guenthernagel • edited Jun 14, 2019 by Zoe

1 Answer

-1

hello i think you have many problems in addresses and configs, i used this code and it works correctly

for erase main program from the flash:

#define Applicationend 0x08040000
#define ApplicationAddress    0x8003000
#define FLASH_PAGE_SIZE    ((uint16_t)0x400)
//////////////////////////////////

     FLASH_UnlockBank1();
   NbrOfPage = (Applicationend - ApplicationAddress) / FLASH_PAGE_SIZE;
   FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);    
     for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
            {
            FLASHStatus = FLASH_ErasePage(ApplicationAddress + (FLASH_PAGE_SIZE * EraseCounter));
            }   

for programming the flash:

 while((Address < (size_of_program)) && (FLASHStatus == FLASH_COMPLETE))
  {

    df_read_open(Address+temp);
  df_read(update_r,2); 

    FLASHStatus = FLASH_ProgramHalfWord((Address+ApplicationAddress),( update_r[0]|(update_r[1]<<8)));
    Address = Address + 2;
  } 
    FLASH_LockBank1();

and for running the main program

    if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
{ 
  /* Jump to user application */
  JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
  Jump_To_Application = (pFunction) JumpAddress;
  /* Initialize user application's Stack Pointer */
  __set_MSP(*(__IO uint32_t*) ApplicationAddress);
  Jump_To_Application();
}   
answered on Stack Overflow Jun 16, 2019 by alireza.roozitalab

User contributions licensed under CC BY-SA 3.0