Hi everyone, I trying to make a flash jump on Nrf51822 in my project. there are 2 programs(program A and program B) below. i am working on to make program A jump to program B correctly.
my problem is in my applications, program A can jump to program B, but the time0 interrupt doesn't works correctly.
in the program A led red and blue blink, and program B led green and yellow blinks, but when program A jumps to B, there are led yellow and red blink, it supposed to led green and yellow blinks. led red still blink , not led green. so i think something wrong with my interrupt operates.
is the VIC not operate right? in ARM7 i can do this
How can i make the interrupts works right in my case. where am i wrong?
program A and B shows below.
program A put at address 0x00000000, here it is:
#define AppStartAddr 0x00010000
void Configure_System_Clock( void )
{
// Start 16 MHz crystal oscillator.
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;
// Wait for the external oscillator to start up.
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
{
// Do nothing.
}
}
void Init_Timer0( unsigned int TimerInterval )
{ NRF_TIMER0->TASKS_STOP = 1; // stop the task first
NRF_TIMER0->MODE = TIMER_MODE_MODE_Timer; // Set the timer in Timer Mode.
NRF_TIMER0->PRESCALER = 1; // Prescaler 1 produces 8MHz timer frequency => 1 tick = 0.125 us.
NRF_TIMER0->BITMODE = TIMER_BITMODE_BITMODE_32Bit; // 32 bit mode.
NRF_TIMER0->TASKS_CLEAR = 1; // clear the task first to be usable for later.
NRF_TIMER0->CC[0] = TimerInterval;
NRF_TIMER0->INTENCLR = 0xFFFFFFFFUL;
NRF_TIMER0->INTENSET = ( TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos );
NRF_TIMER0->TASKS_START = 1; // Start timer.
NVIC_ClearPendingIRQ(TIMER0_IRQn);
NVIC_SetPriority(TIMER0_IRQn, 3);
NVIC_EnableIRQ(TIMER0_IRQn);
}
void Init_WatchDog( void )
{
NRF_WDT->CRV = WATCHDOG_TIMING_3s;
NRF_WDT->RREN = ( WDT_RREN_RR0_Enabled << WDT_RREN_RR0_Pos );
while(NRF_WDT->REQSTATUS == 0U) // Wait for RR[0] START
{
// Do nothing.
}
NRF_WDT->TASKS_START = 1;
while(NRF_WDT->RUNSTATUS == 0U) // Wait for watchdog running
{
// Do nothing.
}
NRF_WDT->RR[0] = WDT_RR_RR_Reload;
}
void WDTFeed( void )
{
NRF_WDT->RR[0] = WDT_RR_RR_Reload;
}
__asm void StartApplication(uint32_t start_addr)
{
LDR R2, [R0] ; Get App MSP.
MSR MSP, R2 ; Set the main stack pointer to the applications MSP.
LDR R3, [R0, #0x00000004] ; Get application reset vector address.
BX R3 ; No return - stack code is now activated only through SVC and plain interrupts.
ALIGN
}
/**
* @brief Function for application main entry.
*/
int main(void)
{
Configure_System_Clock();
Init_GPIO();
Init_Timer0( TIME_INTERVAL_10ms );
while(true)
{
LED_BLUE_BLINK; // led blue blink
nrf_delay_ms( 500 );
IapWaitTime++;
if( IapWaitTime >= 20 )
{
IapWaitTime = 0;
StartApplication(AppStartAddr);
}
}
}
void TIMER0_IRQHandler(void)
{
Flag_counter_10ms++;
if( Flag_counter_10ms == 100 )
{
Flag_counter_10ms = 0;
LED_RED_BLINK; // led red blink
}
NRF_TIMER0->TASKS_CLEAR = 1; // clear the task
NRF_TIMER0->EVENTS_COMPARE[0] = 0; // clear the event
NRF_TIMER0->TASKS_START = 1; // Start timer.
} // */
/** @} */
program B put at address 0x00010000, here it is:
#define AppStartAddr1 0x00000000
void Configure_System_Clock( void )
{
// Start 16 MHz crystal oscillator.
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;
// Wait for the external oscillator to start up.
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
{
// Do nothing.
}
}
void Init_Timer0( unsigned int TimerInterval )
{
NVIC_DisableIRQ(TIMER0_IRQn);
NRF_TIMER0->TASKS_STOP = 1; // stop the task first
NRF_TIMER0->MODE = TIMER_MODE_MODE_Timer; // Set the timer in Timer Mode.
NRF_TIMER0->PRESCALER = 1; // Prescaler 1 produces 8MHz timer frequency => 1 tick = 0.125 us.
NRF_TIMER0->BITMODE = TIMER_BITMODE_BITMODE_32Bit; // 32 bit mode.
NRF_TIMER0->TASKS_CLEAR = 1; // clear the task first to be usable for later.
NRF_TIMER0->CC[0] = TimerInterval;
NRF_TIMER0->INTENCLR = 0xFFFFFFFFUL;
NRF_TIMER0->INTENSET = ( TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos );
NRF_TIMER0->TASKS_START = 1; // Start timer.
NVIC_ClearPendingIRQ(TIMER0_IRQn);
NVIC_SetPriority(TIMER0_IRQn, 3);
NVIC_EnableIRQ(TIMER0_IRQn);
}
void Init_GPIO( void )
{
nrf_gpio_cfg_output(LED_RED);
nrf_gpio_cfg_output(LED_BLUE);
nrf_gpio_cfg_output(LED_GREEN);
nrf_gpio_cfg_output(LED_YELLOW);
nrf_gpio_cfg_output(MODE_DETECTIVE);
}
void Init_WatchDog( void )
{
NRF_WDT->CRV = WATCHDOG_TIMING_3s;
NRF_WDT->RREN = ( WDT_RREN_RR0_Enabled << WDT_RREN_RR0_Pos );
while(NRF_WDT->REQSTATUS == 0U) // Wait for RR[0] START
{
// Do nothing.
}
NRF_WDT->TASKS_START = 1;
while(NRF_WDT->RUNSTATUS == 0U) // Wait for watchdog running
{
// Do nothing.
}
NRF_WDT->RR[0] = WDT_RR_RR_Reload;
}
void WDTFeed( void )
{
NRF_WDT->RR[0] = WDT_RR_RR_Reload;
}
__asm void StartApplication(uint32_t start_addr)
{
LDR R2, [R0] ; Get App MSP.
MSR MSP, R2 ; Set the main stack pointer to the applications MSP.
LDR R3, [R0, #0x00000004] ; Get application reset vector address.
BX R3 ; No return - stack code is now activated only through SVC and plain interrupts.
ALIGN
}
/**
* @brief Function for application main entry.
*/
int main(void)
{
Configure_System_Clock();
Init_GPIO();
Init_WatchDog();
Init_Timer0( TIME_INTERVAL_10ms );
while(true)
{
WDTFeed();
LED_YELLOW_BLINK; // led yellow blink
nrf_delay_ms( 500 );
IapWaitTime++;
if( IapWaitTime >= 20 )
{
IapWaitTime = 0;
StartApplication(AppStartAddr1);
}
}
}
void TIMER0_IRQHandler(void)
{
Flag_counter_10ms++;
if( Flag_counter_10ms == 100 )
{
Flag_counter_10ms = 0;
LED_GREEN_BLINK; // led green blink
}
NRF_TIMER0->TASKS_CLEAR = 1; // clear the task
NRF_TIMER0->EVENTS_COMPARE[0] = 0; // clear the event
NRF_TIMER0->TASKS_START = 1; // Start timer.
}
/** @} */