BLE/CYPRESS

BLE 정리

또난 2015. 10. 15. 10:33

싸이프레스 BLE 정리

 

1.  ADV 주기 조정

CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:

CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);

#define CYBLE_ADVERTISING_FAST                      (0x00u)

#define CYBLE_ADVERTISING_SLOW                      (0x01u)

#define CYBLE_ADVERTISING_CUSTOM                    (0x02u)

2015.11.13  

함수 사용하여 변경 ( solar ble EH_Motherboard 참조)

함수 사용하여 변경 ( solar ble EH_Motherboard 참조)
/******************************************************************************* 
Function Name: Beacon_GappStartAdvertisement
********************************************************************************* 
Summary:
*   This function is used to start the advertisement using the specified interval. 
*   Timeout would never happen.
** Parameters:
*   advertisingInterval - Time in millisecond for advertising interval 
** Return:
*   CYBLE_API_RESULT_T - Return value indicates if the function succeeded or 
*   failed. Following are the possible error codes.*   *   Errors codes                        Description*   ------------                        -----------*   CYBLE_ERROR_OK                      On successful operation.*   CYBLE_ERROR_INVALID_PARAMETER       On passing an invalid parameter.
******************************************************************************/
CYBLE_API_RESULT_T Beacon_GappStartAdvertisement(uint32_t advertisingInterval)
{    
	CYBLE_API_RESULT_T apiResult;        /* Check whether advertisement can be started or not. */    
    if((CYBLE_STATE_DISCONNECTED == CyBle_GetState()) && ((cyBle_eventHandlerFlag & CYBLE_START_FLAG) == 0u))    
    {       /* When timeout value is 0, timeout never happens, advertisement won't stop. */
        cyBle_discoveryModeInfo.advTo = 0;                
        /* cyBle_discoveryModeInfo.advParam->advIntvMin = advertisingInterval / MS_TO_TIMERVALUE_RATIO; */        
        /*  1/MS_TO_TIMERVALUE_RATIO = 1/0.625 = (1*8)/5 = (1<<3)/5  */        
        cyBle_discoveryModeInfo.advParam->advIntvMin = (advertisingInterval << 3) / 5;        
        cyBle_discoveryModeInfo.advParam->advIntvMax = cyBle_discoveryModeInfo.advParam->advIntvMin;
        cyBle_advertisingIntervalType = CYBLE_ADVERTISING_FAST;        
        apiResult = CyBle_GappEnterDiscoveryMode(&cyBle_discoveryModeInfo);            
        /* If start advertisement successfully, set the flag to avoid multiple start. */        
        if(CYBLE_ERROR_OK == apiResult)        
        {            
        	cyBle_eventHandlerFlag |= CYBLE_START_FLAG;        
        }    
    }    /* If advertisement cannot be started in current state. */    
    else    {        apiResult = CYBLE_ERROR_INVALID_STATE;    }
    return (apiResult);
}

 

2.  deep sleep 테스트

   CySysClkEcoStop();    

   //CySysPmDeepSleep();

   CySysPmHibernate();

   

    while(1);

 

3.  저전력 테스트

-    풀업 보다 오픈 드레인 모드, 초기 출력은 Low

-    Debug GPIO 설정

-    IMO (내부 클럭) 16Mhz 이하, ILO Off

-    가속도 센서는 ODR 조정

 

4.  Printf 디버깅 메시지 처리

 

Debug.h
다운로드

 

debug.c
다운로드

 

Softuart TX 추가하고

Debug 파일 추가하고 

(DEBUG_UART_ENABLED == YES)

Shared memory bootable /참조

 

System Tab => Heap Size  0x400 으로 조정

5.  Dynamic adver data

-    Advertising data 가변

-    void DynamicADVPayloadUpdate(void)

-    {

-        static uint16 count = 0;

-        //static uint8 dynamicPayload = MIN_PAYLOAD_VALUE;

-        

-        //if(CyBle_GetBleSsState() == CYBLE_STATE_ADVERTISING)

-        if(CyBle_GetState() == CYBLE_STATE_ADVERTISING)// && buttonState == BUTTON_IS_PRESSED)

-        //if(CyBle_GetBleSsState() == CYBLE_BLESS_STATE_ACTIVE)

-        {

-            count++; /* Loop counter */

-            

-            /* Once the system enters Sleep/Deepsleep mode during advertisement, the source of wake-up is the next 

-             * advertisement interval which has a wakeup interval of 1 advertisement (ADV) interval (100ms).

-             * LOOP_DELAY * ADV interval is the interval after which ADV data is updated in this firmware.*/

-            

-            if(count >= LOOP_DELAY)

-            {

-               count = 0;

-                /* Dynamic payload will be continuously updated */

-                     /*

-                     advPayload[MANUFACTURER_SPECIFIC_DYNAMIC_DATA_INDEX] = dynamicPayload++;

-                if(dynamicPayload == MAX_PAYLOAD_VALUE)

-                {

-                    dynamicPayload = MIN_PAYLOAD_VALUE;

-                }

-                */

-                

-                advPayload[MANUFACTURER_SPECIFIC_DYNAMIC_DATA_INDEX] = Acc_detection;

-                //printf("dynamicPayload %d \r\n",Acc_detection);

-                CyBle_GapUpdateAdvData(cyBle_discoveryModeInfo.advData, cyBle_discoveryModeInfo.scanRspData);

-            }

-        }

-    }

 

6.     외부 메모리 없이 OTA 구현

Shared Memory 예제 참조

128 kb 플래쉬 용량으로 OTA 부트로더에 BLE 기능 구현, 나머지 BLE 외의 기능은 부트로드에이블에 구현

가속도 I2C 는 부트로더에 기능 구현해야 됨?? => 확인 필요

=> I2C 부트로드블에만 구현해도 동작함, 단 워치독 카운터에서는 동작안됨...일반 Main 에서 동작함.

 

 

7.     BT 연결 중 딥 슬립하면 모터 PWM제어 와 디버깅 메시지 안됨.

       

 

 if((CyBle_GetState() != CYBLE_STATE_INITIALIZING ) && (CyBle_GetState() != CYBLE_STATE_CONNECTED))
{
            /* Enter DeepSleep mode between connection intervals */
            lpMode = CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP);
            CyGlobalIntDisable;
            blessState = CyBle_GetBleSsState();
            //DBG_PRINTF("sleep %d - %d\n",lpMode,blessState);
            //if(lpMode == CYBLE_BLESS_DEEPSLEEP && alertLevel == NO_ALERT ) 
            if(lpMode == CYBLE_BLESS_DEEPSLEEP)
            {   
                if(blessState == CYBLE_BLESS_STATE_ECO_ON || blessState == CYBLE_BLESS_STATE_DEEPSLEEP ) 
                {  
                    MT_PWM_Sleep();  
                    CySysPmDeepSleep();  
                    //CySysPmSleep();
                    MT_PWM_Wakeup();  
                }
            }
            else
            {
                if(blessState != CYBLE_BLESS_STATE_EVENT_CLOSE)
                {
                    CySysPmSleep();
                }
            }
            CyGlobalIntEnable;
        }

8. uart 디버깅 메시지 확인 위해 Connection interval 20ms 이상 설정   슬림모드 비활성화 해야 함... 안그러면 연결 해제됨.

 

 

9. 연결 해제

CyBle_GapDisconnect(0);

========================================
				case 'd':                   /* Disconnect */

                apiResult = CyBle_GapDisconnect(cyBle_connHandle.bdHandle);
                DBG_PRINTF("\r\n");
                if(apiResult != CYBLE_ERROR_OK)
                {
                    DBG_PRINTF("Disconnect Device routine Error: %x.\r\n", apiResult);
                }
                else
                {
                    DBG_PRINTF("Disconnect Device routine Success.\r\n");
                }
                break;
========================================

 

      

 

10. Notify 처리

connectionHandle 이벤트 받아야 정상 작동..

case CYBLE_EVT_GATT_CONNECT_IND:
	DBG_PRINTF("EVT_GATT_CONNECT_IND: %x, %x \r\n", cyBle_connHandle.attId, cyBle_connHandle.bdHandle);
    connectionHandle = *(CYBLE_CONN_HANDLE_T *) eventParam;
=======================================================================
void SendDataOverTxDataNotification(uint8 *sendData, uint8 len)
{
 /* 'rgbLednotificationHandle' stores RGB LED notification data parameters */
 CYBLE_GATTS_HANDLE_VALUE_NTF_T sendDatanotificationHandle;

 /* If stack is not busy, then send the notification */
 if(busyStatus == CYBLE_STACK_STATE_FREE)
 {
 /* Update notification handle will CapSense slider data*/
 sendDatanotificationHandle.attrHandle =CYBLE_CUSTOM_SERVICE_CUSTOM_CHARACTERISTIC_CHAR_HANDLE; 
 sendDatanotificationHandle.value.val = sendData;
 sendDatanotificationHandle.value.len = len;

 /* Send the updated handle as part of attribute for notifications */
 CyBle_GattsNotification(connectionHandle,&sendDatanotificationHandle);
   DBG_PRINTF("connectionHandle %d %d \n",connectionHandle.attId, connectionHandle.bdHandle );
 }
}

11. 사용자 데이터 처리

 1) Flash 쓰기 쓰면 됨... 단 펌웨어 업데이트시 삭제됨.

     uint32 CySysFlashWriteRow       (uint32 rowNum, const uint8 rowData[]);

cystatus CyBLE_Nvram_Write (const uint8 buffer[], const uint8 varFlash[], uint16 length);

cystatus CyBLE_Nvram_Erase (const uint8 *varFlash, uint16 length);

  2) User SFlash Write => 펌웨어 업데이트해도 삭제되지 않음. 단 내부 클럭 속도 변화 문제가 발생....소프트 리셋 해야 함..     

 

User SFlash Write.pdf
다운로드

 

User_SFlash_Write (1).zip
다운로드

 

 

 

 

 12. 외부크리스털 오차 조정 (2015-11-11)

   1) main 에서 루프 전에 아래 코드 추가

       CY_SET_XTND_REG32((void CYFAR *)(CYREG_BLE_BLERD_BB_XO_CAPTRIM), 0x00007E7Eu);

 

13. TX Power 조정 (2015.11.13)

/******************************************************************************
* Function Name: ReadAndApplyConfig
*******************************************************************************
*
* Summary:
*   Read configuration in flash and apply. As a result of CyBle_SetTxPowerLevel(), 
*   this function should be invoked in BLE_AppEventHandler().
*
* Parameters:  
*   None
*
* Return: 
*   *pInterval - Time in millisecond for advertising interval 
*   *pSensorFlag - Sensor on/off flag
*******************************************************************************/

void ReadAndApplyConfig(int32_t *pInterval, uint32_t *pSensorFlag)
{
    BeaconConfig *pCFG;
    int32_t txpwr;
    CYBLE_BLESS_PWR_IN_DB_T t_pwr;
    CYBLE_BLESS_PWR_LVL_T param_pwr;

    /* If UserSFlash is not empty, use configuration in UserSFlash. */
    if(pBeaconConfig->SFlashDataFlag == SFLASH_DATA_FLAG_VALID)
    {
        pCFG = pBeaconConfig;
    }

    /* Otherwise default configuration will be used. */
    else
    {
        pCFG = (BeaconConfig *)&DefaultBeaconConfig;
    }

    /* Set UUID */
    memcpy(&(cyBle_discoveryData.advData[ADDR_UUID_OFFSET]), pCFG->uuid, sizeof(pCFG->uuid));

    /* Apply Little Endian to COID, send Lower Byte first. */
    cyBle_discoveryData.advData[ADDR_COID_OFFSET]     = pCFG->comID & 0xFF;
    cyBle_discoveryData.advData[ADDR_COID_OFFSET + 1] = pCFG->comID >> 8;

    /* Apply Big Endian to MAJOR, send Higher Byte first. */
    cyBle_discoveryData.advData[ADDR_MAJOR_OFFSET]     = pCFG->major >> 8;
    cyBle_discoveryData.advData[ADDR_MAJOR_OFFSET + 1] = pCFG->major & 0xFF;

    /* Set RSSI */
    cyBle_discoveryData.advData[ADDR_RSSI_OFFSET] = pCFG->rssi;  

    /* Set Sensor_Flag */
    if(pSensorFlag != NULL)
    {
        *pSensorFlag = pCFG->sensor;
    }
  
    /* Set Advertisement Interval */
    if(pInterval != NULL)
    {
        *pInterval = pCFG->itrvl;
    }

    /* Apply Big Endian to MINOR, send Higher Byte first. */
    cyBle_discoveryData.advData[ADDR_MINOR_OFFSET]     = pCFG->minor >> 8;
    cyBle_discoveryData.advData[ADDR_MINOR_OFFSET + 1] = pCFG->minor & 0xFF;

    /* Set TX power */
    txpwr = pCFG->txpwr;

	/* Valid values are -18, -12, -6, -3, -2, -1, 0 and 3 dBm. */
    if(txpwr == -18)
    {
        param_pwr = CYBLE_LL_PWR_LVL_NEG_18_DBM;
    }

    else if(txpwr == -12)
    {
       param_pwr = CYBLE_LL_PWR_LVL_NEG_12_DBM;
    }
    else if(txpwr == -6)
    {
        param_pwr = CYBLE_LL_PWR_LVL_NEG_6_DBM;
    }
    else if(txpwr == -3)
    {
        param_pwr = CYBLE_LL_PWR_LVL_NEG_3_DBM;
    }
    else if(txpwr == -2)
    {
        param_pwr = CYBLE_LL_PWR_LVL_NEG_2_DBM;
    }
    else if(txpwr == -1)
    {
        param_pwr = CYBLE_LL_PWR_LVL_NEG_1_DBM;
    }
    else if(txpwr == 0)
    {
        param_pwr = CYBLE_LL_PWR_LVL_0_DBM;
    }
    else if(txpwr == 3)
    {
        param_pwr = CYBLE_LL_PWR_LVL_3_DBM;
    }
    else
    {
        param_pwr = CYBLE_LL_PWR_LVL_MAX;
    }
    t_pwr.blePwrLevelInDbm = param_pwr;
    t_pwr.bleSsChId = CYBLE_LL_ADV_CH_TYPE;
    CyBle_SetTxPowerLevel(&t_pwr);
    return;
}

CyBle_Stack.h

 => CYBLE_API_RESULT_T CyBle_SetTxPowerLevel (CYBLE_BLESS_PWR_IN_DB_T *bleSsPwrLvl);

 

14. LED Toggle (15.12.24)
Pin_Red_Write(~Pin_Red_Read());
 

15. Adv Data (16.01.13)

cyble.c

CYBLE_GAPP_DISC_PARAM_T cyBle_discoveryParam =

{

    0x0664u,    /* uint16 advertising_interval_min */

    0x0664u,    /* uint16 advertising_interval_max */

    CYBLE_GAPP_CONNECTABLE_UNDIRECTED_ADV, /* uint8 advertising_type */

    0x00u,      /* uint8 own_addr_type */

    0x00u,      /* uint8 direct_addr_type */

    , /* uint8* direct_addr */

    0x07u,      /* uint8 advertising_channel_map */

    0x00u,      /* uint8 advertising_filter_policy */

};

 

CYBLE_GAPP_DISC_DATA_T cyBle_discoveryData =

{

    { 0x02u, 0x01u, 0x06u, 0x0Au, 0x09u, 0x41u, 0x6Cu,

    0x74u, 0x6Fu, 0x6Eu, 0x20u, 0x54u, 0x61u, 0x67u, 0x0Fu,

    0xFFu, 0x7Cu, 0x01u, 0xF4u, 0x01u, 0x02u, 0x03u, 0x04u,   => 제조사 코드 수정

    0x05u, 0x06u, 0x07u, 0x00u, 0x00u, 0x00u, 0xF5u, 0x00u }, /* uint8 advertising_data[CYBLE_MAX_ADV_DATA_LEN] */

    0x1Eu,      /* uint8 adv_data_length */

};

 

CYBLE_GAPP_SCAN_RSP_DATA_T cyBle_scanRspData =

{

    { 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,

    0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,

    0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,

    0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u }, /* uint8 scan_rsp_data[CYBLE_MAX_SCAN_RSP_DATA_LEN] */

    0x00u,      /* uint8 scan_rsp_data_length */

 

};

 

16. con time update (16.03.29)

if(CyBle_GetState() == CYBLE_STATE_CONNECTED)

{      

if(connUpdate)

            {

                CYBLE_API_RESULT_T conResult;

                static CYBLE_GAP_CONN_UPDATE_PARAM_T hrmConnectionParam =

                {

                    800,        /* Minimum connection interval of 800 * 1.25 = 1000 ms */

                    800,        /* Maximum connection interval of 800 * 1.25 = 1000 ms */

                    0,          /* Slave latency */

                    500        /* Supervision timeout of 5 seconds 500 * 10 */

                };

        conResult = CyBle_L2capLeConnectionParamUpdateRequest(cyBle_connHandle.bdHandle, &hrmConnectionParam);

                if(conResult != CYBLE_ERROR_OK)

                {

                    connUpdate = 0;

                    DBG_PRINTF("connUpdate \r\n");

                }

            }       

 

        }

'BLE > CYPRESS' 카테고리의 다른 글

초기화 되지 않는 변수설정  (0) 2016.09.29
싸이프레스 실수 출력  (0) 2016.06.10
PSoc BLE S-rom 관련  (0) 2015.12.07