싸이프레스 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 디버깅 메시지 처리
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 => 펌웨어 업데이트해도 삭제되지 않음. 단 내부 클럭 속도 변화 문제가 발생....소프트 리셋 해야 함..
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);
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 |