- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I want to be able to control the wake from deep sleep interval using the watchdog timer intrupt. But no matter what value I use for sleep_time, the interval always is about one second. Here is my code:
#define SLEEP_INTERVAL_500MS 500
#define SLEEP_INTERVAL_1000MS 1000
#define SLEEP_INTERVAL_2000MS 2000
#define ILO_FREQ 32000
/*******************************************************************************
* Function Name: InitWatchdog
********************************************************************************
* Summary:
* Initialize watchdog counter0 with specific sleep interval parameter
*
* Parameters:
* uint16 sleep_interval reset interval, in millisecond unit
*
* Return:
* void
*
*******************************************************************************/
void InitWatchdog(uint16 sleep_interval)
{
/*==============================================================================*/
/* configure counter 0 for wakeup interrupt */
/*==============================================================================*/
/* Counter 0 of Watchdog time generates peridically interrupt to wakeup system */
CySysWdtWriteMode(CY_SYS_WDT_COUNTER0, CY_SYS_WDT_MODE_INT);
/* Set interval as desired value */
CySysWdtWriteMatch(CY_SYS_WDT_COUNTER0, ((uint32)(sleep_interval * ILO_FREQ) / 1000));
/* clear counter on match event */
CySysWdtWriteClearOnMatch(CY_SYS_WDT_COUNTER0, 1u);
/*==============================================================================*/
/* enable watchdog */
/*==============================================================================*/
/* enable the counter 0 */
CySysWdtEnable(CY_SYS_WDT_COUNTER0_MASK);
/* check if counter 0 is enabled, otherwise keep looping here */
while(!CySysWdtReadEnabledStatus(CY_SYS_WDT_COUNTER0));
}
CY_ISR(isr_WDT)
{
/* clear interrupt flag to enable next interrupt */
Sensors_Power_Write(1);
ADC_Start(); /* Start up the ADC */
ADC_StartConvert(); /* Start ADC conversion */
ADC_IsEndConversion(ADC_WAIT_FOR_RESULT); /* Wait for result to complete */
ADC_StopConvert(); /* Stop ADC conversions */
updateSensorData(); //read sensordata and alarm, compare update adData if needed(stop advert, update, start advert)
ADC_Sleep();
Sensors_Power_Write(0);
CySysWdtClearInterrupt(CY_SYS_WDT_COUNTER0_INT);
}
int main()
{
/*===========================================================================================
* this code piece initializes the watchdog function
*==========================================================================================*/
/* initialize watchdog */
InitWatchdog(SLEEP_INTERVAL_500MS);
/* connect ISR routine to Watchdog interrupt */
ISR_WDT_StartEx(isr_WDT);
/* set the highest priority to make ISR is executed in all condition */
ISR_WDT_SetPriority(0);
/* enable global interrupt */
CyGlobalIntEnable; /* Enable global interrupts. */
CyBle_Start(Stack_Handler);
//SetupWDT(ONE_SECOND_PERIOD);
for(;;)
{
if(sensor0Counts < alarmValue){
appendFlagToLocalName(0x20);
} else {
appendFlagToLocalName(0x2a);
}
CyBle_ProcessEvents();
/* clear watchdog counter before deep sleep */
CySysWdtResetCounters(CY_SYS_WDT_COUNTER0_RESET);
/* reset watchdog counter requires several LFCLK cycles to take effect */
CyDelayUs(200);
/* go to deep sleep mode */
if( CyBle_EnterLPM( CYBLE_BLESS_DEEPSLEEP ) == CYBLE_BLESS_DEEPSLEEP )
{
ADC_Sleep();
CySysPmDeepSleep();
}
}
}
/* [] END OF FILE *
Also, is there a way to cascade the two counters in the WDT to obtain a sleep interval of 5 or 10 seconds. I read somewhere that the maximum interval is 2048 ms.
Thanks
Solved! Go to Solution.
- Labels:
-
BLE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Check out this example about how to use WDT there is a PDF in the file to explain it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please post your complete code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is my complete application, and thanks:
/* ========================================
*
* Copyright YOUR COMPANY, THE YEAR
* All Rights Reserved
* UNPUBLISHED, LICENSED SOFTWARE.
*
* CONFIDENTIAL AND PROPRIETARY INFORMATION
* WHICH IS THE PROPERTY OF your company.
*
* ========================================
*/
#include <project.h>
#define SLEEP_INTERVAL_500MS 1900
#define SLEEP_INTERVAL_1000MS 1000
#define ILO_FREQ 32000
uint64 TOWCount=0;
uint16 oldTOWCount=0;
//uint8 dynamicPayload = 0x2b;
uint16 alarmValue;//alarmCounts used to decide to increment TOW accumulator or not.
uint16 thermistorCounts;
uint16 sensor0Counts;
//char8 astrixSerialNum[] = "*12345";
char8 SN[6];//position serialNum[0] always left blank
char8 ID[26];//value of ID characteristic
//char8 astrixID[26];
CYBLE_CONN_HANDLE_T connectionHandle;
CYBLE_GATT_HANDLE_VALUE_PAIR_T tempHandle;
CYBLE_GATT_HANDLE_VALUE_PAIR_T sensor0ValueHandle;
CYBLE_GATT_HANDLE_VALUE_PAIR_T IDHandle;
CYBLE_GATT_HANDLE_VALUE_PAIR_T SNHandle;
CYBLE_GATT_HANDLE_VALUE_PAIR_T TOWDateHandle;
CYBLE_GATT_HANDLE_VALUE_PAIR_T TOWTotalHandle;
CYBLE_GATT_HANDLE_VALUE_PAIR_T alarmValueHandle;
CYBLE_GATT_VALUE_T sensorValueStruct;
CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam;
extern CYBLE_GAPP_DISC_MODE_INFO_T cyBle_discoveryModeInfo;
#define advPayload (cyBle_discoveryModeInfo.advData->advData)
#define MANUFACTURER_SPECIFIC_DYNAMIC_DATA_INDEX (25u) // index of the dynamic data in the ADV packet
//uint8 dynamicPalyload;// = 0x2a;//plus sign */
/*void DynamicADVPayloadUpdate(void)
{
if(CyBle_GetBleSsState() == CYBLE_BLESS_STATE_ACTIVE){
CyBle_GapUpdateAdvData(cyBle_discoveryModeInfo.advData, cyBle_discoveryModeInfo.scanRspData);
}
}*/
void appendFlagToLocalName(uint8 dynamicPayload)
{
//CyBle_GappStopAdvertisement();
advPayload[MANUFACTURER_SPECIFIC_DYNAMIC_DATA_INDEX] = dynamicPayload;
CyBle_GapUpdateAdvData(cyBle_discoveryModeInfo.advData, cyBle_discoveryModeInfo.scanRspData);
//CyBle_GappStartAdvertisement( CYBLE_ADVERTISING_FAST );
}
void updateSensorData()
{
//get thermistor counts, store in GATT
thermistorCounts = ADC_GetResult16(0);
tempHandle.attrHandle = CYBLE_TOW_SERVICE_TEMPERATURE_CHAR_HANDLE; //CYBLE_CUSTOM_SERVICE_CUSTOM_CHARACTERISTIC_CHAR_HANDLE;
tempHandle.value.val = (uint8 *)&thermistorCounts;
tempHandle.value.len = 2;
CyBle_GattsWriteAttributeValue(&tempHandle, 0, NULL, CYBLE_GATT_DB_LOCALLY_INITIATED);
//get sensor counts, store in GATT
sensor0Counts = ADC_GetResult16(1);
sensor0ValueHandle.attrHandle = CYBLE_TOW_SERVICE_SENSOR0_VALUE_CHAR_HANDLE; //CYBLE_CUSTOM_SERVICE_CUSTOM_CHARACTERISTIC_CHAR_HANDLE;
sensor0ValueHandle.value.val = (uint8 *)&sensor0Counts;
sensor0ValueHandle.value.len = 2;
CyBle_GattsWriteAttributeValue(&sensor0ValueHandle, 0, NULL, CYBLE_GATT_DB_LOCALLY_INITIATED);
//get alarm threshold value to compare to sensor value
//uint8 alarmValue;
alarmValueHandle.attrHandle = CYBLE_TOW_SERVICE_ALARM_THRESHOLD_VALUE_CHAR_HANDLE;
alarmValueHandle.value.val = (uint8 *)&alarmValue;
alarmValueHandle.value.len = 2;
CyBle_GattsReadAttributeValue(&alarmValueHandle, NULL, CYBLE_GATT_DB_LOCALLY_INITIATED);
IDHandle.attrHandle = CYBLE_TOW_SERVICE_ID_CHAR_HANDLE;
IDHandle.value.val = (uint8 *)ID;
IDHandle.value.len = 20;
CyBle_GattsReadAttributeValue(&IDHandle,&connectionHandle, CYBLE_GATT_DB_LOCALLY_INITIATED);
//decide whether or not to increment TOW Total and append "+" to localName
if (sensor0Counts >= alarmValue) {
TOWCount = TOWCount + 1;
TOWTotalHandle.attrHandle = CYBLE_TOW_SERVICE_TOW_TOTAL_CHAR_HANDLE;
TOWTotalHandle.value.val = (uint8 *)&TOWCount;
TOWTotalHandle.value.len = 8;
CyBle_GattsWriteAttributeValue(&TOWTotalHandle, 0, NULL, CYBLE_GATT_DB_LOCALLY_INITIATED);
}
}
void Stack_Handler( uint32 eventCode, void *eventParam )
{
CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam;
switch ( eventCode )
{
case CYBLE_EVT_STACK_ON:
CyBle_GappStartAdvertisement( CYBLE_ADVERTISING_FAST );
break;
case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
CyBle_GappStartAdvertisement( CYBLE_ADVERTISING_FAST );
break;
case CYBLE_EVT_GATT_CONNECT_IND:
CyBle_GappStopAdvertisement();
connectionHandle = *(CYBLE_CONN_HANDLE_T *)eventParam;
break;
case CYBLE_EVT_GATTS_WRITE_REQ:
wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam;
switch ( wrReqParam->handleValPair.attrHandle )
{
case CYBLE_TOW_SERVICE_ID_CHAR_HANDLE:
//write new 20 char ID to ID characteristic.
CyBle_GattsWriteAttributeValue( &wrReqParam->handleValPair, 0, &connectionHandle, CYBLE_GATT_DB_LOCALLY_INITIATED);
CyBle_GattsWriteRsp(connectionHandle);
//now get the new ID from its charactieristic
IDHandle.attrHandle = CYBLE_TOW_SERVICE_ID_CHAR_HANDLE;
IDHandle.value.val = (uint8 *)ID;
IDHandle.value.len = 20;
CyBle_GattsReadAttributeValue(&IDHandle,&connectionHandle, CYBLE_GATT_DB_LOCALLY_INITIATED);
//get the read-only 6 char SN from its charactieristic
SNHandle.attrHandle = CYBLE_TOW_SERVICE_SN_CHAR_HANDLE;
SNHandle.value.val = (uint8 *)SN;
SNHandle.value.len = 20;
CyBle_GattsReadAttributeValue(&SNHandle,&connectionHandle, CYBLE_GATT_DB_LOCALLY_INITIATED);
//concatenate ID and SN to 26 long advertData
strcat(ID,SN);
//place in advert packet
CyBle_GapSetLocalName(ID);
CyBle_GapUpdateAdvData(cyBle_discoveryModeInfo.advData, cyBle_discoveryModeInfo.scanRspData);
break;
case CYBLE_TOW_SERVICE_TOW_DATE_CHAR_HANDLE:
//write new TOW start Date
CyBle_GattsWriteAttributeValue( &wrReqParam->handleValPair, 0, &connectionHandle,0);
CyBle_GattsWriteRsp(connectionHandle);
//Clear TOW accumulator characteristic to zero
TOWCount = 0;
TOWTotalHandle.attrHandle = CYBLE_TOW_SERVICE_TOW_TOTAL_CHAR_HANDLE;
TOWTotalHandle.value.val = (uint8 *)&TOWCount;
TOWTotalHandle.value.len = 8;
CyBle_GattsWriteAttributeValue(&TOWTotalHandle, 0, NULL, CYBLE_GATT_DB_LOCALLY_INITIATED);
break;
default:
CyBle_GattsWriteAttributeValue( &wrReqParam->handleValPair, 0, &connectionHandle,0);
CyBle_GattsWriteRsp(connectionHandle);
break;
}
default:
break;
}
}
/*******************************************************************************
* Function Name: InitWatchdog
********************************************************************************
* Summary:
* Initialize watchdog counter0 with specific sleep interval parameter
*
* Parameters:
* uint16 sleep_interval reset interval, in millisecond unit
*
* Return:
* void
*
*******************************************************************************/
void InitWatchdog(uint16 sleep_interval)
{
/*==============================================================================*/
/* configure counter 0 for wakeup interrupt */
/*==============================================================================*/
/* Counter 0 of Watchdog time generates peridically interrupt to wakeup system */
CySysWdtWriteMode(CY_SYS_WDT_COUNTER0, CY_SYS_WDT_MODE_INT);
/* Set interval as desired value */
CySysWdtWriteMatch(CY_SYS_WDT_COUNTER0, ((uint32)(sleep_interval * ILO_FREQ) / 1000));
/* clear counter on match event */
CySysWdtWriteClearOnMatch(CY_SYS_WDT_COUNTER0, 1u);
/*==============================================================================*/
/* enable watchdog */
/*==============================================================================*/
/* enable the counter 0 */
CySysWdtEnable(CY_SYS_WDT_COUNTER0_MASK);
/* check if counter 0 is enabled, otherwise keep looping here */
while(!CySysWdtReadEnabledStatus(CY_SYS_WDT_COUNTER0));
}
CY_ISR(isr_WDT)
{
/* clear interrupt flag to enable next interrupt */
//CyBle_GappStopAdvertisement();
Sensors_Power_Write(1);
ADC_Start(); /* Start up the ADC */
ADC_StartConvert(); /* Start ADC conversion */
ADC_IsEndConversion(ADC_WAIT_FOR_RESULT); /* Wait for result to complete */
ADC_StopConvert(); /* Stop ADC conversions */
updateSensorData();
//Sensors_Power_Write(0);
//read sensordata and alarm, compare update adData if needed(stop advert, update, start advert)
ADC_Sleep();
CySysWdtClearInterrupt(CY_SYS_WDT_COUNTER0_INT);
}
int main()
{
/*===========================================================================================
* this code piece initializes the watchdog function
*==========================================================================================*/
/* initialize watchdog */
InitWatchdog(SLEEP_INTERVAL_500MS);
/* connect ISR routine to Watchdog interrupt */
ISR_WDT_StartEx(isr_WDT);
/* set the highest priority to make ISR is executed in all condition */
ISR_WDT_SetPriority(0);
/* enable global interrupt */
CyGlobalIntEnable; /* Enable global interrupts. */
//Sensors_Power_Write(1);
CyBle_Start(Stack_Handler);
//SetupWDT(ONE_SECOND_PERIOD);
/* Place your initialization/startup code here (e.g. MyInst_Start()) */
for(;;)
{
if(sensor0Counts < alarmValue){
appendFlagToLocalName(0x20);
} else {
appendFlagToLocalName(0x2a);
}
CyBle_ProcessEvents();
/* clear watchdog counter before deep sleep */
CySysWdtResetCounters(CY_SYS_WDT_COUNTER0_RESET);
/* reset watchdog counter requires several LFCLK cycles to take effect */
CyDelayUs(200);
/* go to deep sleep mode */
if( CyBle_EnterLPM( CYBLE_BLESS_DEEPSLEEP ) == CYBLE_BLESS_DEEPSLEEP )
{
ADC_Sleep();
CySysPmDeepSleep();
}
}
}
/* [] END OF FILE */
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please post your entire PSOC program So we can check it. Click on file then Create Workspace bundle then attach the file to this using Add Attachments.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks. This looks helpful.