Index: yc_bt.h
===================================================================
--- /YC3121_SDK/fw/sdk/yc_bt.h	(revision 754)
+++ /YC3121_SDK/fw/sdk/yc_bt.h	(working copy)
@@ -68,6 +68,7 @@
 #define BIT_BNEP_SEND_TCP_BIG_DATA        39
 #define BIT_BNEP_SEND_TCP_BIG_DATA_FINISH 40
 #define BIT_BNEP_SEND_TCP_BIG_DATA_STATUS 41
+#define BIT_SET_LPM_MODE                  42
 /*CMD*/
 #define HCI_CMD_SET_BT_ADDR               0x00  //设置 BT3.0 地址
 #define HCI_CMD_SET_BLE_ADDR              0x01  //设置 BLE 地址
@@ -106,6 +107,7 @@
 #define HCI_CMD_DNS_REQ                   0x82 //域名解析指令
 #define HCI_CMD_SEND_UDP_DATA             0x84 //发送UDP数据
 #define HCI_CMD_SEND_BIG_DATA             0x85 //发送TCP大包数据
+#define HCI_CMD_SET_LPM_MODE              0xff //开关低功耗
 
 
 /*EVENT*/
@@ -321,7 +323,7 @@
 
 
 /**
-  * @brief  Bt Enter Sleep mode
+  * @brief  Bt Enter Sleep mode(enter_hibernate)
   * @param  none
   * @retval TRUE:enter sleep mode success
   *
@@ -329,6 +331,15 @@
 Boolean BT_EnterSleepMode(void);
 
 
+/**
+  * @brief  Bt set LPM mode
+  * @param  mode:0x00-close LPM mode; 0x01-open LPM mode
+  * @retval TRUE or FALSE
+  *
+  */
+Boolean BT_SetLpmMode(uint8_t mode);
+
+
 
 /**
   * @brief  Numeric Comparison key matching in paring mode
Index: yc_bt.c
===================================================================
--- /YC3121_SDK/fw/sdk/yc_bt.c	(revision 754)
+++ /YC3121_SDK/fw/sdk/yc_bt.c	(working copy)
@@ -2,6 +2,10 @@
 #include "yc_systick.h"
 #include "yc_timer.h"
 #include "yc_ipc.h"
+
+#define BT_LOG	0
+
+
 static tick StartTick;
 static uint32_t HCI_CMD_BIT_FLAG[2]={0};
 #define BTTIMEOUT 500
@@ -58,7 +62,9 @@
 {
 	BluetoothBuf.ReadIndex+=Num;
 	if(BluetoothBuf.ReadIndex>=BluetoothBuf.BufSize)	BluetoothBuf.ReadIndex-=BluetoothBuf.BufSize;
+	NVIC_DisableIRQ(BT_IRQn);
 	BluetoothBuf.count-=Num;
+	NVIC_EnableIRQ(BT_IRQn);
 }
 
 static void SaveData(uint8_t* data,int len)
@@ -156,7 +162,9 @@
 	TempData=BluetoothBuf.pBuf[BluetoothBuf.ReadIndex];
 	if(UpdataAnalyzeIndex)
 	{
+		NVIC_DisableIRQ(BT_IRQn);
 		BluetoothBuf.count--;
+		NVIC_EnableIRQ(BT_IRQn);
 		BluetoothBuf.ReadIndex++;
 		if(BluetoothBuf.ReadIndex>=BluetoothBuf.BufSize)	BluetoothBuf.ReadIndex=0;
 	}
@@ -480,6 +488,27 @@
 	return TRUE;
 }
 
+extern uint8_t bt_lpm_mode;
+Boolean BT_SetLpmMode(uint8_t mode)
+{
+	HCI_TypeDef msg;
+	bt_lpm_mode = mode;
+	msg.opcode = HCI_CMD_SET_LPM_MODE;
+	msg.DataLen =1;
+	msg.p_data = &bt_lpm_mode;
+	BT_BIT_CLEAR(HCI_CMD_BIT_FLAG,BIT_SET_LPM_MODE);
+	SendCMD(&msg);
+	StartTick=SysTick_GetTick();
+	do
+	{
+		if(BT_BIT_GET(HCI_CMD_BIT_FLAG,BIT_SET_LPM_MODE))
+		{
+			return TRUE;
+		}
+	}  while(!SysTick_IsTimeOut(StartTick, BTTIMEOUT));
+	return FALSE;
+}
+
 
 Boolean BT_ConfirmGkey(uint8_t isMatching)
 {
@@ -505,7 +534,7 @@
 {
 	HCI_TypeDef msg;
 	msg.opcode = HCI_CMD_GET_CREADIT_GIVEN;
-	msg.DataLen =0;
+	msg.DataLen =1;
 	uint8_t temp_packetNum=packetNum;
 	msg.p_data = &temp_packetNum;
 	BT_BIT_CLEAR(HCI_CMD_BIT_FLAG,BIT_GET_CREADIT_GIVEN);
@@ -1163,6 +1192,13 @@
 							}
 							break;
 
+						case HCI_CMD_SET_LPM_MODE:
+							if(!hci_bt.p_data[1])
+							{
+								BT_BIT_SET(HCI_CMD_BIT_FLAG,BIT_SET_LPM_MODE);
+							}
+							break;
+
 						case HCI_CMD_PASSKEY_ENTRY:
 							if(!hci_bt.p_data[1])
 							{
@@ -1358,7 +1394,9 @@
 	{
 		SkipData(3);
 	}
+	NVIC_DisableIRQ(BT_IRQn);
 	PacketNum--;
+	NVIC_EnableIRQ(BT_IRQn);
 	return TempOpcode;
 }
 
@@ -1373,11 +1411,11 @@
 	SkipData(1);
 	OpCode=GetData(TRUE);
 	len=GetData(TRUE);
-	if(OpCode==BLE_DATA)
-	{
-		len-=2;//ble handle 处理
-		SkipData(2);
-	}
+//	if(OpCode==BLE_DATA)
+//	{
+//		len-=2;//ble handle 处理
+//		SkipData(2);
+//	}
 	for(i=0;i<len;i++)
 	{
 		pbuf[i]=GetData(TRUE);
Index: yc_ipc.h
===================================================================
--- /YC3121_SDK/fw/sdk/yc_ipc.h	(revision 754)
+++ /YC3121_SDK/fw/sdk/yc_ipc.h	(working copy)
@@ -18,6 +18,12 @@
 #define RB_UPDATE_PTR(p,s,e)       ((p) == (e))?((p)=(s)):((p)++)
 #define M0_BASE_ADDR               0xC0000
 
+#define MEM_SPP_FLOWCTRL_FLAG_ADDR    (0xc453d)
+#define MEM_SPP_FLOWCTRL_FLAG_VALUE   (0x01)	//0x00:disable flowctrl  0x01:enable flowctrl
+
+#define MEM_RFCOMM_LMP_DIS_FLAG_ADDR	(0xc4acf)
+#define MEM_RFCOMM_LMP_DIS_FLAG_VALUE	(0x00)	//0x00:յ rfcomm disconnected Ͽlmp   0x01:յrfcomm disconnectedϿlmp
+
 #pragma pack(1)
 typedef struct
 {
Index: yc_ipc.c
===================================================================
--- /YC3121_SDK/fw/sdk/yc_ipc.c	(revision 754)
+++ /YC3121_SDK/fw/sdk/yc_ipc.c	(working copy)
@@ -6,6 +6,7 @@
 IPC_TypeDef *IpcTx = (IPC_TypeDef *)(IPC_TX_START_ADDR);
 
 uint8_t ipcrecbuf[IPCREVSIZE] = {0};
+uint8_t bt_lpm_mode=0;
 
 Boolean IPC_have_data()
 {
@@ -14,6 +15,13 @@
 
 uint16_t IPC_get_available_size()
 {
+		uint16_t retLen=0;
+		if(bt_lpm_mode==1)
+		{
+			WAKEUP_BT |= (1 << WAKEUP_BT_FLAG);
+			IPC_HOLD_BT  = 1;
+			delay_ms(10);
+		}
     uint16_t readtx = HR_REG_16BIT(&IpcTx->ReadPtr);
     uint16_t wrtptr = HR_REG_16BIT(&IpcTx->WrtiePtr);
     uint16_t ipcendaddr = HR_REG_16BIT(&IpcTx->IpcEndAddr);
@@ -21,12 +29,18 @@
 
     if (readtx > wrtptr)
     {
-        return readtx - wrtptr;
+        retLen = readtx - wrtptr;
     }
     else
     {
-        return ((ipcendaddr - ipcstartaddr + 1) - (readtx - wrtptr));
+        retLen = ((ipcendaddr - ipcstartaddr + 1) - (readtx - wrtptr));
     }
+		if(bt_lpm_mode==1)
+		{
+			IPC_HOLD_BT = 0;
+			WAKEUP_BT &= ~(1 << WAKEUP_BT_FLAG);
+		}
+		return retLen;
 }
 
 void IPC_TxData(HCI_TypeDef *IpcData)
@@ -34,9 +48,12 @@
 	#ifdef IPC_DEBUG
 	PrintHCIPack(IpcData,"tx");
 	#endif
-    WAKEUP_BT |= (1 << WAKEUP_BT_FLAG);
-    IPC_HOLD_BT  = 1;
-    delay_ms(10);
+		if(bt_lpm_mode==1)
+		{
+			WAKEUP_BT |= (1 << WAKEUP_BT_FLAG);
+			IPC_HOLD_BT  = 1;
+			delay_ms(10);
+		}
     uint16_t Wptr  = HR_REG_16BIT(&IpcTx->WrtiePtr);
     uint16_t Len   = IpcData->DataLen + 3;
     uint8_t *Rptr = (uint8_t *)IpcData;
@@ -49,8 +66,11 @@
     }
 
     HW_REG_16BIT(&IpcTx->WrtiePtr, (uint32_t)Wptr);
-    IPC_HOLD_BT = 0;
-    WAKEUP_BT &= ~(1 << WAKEUP_BT_FLAG);
+		if(bt_lpm_mode==1)
+		{
+			IPC_HOLD_BT = 0;
+			WAKEUP_BT &= ~(1 << WAKEUP_BT_FLAG);
+		}
 }
 
 Boolean IPC_PutBtData(const void *buf, uint32_t size)
@@ -176,7 +196,23 @@
         btcode += 2;
         addr = GETWORD(btcode) | 0xc0000;
         btcode += 2;
-        _dmacopy((byte *)addr, (byte *)btcode, len);
+        if(addr==MEM_SPP_FLOWCTRL_FLAG_ADDR && len==0x0004)
+        {
+            byte mem_spp_flowctrl_buf[4];
+            mem_spp_flowctrl_buf[0]=MEM_SPP_FLOWCTRL_FLAG_VALUE;
+            memcpy((byte*)&mem_spp_flowctrl_buf[1],btcode+1,3);
+            _dmacopy((byte *)addr, mem_spp_flowctrl_buf, len);
+        }
+        else if(addr==MEM_RFCOMM_LMP_DIS_FLAG_ADDR && len==0x0001)
+        {
+            byte mem_rfcomm_lmp_dis_flag;
+            mem_rfcomm_lmp_dis_flag=MEM_RFCOMM_LMP_DIS_FLAG_VALUE;
+            _dmacopy((byte *)addr, (byte *)&mem_rfcomm_lmp_dis_flag, len);
+        }
+        else
+        {
+          _dmacopy((byte *)addr, (byte *)btcode, len);
+        }
         btcode += len;
     }
 }
@@ -197,7 +233,9 @@
 {
     uint16_t addr = 0;
     addr  = (*(uint8_t *)(0xc800e));
+    delay_us(1100);
     addr += (*(uint8_t *)(0xc800f)) << 8;
+    delay_us(1100);
     return addr;
 }
 
@@ -245,11 +283,12 @@
         disable_intr(INTR_BT);
         ipc_inited = TRUE;
 
-        lpm_bt_write(1, 0xd00000);
-        delay_us(1000);
-
         SYSCTRL_ROM_SWITCH = 0x94;
         delay(10000);   //wait rom switch ok
+
+        lpm_bt_write(1, 0xd00000);
+        delay_us(1000);
+        
         BT_RESET = 1;
         delay(10000);   //wait for reset ok
         while (!(BT_CONFIG & (1 << BT_INIT_FLAG)));
@@ -278,7 +317,7 @@
     {
         MyPrintf("%02x ", msg->p_data[cnt]);
         if ((cnt % 16) == 0&&cnt!=0)
-            MyPrintf("\n");
+        MyPrintf("\n");
     }
     MyPrintf("\n");
 }
