PLEASE, about bootloader uart example

General discussion on mikroC PRO for ARM.
Post Reply
Author
Message
orpheedulogis
Posts: 240
Joined: 16 Jan 2010 22:26

PLEASE, about bootloader uart example

#1 Post by orpheedulogis » 08 Mar 2023 11:54

Did someone try this example ? that's the question.

This because , for me, it doesn't work at all.
I tried it with a STM32L151RDT6 but, because it doesn't works, I just tested it with STM32F051 (but K6 version)
If you take a look on code, you can see it will use "Write_Begin" to write at START_PROGRAM_ADDR .
OK, but after doing this, it will erase and coping file starting at address 0 , not START_PROGRAM_ADRESS !!
In practice I can see , using mikrobootloader, download starting and ... freezing .
Looking on memory content, bootloader has been partially erased so it confirm there is an addressing memory problem

Here y actual 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 -> STM32F051K6
https://www.st.com/resource/en/datashee ... f051r8.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>
////////////////////////////////////////////////////////////////////////////////
#define AdresseBase 0x200

#pragma orgall AdresseBase
#define BOOTLOADER_START_ADDR AdresseBase
#define START_PROGRAM_ADDR 0x15C0

////////////////////////////////////////////////////////////////////////////////

const MaskPin00 = 0x1;
const MaskPin01 = 0x2;
const MaskPin02 = 0x4;
const MaskPin03 = 0x8;
const MaskPin04 = 0x10;
const MaskPin05 = 0x20;
const MaskPin06 = 0x40;
const MaskPin07 = 0x80;
const MaskPin08 = 0x100;
const MaskPin09 = 0x200;
const MaskPin10 = 0x400;
const MaskPin11 = 0x800;
const MaskPin12 = 0x1000;
const MaskPin13 = 0x2000;
const MaskPin14 = 0x4000;
const MaskPin15 = 0x8000;

////////////////////////////////////////////////////////////////////////////////
#define LedTest_OFF {p_Led1=1;p_Led2=1;}
#define LedTest_GREEN {p_Led1=1;p_Led2=0;}
#define LedTest_RED {p_Led1=0;p_Led2=1;}
#define LedTest_Reverse { if(p_Led1) {p_Led1=0;p_Led2=1;} else {p_Led1=1;p_Led2=0;}}
#define LedTest_ReverseGreen { if(p_Led1) {p_Led1=0;p_Led2=0;} else {p_Led1=1;p_Led2=0;}}
#define LedTest_ReverseRed { if(p_Led2) {p_Led2=0;p_Led1=0;} else {p_Led2=1;p_Led1=0;}}
////////////////////////////////////////////////////////////////////////////////
sbit p_Led1 at GPIOB_ODR.B1;
sbit p_Led2 at GPIOB_ODR.B2;
////////////////////////////////////////////////////////////////////////////////

static char block[1024];
////////////////////////////////////////////////////////////////////////////////
void Start_Program() org START_PROGRAM_ADDR
{
while(1){LedTest_ReverseGreen; delay_ms(1000);};
}
////////////////////////////////////////////////////////////////////////////////
unsigned short Uart1_Write_Loop(char send, char receive)
{
unsigned int rslt = 0;

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

rslt++;
if (rslt == 0x0600) return 0;
if(Uart1_Data_Ready())
{
if(Uart1_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;
unsigned 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) // !! PROBLEM HERE !!
{
FLASH_EraseWritePage(j);
}

i = 0;
j += 0x400;
}
//--- Ask for yy
Uart1_Write('y');
while (!Uart1_Data_Ready()) ;
//--- Read yy
yy = Uart1_Read();
//--- Ask for xx
Uart1_Write('x');
while (!Uart1_Data_Ready()) ;
//--- Read xx
xx = Uart1_Read();
//--- Save xxyy in block
block[i++] = yy;
block[i++] = xx;
}
}
////////////////////////////////////////////////////////////////////////////////
void main() org BOOTLOADER_START_ADDR
{
// Main program
GPIO_Config(&GPIOB_BASE, MaskPin01 | MaskPin02,_GPIO_CFG_MODE_OUTPUT |_GPIO_CFG_PULL_NO);
Uart1_Init(9600);
//Uart1_Init_Advanced(9600,_UART_8_BIT_DATA, _UART_NOPARITY, _UART_ONE_STOPBIT,&_GPIO_MODULE_USART2_PA14_15);
Delay_100ms();


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

AntiMember
Posts: 136
Joined: 02 Jan 2020 19:00

Re: PLEASE, about bootloader uart example

#2 Post by AntiMember » 08 Mar 2023 15:53

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

STM32F051K6
#pragma orgall 0x6C00
#define BOOTLOADER_START_ADDR 0x6C00
#define START_PROGRAM_ADDR 0x7C00

orpheedulogis
Posts: 240
Joined: 16 Jan 2010 22:26

Re: PLEASE, about bootloader uart example

#3 Post by orpheedulogis » 09 Mar 2023 14:08

Ok, I understood: my error was about the meaning of "START_PROGRAM_ADDR " : it's not the future program area, just a link for bootloader program informations.

Post Reply

Return to “mikroC PRO for ARM General”