AXM0F243 flashing through a bootloader

I am using following code to write to flash from a boot loader code i am trying to implement . The flash write API doesn’t generate any error but the bytes that is flashed hss some error in random location but are repeatable . i am using this API after performing erase from the location that the application is starting.
flash_unlock();
dest=Address;
pt1=data_ptr;
for(loop=0;loop<(datalen/2);loop++)
{
tempdata=0;
tempdata=*pt1;
pt1++;
tempdata = tempdata | ((*pt1)<<8);
if(flash_write(dest,tempdata))
{
return 12;
}
pt1++;
dest=dest+2;
delay_ms(10);
}
flash_lock();
what delay or function do i add for reliable flash writes

i have used datalen of 32

Hello. Since the ‘errors in random location’ are repeatable, have you tried to write starting from a different dest address? Does the behavior change?
Regarding the delay needed, please be sure to fulfill the timing requirements as reported in Table 26 of the datasheet:

Please refer to the AXM0F243 Programming Manual for more details.

Thank you for the reply
In the libmf API provided they have said that for the ARM variant the function itself handles the wait state
also the erase API has the erase for individual page which i guess can work in parallel if there are no wait state handler and it take like 2 sec to erase from address 6400-ff80
The flash write API has a write of 2 bytes so for each simultaneous write will be in the same row there fore i have to insert a delay of 4 ms right?
I have inserted a delay of 2 ms currently and have found success with it i will be increasing it to 4 ms
The issue i am facing now is the program jumps to the correct location but doesnt have indication(used led) but when i reconnect power supply it starts working

if((Hal_GetTick()-msec)>delay2 || endrecord_received )
{
// if(endrecord_received)
// {
// __disable_irq();
// NVIC_SystemReset();
// }
msec=Hal_GetTick();
temp=*((uint32_t *)0xEFFC);//address to confirm program write

		if(temp==0xDEADBEEF )
		{
		    __set_CONTROL(__get_CONTROL( ) & ~CONTROL_nPRIV_Msk);
            typedef  void (*pFunction)(void);
			temp=*((uint32_t *)0x00007404);
			pFunction Jump_To_Fixed;
            uart0_stop();
			__disable_irq();
            NVIC->ICER[ 0 ] = 0xFFFFFFFFu ;
            NVIC->ICPR[ 0 ] = 0xFFFFFFFFu ;

// for (i = 0; i < 8; i++)
// {
// NVIC->ICER[i] = 0xFFFFFFFF;
// NVIC->ICPR[i] = 0xFFFFFFFF;
// }
SysTick->CTRL = 0 ;
SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk ;
if( CONTROL_SPSEL_Msk & __get_CONTROL( ) )
{ /* MSP is not active */
__set_MSP( __get_PSP( ) ) ;
__set_CONTROL( __get_CONTROL( ) & ~CONTROL_SPSEL_Msk ) ;
}
// __set_MSP(0x00007400);
Jump_To_Fixed = (pFunction) temp; // ODD Thumb Addr
SCB->VTOR = 0x00007400;
Jump_To_Fixed();
}
this is my jump code

also is there a setting in axcode block that we can see the dependent files in real time while in IDE like the startup file ,libmf files etc

Hello. In order to quickly lookup functions while coding in AX::CB you will need to be sure that the source code at “C:\Program Files (x86)\ON Semiconductor\AXSDB\libmf” is correctly indexed by your project.
There are also plugins for thi0s like Cscope plugin - CodeBlocks
Also look at codeblocks - Code::Blocks cannot find function declarations or definitions - Stack Overflow

Thank you for the reply
I will check it out
what are your views in relation to the problem above what states might be different when jumping directly or resetting the device and then jumping.
I have 2 different boat loader one that accepts command through UART and another through wireless from another device(AXM0f243) . the flash writes are confirmed as it works after resetting(reinserting power supply)
Also i cant seem to disable the watchdog interrupt with NVIC_DisableIRQ(WDT_IRQn); i have placed this just below the main before enableirq. and this
SRSSLT->WDT_DISABLE_KEY = 0xACED8865u
The link register shows the value of fffffff9 when jumping directly but is fine when i reinsert the device and make the jump

If you have a example code for bootloader that would be a great help thank you

Hello. We do not have such examples for the AXM0F243 platform. What we have, is an app note on this topic for the AX8052F143. https://www.onsemi.com/pub/Collateral/AND9331-D.PDF AX8052_SerialBootLoader_V1.1.zip (78.6 KB)

1 Like

Hello georgi the byte error is seems to be solved by writing to the page as a whole by changing the API now the only problem i am facing is while jumping the address and all registers are in predictable condition but i am not able to get the response from peripherals(led wireless etc). Also when i reconnect the device (hard reset(brown-out)) or re flash the boot loader then the jump results in peripherals working correctly what might be the reason for this?

how can i generate a brown out reset manually?

I don`t understand fully the issue. You should include the correct HW initialization functions in the ‘coldstart’ and ‘warmstart’ conditions so that, after wakeup or upon reset, the peripherals are correctly re-initialized.

Hello. To quickly issue a brown out you could connect your board to a bench power supply and start decreasing VDD below the triggering thresholds.

Thank you for the brief reply the code i use for jump is.
uint32_t ADR;
ADR=(uint32_t
)0x7400;
led0_on();
for(uint16_t k=0; k<1000; k++)
delay(100);
__disable_irq();
uart0_stop();
// Disable SysTick
SysTick->CTRL = 0 ;
SysTick->LOAD = 0 ;
SysTick->VAL = 0 ;
SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk ;
// Disable IRQs & clear pending IRQs
for (i = 0; i < 8; i++)
{
NVIC->IP[i] = 0x00000000;
}
NVIC->ICER[ 0 ] = 0xFFFFFFFFu ;
NVIC->ICPR[ 0 ] = 0xFFFFFFFFu ;
__set_CONTROL(__get_CONTROL( ) & ~CONTROL_nPRIV_Msk);
SCB->VTOR =(uint32_t)0x7400;
__DSB();
__ISB();
jumpapp(ADR[0],ADR[1]);

attribute((naked,noreturn)) void jumpapp (uint32_t SP, uint32_t PC)
{
__ASM(“MSR MSP,r0”);
__ASM(“BX r1”);
}

when i jump after programming or perform a soft reset and program the jump does work but the indication is not visible(led).
when i reconnect the device or reflash the device start indicating correctly.
the only peripheral that i cannot seem to disable are the timers.

I tried deiniting that
NVIC_DisableIRQ(WCOWDT_IRQn);
NVIC_DisableIRQ(TCPWM4_IRQn);
TCPWM->CMD = 0x01000000;//stop counter
TCPWM->CTRL &= ~0x0000001F;//reset

WCO->WDT_CONFIG = 0x00000000;//RESET
WCO->WDT_CONTROL = 0x00000000;//RESET
//while (!(WCO->WDT_CONTROL & 0x00000002)); //FIX IF CONTROL DOENOT CHANGE


// divider 5: divide by 1
PERI->PCLK_CTL8 = 0x000000C7;//reset value
TCPWM_CNT4->PERIOD = 0x0000FFFF;//reset value

TCPWM_CNT4->INTR_MASK = 0x00000000;//reset
TCPWM_CNT4->TR_CTRL1 = 0x000003FF;//reset

TCPWM_CNT4->INTR = 0x0;//RESET

NVIC_ClearPendingIRQ(WCOWDT_IRQn);
NVIC_ClearPendingIRQ(TCPWM4_IRQn);

but same results

I want to hard reset my device using software i cannot seem to find one except the wdt reset

the initialization are same for BL and my application program. and theres no way for me to know if theres a warm start or cold start in the appliaction code as when i jump the debugger loses control and i cannot debug in steps.

if AXCODE block had a way to access the registers(not the CPU registers) it would have been possible to debug whats happening in application program.

Also i have tried the disable irq after uart same results.

If i include HW initialization in the warm start it will reinitialize all the peripherals every sleep cycle.

the application program has a program generated by ax radio which wakes up controller every second and so i think timer might be causing issues?