
#include "stm32f10x.h"
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
#include "string.h"
#include "debug.h"
#include "core_delay.h"
#include "stdio.h"
#include "mystdlib.h"
#include "signal.h"
#include "dev_backup.h"
#include "stdlib.h"


#define _SCB_BASE       (0xE000E010UL)
#define _SYSTICK_CTRL   (*(rt_uint32_t *)(_SCB_BASE + 0x0))
#define _SYSTICK_LOAD   (*(rt_uint32_t *)(_SCB_BASE + 0x4))
#define _SYSTICK_VAL    (*(rt_uint32_t *)(_SCB_BASE + 0x8))
#define _SYSTICK_CALIB  (*(rt_uint32_t *)(_SCB_BASE + 0xC))
#define _SYSTICK_PRI    (*(rt_uint8_t  *)(0xE000ED23UL))

static uint32_t _SysTick_Config(rt_uint32_t ticks)
{
  if ((ticks - 1) > 0xFFFFFF)
  {
    return 1;
  }
  
  _SYSTICK_LOAD = ticks - 1; 
  _SYSTICK_PRI = 0xFF;
  _SYSTICK_VAL  = 0;
  _SYSTICK_CTRL = 0x07;  
  
  return 0;
}

#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
static uint32_t g_heap[10*1024/4];
RT_WEAK void *rt_heap_begin_get(void)
{
  return (void *)g_heap;
}

RT_WEAK void *rt_heap_end_get(void)
{
  return (void *)((int)g_heap+sizeof(g_heap));
}
#endif


#ifdef RT_THREAD



void rt_hw_board_init()
{	
  NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x4000);
	// 1ms一个tick
	_SysTick_Config (72000000/1000);
  rt_system_heap_init(rt_heap_begin_get(),rt_heap_end_get());
  mem_init();
  tempptr_init();
  delay_init();
  signal_init();
  

}

void SysTick_Handler(void)
{
	rt_interrupt_enter();
	rt_tick_increase();
	rt_interrupt_leave();
}


#endif

void *dev_get(const char *name)
{
#if defined (__CC_ARM)  
  extern const int devstruct$$Base;
  extern const int devstruct$$Limit;
  struct dev_struct *start=(struct dev_struct *)&devstruct$$Base;
  struct dev_struct *end=(struct dev_struct *)&devstruct$$Limit;
#elif defined (__GNUC__)
  extern const int __start_devstruct;
  extern const int __stop_devstruct;
  struct dev_struct *start=(struct dev_struct *)&__start_devstruct;
  struct dev_struct *end=(struct dev_struct *)&__stop_devstruct;
#endif
  for(struct dev_struct *t=start;t<end;t++)
  {
    if(strcmp(t->name,name)==0)
    {
      return t->dev;
    }
  }
  param_check(0);
  return 0;
}


void param_err_handle(const char *param,const char *file,const char *fun,int line)
{
//  printf("param=%s,file=%s,fun=%s,line=%d.\r\n",param,file,fun,line);
  DBG_ERR("param=%s,file=%s,fun=%s,line=%d.\r\n",param,file,fun,line);
  bk_reboot_param_err();
  while(1);
}





void app_init(void)
{
#if defined (__CC_ARM)  
  extern const int initstruct$$Base;
  extern const int initstruct$$Limit;
  struct init_struct *start=(struct init_struct *)&initstruct$$Base;
  struct init_struct *end=(struct init_struct *)&initstruct$$Limit;
#elif defined (__GNUC__)
  extern const int __start_initstruct;
  extern const int __stop_initstruct;
  struct init_struct *start=(struct init_struct *)&__start_initstruct;
  struct init_struct *end=(struct init_struct *)&__stop_initstruct;
#endif
  int ret=0;
  for(struct init_struct *t=start;t<end;t++)
  {
    if(ret=t->init_fun(),ret<0)
    {
      DBG_WARN("fun:%08x init failed,ret=%d",t->init_fun,ret);
    }
  }
}







typedef struct _params_def{
  const char *name;
  void *p;
  void (*fun)(void *t);
  void *t;
  void (*del)(void *t);
  struct _params_def *next;
}params_def;
static params_def *g_parhead=0;
// 设置变量，返回变量指针
// 如果变量已设置，则返回之前设置的变量指针
void *app_variable(const char *name,void *p,void (*del)(void *t))
{
  params_def *t=g_parhead;
  params_def *prev=0;
  if(name){
    while(t!=0){
      if(strcmp(t->name,name)==0){
        if(p){
          if(t->del) t->del(t->p);
          t->p=p;
          if(t->fun){
            t->fun(t->t);
            t->fun=0;
            t->t=0;
          }
        }
        return t->p;
      }
      prev=t;
      t=t->next;
    }
  }
  if(p){
    t=calloc(1,sizeof(params_def));
    t->name=name;
    t->p=p;
    t->del=del;
    t->next=0;
    if(g_parhead==0) g_parhead=t;
    else prev->next=t;
    return t->p;
  }
  return 0;
}
// 在变量有效时调用
void app_valid_call(const char *name,void (*fun)(void *t),void *t)
{
  void *par=app_variable(name,0,0);
  if(fun==0) return;
  if(par){
    fun(t);
  }else{
    // 把函数挂在变量上
    params_def *t=g_parhead;
    params_def *prev=0;
    if(name){
      while(t!=0){
        prev=t;
        t=t->next;
      }
      t=calloc(1,sizeof(params_def));
      t->name=name;
      t->next=0;
      t->fun=fun;
      t->t=t;
      if(g_parhead==0) g_parhead=t;
      else prev->next=t;
    }
  }
}




void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte)
{
  for(int i=0;i<num_4byte;i++)
  {
    dst[i]=src[i];
  }
}









#ifdef __GNUC__

/* With GCC, small printf (option LD Linker->Libraries->Small printf
   set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

#else

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#pragma import(__use_no_semihosting)   

#endif /* __GNUC__ */



struct __FILE 
{ 
	int handle; 
}; 

FILE __stdout;       

void _sys_exit(int x) 
{ 
	x = x; 
} 

PUTCHAR_PROTOTYPE
{
//	SEGGER_RTT_PutChar(0,ch);
	return ch;
}




