/********************************** (C) COPYRIGHT *******************************
* File Name          : MCU.c
* Author             : WCH
* Version            : V1.1
* Date               : 2019/11/05
* Description        : 硬件任务处理函数及BLE和硬件初始化
*******************************************************************************/

/******************************************************************************/
/* 头文件包含 */
#include "CH57x_common.h"
#include "HAL.h"
                                                
tmosTaskID halTaskID;

#if BLE_CODE_EN
__align(4) u32 MEM_BUF[BLE_MEMHEAP_SIZE/4];    //蓝牙协议栈需要的内存
#endif

/*******************************************************************************
 * @fn          Lib_Calibration_LSI
 *
 * @brief       内部32k校准
 *
 * input parameters
 *
 * @param       None.
 *
 * output parameters
 *
 * @param       None.
 *
 * @return      None.
 */
void Lib_Calibration_LSI( void )
{
	if( Calibration_LSI() > 2 )
	{
		Calibration_LSI();
	}
}

/*******************************************************************************
 * @fn          CH57X_BLEInit
 *
 * @brief       BLE 库初始化
 *
 * input parameters
 *
 * @param       None.
 *
 * output parameters
 *
 * @param       None.
 *
 * @return      None.
 */
#if BLE_CODE_EN

void CH57X_BLEInit( void )
{
  uint8 i;
  bleConfig_t cfg;

  if( tmos_memcmp( VER_LIB,VER_FILE,strlen(VER_FILE)) == FALSE ){
    PRINT("head file error...\n");
    while(1);
  }
  R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;	      //写入0x57	
  R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;        //再写入0xA8，接下来约16个周期将打开安全锁，进入安全访问模式
  R16_CLK_SYS_CFG = RB_CLK_OSC32M_XT|(2<<6)|0x08;			// 32M -> Fsys （配置系统时钟，采用外部晶振，32M作为系统主频）
  R8_SAFE_ACCESS_SIG = 0;                             //退出安全模式
//  SysTick_Config( SysTick_LOAD_RELOAD_Msk );          //配置滴答定时器
//  SysTick->CTRL  &= ~SysTick_CTRL_TICKINT_Msk ;   /* disable SysTick IRQ */
  tmos_memset(&cfg,0,sizeof(bleConfig_t));
	cfg.MEMAddr  		= (u32)MEM_BUF;
	cfg.MEMLen   		= (u32)BLE_MEMHEAP_SIZE;         //蓝牙协议栈使用的RAM大小，不小于6K
	cfg.BufMaxLen		= (u32)BLE_BUFF_MAX_LEN;         //单个连接最大包长度
	cfg.BufNumber		= (u32)BLE_BUFF_NUM;             //控制器缓存的包数量
	cfg.TxNumEvent  = (u32)BLE_TX_NUM_EVENT;         //单个连接事件最多可以发多少个数据包
	cfg.TxPower			= (u32)BLE_TX_POWER;            //蓝牙发射功率
#if (defined (BLE_SNV)) && (BLE_SNV == TRUE)
	cfg.SNVAddr			= (u32)BLE_SNV_ADDR;
#endif
#if( CLK_OSC32K )	
	cfg.SelRTCClock	= (u32)CLK_OSC32K;
#endif
	cfg.ConnectNumber  = (PERIPHERAL_MAX_CONNECTION&3)|(CENTRAL_MAX_CONNECTION<<2);     //
  cfg.srandCB = SYS_GetSysTickCnt;                                                    //注册生成随机种子的程序
#if (defined TEM_SAMPLE)  && (TEM_SAMPLE == TRUE)
  cfg.tsCB = HAL_GetInterTempValue;  // 根据温度变化校准RF和内部RC( 大于7摄氏度 )
#if( CLK_OSC32K )
  cfg.rcCB = Lib_Calibration_LSI; // 内部32K时钟校准  
#endif
#endif
#if (defined (HAL_SLEEP)) && (HAL_SLEEP == TRUE)
  cfg.WakeUpTime = WAKE_UP_RTC_MAX_TIME;  
  cfg.sleepCB = CH57X_LowPower;  // 启用睡眠
#endif
#if (defined (BLE_MAC)) && (BLE_MAC == TRUE)
	for(i=0;i<6;i++) cfg.MacAddr[i]  = MACAddr[5-i];     //MAC地址
#endif
	if( !cfg.MEMAddr || cfg.MEMLen < 4*1024 )while(1);
#if (defined 	HAL_SLEEP) && (HAL_SLEEP == TRUE)
	if( (u32)MEM_BUF < (u32)0x20003800 ){
    PRINT("RAM config error...\n");
		PRINT("MEM_BUF：%p\n", MEM_BUF);
		PRINT("BLE_MEMHEAP_SIZE：%d\n", BLE_MEMHEAP_SIZE);
		
    while(1);
  }		
#endif
  i = BLE_LibInit( &cfg );
  if(i){
    PRINT("LIB init error code: %x ...\n",i);
    while(1);
  }
}

#endif

/*******************************************************************************
 * @fn          HAL_ProcessEvent
 *
 * @brief       硬件层事务处理
 *
 * input parameters
 *
 * @param       task_id.
 * @param       events.
 *
 * output parameters
 *
 * @param       events.
 *
 * @return      None.
 */
tmosEvents HAL_ProcessEvent( tmosTaskID task_id, tmosEvents events )
{
	uint8 * msgPtr;

  if( events & SYS_EVENT_MSG ){  // 处理HAL层消息，调用tmos_msg_receive读取消息，处理完成后删除消息。
		msgPtr = tmos_msg_receive(task_id);   //receive a msg
    if( msgPtr ){
      /* De-allocate */
      tmos_msg_deallocate( msgPtr );  //delete a msg
    }
    return events ^ SYS_EVENT_MSG;
	}
  if ( events & LED_BLINK_EVENT ){
#if (defined HAL_LED) && (HAL_LED == TRUE)
  	HalLedUpdate( );
#endif // HAL_LED
		return events ^ LED_BLINK_EVENT;
  }
  if( events & HAL_KEY_EVENT ){
#if (defined HAL_KEY) && (HAL_KEY == TRUE)
    HAL_KeyPoll();              /* Check for keys */
    if (!Hal_KeyIntEnable){        
			tmos_start_task( halTaskID, HAL_KEY_EVENT, MS1_TO_SYSTEM_TIME(100) );
    }
		return events ^ HAL_KEY_EVENT;
#endif
  }
  if( events & HAL_REG_INIT_EVENT ){
#if (defined BLE_CALIBRATION_ENABLE) && (BLE_CALIBRATION_ENABLE == TRUE)	// 校准任务，单次校准耗时小于10ms
    BLE_RegInit();  // 校准RF
#if( CLK_OSC32K )	
    Lib_Calibration_LSI();  // 校准内部RC
#endif
    tmos_start_task( halTaskID , HAL_REG_INIT_EVENT ,MS1_TO_SYSTEM_TIME(BLE_CALIBRATION_PERIOD) ); 
		return events ^ HAL_REG_INIT_EVENT;
#endif
  }
  if( events & HAL_TEST_EVENT ){
    PRINT("* ");
    tmos_start_task( halTaskID , HAL_TEST_EVENT ,MS1_TO_SYSTEM_TIME(10000) ); 
		return events ^ HAL_TEST_EVENT;
  }
  return 0;
}

/*******************************************************************************
 * @fn          HAL_Init
 *
 * @brief       硬件初始化
 *
 * input parameters
 *
 * @param       None.
 *
 * output parameters
 *
 * @param       None.
 *
 * @return      None.
 */
 void HAL_Init( )
{
  halTaskID = TMOS_ProcessEventRegister( HAL_ProcessEvent );    //注册一个 TMOS 回调函数，并分配 ID
  HAL_TimeInit( );
#if (defined HAL_SLEEP) && (HAL_SLEEP == TRUE)
  HAL_SleepInit( );
#endif
#if (defined HAL_LED) && (HAL_LED == TRUE)
  HAL_LedInit( );
#endif
#if (defined HAL_KEY) && (HAL_KEY == TRUE)
  HAL_KeyInit( );
#endif
  __enable_irq();
#if (defined BLE_CALIBRATION_ENABLE) && (BLE_CALIBRATION_ENABLE == TRUE)
	tmos_start_task( halTaskID , HAL_REG_INIT_EVENT ,MS1_TO_SYSTEM_TIME(BLE_CALIBRATION_PERIOD) );	// 添加校准任务，单次校准耗时小于10ms
#endif
//  tmos_start_task( halTaskID , HAL_TEST_EVENT ,1000 ); // 添加一个测试任务
}

/*******************************************************************************
 * @fn          LLE_IRQHandler
 *
 * @brief       LLE interrupt function 
 *
 * input parameters
 *
 * @param       None.
 *
 * output parameters
 *
 * @param       None.
 *
 * @return      None.
 */
void LLE_IRQHandler(void)
{
  BLE_IRQHandler();
}

/*******************************************************************************
 * @fn          HAL_GetInterTempValue
 *
 * @brief       None.
 *
 * input parameters
 *
 * @param       None.
 *
 * output parameters
 *
 * @param       None.
 *
 * @return      None.
 */
uint16 HAL_GetInterTempValue( void )
{
  uint8 sensor,channel,config;
  uint16 adc_data;
  
  sensor  = R8_TEM_SENSOR;
  channel = R8_ADC_CHANNEL;
  config  = R8_ADC_CFG;
  R8_TEM_SENSOR |= RB_TEM_SEN_PWR_ON;
  R8_ADC_CHANNEL = CH_INTE_VTEMP;
  R8_ADC_CFG = RB_ADC_POWER_ON|( 2<<4 )	;
  R8_ADC_CONVERT |= RB_ADC_START;
  while( R8_ADC_CONVERT & RB_ADC_START );
  adc_data = R16_ADC_DATA;
  R8_TEM_SENSOR  = sensor;
  R8_ADC_CHANNEL = channel;
  R8_ADC_CFG = config;
  return( adc_data );
}

/******************************** endfile @ mcu ******************************/
