nrf52810蓝牙芯片led应用组件,句柄操作led 亮灭,包括大数据传输和flash读写操作

#include  "uart_big_data.h"
#include  "ble_nus.h"  




#define  BIG_DATA_HEADER     0x48
#define  UART_FRAME_LENTH    20
#define  SERIAL_NUM_SIZE     2
#define  HEADER_SIZE         1
#define  START_SERIAL_NUM    1
#define  FILL_BOX_NUM        100
#define  START_MAX_SERIAL    100
#define  BIG_DATA_RX_CMD     BIG_DATA_HEADER
#define  BIG_DATA_START_CMD    0x4A
#define  BIG_DATA_END_CMD      0x49
#define  FRAME_PUT_IN_MAX_NUM  100


static  uint8_t  BigDataRxStatus = 0;
static  uint8_t  FrameFillSerial = START_SERIAL_NUM;  
static  uint8_t  FrameFillIndex  = 0;


static  uint8_t  InvalidUartFrameNum;
static  uint8_t  InvalidUartFramePos[FILL_BOX_NUM];
static  uint8_t  BigDataCmdSta;
static  bool  BigDataBleTxStart;




#define  BLE_TX_DATA_MAX_SIZE    20
#define  BLE_REPLY_SIZE          15


#define  CENTRAL_BIG_DATA_RX_START_CMD    0x4D
#define  CENTRAL_BIG_DATA_RX_END_CMD      0x4E
#define  CENTRAL_BIG_DATA_RX_PROGRE_CMD   0x4F




#define  BIG_DATA_START_EVT    1
#define  BIG_DATA_SEND_EVT     2




typedef  struct
{
uint8_t  CentralBleBigDataRxCmdType;
    uint8_t  CentralBleTxStoreBuf[BLE_TX_DATA_MAX_SIZE];
 uint16_t CentralBleRxBytes;
 uint8_t  CentralBleReply[BLE_REPLY_SIZE];
 uint8_t  CentralReplyLenth;
}BleBigDataTx_t;


static BleBigDataTx_t   BleBigDataTx;




void  UartBigDataRxHandle(uint8_t *UartFrameData, uint8_t *RxStaCtrlType)
{
   uint8_t   i;
   uint16_t  CurSerialNum;
   bool  IsFrameHeadOk = true;
   uint8_t  UartBigDataFrame[UART_FRAME_LENTH];
   
   if(UartFrameData[0] != BIG_DATA_HEADER)
{
printf("\r\nbig data frame header error  0x48 is ok\r\n");
 IsFrameHeadOk  = false;
}


i = 0;
      while(UartFrameData[i] != '\n')
      {
i++;
}


      if(i != (GetUartFrameDataLenth() + SERIAL_NUM_SIZE + HEADER_SIZE))
      {
printf("\r\n uart frame lenth error  23 bytes is ok\r\n");
 return;
}

if(IsFrameHeadOk == false)
{
return;
}

CurSerialNum = (((uint16_t)UartFrameData[1]) << 8) | ((uint16_t)UartFrameData[2]);

switch(BigDataRxStatus)
      {
case  0: 
if(CurSerialNum != FrameFillSerial)
{
printf("\r\nstart frame serial number error\r\n");
   return;
}
else
{
   printf("\r\nUart frame buffer fill in ok\r\n");
   SetUartFrameInvalidPosSeriNum(FrameFillIndex, CurSerialNum);
   memcpy(UartBigDataFrame, &UartFrameData[3], sizeof(UartBigDataFrame));
   FillUartFrameToCorrectAdd(FrameFillIndex, UartBigDataFrame);
   SetCurMaxFrameSeriNum(CurSerialNum);
   SetCurTxFrameSerial(START_SERIAL_NUM);
   
   FrameFillIndex++;
   FrameFillSerial++;
   
   if(FrameFillIndex >= FILL_BOX_NUM)
{
FrameFillIndex  = 0;
 FrameFillSerial = START_SERIAL_NUM;
 BigDataRxStatus = 1;
 SetCurMaxFrameSeriNum(START_MAX_SERIAL);
 SetCurTxFrameSerial(START_SERIAL_NUM);
 *RxStaCtrlType  = 2;
}
}
break;
 
case  1:
 
  if(GetCurMaxFrameSeriNum() >= GetUartFrameMaxRxSeri())
{
printf("\r\nUart frame Rx  should be end\r\n");
   *RxStaCtrlType  = 1;
   break;
}
memset(InvalidUartFramePos, 0, sizeof(InvalidUartFramePos));
  InvalidUartFrameNum  = 0;
GetUartFrameTransferInPrama(&InvalidUartFrameNum, InvalidUartFramePos);

  if(InvalidUartFrameNum > 0)
{
if(CurSerialNum == (GetCurMaxFrameSeriNum()+1))
{
 printf("\r\nUart Rx Handle Enable\r\n");
SetCurMaxFrameSeriNum(CurSerialNum);
 SetUartFrameInvalidPosSeriNum(InvalidUartFramePos[0],CurSerialNum); 
 InvalidUartFrameNum--;
 memcpy(UartBigDataFrame, &UartFrameData[3], sizeof(UartBigDataFrame));
 FillUartFrameToCorrectAdd(InvalidUartFramePos[0], UartBigDataFrame);
 if(InvalidUartFrameNum != 0)
{
BigDataRxStatus  = 2;
 for(i = 0; i < InvalidUartFrameNum; i++)
 {
InvalidUartFramePos[i] = InvalidUartFramePos[i+1];
}
}
}
else
{
printf("\r\nUart frame serial number error\r\n");
}
}
else
{
   prinrf("\r\nNo Memory for Uart Rx, Tx On Busy\r\n");
}
break;  
 
case  2:
 
   if(GetCurMaxFrameSeriNum() >= GetUartFrameMaxRxSeri())
{
printf("\r\nUart frame Rx  should be end\r\n");
 *RxStaCtrlType  = 1;
   break;
}
 
if(CurSerialNum == (GetCurMaxFrameSeriNum()+1))
{
printf("\r\nUart Rx Handle Enable\r\n");
SetCurMaxFrameSeriNum(CurSerialNum);
 SetUartFrameInvalidPosSeriNum(InvalidUartFramePos[InvalidUartFrameNum - 1],CurSerialNum); 
 memcpy(UartBigDataFrame, &UartFrameData[3], sizeof(UartBigDataFrame));
 FillUartFrameToCorrectAdd(InvalidUartFramePos[InvalidUartFrameNum - 1], UartBigDataFrame);
 InvalidUartFrameNum--;
 if(InvalidUartFrameNum == 0)
{
BigDataRxStatus  = 1;
}
}
else
{
printf("\r\nUart frame serial number error\r\n");
}
break;
}
}








void   BigDataHandleInit(void)
{
BigDataRxStatus   = 0;
   FrameFillSerial   = START_SERIAL_NUM;
   FrameFillIndex    = 0;
   BigDataBleTxStart = false;
}








void   UartBigDataCmdProcess(const uint8_t *UartFrameCmdDat)
{
   uint8_t  RxStaCtrlType = 0;
   uint8_t  i;
   

   switch(BigDataCmdSta)
{
case  0:
if(UartFrameCmdDat[0] == BIG_DATA_START_CMD)
{
   if((CurUartFrameCanPutInNum() == FRAME_PUT_IN_MAX_NUM) && (GetLastUartFrameTxSta()))
{
BigDataCmdSta  = 1;
printf("\r\nBig data Uart frame can start rx\r\n");
InitUartBigDataAppParma();
BigDataHandleInit();
}
else
{
printf("\r\nBig data buffer busy on tx\r\n");
}
}
else
{
printf("\r\nBig data start rx cmd error\r\n");
}
break;
 
case  1:
if(UartFrameCmdDat[0] == BIG_DATA_RX_CMD)
{
UartBigDataRxHandle(UartFrameCmdDat, &RxStaCtrlType);
 
   if(RxStaCtrlType == 1)
{
BigDataCmdSta  = 2;
   printf("\r\nPlease let rx end\r\n");
   SetUartFrameRxFinish();
 }
else if(RxStaCtrlType == 2)
{
//启动蓝牙向手机发送大数据命令
 BigDataBleTxStart  = true;
 BigDataTaskAction(BIG_DATA_START_EVT, 10);
}
}
else if(UartFrameCmdDat[0] == BIG_DATA_END_CMD)
{
   if(UartFrameCmdDat[1] == 0)
{
SetLastUartFrameTxSta(1);
}
else if((UartFrameCmdDat[1] != 0) && (UartFrameCmdDat[1] <= GetUartFrameDataLenth()))
{
StoreLastUartFrameTxData(UartFrameCmdDat[1], &UartFrameCmdDat[2]);
 SetLastUartFrameTxSta(0);
}
BigDataCmdSta = 0;
SetUartFrameRxFinish();

if(BigDataBleTxStart == false)
{
 //启动蓝牙向手机发送大数据命令
BigDataBleTxStart  = true;
 BigDataTaskAction(BIG_DATA_START_EVT, 10);
}
}
else
{
printf("\r\nbig data frame header error  0x48 is ok\r\n");
}
break;
 
case  2:
if(UartFrameCmdDat[0] == BIG_DATA_END_CMD)
{
if(UartFrameCmdDat[1] == 0)
{
SetLastUartFrameTxSta(1);
}
else if((UartFrameCmdDat[1] != 0) && (UartFrameCmdDat[1] <= GetUartFrameDataLenth()))
{
StoreLastUartFrameTxData(UartFrameCmdDat[1], &UartFrameCmdDat[2]);
   SetLastUartFrameTxSta(0);
}
BigDataCmdSta = 0;
}
else
{
printf("\r\nbig data end command error \r\n");
}
break;
}
}








void  big_data_evt_create(void)
{
uint32_t err_code;

   err_code = app_timer_create(&BigDataClock, APP_TIMER_MODE_SINGLE_SHOT, BigDataStartHandle);
   APP_ERROR_CHECK(err_code);

   err_code = app_timer_create(&BigDataTxClock, APP_TIMER_MODE_SINGLE_SHOT, BigDataTxProgreHandle);
   APP_ERROR_CHECK(err_code);
}






void  BigDataTaskAction(uint8_t TaskId, uint16_t TaskDelay)
{
   uint32_t err_code;
switch(TaskId)
{
 case  BIG_DATA_START_EVT:
 err_code = app_timer_start(BigDataClock, APP_TIMER_TICKS(TaskDelay), NULL);
     APP_ERROR_CHECK(err_code);
 break;

case  BIG_DATA_SEND_EVT:
 err_code = app_timer_start(BigDataTxClock, APP_TIMER_TICKS(TaskDelay), NULL);
     APP_ERROR_CHECK(err_code);
 break;
}
}






void  BigDataTaskStop(uint8_t TaskId)
{
uint32_t err_code;
   switch(TaskId)
{
case  BIG_DATA_START_EVT:
err_code  = app_timer_stop(&BigDataClock);
   APP_ERROR_CHECK(err_code);
   break;

case  BIG_DATA_SEND_EVT:
 err_code  = app_timer_stop(&BigDataTxClock);
   APP_ERROR_CHECK(err_code);
   break;
}
}








void BigDataStartHandle(void * p_context)
{
   uint32_t err_code;

   BleBigDataTx.CentralBleBigDataRxCmdType  = CENTRAL_BIG_DATA_RX_START_CMD;
memset(BleBigDataTx.CentralBleTxStoreBuf, 0, sizeof(BleBigDataTx.CentralBleTxStoreBuf));
BleBigDataTx.CentralBleTxStoreBuf[0] = BleBigDataTx.CentralBleBigDataRxCmdType;
   BleBigDataTx.CentralBleRxBytes  =  1;

   if(Tx_Rx_Nux.conn_handle != BLE_CONN_HANDLE_INVALID)
{
err_code = BleAirDataTxStartCmdSend(&BleBigDataTx);

 if ( (err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY) )
{
APP_ERROR_CHECK(err_code);
}

if(err_code  == NRF_SUCCESS)
{
BigDataTaskAction(BIG_DATA_START_EVT, 10000);
 FillBigDataReplyString("startcmdok",  sizeof("startcmdok") - 1);
}
   else if(err_code == NRF_ERROR_BUSY)
{
BigDataTaskAction(BIG_DATA_START_EVT, 10);
}
}
else
{
BigDataTaskAction(BIG_DATA_START_EVT, 5000);
}
}






void  BigDataTxProgreHandle(void * p_context)
{
   uint16_t  CurTxFrame;
      uint8_t   CurTxFrameOperaAddr;
      uint32_t  err_code;  

if(Tx_Rx_Nux.conn_handle != BLE_CONN_HANDLE_INVALID)
{
  if(!IsUartFrameArriveEnd())
{
  CurTxFrame  =  GetCurTxFrameSerial();
if(CurTxFrame <= GetCurMaxFrameSeriNum())
{
CurTxFrameOperaAddr  =  GetUartFrameDataTabOperaAddr(CurTxFrame);
   memset(BleBigDataTx.CentralBleTxStoreBuf, 0, sizeof(BleBigDataTx.CentralBleTxStoreBuf));
   GetUartFrameFromDataTab(CurTxFrameOperaAddr, BleBigDataTx.CentralBleTxStoreBuf);
   BleBigDataTx.CentralBleRxBytes  = sizeof(BleBigDataTx.CentralBleTxStoreBuf);
   err_code = BleAirDataTxStartCmdSend(&BleBigDataTx);
 
   if ( (err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY) )
{
APP_ERROR_CHECK(err_code);
}

if(err_code  ==  NRF_SUCCESS)
{
BigDataTaskAction(BIG_DATA_SEND_EVT, 10000);
   FillBigDataReplyString("sendframeok",  sizeof("sendframeok") - 1);
}
else if(err_code  == NRF_ERROR_BUSY)
{
BigDataTaskAction(BIG_DATA_SEND_EVT, 10);
}
}
else
{
BigDataTaskAction(BIG_DATA_SEND_EVT, 300);
}
}
else
{
CurTxFrame  =  GetCurTxFrameSerial();
   if(CurTxFrame == (GetCurMaxFrameSeriNum()+1))
{
if(GetLastUartFrameTxSta() == 0)  //最后一帧有数据要发
{
memset(BleBigDataTx.CentralBleTxStoreBuf, 0, sizeof(BleBigDataTx.CentralBleTxStoreBuf));
   GetLastUartFrameTxParma(&BleBigDataTx.CentralBleRxBytes, BleBigDataTx.CentralBleTxStoreBuf);
   err_code = BleAirDataTxStartCmdSend(&BleBigDataTx);

   if ( (err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY) )
       {
     APP_ERROR_CHECK(err_code);
       }

if(err_code == NRF_SUCCESS)
{
BigDataTaskAction(BIG_DATA_SEND_EVT, 10000);
 FillBigDataReplyString("endframeok",  sizeof("endframeok") - 1);
}
else if(err_code  == NRF_ERROR_BUSY)
{
BigDataTaskAction(BIG_DATA_SEND_EVT, 10);
}
}
}
else
{
CurTxFrameOperaAddr  =  GetUartFrameDataTabOperaAddr(CurTxFrame);
   memset(BleBigDataTx.CentralBleTxStoreBuf, 0, sizeof(BleBigDataTx.CentralBleTxStoreBuf));
   GetUartFrameFromDataTab(CurTxFrameOperaAddr, BleBigDataTx.CentralBleTxStoreBuf);
   BleBigDataTx.CentralBleRxBytes  = sizeof(BleBigDataTx.CentralBleTxStoreBuf);
   err_code = BleAirDataTxStartCmdSend(&BleBigDataTx);
   
   if ( (err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY) )
 {
APP_ERROR_CHECK(err_code);
 }

if(err_code  ==  NRF_SUCCESS)
{
BigDataTaskAction(BIG_DATA_SEND_EVT, 10000);
    FillBigDataReplyString("sendframeok",  sizeof("sendframeok") - 1);
}
else if(err_code  == NRF_ERROR_BUSY)
 {
BigDataTaskAction(BIG_DATA_SEND_EVT, 10);
 }
}
}
}
else
{
BigDataTaskAction(BIG_DATA_SEND_EVT, 2000);
}
}




void  FillBigDataReplyString(uint8_t *ReplyStr,  uint8_t FillSize)
{
   memset(BleBigDataTx.CentralBleReply, 0, sizeof(BleBigDataTx.CentralBleReply));
memcpy(BleBigDataTx.CentralBleReply, ReplyStr, FillSize);
   BleBigDataTx.CentralReplyLenth  = FillSize;
}






void  BleBigDataReplyProcess(void)
{
   uint16_t  CurTxFrame;

 if(strncmp(APP_ReceiveData, BleBigDataTx.CentralBleReply, BleBigDataTx.CentralReplyLenth) == 0)
{
if(strncmp(BleBigDataTx.CentralBleReply, "startcmdok", sizeof("startcmdok") - 1) == 0)
{
BigDataTaskStop(BIG_DATA_START_EVT);
   BigDataTaskAction(BIG_DATA_SEND_EVT, 50);
}
else if(strncmp(BleBigDataTx.CentralBleReply, "sendframeok", sizeof("sendframeok") - 1) == 0)
{
BigDataTaskStop(BIG_DATA_SEND_EVT);
   BigDataTaskAction(BIG_DATA_SEND_EVT, 2);
   CurTxFrame  =  GetCurTxFrameSerial();
   SetCurTxFrameSerial(CurTxFrame + 1);
   SetUartFrameSerialNumInvalid(GetUartFrameDataTabOperaAddr(CurTxFrame));
}
else if(strncmp(BleBigDataTx.CentralBleReply, "endframeok", sizeof("endframeok") - 1) == 0)
{
BigDataTaskStop(BIG_DATA_SEND_EVT);
   BigDataTaskAction(BIG_DATA_SEND_EVT, 50);
   SetLastUartFrameTxSta(1);
}
}
}






uint32_t  BleAirDataTxStartCmdSend(BleBigDataTx_t *BleBigDataTx)
{
   ble_gatts_hvx_params_t hvx_params;

   memset(&hvx_params, 0, sizeof(hvx_params));

   hvx_params.handle = Tx_Rx_Nux.tx_handles.value_handle;
      hvx_params.p_data = BleBigDataTx->CentralBleTxStoreBuf;
      hvx_params.p_len  = &BleBigDataTx->CentralBleRxBytes;
      hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;


      return sd_ble_gatts_hvx(p_nus->conn_handle, &hvx_params);

}


#include  "cmd_packet.h"
#include  "dr_lock_cmd.h"








#define  CMD_STR_SIZE   150






void CalculaLockCmdPacketLrc(LockUartCmd_t *LockUartCmd)
{
   uint8_t  i;
LockUartCmd->Lcr = 0x0000;
   LockUartCmd->Lcr +=  LockUartCmd->lenth;
   LockUartCmd->Lcr +=  LockUartCmd->FunCode;

   for(i = 0; i < LockUartCmd->lenth-1; i++)
   {
LockUartCmd->Lcr += LockUartCmd->Content[i];
}
}








void LockCmdPacketStringToUart(LockUartCmd_t *LockUartCmd)
{
uint8_t  LockCmdStrData[CMD_STR_SIZE];
   uint8_t  i;

   LockCmdStrData[0]  =  LockUartCmd->CmdHeader;
      LockCmdStrData[1]  =  (uint8_t)((LockUartCmd->Lcr >> 8) & 0x000000FF);
      LockCmdStrData[2] =  (uint8_t)(LockUartCmd->Lcr & 0x000000FF);
   LockCmdStrData[3]  =  LockUartCmd->lenth;
   LockCmdStrData[4]  =  LockUartCmd->FunCode;

   for(i = 0; i < LockUartCmd->lenth-1; i++)
   {
LockCmdStrData[i+5] =  LockUartCmd->Content[i];
}

UartSendBytesToDorLock(LockCmdStrData, LockUartCmd->lenth+4);
}



#ifndef   _CMD_PACKET_H_
#define   _CMD_PACKET_H_












#include  "dorlock_user_mgr.h"




void CalculaLockCmdPacketLrc(LockUartCmd_t *LockUartCmd);
void LockCmdPacketStringToUart(LockUartCmd_t *LockUartCmd);



#endif


#include <stdint.h>
#include <string.h>
#include <stdbool.h>


#include "dr_lock_cmd.h"
#include "app_uart.h"
#include "nrf_log.h"
#include "app_scheduler.h"
#include "ble_nus.h"




#define cmdLenMax 128




#define CMD_STATE_IDILE 0
#define CMD_STATE_HEADER 1
#define CMD_STATE_CHECKSUM 2
#define CMD_STATE_LENGTH 3




static uint8_t cmdLine[cmdLenMax];


uint16_t  data_len;


uint8_t state;


void uart_recv(void)
{
static uint8_t *pCmdLine;
uint8_t temp;
static uint8_t index;


    app_uart_get(&temp);
//NRF_LOG_INFO("- %x" , temp);
    switch(state)
    {
case CMD_STATE_IDILE: 
          if(temp == 0xF5) {
 NRF_LOG_INFO("CMD start");
pCmdLine = cmdLine;
*pCmdLine = temp;
pCmdLine++;
 state = CMD_STATE_HEADER;
index = 0;
}
break;

case CMD_STATE_HEADER: 
*pCmdLine = temp;
pCmdLine++;
 index++;


 if(index >= 3) {
 state = CMD_STATE_LENGTH;
              data_len = temp;
 index = 0;
}
break;

case CMD_STATE_LENGTH: 
*pCmdLine = temp;
pCmdLine++;
 index++;
          if(index >= data_len ) {

state = CMD_STATE_IDILE;
NRF_LOG_INFO("data_len %d" ,data_len);
            //NRF_LOG_HEXDUMP_DEBUG(cmdLine, data_len+4);
scheduler_proc(recv_proc);
}
break;


default:


state = CMD_STATE_IDILE;
break;


}

}






void recv_proc(void )
{
// ble_send_data(cmdLine,data_len+4);
//  ProxReporter_SetParameter(&Tx_Rx_Nux, uint8_t * p_string, uint16_t * p_length);
   LockUartReplyProcess(cmdLine,data_len+4);
}












void scheduler_proc(sched_handler_t pro_func)
{


 app_sched_event_put(NULL, 0, (app_sched_event_handler_t)pro_func);


    NRF_LOG_INFO("scheduler_proc");
}




void  DisplayOneByte(uint8_t  ShowByte)
{
 uint32_t err_code; 
do
    {
                err_code = app_uart_put(ShowByte);
                if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY))
                {
                    NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code);
                    APP_ERROR_CHECK(err_code);
                }
    } while (err_code == NRF_ERROR_BUSY);
}






void  UartSendBytesToDorLock(uint8_t *p_data_tx_buf, uint16_t size_bytes)
{
 for (uint32_t i = 0; i < size_bytes; i++)
    {
          DisplayOneByte(p_data_tx_buf[i]);  
    }
}








void  DisplayWholeChrater(uint8_t *p_data_tx_buf, uint8_t EndChar)
{
 uint8_t  LastByte = '\n';
 for(uint32_t i = 0; p_data_tx_buf[i] != EndChar; i++)
 {
DisplayOneByte(p_data_tx_buf[i]); 
}

DisplayOneByte(LastByte);
}










/**
  * @}

  */



#ifndef __DR_LOCK_CMD_H
#define __DR_LOCK_CMD_H


#include <stdint.h>
#include <string.h>




   
#define   DOOR_LOCK_CMD_HEAD       0xF5
#define   DOOR_LOCK_CMD_ADD_USER   0x19


extern void ble_send_data(uint8_t *buf, uint8_t len);


typedef void (*sched_handler_t)(void);




void recv_proc(void );


void uart_recv(void);
void  UartSendBytesToDorLock(uint8_t *p_data_tx_buf, uint16_t size_bytes);


void scheduler_proc(sched_handler_t at_func);


#endif


#include "sdk_errors.h"
#include "fds.h"
#include "string.h"








#define RETURN_IF_ERROR(PARAM)                                                                     \
    if ((PARAM) != NRF_SUCCESS)                                                                    \
    {                                                                                              \
        return (PARAM);                                                                            \
    }



typedef  struct
{
uint16_t          record_key;
    uint16_t          file_id;
 uint8_t *         p_data;
    uint16_t          size_bytes;
}flash_access_params_t;




#define   DATA_WRITE_BUF_SIZE   200


__ALIGN(4)  static  uint8_t  CommonDataBuf[DATA_WRITE_BUF_SIZE];


static bool volatile m_wri_pending_ops;
static bool volatile m_fds_initialized;
static bool volatile m_del_pending_ops;
static bool volatile m_gc_pending_ops;


/* Array to map FDS return values to strings. */
char const * fds_err_str[] =
{
    "FDS_SUCCESS",
    "FDS_ERR_OPERATION_TIMEOUT",
    "FDS_ERR_NOT_INITIALIZED",
    "FDS_ERR_UNALIGNED_ADDR",
    "FDS_ERR_INVALID_ARG",
    "FDS_ERR_NULL_ARG",
    "FDS_ERR_NO_OPEN_RECORDS",
    "FDS_ERR_NO_SPACE_IN_FLASH",
    "FDS_ERR_NO_SPACE_IN_QUEUES",
    "FDS_ERR_RECORD_TOO_LARGE",
    "FDS_ERR_NOT_FOUND",
    "FDS_ERR_NO_PAGES",
    "FDS_ERR_USER_LIMIT_REACHED",
    "FDS_ERR_CRC_CHECK_FAILED",
    "FDS_ERR_BUSY",
    "FDS_ERR_INTERNAL",
};




/* Array to map FDS events to strings. */
static char const * fds_evt_str[] =
{
    "FDS_EVT_INIT",
    "FDS_EVT_WRITE",
    "FDS_EVT_UPDATE",
    "FDS_EVT_DEL_RECORD",
    "FDS_EVT_DEL_FILE",
    "FDS_EVT_GC",
};




ret_code_t   FdsReadOperation(const flash_access_params_t * p_params)
{
ret_code_t         err_code;
   fds_flash_record_t record = {0};
      fds_record_desc_t  desc   = {0};
      fds_find_token_t   ft     = {0};

err_code = fds_record_find(p_params->file_id, p_params->record_key, &desc, &ft);
RETURN_IF_ERROR(err_code);
//找到对应数据存储
err_code = fds_record_open(&desc, &record);
      RETURN_IF_ERROR(err_code);

memcpy(p_params->p_data, record.p_data, p_params->size_bytes);

err_code = fds_record_close(&desc);
      RETURN_IF_ERROR(err_code);

return NRF_SUCCESS; 
}






ret_code_t   FdsWriteOperation(const flash_access_params_t * p_params)
{
   ret_code_t         err_code;
fds_record_desc_t  desc   = {0};
fds_find_token_t   ft     = {0};
fds_record_t       record_to_write =
{
.data.p_data = CommonDataBuf,
.file_id     = p_params->file_id,
 .key         = p_params->record_key,
 .data.length_words  = (p_params->size_bytes +3) / 4,
};

memset(CommonDataBuf, 0, sizeof(CommonDataBuf));

err_code = fds_record_find(p_params->file_id, p_params->record_key, &desc, &ft);

memcpy(CommonDataBuf, p_params->p_data, p_params->size_bytes);

if (err_code == FDS_ERR_NOT_FOUND)
      {
          err_code = fds_record_write(&desc, &record_to_write);
      }
      else
      {
          err_code = fds_record_update(&desc, &record_to_write);
      }

if(err_code == FDS_ERR_NO_SPACE_IN_FLASH)
 {
err_code = fds_gc();
          if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES)
          {
                      // Retry.
          }
          else
          {
RETURN_IF_ERROR(err_code);
 m_gc_pending_ops  = false;
          }
}
else
{
RETURN_IF_ERROR(err_code);
 m_wri_pending_ops  = false;
}

return NRF_SUCCESS;
}


#include "led_app_cfg.h"














void  SetLedConstMode(LedAppParma_t *LedAppParma, uint8_t LedSta, uint16_t LedKeepTime)
{
LedAppParma->LedConstExeSta  = LedSta;
 LedAppParma->LedMode = LED_CONST_MODE;
 LedAppParma->LedConstExeTime  = LedKeepTime;
}




void  SetLedNowSta(LedAppParma_t *LedAppParma, uint8_t LedSta)
{
LedAppParma->LedCurSta = LedSta;
}




void  SetLedCycleMode(LedAppParma_t *LedAppParma, uint16_t LedOnTime, uint16_t LedOffTime)
{
 LedAppParma->LedOpenTime  = LedOnTime;
 LedAppParma->LedCloseTime = LedOffTime;
 LedAppParma->LedMode  = LED_CYCLE_MODE;
}


#ifndef  _LED_APP_CFG_H_
#define  _LED_APP_CFG_H_






#include "socket_io_cfg.h"


#define   LED_CONST_MODE   0
#define   LED_CYCLE_MODE   1




#define   LED_OPEN     1
#define   LED_CLOSE    0




typedef struct
{
uint8_t    LedCurSta;
 uint8_t    LedMode;
    uint16_t   LedOpenTime;
 uint16_t   LedCloseTime;
    uint8_t    LedConstExeSta;
    uint8_t    LedCycleExeSta;
 uint16_t   LedConstExeTime;   //值为0表示没有时间限制
}LedAppParma_t;








extern void  SetLedConstMode(LedAppParma_t *LedAppParma, uint8_t LedSta, uint16_t LedKeepTime);
extern void  SetLedNowSta(LedAppParma_t *LedAppParma, uint8_t LedSta);
extern void  SetLedCycleMode(LedAppParma_t *LedAppParma, uint16_t LedOnTime, uint16_t LedOffTime);
















#endif


#include  "socket_io_cfg.h"
#include  "sk_io_dri.h"
#include  "led_app_cfg.h"
#include  "socket_cfg.h"
#include  "led_handle.h"








#define   LED_ON_TIME         100
#define   POWER_ON_LED_STA    LED_OPEN
#define   LED_OFF_TIME        2000
#define   LED_HOLD_TIME       3000


#define   SOCKET_LED_SIZE     SOCKET_SWITCH_NUM
#define   SOCKET_KEY_SIZE     SOCKET_SWITCH_NUM


uint8_t  SocketSwitchCurSta[SOCKET_SWITCH_NUM] = {SWITCH_BREAK};
SkOneGrpCtrlPin_t  SkAllSwitchCtrlGrp[SOCKET_SWITCH_NUM];
SkDevDriAtt_t    SwitchGrpDriAtt[SOCKET_SWITCH_NUM];
LedAppParma_t    SwitchLedParma[SOCKET_SWITCH_NUM];


static  bool  SwitchPinAttInitialed  = 0;


void   InitSwitchPinGrpAtt(const SkOneGrpCtrlPin_t *PinCtrlSrc, uint8_t SwitchIndex)
{
 ASSERT(SwitchIndex  <= SOCKET_SWITCH_NUM);
 uint8_t LedPinId  = PinCtrlSrc->LedPinNum; 
 uint8_t LedOnLevel = PinCtrlSrc->LedActiveSta; 
 uint8_t RelayPinId = PinCtrlSrc->RelayPinNum; 
 uint8_t RelayOnLevel = PinCtrlSrc->RelayActiveSta;
 uint8_t KeyPinId = PinCtrlSrc->KeyPinNum; 
 uint8_t KeyDownLevel = PinCtrlSrc->KeyActiveSta;
 LedUserCtrl_t LedDeal = PinCtrlSrc->LedUserCtrl;
 RelayUserCtrl_t RelayDeal = PinCtrlSrc->RelayUserCtrl;
 SetCurrentSwitchOutPinAtt(LedPinId, LedOnLevel, RelayPinId, RelayOnLevel);
 SetCurrentSwitchInPinAtt(KeyPinId, KeyDownLevel);
 SetCurrentSwitchEvent(LedDeal, RelayDeal);
 SocketOneGroupCtrlCfg(SkAllSwitchCtrlGrp, SwitchIndex-1, SOCKET_SWITCH_NUM);
}






void  InitSwitchDriAtt(uint8_t SwitchIndex)
{
uint8_t DriAttType;

 ASSERT(SwitchIndex  <= SOCKET_SWITCH_NUM);

 DriAttType = GetSwitchDriAttCfgType(&SkAllSwitchCtrlGrp[SwitchIndex-1]);
 CurrrentSwitchDriverCfg(DriAttType);
 SocketSwitchDriAttCfg(SwitchGrpDriAtt, SwitchIndex-1, SOCKET_SWITCH_NUM);
}






bool  GetLedOpenDriLevel(uint8_t SwitchIndex)
{
ASSERT(SwitchIndex  <= SOCKET_SWITCH_NUM);
 
 return  SwitchGrpDriAtt[SwitchIndex-1].LedOpenLevel;
}




bool  GetLedCloseDriLevel(uint8_t SwitchIndex)
{
ASSERT(SwitchIndex  <= SOCKET_SWITCH_NUM);

 return  SwitchGrpDriAtt[SwitchIndex-1].LedCloseLevel;
}




bool  GetRelayOpenDriLevel(uint8_t SwitchIndex)
{
ASSERT(SwitchIndex  <= SOCKET_SWITCH_NUM);

 return  SwitchGrpDriAtt[SwitchIndex-1].RelayOpenLevel;
}




bool  GetRelayCloseDriLevel(uint8_t SwitchIndex)
{
ASSERT(SwitchIndex  <= SOCKET_SWITCH_NUM);

 return  SwitchGrpDriAtt[SwitchIndex-1].RelayCloseLevel;
}






void  SetSwitchOpen(uint8_t SwitchIndex)
{
ASSERT(SwitchIndex  <= SOCKET_SWITCH_NUM);

 bool  LedOnDri;
 bool  RelayOnDri;
 uint8_t  LedCtrlPin;
 uint8_t  RelayCtrlPin;

 LedOnDri  = SwitchGrpDriAtt[SwitchIndex-1].LedOpenLevel;
 RelayOnDri = SwitchGrpDriAtt[SwitchIndex-1].RelayOpenLevel;
 LedCtrlPin = SkAllSwitchCtrlGrp[SwitchIndex-1].LedPinNum;
 RelayCtrlPin = SkAllSwitchCtrlGrp[SwitchIndex-1].RelayPinNum;

 SetSwitchAction(LedCtrlPin, RelayCtrlPin, LedOnDri, RelayOnDri);
 SocketSwitchCurSta[SwitchIndex-1] = SWITCH_CONNECT;
 SwitchLedParma[SwitchIndex-1].LedCurSta  = LED_OPEN;
}




void  SetSwitchClose(uint8_t SwitchIndex)
{
ASSERT(SwitchIndex  <= SOCKET_SWITCH_NUM);

 bool  LedOffDri;
 bool  RelayOffDri;
 uint8_t  LedCtrlPin;
 uint8_t  RelayCtrlPin;

 LedOffDri  = SwitchGrpDriAtt[SwitchIndex-1].LedCloseLevel;
 RelayOffDri = SwitchGrpDriAtt[SwitchIndex-1].RelayCloseLevel;
 LedCtrlPin = SkAllSwitchCtrlGrp[SwitchIndex-1].LedPinNum;
 RelayCtrlPin = SkAllSwitchCtrlGrp[SwitchIndex-1].RelayPinNum;

 SetSwitchAction(LedCtrlPin, RelayCtrlPin, LedOffDri, RelayOffDri);
 SocketSwitchCurSta[SwitchIndex-1] = SWITCH_BREAK;
 SwitchLedParma[SwitchIndex-1].LedCurSta  = LED_CLOSE;
}








void  InitSwitchPinOutEnable(uint8_t SwitchSize)
{
ASSERT(SwitchSize  == SOCKET_SWITCH_NUM);

 uint8_t i;

 for(i = 0; i < SwitchSize; i++)
    {
SetSwitchPinCfgEnable(&SkAllSwitchCtrlGrp[i], &SwitchGrpDriAtt[i]);
}
}






void  InitSwitchLedAppParma(uint8_t SwitchSize, uint8_t InitSelect)
{
ASSERT(SwitchSize  == SOCKET_SWITCH_NUM);

 uint8_t i;

 for(i = 0; i< SwitchSize; i++)
    {
   if(InitSelect)
{
SetLedCycleMode(&SwitchLedParma[i], LED_ON_TIME, LED_OFF_TIME);
}
else
{
SetLedConstMode(&SwitchLedParma[i], POWER_ON_LED_STA, LED_HOLD_TIME);
}
}
}








void  SetSocketLedAppParma(SocketLedApp_t *LedAppCfg)  
{
 ASSERT(LedAppCfg->LedIndex  < SOCKET_LED_SIZE);

 if(LedAppCfg->LedMode == LED_CONST_MODE)
{
SetLedConstMode(&SwitchLedParma[LedAppCfg->LedIndex], LedAppCfg->LedExeSta, LedAppCfg->LedKeepTime);
}
else if(LedAppCfg->LedMode == LED_CYCLE_MODE)
{
SetLedCycleMode(&SwitchLedParma[LedAppCfg->LedIndex], LedAppCfg->LedOnTime, LedAppCfg->LedOffTime);
}
}






void  GetLedConstModeParma(uint8_t *LedConstSta, uint16_t *LedKeepTime, uint8_t LedId)
{
*LedConstSta = SwitchLedParma[LedId].LedConstExeSta;
 *LedKeepTime = SwitchLedParma[LedId].LedConstExeTime;
}




void  GetLedCycleModeParma(uint16_t *LedOpenTime, uint16_t *LedCloseTime, uint8_t LedId)
{
*LedOpenTime  = SwitchLedParma[LedId].LedOpenTime;
 *LedCloseTime = SwitchLedParma[LedId].LedCloseTime;
}




void  SetSocketLedCurSta(uint8_t LedSta, uint8_t LedId)
{
 ASSERT(LedId  < SOCKET_LED_SIZE);
SetLedNowSta(&SwitchLedParma[LedId], LedSta);
}






void  SetSocketLedHandleMode(uint8_t LedId, uint8_t LedMode)
{
ASSERT(LedId  < SOCKET_LED_SIZE);

 SwitchLedParma[LedId].LedMode  = LedMode;
}




uint8_t  GetSocketLedCurSta(uint8_t LedId)
{
ASSERT(LedId  < SOCKET_LED_SIZE);
 
 return  SwitchLedParma[LedId].LedCurSta;  
}




uint8_t  GetSocketLedCurMode(uint8_t LedId)
{
ASSERT(LedId  < SOCKET_LED_SIZE);

 return  SwitchLedParma[LedId].LedMode;
}




uint8_t   GetSocketLedCtrlPin(uint8_t LedId)
{
ASSERT(LedId  < SOCKET_LED_SIZE);

 return  SkAllSwitchCtrlGrp[LedId].LedPinNum;
}






uint8_t  GetSocketRelayCtrlPin(uint8_t SwitchIndex)
{
ASSERT(SwitchIndex  <= SOCKET_SWITCH_NUM);

 return  SkAllSwitchCtrlGrp[SwitchIndex - 1].RelayPinNum;
}






void  GetSocketBtnPinAtt(uint8_t *KeyPinNum, uint8_t *KeyActiveVal, uint8_t KeyId)
{
ASSERT(KeyId  < SOCKET_KEY_SIZE);

 *KeyPinNum      = SkAllSwitchCtrlGrp[KeyId].KeyPinNum;
 *KeyActiveVal   = SkAllSwitchCtrlGrp[KeyId].KeyActiveSta;
}






uint8_t  GetSocketSwitchSta(uint8_t SwitchIndex)
{
ASSERT(SwitchIndex  <= SOCKET_SWITCH_NUM);

 return  SocketSwitchCurSta[SwitchIndex-1];
}






void  SetSocketSwitchSta(uint8_t SwitchIndex, uint8_t RelaySta)
{
ASSERT(SwitchIndex  <= SOCKET_SWITCH_NUM);
 
 SocketSwitchCurSta[SwitchIndex-1] = RelaySta;
}






void  GetDevSwitchCtrlPramaStoreAddr(SkOneGrpCtrlPin_t* *SwitchCtrlPin, SkDevDriAtt_t* *SwitchDriVal, uint8_t SwitchNum)
{
ASSERT(SwitchNum  < SOCKET_SWITCH_NUM);

 *SwitchCtrlPin = &SkAllSwitchCtrlGrp[SwitchNum];
 *SwitchDriVal  = &SwitchGrpDriAtt[SwitchNum];
}


#ifndef  _LED_HANDLE_H_
#define  _LED_HANDLE_H_






typedef  struct
{
     uint8_t  LedMode;
  uint8_t  LedIndex;
  uint16_t LedOnTime;
     uint16_t LedOffTime;
     uint8_t  LedExeSta;
     uint16_t LedKeepTime;  
}SocketLedApp_t;






#define  SWITCH_CONNECT   1
#define  SWITCH_BREAK     0




extern void  InitSwitchPinGrpAtt(const SkOneGrpCtrlPin_t *PinCtrlSrc, uint8_t SwitchIndex);
extern void  InitSwitchDriAtt(uint8_t SwitchIndex);
extern bool  GetLedOpenDriLevel(uint8_t SwitchIndex);
extern bool  GetLedCloseDriLevel(uint8_t SwitchIndex);
extern bool  GetRelayOpenDriLevel(uint8_t SwitchIndex);
extern bool  GetRelayCloseDriLevel(uint8_t SwitchIndex);
extern void  SetSwitchOpen(uint8_t SwitchIndex);
extern void  SetSwitchClose(uint8_t SwitchIndex);
extern void  InitSwitchPinOutEnable(uint8_t SwitchSize);
extern void  InitSwitchLedAppParma(uint8_t SwitchSize, uint8_t InitSelect);
extern void  SetSocketLedAppParma(SocketLedApp_t *LedAppCfg);
extern void  SetSocketLedCurSta(uint8_t LedSta, uint8_t LedId);
extern uint8_t  GetSocketLedCurSta(uint8_t LedId);
extern uint8_t  GetSocketLedCurMode(uint8_t LedId);
extern uint8_t  GetSocketLedCtrlPin(uint8_t LedId);
extern uint8_t  GetSocketRelayCtrlPin(uint8_t SwitchIndex);
extern uint8_t  GetSocketSwitchSta(uint8_t SwitchIndex);
extern void  GetLedConstModeParma(uint8_t *LedConstSta, uint16_t *LedKeepTime, uint8_t LedId);
extern void  SetSocketLedHandleMode(uint8_t LedId, uint8_t LedMode);
extern void  GetLedCycleModeParma(uint16_t *LedOpenTime, uint16_t *LedCloseTime, uint8_t LedId);
extern void  GetSocketBtnPinAtt(uint8_t *KeyPinNum, uint8_t *KeyActiveVal, uint8_t KeyId);
extern void  SetSocketSwitchSta(uint8_t SwitchIndex, uint8_t RelaySta);
extern void  GetDevSwitchCtrlPramaStoreAddr(SkOneGrpCtrlPin_t* *SwitchCtrlPin, SkDevDriAtt_t* *SwitchDriVal, uint8_t SwitchNum);






#endif

#include "socket_io_cfg.h"
#include "app_timer.h"
#include "socket_cfg.h"
#include "led_handle.h"
#include "led_app_cfg.h"
#include "sk_io_dri.h"
#include "led_task.h"




//如果再多一个灯,就要对应再建一个定时器和写一个led处理函数
void LedFlashHandle(void * p_context);




void  sk_event_create(void)
{
uint32_t err_code;

   err_code = app_timer_create(&LedFlashClock, APP_TIMER_MODE_SINGLE_SHOT, LedFlashHandle);
   APP_ERROR_CHECK(err_code);
}






void  SocketTaskAction(uint8_t TaskId, uint16_t TaskDelay)
{
uint32_t err_code;

 switch(TaskId)
{
case  LED_FLASH:
err_code = app_timer_start(LedFlashClock, APP_TIMER_TICKS(TaskDelay), NULL);
       APP_ERROR_CHECK(err_code);
break;
}
}






void LedFlashHandle(void * p_context)
{
   uint8_t   Led0Pin;
   uint8_t   Led0Opera;
   uint16_t  LedHoldTime;

   uint16_t  LedCycOpenTime;
   uint16_t  LedCycCloseTime;
  
switch(GetSocketLedCurMode(LED0_ID))
{
case  LED_CONST_MODE:
Led0Pin = GetSocketLedCtrlPin(LED0_ID);
       GetLedConstModeParma(&Led0Opera, &LedHoldTime, LED0_ID);
       if(Led0Opera == LED_OPEN)
{
SetLedAction(Led0Pin, GetLedOpenDriLevel(1));
 SetSocketLedCurSta(LED_OPEN, LED0_ID);
}
else if(Led0Opera == LED_CLOSE)
{
SetLedAction(Led0Pin, GetLedCloseDriLevel(1));
 SetSocketLedCurSta(LED_CLOSE, LED0_ID);
}

if(LedHoldTime != 0)
{
 SetSocketLedHandleMode(LED0_ID, LED_CYCLE_MODE);
SocketTaskAction(LED_FLASH, LedHoldTime);
}
break;

case  LED_CYCLE_MODE:
     Led0Pin = GetSocketLedCtrlPin(LED0_ID);
       GetLedCycleModeParma(&LedCycOpenTime, &LedCycCloseTime, LED0_ID);
       if(GetSocketLedCurSta(LED0_ID) == LED_OPEN)
{
SetLedAction(Led0Pin, GetLedCloseDriLevel(1));
 SetSocketLedCurSta(LED_CLOSE, LED0_ID);
 SocketTaskAction(LED_FLASH, LedCycCloseTime);
}
else
{
SetLedAction(Led0Pin, GetLedOpenDriLevel(1));
 SetSocketLedCurSta(LED_OPEN, LED0_ID);
 SocketTaskAction(LED_FLASH, LedCycOpenTime);
}
break;
}
}








static void  SetLedConstModeAction(uint8_t LedId, uint8_t LedOperaSta, uint16_t LedStaHoldTime)
{
   SocketLedApp_t LedAppSetting =
   {
.LedMode      = LED_CONST_MODE,
 .LedIndex     = LedId,
 .LedExeSta    = LedOperaSta,
 .LedKeepTime  = LedStaHoldTime,
};
SetSocketLedAppParma(&LedAppSetting);
switch(LedId)
{
case  LED0_ID:
     SocketTaskAction(LED_FLASH, 10);
break;
}
}






void  SetLedCycleModeAction(uint8_t LedId, uint16_t LedOpenTime, uint16_t LedCloseTime)
{
SocketLedApp_t  LedAppSetting =
   {
.LedMode    = LED_CYCLE_MODE,
 .LedIndex   = LedId,
 .LedOnTime  = LedOpenTime,
 .LedOffTime = LedCloseTime,
};

SetSocketLedAppParma(&LedAppSetting);
switch(LedId)
{
case  LED0_ID:
     SocketTaskAction(LED_FLASH, 10);
break;
     
}
}






void  SetLedConstOpenDislimit(uint8_t LedId)
{
SetLedConstModeAction(LedId, LED_OPEN, 0);
}




void  SetLedConstCloseDislimit(uint8_t LedId)
{
SetLedConstModeAction(LedId, LED_CLOSE, 0);
}




void  SetLedConstOpenEnlimit(uint8_t LedId, uint16_t LedHoldTime)
{
SetLedConstModeAction(LedId, LED_OPEN, LedHoldTime);
}




void  SetLedConstCloseEnlimit(uint8_t LedId, uint16_t LedHoldTime)
{
SetLedConstModeAction(LedId, LED_CLOSE, LedHoldTime);
}






void  SetRelayOpen(uint8_t RelayId)
{
uint8_t RelayPinNum;

 RelayPinNum  = GetSocketRelayCtrlPin(RelayId);
 SetRelayAction(RelayPinNum, GetRelayOpenDriLevel(RelayId));
 SetSocketSwitchSta(RelayId, SWITCH_CONNECT);
}






void  SetRelayClose(uint8_t RelayId)
{
uint8_t RelayPinNum;

 RelayPinNum = GetSocketRelayCtrlPin(RelayId);
 SetRelayAction(RelayPinNum, GetRelayCloseDriLevel(RelayId));
 SetSocketSwitchSta(RelayId, SWITCH_BREAK);
}






void  SetAllRelaySameSta(uint8_t  RelaySize, uint8_t ExeSta)
{
uint8_t  i;
 
 if(ExeSta == SWITCH_CONNECT)
{
for(i = 1; i <= RelaySize; i++)
{
SetRelayOpen(i);
}
}
else if(ExeSta == SWITCH_BREAK)
{
for(i = 1; i <= RelaySize; i++)
 {
SetRelayClose(i);
}
}
}



#ifndef  _LED_TASK_H_
#define  _LED_TASK_H_










#define  LED_FLASH        2


APP_TIMER_DEF(LedFlashClock);








extern void  sk_event_create(void);
extern void  SocketTaskAction(uint8_t TaskId, uint16_t TaskDelay);
extern void  SetLedCycleModeAction(uint8_t LedId, uint16_t LedOpenTime, uint16_t LedCloseTime);
extern void  SetLedConstOpenDislimit(uint8_t LedId);
extern void  SetLedConstCloseDislimit(uint8_t LedId);
extern void  SetLedConstOpenEnlimit(uint8_t LedId, uint16_t LedHoldTime);
extern void  SetLedConstCloseEnlimit(uint8_t LedId, uint16_t LedHoldTime);
extern void  SetRelayOpen(uint8_t RelayId);
extern void  SetRelayClose(uint8_t RelayId);




#endif



#include "sk_io_dri.h"
#include "nrf_gpio.h"




void  SetLedAction(uint8_t  LedId, bool LedSta)
{
 nrf_gpio_pin_write(LedId, LedSta);
}






void  SetRelayAction(uint8_t  RelayId, bool  RelaySta)
{
nrf_gpio_pin_write(RelayId, RelaySta);
}






void  SetAllLedSameAction(uint8_t *LedPinNum, uint8_t LedSize, bool LedSta)
{
ASSERT(LedPinNum  != NULL);
 ASSERT(sizeof(LedPinNum)/sizeof(uint8_t) == LedSize);

 uint8_t i;

 for(i = 0; i < LedSize; i++)
 {
SetLedAction(LedPinNum[i], LedSta);
}
}






void  SetAllRelaySameAction(uint8_t *RelayPinNum, uint8_t RelaySize, bool RelaySta)
{
ASSERT(RelayPinNum  != NULL);
 ASSERT(sizeof(RelayPinNum)/sizeof(uint8_t) == RelaySize);

 uint8_t  i;
 
 for(i = 0; i < RelaySize; i++)
 {
SetRelayAction(RelayPinNum[i], RelaySta);
}
}






void  SetSwitchAction(uint8_t LedId, uint8_t RelayId, bool LedSta, bool  RelaySta)
{
nrf_gpio_pin_write(LedId, LedSta);
 nrf_gpio_pin_write(RelayId, RelaySta);
}


#ifndef  _SK_IO_DRI_H_
#define  _SK_IO_DRI_H_






#include "socket_io_cfg.h"






extern void  SetLedAction(uint8_t  LedId, bool LedSta);
extern void  SetRelayAction(uint8_t  RelayId, bool  RelaySta);
extern void  SetAllLedSameAction(uint8_t *LedPinNum, uint8_t LedSize, bool LedSta);
extern void  SetAllRelaySameAction(uint8_t *RelayPinNum, uint8_t RelaySize, bool RelaySta);
extern void  SetSwitchAction(uint8_t LedId, uint8_t RelayId, bool LedSta, bool  RelaySta);


























#endif


#ifndef  _SOCKET_CFG_H_
#define  _SOCKET_CFG_H_














#define  SOCKET_SWITCH_NUM      1




#if (SOCKET_SWITCH_NUM >= 1)
#define  LED0_ID    0
#endif


#if (SOCKET_SWITCH_NUM >= 2)
#define  LED1_ID    1
#endif


#if (SOCKET_SWITCH_NUM >= 3)
#define  LED2_ID    2
#endif






#define   LED0_SIGN_PIN          5
#define   RELAY0_SIGN_PIN        6
#define   KEY0_SIGN_PIN          14


#define   LED0_ACTIVE_STA        1
#define   RELAY0_ACTIVE_STA      1
#define   KEY0_ACTIVE_STA        0










#endif

#include "socket_io_cfg.h"
#include "nrf_gpio.h"
#include "app_button.h"


#define   LED_OPEN_HIGH       1
#define   LED_OPEN_LOW        0
#define   RELAY_OPEN_HIGH     1
#define   RELAY_OPEN_LOW      0


static SkOneGrpCtrlPin_t  PinCtrlCfgVal = {0};
static SkDevDriAtt_t  DriAttVal = {0};




//函数功能
//设置当前开关驱动属性
//参数
//DriverSelect:input 


//返回:none
void  CurrrentSwitchDriverCfg(uint8_t DriverSelect)
{
 switch(DriverSelect)
{
case  LED_OPEN_HIGH_RELAY_OPEN_HIGH:
         DriAttVal.LedCloseLevel = 0;
DriAttVal.LedOpenLevel  = 1;
           DriAttVal.RelayCloseLevel = 0;
DriAttVal.RelayOpenLevel  = 1;
break;
 
case  LED_OPEN_LOW_RELAY_OPEN_HIGH:
DriAttVal.LedCloseLevel = 1;
DriAttVal.LedOpenLevel  = 0;
           DriAttVal.RelayCloseLevel = 0;
DriAttVal.RelayOpenLevel  = 1;
break;
 
case  LED_OPEN_HIGH_RELAY_OPEN_LOW:
DriAttVal.LedCloseLevel = 0;
DriAttVal.LedOpenLevel  = 1;
           DriAttVal.RelayCloseLevel = 1;
DriAttVal.RelayOpenLevel  = 0;
break;
 
case  LED_OPEN_LOW_RELAY_OPEN_LOW:
DriAttVal.LedCloseLevel = 1;
DriAttVal.LedOpenLevel  = 0;
           DriAttVal.RelayCloseLevel = 1;
DriAttVal.RelayOpenLevel  = 0;
break;
}
}






//函数功能
//获取开关驱动属性类型
//参数
//PinCtrlSrc:input 


//返回:驱动属性类型
uint8_t  GetSwitchDriAttCfgType(const SkOneGrpCtrlPin_t *PinCtrlSrc)
{
if((PinCtrlSrc->LedActiveSta == LED_OPEN_HIGH) && (PinCtrlSrc->RelayActiveSta == RELAY_OPEN_HIGH))
{
return  LED_OPEN_HIGH_RELAY_OPEN_HIGH;
}
else if((PinCtrlSrc->LedActiveSta == LED_OPEN_LOW) && (PinCtrlSrc->RelayActiveSta == RELAY_OPEN_HIGH))
 {
return  LED_OPEN_LOW_RELAY_OPEN_HIGH;
}
else if((PinCtrlSrc->LedActiveSta == LED_OPEN_HIGH) && (PinCtrlSrc->RelayActiveSta == RELAY_OPEN_LOW))
{
return  LED_OPEN_HIGH_RELAY_OPEN_LOW;
}
else if((PinCtrlSrc->LedActiveSta == LED_OPEN_LOW) && (PinCtrlSrc->RelayActiveSta == RELAY_OPEN_LOW))
{
return  LED_OPEN_LOW_RELAY_OPEN_LOW;
}

return  LED_RELAY_DRIVER_CFG_ERROR;
}




//函数功能
//设置当前开关输出引脚属性
//参数
//LedPinId:input 
//LedOnLevel:input
//RelayPinId:input
//RelayOnLevel:input
//返回:none
void  SetCurrentSwitchOutPinAtt(uint8_t LedPinId, uint8_t LedOnLevel, uint8_t RelayPinId, uint8_t RelayOnLevel)
{
PinCtrlCfgVal.LedActiveSta  = LedOnLevel;
 PinCtrlCfgVal.LedPinNum  = LedPinId;
 PinCtrlCfgVal.RelayActiveSta  = RelayOnLevel;
 PinCtrlCfgVal.RelayPinNum  = RelayPinId;
}




//函数功能
//设置当前开关输入引脚属性
//参数
//KeyPinId:input 
//KeyDownLevel:input


//返回:none
void  SetCurrentSwitchInPinAtt(uint8_t KeyPinId, uint8_t KeyDownLevel)
{
PinCtrlCfgVal.KeyActiveSta = KeyDownLevel;
 PinCtrlCfgVal.KeyPinNum  = KeyPinId;
}






void  SetCurrentSwitchEvent(LedUserCtrl_t LedProcess, RelayUserCtrl_t RelayProcess)
{
PinCtrlCfgVal.LedUserCtrl = LedProcess;
 PinCtrlCfgVal.RelayUserCtrl = RelayProcess;
}




//函数功能
//某个开关引脚功能控制配置
//参数
//PinCtrlSrc:output 
//SwitchNum:input
//PinCtrlCfgVal:input
//AllSwitchNum:input
//返回:none
void   SocketOneGroupCtrlCfg(SkOneGrpCtrlPin_t *PinCtrlSrc, uint8_t SwitchNum, uint8_t AllSwitchNum)
{
 ASSERT(PinCtrlSrc  != NULL);


ASSERT(SwitchNum  < AllSwitchNum);

PinCtrlSrc[SwitchNum].KeyActiveSta =  PinCtrlCfgVal.KeyActiveSta;
 PinCtrlSrc[SwitchNum].KeyPinNum    =  PinCtrlCfgVal.KeyPinNum;
 PinCtrlSrc[SwitchNum].LedActiveSta =  PinCtrlCfgVal.LedActiveSta;
 PinCtrlSrc[SwitchNum].LedPinNum    =  PinCtrlCfgVal.LedPinNum;
 PinCtrlSrc[SwitchNum].RelayActiveSta  = PinCtrlCfgVal.RelayActiveSta;
 PinCtrlSrc[SwitchNum].RelayPinNum  =  PinCtrlCfgVal.RelayPinNum;
 PinCtrlSrc[SwitchNum].LedUserCtrl  =  PinCtrlCfgVal.LedUserCtrl;
PinCtrlSrc[SwitchNum].RelayUserCtrl =  PinCtrlCfgVal.RelayUserCtrl;
}




//函数功能
//某个开关引脚控制属性配置
//参数
//DevGrpDriAtt:output 
//SwitchNum:input
//DriAttVal:input
//AllSwitchNum:input
//返回:none
void  SocketSwitchDriAttCfg(SkDevDriAtt_t *DevGrpDriAtt, uint8_t SwitchNum, uint8_t AllSwitchNum)
{
ASSERT(DevGrpDriAtt  != NULL);

ASSERT(SwitchNum  < AllSwitchNum);

 DevGrpDriAtt[SwitchNum].LedCloseLevel = DriAttVal.LedCloseLevel;
 DevGrpDriAtt[SwitchNum].LedOpenLevel  = DriAttVal.LedOpenLevel;
 DevGrpDriAtt[SwitchNum].RelayCloseLevel = DriAttVal.RelayCloseLevel;
 DevGrpDriAtt[SwitchNum].RelayOpenLevel  = DriAttVal.RelayOpenLevel;
}






//函数功能
//设置所有开关引脚相同驱动属性
//参数
//DevGrpDriAtt:input 
//SwitchSize:input


//返回:none
void  SetAllSwitchSameDriAtt(SkDevDriAtt_t *DevGrpDriAtt, uint8_t SwitchSize)
{
uint8_t  i;

 for(i = 0; i < SwitchSize; i++)
 {
SocketSwitchDriAttCfg(DevGrpDriAtt, i, SwitchSize);
}
}




//函数功能
//设开关引脚使能配置
//参数
//PinCtrlSrc:input 
//DevGrpDriAtt:input


//返回:none
void  SetSwitchPinCfgEnable(SkOneGrpCtrlPin_t *PinCtrlSrc, SkDevDriAtt_t *DevGrpDriAtt)
{
nrf_gpio_cfg_output(PinCtrlSrc->LedPinNum);
 nrf_gpio_pin_write(PinCtrlSrc->LedPinNum, DevGrpDriAtt->LedCloseLevel);
 
 nrf_gpio_cfg_output(PinCtrlSrc->RelayPinNum);
 nrf_gpio_pin_write(PinCtrlSrc->RelayPinNum, DevGrpDriAtt->RelayCloseLevel);
}




//函数功能
//服务于按键初始化的按键参数配置
//参数
//PinCtrlSrc:input 
//button:output


//返回:none
void  BtnPramaCfgSrvForKeyInit(const SkOneGrpCtrlPin_t *PinCtrlSrc, app_button_cfg_t *button)
{
button->pin_no  = PinCtrlSrc->KeyPinNum;
button->active_state  =  PinCtrlSrc->KeyActiveSta;
}


#ifndef  _SOCKET_IO_CFG_H_
#define  _SOCKET_IO_CFG_H_




#include <stdint.h>
#include <nrf_assert.h>




typedef  void  (*LedUserCtrl_t)(uint8_t, uint8_t, uint16_t);
typedef  void  (*RelayUserCtrl_t)(uint8_t, uint8_t, uint16_t);




typedef  struct  SocketOneGrpPinSrc
{
uint8_t  KeyPinNum;
 uint8_t  LedPinNum;
 uint8_t  RelayPinNum;
 uint8_t  KeyActiveSta;
 uint8_t  LedActiveSta;
 uint8_t  RelayActiveSta;
 LedUserCtrl_t  LedUserCtrl;
 RelayUserCtrl_t  RelayUserCtrl;
}SkOneGrpCtrlPin_t;




//#define  SOCKET_SWITCH_NUM   3
//SkOneGrpCtrlPin_t  SkAllUserCtrlGrp[SOCKET_SWITCH_NUM] = {0};
typedef  struct
{
bool  LedOpenLevel;
 bool  LedCloseLevel;
 bool  RelayOpenLevel;
 bool  RelayCloseLevel;  
}SkDevDriAtt_t;




typedef enum
{
LED_OPEN_HIGH_RELAY_OPEN_HIGH = 0,
 LED_OPEN_LOW_RELAY_OPEN_HIGH,
 LED_OPEN_HIGH_RELAY_OPEN_LOW,
 LED_OPEN_LOW_RELAY_OPEN_LOW,
 LED_RELAY_DRIVER_CFG_ERROR,
}TypDef_DevDri_t;














extern void  CurrrentSwitchDriverCfg(uint8_t DriverSelect);
extern uint8_t  GetSwitchDriAttCfgType(const SkOneGrpCtrlPin_t *PinCtrlSrc);
extern void  SetCurrentSwitchOutPinAtt(uint8_t LedPinId, uint8_t LedOnLevel, uint8_t RelayPinId, uint8_t RelayOnLevel);
extern void  SetCurrentSwitchInPinAtt(uint8_t KeyPinId, uint8_t KeyDownLevel);
extern void  SetCurrentSwitchEvent(LedUserCtrl_t LedProcess, RelayUserCtrl_t RelayProcess);
extern void  SocketOneGroupCtrlCfg(SkOneGrpCtrlPin_t *PinCtrlSrc, uint8_t SwitchNum, uint8_t AllSwitchNum);
extern void  SocketSwitchDriAttCfg(SkDevDriAtt_t *DevGrpDriAtt, uint8_t SwitchNum, uint8_t AllSwitchNum);
extern void  SetSwitchPinCfgEnable(SkOneGrpCtrlPin_t *PinCtrlSrc, SkDevDriAtt_t *DevGrpDriAtt);












#endif 

#include "string.h"


#include "nrf_assert.h"




#define  TRANSFER_FRAME_SIZE   20
#define  FRAME_NUM_FILL_SIZE   100
#define  BIG_DATA_STORE_SIZE   (TRANSFER_FRAME_SIZE*FRAME_NUM_FILL_SIZE)
#define  INVALID_SERIAL_NUM    0x0000
#define  MAX_RX_FRAME_NUM      65534
#define  RX_MAX_DATA_SIZE      (MAX_RX_FRAME_NUM*TRANSFER_FRAME_SIZE)






typedef struct
{
    uint8_t   UartFrameStoreAddr;
 uint16_t  UartFrameSerialNum;
}UartFrameInfor_t;


typedef struct
{
uint8_t   UartFrameTransferMaxSize;
 uint16_t  NextUartFrameSeriNum;     //下一个  接受帧序列号 
 uint16_t  CurAllFrameMaxSeriNum;   //所有帧最大序列号
 uint16_t  CurTxFrameSeriNum;
    uint8_t   FrameDataStoreBuf[BIG_DATA_STORE_SIZE];
 uint32_t  EnUartRxFrameTotalNum;
 UartFrameInfor_t  UartFrameInfor[FRAME_NUM_FILL_SIZE];
 uint8_t   LastFrameDataTxDone;
 uint8_t   LastFrameLenth;
 uint8_t   UartFrameEndSignal;
}UartBigDatOpera_t;




static UartBigDatOpera_t  UartBigDatOpera;
static uint8_t  LastUartFrameDataBuf[TRANSFER_FRAME_SIZE+1];




void  InitUartBigDataAppParma(void)
{
UartBigDatOpera.UartFrameTransferMaxSize = TRANSFER_FRAME_SIZE;
 UartBigDatOpera.CurAllFrameMaxSeriNum  = 0;
 UartBigDatOpera.NextUartFrameSeriNum = 1;
 memset(UartBigDatOpera.FrameDataStoreBuf, 0, sizeof(UartBigDatOpera.FrameDataStoreBuf));
 UartBigDatOpera.EnUartRxFrameTotalNum = MAX_RX_FRAME_NUM;
 memset(UartBigDatOpera.UartFrameInfor, 0, sizeof(UartBigDatOpera.UartFrameInfor));
 UartBigDatOpera.CurTxFrameSeriNum  = 0;
 memset(LastUartFrameDataBuf, 0, sizeof(LastUartFrameDataBuf));
 UartBigDatOpera.LastFrameDataTxDone  =  1;
 UartBigDatOpera.LastFrameLenth  =  0;
 UartBigDatOpera.UartFrameEndSignal  = 0;
}






void  SetUartFrameRxFinish(void)
{
UartBigDatOpera.UartFrameEndSignal  =  1;
}



uint8_t  IsUartFrameArriveEnd(void)
{
return  UartBigDatOpera.UartFrameEndSignal;
}




void   StoreLastUartFrameTxData(uint8_t DataSize, uint8_t *TxVal)
{
 uint8_t i;
 for(i = 0; i < DataSize; i++)
 {
LastUartFrameDataBuf[i] = TxVal[i];
}
UartBigDatOpera.LastFrameLenth  =  DataSize;

}






void  GetLastUartFrameTxParma(uint8_t *size, uint8_t *LastDataBuf)
{
 uint8_t  i;
*size  =  UartBigDatOpera.LastFrameLenth;
    for(i = 0; i < UartBigDatOpera.LastFrameLenth; i++)
    {
LastDataBuf[i] = LastUartFrameDataBuf[i];
}
}






void  SetLastUartFrameTxSta(uint8_t  FrameTxSta)
{
UartBigDatOpera.LastFrameDataTxDone  =  FrameTxSta;
}






uint8_t  GetLastUartFrameTxSta(void)
{
return  UartBigDatOpera.LastFrameDataTxDone;
}




uint8_t  GetUartFrameDataLenth(void)
{
return  UartBigDatOpera.UartFrameTransferMaxSize;
}




uint16_t  GetUartFrameMaxRxSeri(void)
{
return  UartBigDatOpera.EnUartRxFrameTotalNum;
}  




uint8_t  SearchUartFrameValidStoreAdd(void)
{
uint8_t i;

 for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum == INVALID_SERIAL_NUM)
{
return  i;
}
}

return  FRAME_NUM_FILL_SIZE;
}








uint8_t  GetUartFrameStoreAddr(uint8_t FrameIndex)
{
 ASSERT(FrameIndex  < FRAME_NUM_FILL_SIZE);
return  UartBigDatOpera.UartFrameInfor[FrameIndex].UartFrameStoreAddr;
}






uint8_t  GetUartFrameMaxSeriNum(void)
{
uint8_t FrameMaxSeriNum = 0;
    uint8_t i;
    
for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(FrameMaxSeriNum < UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum)
{
FrameMaxSeriNum  = UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum;
}
}

return  FrameMaxSeriNum;
}




uint8_t  GetUartFrameMinSeriNum(void)
{
uint16_t FrameMinSeriNum = MAX_RX_FRAME_NUM+1;
    uint8_t i;

 for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum != 0)
{
if(FrameMinSeriNum > UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum)
{
FrameMinSeriNum  =  UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum;
}
}
}

return  FrameMinSeriNum;
}






void   FillUartFrameToCorrectAdd(uint8_t FillAddr, const uint8_t *UartFrame)
{
 ASSERT(UartFrame != NULL);
 ASSERT(sizeof(UartFrame) == TRANSFER_FRAME_SIZE);
 ASSERT(FillAddr < FRAME_NUM_FILL_SIZE);
 
memcpy(&UartBigDatOpera.FrameDataStoreBuf[TRANSFER_FRAME_SIZE*FillAddr], UartFrame, TRANSFER_FRAME_SIZE);
}






void   GetUartFrameFromDataTab(uint8_t GetAddr, uint8_t *UartFrame)
{
ASSERT(UartFrame != NULL);
 ASSERT(sizeof(UartFrame) == TRANSFER_FRAME_SIZE);
 ASSERT(GetAddr < FRAME_NUM_FILL_SIZE);

 memcpy(UartFrame, &UartBigDatOpera.FrameDataStoreBuf[TRANSFER_FRAME_SIZE*GetAddr], TRANSFER_FRAME_SIZE);
}








uint8_t  GetUartFrameDataTabOperaAddr(uint16_t UartFrameSerialNum)
{
ASSERT(UartFrameSerialNum < MAX_RX_FRAME_NUM+1);

 uint8_t i;

 for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum == UartFrameSerialNum)
{
return i;
}
}

return  FRAME_NUM_FILL_SIZE;
}










void  SetUartFrameSerialNumInvalid(uint8_t UartFrameIndex)
{
ASSERT(UartFrameIndex  < FRAME_NUM_FILL_SIZE);

 UartBigDatOpera.UartFrameInfor[UartFrameIndex].UartFrameSerialNum  = INVALID_SERIAL_NUM;
}






void  SetUartFrameInvalidPosSeriNum(uint8_t UartFrameIndex, uint16_t UartFrameSerial)
{
ASSERT(UartFrameIndex  < FRAME_NUM_FILL_SIZE);
 ASSERT(UartFrameSerial  < MAX_RX_FRAME_NUM+1);
 ASSERT(UartBigDatOpera.UartFrameInfor[UartFrameIndex].UartFrameSerialNum == INVALID_SERIAL_NUM);

 UartBigDatOpera.UartFrameInfor[UartFrameIndex].UartFrameSerialNum = UartFrameSerial;
}








uint8_t  CurUartFrameCanPutInNum(void)
{
uint8_t i;
 uint8_t InvalidUartFrameAccu = 0;

 for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum == INVALID_SERIAL_NUM)
{
InvalidUartFrameAccu++;
}
}

return  InvalidUartFrameAccu;
}  








uint8_t  CurUartFrameCanPutOutNum(void)
{
uint8_t i;
 uint8_t ValidUartFrameAccu = 0;

 for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum != INVALID_SERIAL_NUM)
{
ValidUartFrameAccu++;
}
}

return ValidUartFrameAccu;
}








void   GetUartFrameTransferInPrama(uint8_t *InvalidUartFrameNum, uint8_t *RecordValidUartFramePos)
{
uint8_t  i;
 uint8_t  InvalidUartFrameCnt = 0;
 uint8_t  RecordValidIndex = 0;

 for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum == INVALID_SERIAL_NUM)
{
InvalidUartFrameCnt++;
   *InvalidUartFrameNum  = InvalidUartFrameCnt;
   RecordValidUartFramePos[RecordValidIndex] = i;
   RecordValidIndex++;
}
}
}






void  SetCurMaxFrameSeriNum(uint16_t FrameSeriNum)
{
 
UartBigDatOpera.CurAllFrameMaxSeriNum  = FrameSeriNum;
}




uint16_t  GetCurMaxFrameSeriNum(void)
{
return  UartBigDatOpera.CurAllFrameMaxSeriNum;
}




void  SetCurTxFrameSerial(uint16_t TxSeriNum)
{
ASSERT(TxSeriNum  < MAX_RX_FRAME_NUM+1);

 UartBigDatOpera.CurTxFrameSeriNum  = TxSeriNum;
}






uint16_t  GetCurTxFrameSerial(void)
{
return  UartBigDatOpera.CurTxFrameSeriNum;
}


#ifndef  _UART_BIG_DATA_H_
#define  _UART_BIG_DATA_H_








#include <stdint.h>






extern void  InitUartBigDataAppParma(void);
extern uint8_t  SearchUartFrameValidStoreAdd(void);
extern uint8_t  GetUartFrameMaxSeriNum(void);
extern uint8_t  GetUartFrameMinSeriNum(void);
extern void   FillUartFrameToCorrectAdd(uint8_t FillAddr, const uint8_t *UartFrame);
extern void   GetUartFrameFromDataTab(uint8_t GetAddr, uint8_t *UartFrame);
extern uint8_t  GetUartFrameDataTabOperaAddr(uint16_t UartFrameSerialNum);
extern void  SetUartFrameSerialNumInvalid(uint8_t UartFrameIndex);
extern void  SetUartFrameInvalidPosSeriNum(uint8_t UartFrameIndex, uint16_t UartFrameSerial);
extern uint8_t  CurUartFrameCanPutInNum(void);
extern uint8_t  CurUartFrameCanPutOutNum(void);
extern uint16_t  GetUartFrameMaxRxSeri(void);
extern uint8_t  GetLastUartFrameTxSta(void);
extern void   StoreLastUartFrameTxData(uint8_t DataSize, uint8_t *TxVal);
extern void  SetLastUartFrameTxSta(uint8_t  FrameTxSta);
extern void  SetUartFrameRxFinish(void);
extern uint8_t  IsUartFrameArriveEnd(void);
extern void  GetLastUartFrameTxParma(uint8_t *size, uint8_t *LastDataBuf);






#endif



/**
 * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 * 
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 * 
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 * 
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 * 
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */
/** @file
 *
 * @defgroup ble_sdk_uart_over_ble_main main.c
 * @{
 * @ingroup  ble_sdk_app_nus_eval
 * @brief    UART over BLE application main file.
 *
 * This file contains the source code for a sample application that uses the Nordic UART service.
 * This application uses the @ref srvlib_conn_params module.
 */






#include <stdint.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf.h"
#include "ble_hci.h"
#include "ble_advdata.h"
#include "ble_advertising.h"
#include "ble_conn_params.h"
#include "nrf_sdh.h"
#include "nrf_sdh_soc.h"
#include "nrf_sdh_ble.h"
#include "nrf_ble_gatt.h"
#include "app_timer.h"
#include "ble_nus.h"
#include "app_uart.h"
#include "app_util_platform.h"
#include "bsp_btn_ble.h"
#include "socket_io_cfg.h"
#include "led_handle.h"
#include "socket_cfg.h"
#include "led_app_cfg.h"
#include "led_task.h"


#if defined (UART_PRESENT)
#include "nrf_uart.h"
#endif
#if defined (UARTE_PRESENT)
#include "nrf_uarte.h"
#endif


#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"


#define APP_BLE_CONN_CFG_TAG            1                                           /**< A tag identifying the SoftDevice BLE configuration. */


#define APP_FEATURE_NOT_SUPPORTED       BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2        /**< Reply when unsupported features are requested. */


#define DEVICE_NAME                     "Nordic_UART"                               /**< Name of device. Will be included in the advertising data. */
#define NUS_SERVICE_UUID_TYPE           BLE_UUID_TYPE_VENDOR_BEGIN                  /**< UUID type for the Nordic UART Service (vendor specific). */


#define APP_BLE_OBSERVER_PRIO           3                                           /**< Application's BLE observer priority. You shouldn't need to modify this value. */


#define APP_ADV_INTERVAL                64                                          /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
#define APP_ADV_TIMEOUT_IN_SECONDS      180                                         /**< The advertising timeout (in units of seconds). */


#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)             /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(75, UNIT_1_25_MS)             /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
#define SLAVE_LATENCY                   0                                           /**< Slave latency. */
#define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */
#define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                       /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                      /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT    3                                           /**< Number of attempts before giving up the connection parameter negotiation. */


#define DEAD_BEEF                       0xDEADBEEF                                  /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */


#define UART_TX_BUF_SIZE                256                                         /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE                256                                         /**< UART RX buffer size. */




BLE_NUS_DEF(m_nus);                                                                 /**< BLE NUS service instance. */
NRF_BLE_GATT_DEF(m_gatt);                                                           /**< GATT module instance. */
BLE_ADVERTISING_DEF(m_advertising);                                                 /**< Advertising module instance. */


static uint16_t   m_conn_handle          = BLE_CONN_HANDLE_INVALID;                 /**< Handle of the current connection. */
static uint16_t   m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - 3;            /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
static ble_uuid_t m_adv_uuids[]          =                                          /**< Universally unique service identifier. */
{
    {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}
};




/**@brief Function for assert macro callback.
 *
 * @details This function will be called in case of an assert in the SoftDevice.
 *
 * @warning This handler is an example only and does not fit a final product. You need to analyse
 *          how your product is supposed to react in case of Assert.
 * @warning On assert from the SoftDevice, the system can only recover on reset.
 *
 * @param[in] line_num    Line number of the failing ASSERT call.
 * @param[in] p_file_name File name of the failing ASSERT call.
 */
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
{
    app_error_handler(DEAD_BEEF, line_num, p_file_name);
}




/**@brief Function for the GAP initialization.
 *
 * @details This function will set up all the necessary GAP (Generic Access Profile) parameters of
 *          the device. It also sets the permissions and appearance.
 */
static void gap_params_init(void)
{
    uint32_t                err_code;
    ble_gap_conn_params_t   gap_conn_params;
    ble_gap_conn_sec_mode_t sec_mode;


    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);


    err_code = sd_ble_gap_device_name_set(&sec_mode,
                                          (const uint8_t *) DEVICE_NAME,
                                          strlen(DEVICE_NAME));
    APP_ERROR_CHECK(err_code);


    memset(&gap_conn_params, 0, sizeof(gap_conn_params));


    gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
    gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
    gap_conn_params.slave_latency     = SLAVE_LATENCY;
    gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;


    err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
    APP_ERROR_CHECK(err_code);
}




/**@brief Function for handling the data from the Nordic UART Service.
 *
 * @details This function will process the data received from the Nordic UART BLE Service and send
 *          it to the UART module.
 *
 * @param[in] p_nus    Nordic UART Service structure.
 * @param[in] p_data   Data to be send to UART module.
 * @param[in] length   Length of the data.
 */
/**@snippet [Handling the data received over BLE] */


static void nus_data_handler(ble_nus_evt_t * p_evt)
{


    if (p_evt->type == BLE_NUS_EVT_RX_DATA)
    {
        uint32_t err_code;


        NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART.");
        NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);


        for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++)
        {
            do
            {
                err_code = app_uart_put(p_evt->params.rx_data.p_data[i]);
                if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY))
                {
                    NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code);
                    APP_ERROR_CHECK(err_code);
                }
            } while (err_code == NRF_ERROR_BUSY);
        }
        if (p_evt->params.rx_data.p_data[p_evt->params.rx_data.length-1] == '\r')
        {
            while (app_uart_put('\n') == NRF_ERROR_BUSY);
        }
    }


}


/*
static void nus_data_handler(ble_nus_evt_t * p_evt)
{


    if (p_evt->type == BLE_NUS_EVT_RX_DATA)
    {


        NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART.");
        NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);


        send_data_to_boad((uint8_t *)p_evt->params.rx_data.p_data,p_evt->params.rx_data.length);
    }


}
*/
/**@snippet [Handling the data received over BLE] */




/**@brief Function for initializing services that will be used by the application.
 */
static void services_init(void)
{
    uint32_t       err_code;
    ble_nus_init_t nus_init;


    memset(&nus_init, 0, sizeof(nus_init));


    nus_init.data_handler = nus_data_handler;


    err_code = ble_nus_init(&m_nus, &nus_init);
Tx_Rx_Nux = m_nus;
    APP_ERROR_CHECK(err_code);
}




/**@brief Function for handling an event from the Connection Parameters Module.
 *
 * @details This function will be called for all events in the Connection Parameters Module
 *          which are passed to the application.
 *
 * @note All this function does is to disconnect. This could have been done by simply setting
 *       the disconnect_on_fail config parameter, but instead we use the event handler
 *       mechanism to demonstrate its use.
 *
 * @param[in] p_evt  Event received from the Connection Parameters Module.
 */
static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
{
    uint32_t err_code;


    if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
    {
        err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
        APP_ERROR_CHECK(err_code);
    }
}




/**@brief Function for handling errors from the Connection Parameters module.
 *
 * @param[in] nrf_error  Error code containing information about what went wrong.
 */
static void conn_params_error_handler(uint32_t nrf_error)
{
    APP_ERROR_HANDLER(nrf_error);
}




/**@brief Function for initializing the Connection Parameters module.
 */
static void conn_params_init(void)
{
    uint32_t               err_code;
    ble_conn_params_init_t cp_init;


    memset(&cp_init, 0, sizeof(cp_init));


    cp_init.p_conn_params                  = NULL;
    cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
    cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
    cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
    cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
    cp_init.disconnect_on_fail             = false;
    cp_init.evt_handler                    = on_conn_params_evt;
    cp_init.error_handler                  = conn_params_error_handler;


    err_code = ble_conn_params_init(&cp_init);
    APP_ERROR_CHECK(err_code);
}




/**@brief Function for putting the chip into sleep mode.
 *
 * @note This function will not return.
 */
static void sleep_mode_enter(void)
{
    uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE);
    APP_ERROR_CHECK(err_code);


    // Prepare wakeup buttons.
    err_code = bsp_btn_ble_sleep_mode_prepare();
    APP_ERROR_CHECK(err_code);


    // Go to system-off mode (this function will not return; wakeup will cause a reset).
    err_code = sd_power_system_off();
    APP_ERROR_CHECK(err_code);
}




/**@brief Function for handling advertising events.
 *
 * @details This function will be called for advertising events which are passed to the application.
 *
 * @param[in] ble_adv_evt  Advertising event.
 */
static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
    uint32_t err_code;


    switch (ble_adv_evt)
    {
        case BLE_ADV_EVT_FAST:
            err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
            APP_ERROR_CHECK(err_code);
            break;
        case BLE_ADV_EVT_IDLE:
            sleep_mode_enter();
            break;
        default:
            break;
    }
}




/**@brief Function for handling BLE events.
 *
 * @param[in]   p_ble_evt   Bluetooth stack event.
 * @param[in]   p_context   Unused.
 */
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    uint32_t err_code;


    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            NRF_LOG_INFO("Connected");
            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
            break;


        case BLE_GAP_EVT_DISCONNECTED:
            NRF_LOG_INFO("Disconnected");
            // LED indication will be changed when advertising starts.
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
            break;


#ifndef S140
        case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
        {
            NRF_LOG_DEBUG("PHY update request.");
            ble_gap_phys_t const phys =
            {
                .rx_phys = BLE_GAP_PHY_AUTO,
                .tx_phys = BLE_GAP_PHY_AUTO,
            };
            err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
            APP_ERROR_CHECK(err_code);
        } break;
#endif


        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
            // Pairing not supported
            err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
            APP_ERROR_CHECK(err_code);
            break;
#if !defined (S112)
         case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
        {
            ble_gap_data_length_params_t dl_params;


            // Clearing the struct will effectivly set members to @ref BLE_GAP_DATA_LENGTH_AUTO
            memset(&dl_params, 0, sizeof(ble_gap_data_length_params_t));
            err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle, &dl_params, NULL);
            APP_ERROR_CHECK(err_code);
        } break;
#endif //!defined (S112)
        case BLE_GATTS_EVT_SYS_ATTR_MISSING:
            // No system attributes have been stored.
            err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
            APP_ERROR_CHECK(err_code);
            break;


        case BLE_GATTC_EVT_TIMEOUT:
            // Disconnect on GATT Client timeout event.
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;


        case BLE_GATTS_EVT_TIMEOUT:
            // Disconnect on GATT Server timeout event.
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;


        case BLE_EVT_USER_MEM_REQUEST:
            err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gattc_evt.conn_handle, NULL);
            APP_ERROR_CHECK(err_code);
            break;


        case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
        {
            ble_gatts_evt_rw_authorize_request_t  req;
            ble_gatts_rw_authorize_reply_params_t auth_reply;


            req = p_ble_evt->evt.gatts_evt.params.authorize_request;


            if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
            {
                if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ)     ||
                    (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
                    (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
                {
                    if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
                    {
                        auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
                    }
                    else
                    {
                        auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
                    }
                    auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED;
                    err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle,
                                                               &auth_reply);
                    APP_ERROR_CHECK(err_code);
                }
            }
        } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST


        default:
            // No implementation needed.
            break;
    }
}




/**@brief Function for the SoftDevice initialization.
 *
 * @details This function initializes the SoftDevice and the BLE event interrupt.
 */
static void ble_stack_init(void)
{
    ret_code_t err_code;


    err_code = nrf_sdh_enable_request();
    APP_ERROR_CHECK(err_code);


    // Configure the BLE stack using the default settings.
    // Fetch the start address of the application RAM.
    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);


    // Enable BLE stack.
    err_code = nrf_sdh_ble_enable(&ram_start);
    APP_ERROR_CHECK(err_code);


    // Register a handler for BLE events.
    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}




/**@brief Function for handling events from the GATT library. */
void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
{
    if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
    {
        m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
        NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
    }
    NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
                  p_gatt->att_mtu_desired_central,
                  p_gatt->att_mtu_desired_periph);
}




/**@brief Function for initializing the GATT library. */
void gatt_init(void)
{
    ret_code_t err_code;


    err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
    APP_ERROR_CHECK(err_code);


    err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, 64);
    APP_ERROR_CHECK(err_code);
}




/**@brief Function for handling events from the BSP module.
 *
 * @param[in]   event   Event generated by button press.
 */
void bsp_event_handler(bsp_event_t event)
{
    uint32_t err_code;
    switch (event)
    {
        case BSP_EVENT_SLEEP:
            sleep_mode_enter();
            break;


        case BSP_EVENT_DISCONNECT:
            err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            if (err_code != NRF_ERROR_INVALID_STATE)
            {
                APP_ERROR_CHECK(err_code);
            }
            break;


        case BSP_EVENT_WHITELIST_OFF:
            if (m_conn_handle == BLE_CONN_HANDLE_INVALID)
            {
                err_code = ble_advertising_restart_without_whitelist(&m_advertising);
                if (err_code != NRF_ERROR_INVALID_STATE)
                {
                    APP_ERROR_CHECK(err_code);
                }
            }
            break;


        default:
            break;
    }
}




/**@brief   Function for handling app_uart events.
 *
 * @details This function will receive a single character from the app_uart module and append it to
 *          a string. The string will be be sent over BLE when the last character received was a
 *          'new line' '\n' (hex 0x0A) or if the string has reached the maximum data length.
 */
/**@snippet [Handling the data received over UART] */
void uart_event_handle(app_uart_evt_t * p_event)
{
    static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
    static uint8_t index = 0;
    uint32_t       err_code;


    switch (p_event->evt_type)
    {
        case APP_UART_DATA_READY:
            UNUSED_VARIABLE(app_uart_get(&data_array[index]));
            index++;


            if ((data_array[index - 1] == '\n') || (index >= (m_ble_nus_max_data_len)))
            {
                NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                NRF_LOG_HEXDUMP_DEBUG(data_array, index);


                do
                {
                    uint16_t length = (uint16_t)index;
                    err_code = ble_nus_string_send(&m_nus, data_array, &length);
                    if ( (err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_BUSY) )
                    {
                        APP_ERROR_CHECK(err_code);
                    }
                } while (err_code == NRF_ERROR_BUSY);


                index = 0;
            }
            break;


        case APP_UART_COMMUNICATION_ERROR:
//            APP_ERROR_HANDLER(p_event->data.error_communication);
            break;


        case APP_UART_FIFO_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_code);
            break;


        default:
            break;
    }
}
/**@snippet [Handling the data received over UART] */




/**@brief  Function for initializing the UART module.
 */
/**@snippet [UART Initialization] */
static void uart_init(void)
{
    uint32_t                     err_code;
    app_uart_comm_params_t const comm_params =
    {
        .rx_pin_no    = RX_PIN_NUMBER1,
        .tx_pin_no    = TX_PIN_NUMBER1,
        .rts_pin_no   = RTS_PIN_NUMBER,
        .cts_pin_no   = CTS_PIN_NUMBER,
        .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
        .use_parity   = false,
        .baud_rate    = NRF_UART_BAUDRATE_115200
    };


    APP_UART_FIFO_INIT(&comm_params,
                       UART_RX_BUF_SIZE,
                       UART_TX_BUF_SIZE,
                       uart_event_handle,
                       APP_IRQ_PRIORITY_LOWEST,
                       err_code);
    APP_ERROR_CHECK(err_code);
}
/**@snippet [UART Initialization] */




/**@brief Function for initializing the Advertising functionality.
 */
static void advertising_init(void)
{
ret_code_t    err_code;
 ble_gap_addr_t device_addr;
 uint8 i;
//  InitAdvData();
 err_code = sd_ble_gap_addr_get(&device_addr);
 APP_ERROR_CHECK(err_code);
 
 for(i=0; i< BLE_GAP_ADDR_LEN; i++)
 {
advertData[14-i] = device_addr.addr[i];
}

// advertData[22] = (IsPassWordModify()) ? 1:0;
#if 1
if(IsPassWordModify())
{
advertData[22] = 1;
}
else
{
advertData[22] = 0;
}
#endif
 uint16 sk_scrp_length = sizeof(deviceName);
 err_code = sd_ble_gap_adv_data_set(advertData, sk_adv_length, deviceName, sk_scrp_length);
 APP_ERROR_CHECK(err_code);


}




/**@brief Function for initializing buttons and leds.
 *
 * @param[out] p_erase_bonds  Will be true if the clear bonding button was pressed to wake the application up.
 */
static void buttons_leds_init(bool * p_erase_bonds)
{
    bsp_event_t startup_event;


    uint32_t err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS, bsp_event_handler);
    APP_ERROR_CHECK(err_code);


    err_code = bsp_btn_ble_init(NULL, &startup_event);
    APP_ERROR_CHECK(err_code);


    *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
}




/**@brief Function for initializing the nrf log module.
 */
static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);


    NRF_LOG_DEFAULT_BACKENDS_INIT();
}




/**@brief Function for placing the application in low power state while waiting for events.
 */
static void power_manage(void)
{
    uint32_t err_code = sd_app_evt_wait();
    APP_ERROR_CHECK(err_code);
}




static void timers_init(void)
{
uint32_t err_code;
err_code = app_timer_init();
   APP_ERROR_CHECK(err_code);
}


/*
static  void  socket_base_init(void)
{
SkOneGrpCtrlPin_t  DevicePinCfg =
 {
.KeyPinNum = KEY0_SIGN_PIN,
 .LedPinNum = LED0_SIGN_PIN,
 .RelayPinNum = RELAY0_SIGN_PIN,
 .KeyActiveSta = KEY0_ACTIVE_STA,
 .LedActiveSta = LED0_ACTIVE_STA,
 .RelayActiveSta = RELAY0_ACTIVE_STA,
 .LedUserCtrl = NULL,
 .RelayUserCtrl = NULL,
};

InitSwitchPinGrpAtt(&DevicePinCfg, 1);
InitSwitchDriAtt(1);
#if  0
nrf_gpio_cfg_output(DevicePinCfg.LedPinNum);
 nrf_gpio_pin_write(DevicePinCfg.LedPinNum, GetLedCloseDriLevel(1));
 
 nrf_gpio_cfg_output(DevicePinCfg.RelayPinNum);
 nrf_gpio_pin_write(DevicePinCfg.RelayPinNum, GetRelayCloseDriLevel(1));

SetSocketLedCurSta(LED_CLOSE, LED0_ID);
#endif
nrf_gpio_cfg_output(GetSocketLedCtrlPin(0));
nrf_gpio_cfg_output(GetSocketRelayCtrlPin(1));
SetSwitchClose(1);
}
*/


/**@brief Application main function.
 */
int main(void)
{
    uint32_t err_code;
    bool     erase_bonds;


    // Initialize.
    
    timers_init();
//    sk_event_create();
    uart_init();
    log_init();


//    buttons_leds_init(&erase_bonds);
//  socket_base_init();
    ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
//    advertising_init();
    conn_params_init();


    printf("\r\nUART Start!\r\n");
    NRF_LOG_INFO("UART Start!");
//    err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
//    APP_ERROR_CHECK(err_code);

// SetLedCycleModeAction(LED0_ID, 100, 2000);


    // Enter main loop.
    for (;;)
    {
        UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
        power_manage();
    }
}




/**
 * @}
 */















































































































































































































































猜你喜欢

转载自blog.csdn.net/liqiqian19871027/article/details/80497547