//------------------------------------------------------------------------------
// Copyright (c) 2013 by Silicon Laboratories.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Silicon Laboratories End User
// License Agreement which accompanies this distribution, and is available at
// http://developer.silabs.com/legal/version/v10/License_Agreement_v10.htm
// Original content and implementation provided by Silicon Laboratories.
//------------------------------------------------------------------------------

/*
 * main.c
 *
 *  Created on: February 4, 2013
 *      Author: fbar / cmenke
 */

#include "global.h"


//------------------------------------------------------------------------------
// Function Prototypes
//------------------------------------------------------------------------------
int main (void);

#if defined(__CC_ARM)
__asm void user_app_jump(uint32_t addr);
#elif defined(__GNUC__)
void user_app_jump(uint32_t addr);
#elif defined(__IAR_SYSTEMS_ICC__)
void user_app_jump(uint32_t addr);
#endif

//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
uint32_t trigger;
uint32_t flash_size;
uint32_t ram_size;

//------------------------------------------------------------------------------
// Main Routine
//------------------------------------------------------------------------------
int main (void)
{
   // Initialize device and execute boot handler
   DEVICE_Init();

   // Update Firmware or Jump to User Application
   if(trigger)
   {
      //Update Firmware
      DFU_Firmware_Update(trigger & AUTO_TRIGGER);
   }
   else
   {
      // Restore all registers to reset values
      DEVICE_Restore();

      // Relocate the interrupt vector base address
      DEVICE_RedirectInterrupts(USER_APP_START_ADDR);

      // Jump to the user application
      user_app_jump(USER_APP_START_ADDR);

   }

   while(1);

}

void SystemInit(void)
{
}

//------------------------------------------------------------------------------
// user_app_jump()
//------------------------------------------------------------------------------

#if defined(__CC_ARM)
__asm void user_app_jump(uint32_t addr)
{
   LDR SP, [R0]                  ; Initialze stack pointer
   LDR PC, [R0, #4]              ; Initialize program counter
}
#elif defined(__GNUC__)
void __attribute__ ((naked)) user_app_jump(uint32_t addr)
{
   __asm(
"  LDR SP, [R0]\n"
"  LDR PC, [R0, #4]\n"
   );
}
#elif defined(__IAR_SYSTEMS_ICC__)
void user_app_jump(uint32_t addr)
{
   asm("LDR SP, [R0]");
   asm("LDR PC, [R0, #4]");
}
#endif
