diff --git a/2020TPCApp1.cydsn/2020TPCApp1.cyprj b/2020TPCApp1.cydsn/2020TPCApp1.cyprj
index cc78e20..16ff818 100644
--- a/2020TPCApp1.cydsn/2020TPCApp1.cyprj
+++ b/2020TPCApp1.cydsn/2020TPCApp1.cyprj
@@ -1516,6 +1516,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -5976,7 +5990,7 @@
-
+
diff --git a/2020TPCApp1.cydsn/COMM/BLE/COMM_BLE.c b/2020TPCApp1.cydsn/COMM/BLE/COMM_BLE.c
index bb57994..db043ab 100644
--- a/2020TPCApp1.cydsn/COMM/BLE/COMM_BLE.c
+++ b/2020TPCApp1.cydsn/COMM/BLE/COMM_BLE.c
@@ -22,11 +22,18 @@ TaskHandle_t COMM_BLE_Task_Handle;
/* Private Variables */
+static const char *TAG = "BLE";
static const TickType_t BLE_Task_Delay = BLE_TASK_PERIOD_IN_ms / portTICK_PERIOD_MS;
static COMM_BLE_StateID_T Current_State = COMM_BLE_DEFAULT;
static COMM_BLE_StateID_T Next_State = COMM_BLE_INITIALIZING;
static bool State_Changed = false;
static TickType_t Time_At_State_Entry_In_Ticks;
+static bool Is_Quiet = false;
+static bool Was_Advertising = false;
+static BLE_AdvertisingData_T Cached_Advertising_Data;
+
+static TimerHandle_t BLEUnquietTimer = NULL;
+static StaticTimer_t xBLEUnquietTimerBuffer;
//! Immediate Alert Service alert level value.
volatile uint8_t COMM_BLE_IASAlertLevel = 0;
@@ -192,6 +199,22 @@ void COMM_BLE_Task(void * pvParameters)
switch (command.ID)
{
+ case COMM_BLE_STOP_SCANNING:
+ {
+ cy_en_ble_api_result_t apiResult = Cy_BLE_GAPC_StopScan();
+
+ if (apiResult != CY_BLE_SUCCESS)
+ {
+#ifdef TRACE_BLE
+ COMM_Console_Print_String("[BLE] Cy_BLE_GAPC_StopScan API Error: 0x");
+ COMM_Console_Print_UInt32AsHex(apiResult);
+ COMM_Console_Print_String("\n");
+#endif // TRACE_BLE
+ }
+ COMM_BLE_RequestState(COMM_BLE_IDLE);
+ }
+ break;
+
case COMM_BLE_STOP_ADVERTISING:
{
cy_en_ble_api_result_t apiResult = Cy_BLE_GAPP_StopAdvertisement();
@@ -272,6 +295,69 @@ void COMM_BLE_Task(void * pvParameters)
#endif // TRACE_BLE
}
}
+
+ switch (command.ID)
+ {
+ case COMM_BLE_STOP_SCANNING:
+ {
+ cy_en_ble_api_result_t apiResult = Cy_BLE_GAPC_StopScan();
+
+ if (apiResult != CY_BLE_SUCCESS)
+ {
+#ifdef TRACE_BLE
+ COMM_Console_Print_String("[BLE] Cy_BLE_GAPC_StopScan API Error: 0x");
+ COMM_Console_Print_UInt32AsHex(apiResult);
+ COMM_Console_Print_String("\n");
+#endif // TRACE_BLE
+ }
+
+ apiResult = Cy_BLE_GAPP_StopAdvertisement();
+
+ if (apiResult != CY_BLE_SUCCESS)
+ {
+#ifdef TRACE_BLE
+ COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_StopAdvertisement API Error: 0x");
+ COMM_Console_Print_UInt32AsHex(apiResult);
+ COMM_Console_Print_String("\n");
+#endif // TRACE_BLE
+ }
+
+ COMM_BLE_RequestState(COMM_BLE_ADVERTISING_AS_BROADCASTER);
+ }
+ break;
+
+ case COMM_BLE_STOP_ADVERTISING:
+ {
+ cy_en_ble_api_result_t apiResult = Cy_BLE_GAPC_StopScan();
+
+ if (apiResult != CY_BLE_SUCCESS)
+ {
+#ifdef TRACE_BLE
+ COMM_Console_Print_String("[BLE] Cy_BLE_GAPC_StopScan API Error: 0x");
+ COMM_Console_Print_UInt32AsHex(apiResult);
+ COMM_Console_Print_String("\n");
+#endif // TRACE_BLE
+ }
+
+ apiResult = Cy_BLE_GAPP_StopAdvertisement();
+
+ if (apiResult != CY_BLE_SUCCESS)
+ {
+#ifdef TRACE_BLE
+ COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_StopAdvertisement API Error: 0x");
+ COMM_Console_Print_UInt32AsHex(apiResult);
+ COMM_Console_Print_String("\n");
+#endif // TRACE_BLE
+ }
+
+ COMM_BLE_RequestState(COMM_BLE_SCANNING_FOR_KTAG_PACKETS);
+ }
+ break;
+
+ default:
+ // All other commands are ignored in this state.
+ break;
+ }
}
break;
}
@@ -326,20 +412,180 @@ SystemKResult_T BLE_GetMyAddress(uint8_t * BD_ADDR)
SystemKResult_T BLE_ScanAndAdvertise(void)
{
- COMM_BLE_Command_T command = { .ID = COMM_BLE_SCAN_AND_ADVERTISE, .Data = (void *)0x00 };
- xQueueSend(COMM_BLE_CommandQueue, &command, 0);
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "BLE_ScanAndAdvertise()");
+#endif // TRACE_BLE
+
+ if (Is_Quiet == false)
+ {
+ COMM_BLE_Command_T command = { .ID = COMM_BLE_SCAN_AND_ADVERTISE, .Data = (void *)0x00 };
+ xQueueSend(COMM_BLE_CommandQueue, &command, 0);
+ }
+ else
+ {
+ // If we are quiet, we don't want to advertise yet,
+ // but we will remember that we were asked to advertise.
+ Was_Advertising = true;
+ }
return SYSTEMK_RESULT_SUCCESS;
}
SystemKResult_T BLE_StopAdvertising(void)
{
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "BLE_StopAdvertising()");
+#endif // TRACE_BLE
+
COMM_BLE_Command_T command = { .ID = COMM_BLE_STOP_ADVERTISING, .Data = (void *)0x00 };
xQueueSend(COMM_BLE_CommandQueue, &command, 0);
return SYSTEMK_RESULT_SUCCESS;
}
+SystemKResult_T BLE_StopScanning(void)
+{
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "BLE_StopScanning()");
+#endif // TRACE_BLE
+
+ COMM_BLE_Command_T command = { .ID = COMM_BLE_STOP_SCANNING, .Data = (void *)0x00 };
+ xQueueSend(COMM_BLE_CommandQueue, &command, 0);
+
+ return SYSTEMK_RESULT_SUCCESS;
+}
+
+static void Unquiet_Timer_Callback(TimerHandle_t xTimer)
+{
+ KLOG_INFO(TAG, "Unquiet timer expired after %lu ms.", (xTimerGetPeriod(xTimer) / portTICK_PERIOD_MS));
+ BLE_Unquiet();
+}
+
+SystemKResult_T BLE_Quiet(uint32_t duration_ms)
+{
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "BLE_Quiet(%lu)", duration_ms);
+#endif // TRACE_BLE
+
+ SystemKResult_T result = SYSTEMK_RESULT_NOT_READY;
+
+ if (Is_Quiet == true)
+ {
+ // Already quiet; reset timer with new duration if duration_ms > 0.
+ if (duration_ms > 0)
+ {
+ // Stop and delete existing timer if it exists.
+ if (BLEUnquietTimer != NULL)
+ {
+ xTimerStop(BLEUnquietTimer, 0);
+ xTimerDelete(BLEUnquietTimer, 0);
+ BLEUnquietTimer = NULL;
+ }
+
+ // Create and start new timer with the new duration.
+ BLEUnquietTimer = xTimerCreateStatic(
+ "BLEUnquietTimer",
+ pdMS_TO_TICKS(duration_ms),
+ pdFALSE,
+ (void *)0,
+ Unquiet_Timer_Callback,
+ &xBLEUnquietTimerBuffer);
+
+ if (BLEUnquietTimer == NULL)
+ {
+ KLOG_ERROR(TAG, "Couldn't create the BLEUnquietTimer!");
+ result = SYSTEMK_RESULT_FAILED_TO_CREATE_RTOS_TIMER;
+ }
+ else
+ {
+ if (xTimerStart(BLEUnquietTimer, 0) != pdPASS)
+ {
+ KLOG_ERROR(TAG, "Couldn't start the BLEUnquietTimer!");
+ result = SYSTEMK_RESULT_FAILED_TO_START_RTOS_TIMER;
+ }
+ }
+ }
+ else
+ {
+ // If duration_ms is 0, stop and delete the timer to stay quiet indefinitely.
+ if (BLEUnquietTimer != NULL)
+ {
+ xTimerStop(BLEUnquietTimer, 0);
+ xTimerDelete(BLEUnquietTimer, 0);
+ BLEUnquietTimer = NULL;
+ }
+ }
+ result = SYSTEMK_RESULT_SUCCESS;
+ }
+ else
+ {
+ Is_Quiet = true;
+
+ if ((Current_State == COMM_BLE_SCANNING_AND_ADVERTISING) ||
+ (Current_State == COMM_BLE_ADVERTISING_AS_BROADCASTER))
+ {
+ result = BLE_StopAdvertising();
+ Was_Advertising = true;
+ }
+
+ if (duration_ms > 0)
+ {
+ // Set a timer to unquiet after the specified duration.
+ BLEUnquietTimer = xTimerCreateStatic(
+ "BLEUnquietTimer",
+ pdMS_TO_TICKS(duration_ms),
+ pdFALSE,
+ (void *)0,
+ Unquiet_Timer_Callback,
+ &xBLEUnquietTimerBuffer);
+
+ if (BLEUnquietTimer == NULL)
+ {
+ KLOG_ERROR(TAG, "Couldn't create the BLEUnquietTimer!");
+ result = SYSTEMK_RESULT_FAILED_TO_CREATE_RTOS_TIMER;
+ }
+ else
+ {
+ if (xTimerStart(BLEUnquietTimer, 0) != pdPASS)
+ {
+ KLOG_ERROR(TAG, "Couldn't start the BLEUnquietTimer!");
+ result = SYSTEMK_RESULT_FAILED_TO_START_RTOS_TIMER;
+ }
+ }
+ }
+ result = SYSTEMK_RESULT_SUCCESS;
+ }
+
+ return result;
+}
+
+SystemKResult_T BLE_Unquiet(void)
+{
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "BLE_Unquiet()");
+#endif // TRACE_BLE
+
+ SystemKResult_T result = SYSTEMK_RESULT_NOT_READY;
+
+ if (Is_Quiet == false)
+ {
+ // Already unquiet; no action needed.
+ return SYSTEMK_RESULT_SUCCESS;
+ }
+ else
+ {
+ Is_Quiet = false;
+ if (Was_Advertising == true)
+ {
+ BLE_ScanAndAdvertise();
+ Was_Advertising = false;
+ }
+ result = SYSTEMK_RESULT_SUCCESS;
+ }
+
+ return result;
+}
+
void COMM_BLE_RequestState(COMM_BLE_StateID_T state)
{
Next_State = state;
@@ -364,6 +610,10 @@ SystemKResult_T BLE_SetAdvertisingData(BLE_AdvertisingData_T * data)
Advertising_Data.advDataLen = BLE_KTAG_PACKET_TOTAL_SIZE;
memcpy(Advertising_Data.advData, data, BLE_KTAG_PACKET_TOTAL_SIZE);
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "Setting advertising data for packet type %u.", data->data[8]);
+#endif // TRACE_BLE
+
cy_en_ble_api_result_t result = Cy_BLE_GAPP_UpdateAdvScanData(&Advertising_Info);
if (result != CY_BLE_SUCCESS)
@@ -372,8 +622,14 @@ SystemKResult_T BLE_SetAdvertisingData(BLE_AdvertisingData_T * data)
COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_UpdateAdvScanData Error: 0x");
COMM_Console_Print_UInt32AsHex(result);
COMM_Console_Print_String("\n");
+
+ vTaskDelay(100);
#endif // TRACE_BLE
}
+
+ // Save a copy for later.
+ Cached_Advertising_Data.length = BLE_KTAG_PACKET_TOTAL_SIZE;
+ memcpy(&Cached_Advertising_Data, data, BLE_KTAG_PACKET_TOTAL_SIZE);
}
return result;
@@ -588,8 +844,8 @@ static void BLE_EventHandler(uint32_t event, void * eventParam)
COMM_Console_Print_String(" KTag 'Instigate Game' packet found!");
break;
- case BLE_PACKET_TYPE_JOIN_NOW:
- COMM_Console_Print_String(" KTag 'Join Now' packet found!");
+ case BLE_PACKET_TYPE_EVENT:
+ COMM_Console_Print_String(" KTag 'Event' packet found!");
break;
case BLE_PACKET_TYPE_TAG:
@@ -603,9 +859,17 @@ static void BLE_EventHandler(uint32_t event, void * eventParam)
case BLE_PACKET_TYPE_STATUS:
COMM_Console_Print_String(" KTag 'Status' packet found!");
break;
+
+ case BLE_PACKET_TYPE_PARAMETERS:
+ COMM_Console_Print_String(" KTag 'Parameters' packet found!");
+ break;
+
+ case BLE_PACKET_TYPE_HELLO:
+ COMM_Console_Print_String(" KTag 'Hello' packet found!");
+ break;
default:
- COMM_Console_Print_String(" Unknown KTag packet found!");
+ KLOG_ERROR(TAG, " Unknown KTag packet found: 0x%02X", packet->Generic.type);
break;
}
@@ -724,6 +988,30 @@ static void BLE_EventHandler(uint32_t event, void * eventParam)
COMM_Console_Print_String("\n");
#endif // TRACE_BLE
+ // Restore the previous;y set advertising packet.
+ if (Cy_BLE_GetAdvertisementState() == CY_BLE_ADV_STATE_ADVERTISING)
+ {
+ Advertising_Data.advDataLen = BLE_KTAG_PACKET_TOTAL_SIZE;
+ memcpy(Advertising_Data.advData, &Cached_Advertising_Data, BLE_KTAG_PACKET_TOTAL_SIZE);
+
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "Setting advertising data from cached copy for packet type %u.", Cached_Advertising_Data.data[8]);
+#endif // TRACE_BLE
+
+ cy_en_ble_api_result_t result = Cy_BLE_GAPP_UpdateAdvScanData(&Advertising_Info);
+
+ if (result != CY_BLE_SUCCESS)
+ {
+#ifdef TRACE_BLE
+ COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_UpdateAdvScanData Error: 0x");
+ COMM_Console_Print_UInt32AsHex(result);
+ COMM_Console_Print_String("\n");
+
+ vTaskDelay(100);
+#endif // TRACE_BLE
+ }
+ }
+
#if 0
if (Cy_BLE_GetAdvertisementState() == CY_BLE_ADV_STATE_STOPPED)
{
diff --git a/2020TPCApp1.cydsn/COMM/BLE/COMM_BLE.h b/2020TPCApp1.cydsn/COMM/BLE/COMM_BLE.h
index 83701e6..e358b48 100644
--- a/2020TPCApp1.cydsn/COMM/BLE/COMM_BLE.h
+++ b/2020TPCApp1.cydsn/COMM/BLE/COMM_BLE.h
@@ -22,7 +22,7 @@ extern "C" {
//#define TRACE_BLE
//#define VERBOSE_BLE_TRACE
-#define COMM_BLE_TASK_STACK_SIZE_in_bytes 4096
+#define COMM_BLE_TASK_STACK_SIZE_in_bytes 6144
typedef enum
{
@@ -43,6 +43,7 @@ typedef enum
COMM_BLE_SCAN_FOR_KTAG_PACKETS,
COMM_BLE_ADVERTISE_AS_BROADCASTER,
COMM_BLE_ADVERTISE_AS_PERIPHERAL,
+ COMM_BLE_STOP_SCANNING,
COMM_BLE_STOP_ADVERTISING,
COMM_BLE_SCAN_AND_ADVERTISE,
// COMM_BLE_COMMAND_IS_OUT_OF_RANGE is one more than the last valid command.
diff --git a/2020TPCApp1.cydsn/SystemK b/2020TPCApp1.cydsn/SystemK
index 7aa8275..430aec5 160000
--- a/2020TPCApp1.cydsn/SystemK
+++ b/2020TPCApp1.cydsn/SystemK
@@ -1 +1 @@
-Subproject commit 7aa827563a00b9bfa74e89be60f8529259ddac99
+Subproject commit 430aec54b8d6edde82c3bc9240e34b6a9e31aa09
diff --git a/2020TPCAppNoDFU.cydsn/2020TPCAppNoDFU.cyprj b/2020TPCAppNoDFU.cydsn/2020TPCAppNoDFU.cyprj
index e090c8a..377efd5 100644
--- a/2020TPCAppNoDFU.cydsn/2020TPCAppNoDFU.cyprj
+++ b/2020TPCAppNoDFU.cydsn/2020TPCAppNoDFU.cyprj
@@ -1545,6 +1545,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/2020TPCAppNoDFU.cydsn/COMM/BLE/COMM_BLE.c b/2020TPCAppNoDFU.cydsn/COMM/BLE/COMM_BLE.c
index bb57994..db043ab 100644
--- a/2020TPCAppNoDFU.cydsn/COMM/BLE/COMM_BLE.c
+++ b/2020TPCAppNoDFU.cydsn/COMM/BLE/COMM_BLE.c
@@ -22,11 +22,18 @@ TaskHandle_t COMM_BLE_Task_Handle;
/* Private Variables */
+static const char *TAG = "BLE";
static const TickType_t BLE_Task_Delay = BLE_TASK_PERIOD_IN_ms / portTICK_PERIOD_MS;
static COMM_BLE_StateID_T Current_State = COMM_BLE_DEFAULT;
static COMM_BLE_StateID_T Next_State = COMM_BLE_INITIALIZING;
static bool State_Changed = false;
static TickType_t Time_At_State_Entry_In_Ticks;
+static bool Is_Quiet = false;
+static bool Was_Advertising = false;
+static BLE_AdvertisingData_T Cached_Advertising_Data;
+
+static TimerHandle_t BLEUnquietTimer = NULL;
+static StaticTimer_t xBLEUnquietTimerBuffer;
//! Immediate Alert Service alert level value.
volatile uint8_t COMM_BLE_IASAlertLevel = 0;
@@ -192,6 +199,22 @@ void COMM_BLE_Task(void * pvParameters)
switch (command.ID)
{
+ case COMM_BLE_STOP_SCANNING:
+ {
+ cy_en_ble_api_result_t apiResult = Cy_BLE_GAPC_StopScan();
+
+ if (apiResult != CY_BLE_SUCCESS)
+ {
+#ifdef TRACE_BLE
+ COMM_Console_Print_String("[BLE] Cy_BLE_GAPC_StopScan API Error: 0x");
+ COMM_Console_Print_UInt32AsHex(apiResult);
+ COMM_Console_Print_String("\n");
+#endif // TRACE_BLE
+ }
+ COMM_BLE_RequestState(COMM_BLE_IDLE);
+ }
+ break;
+
case COMM_BLE_STOP_ADVERTISING:
{
cy_en_ble_api_result_t apiResult = Cy_BLE_GAPP_StopAdvertisement();
@@ -272,6 +295,69 @@ void COMM_BLE_Task(void * pvParameters)
#endif // TRACE_BLE
}
}
+
+ switch (command.ID)
+ {
+ case COMM_BLE_STOP_SCANNING:
+ {
+ cy_en_ble_api_result_t apiResult = Cy_BLE_GAPC_StopScan();
+
+ if (apiResult != CY_BLE_SUCCESS)
+ {
+#ifdef TRACE_BLE
+ COMM_Console_Print_String("[BLE] Cy_BLE_GAPC_StopScan API Error: 0x");
+ COMM_Console_Print_UInt32AsHex(apiResult);
+ COMM_Console_Print_String("\n");
+#endif // TRACE_BLE
+ }
+
+ apiResult = Cy_BLE_GAPP_StopAdvertisement();
+
+ if (apiResult != CY_BLE_SUCCESS)
+ {
+#ifdef TRACE_BLE
+ COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_StopAdvertisement API Error: 0x");
+ COMM_Console_Print_UInt32AsHex(apiResult);
+ COMM_Console_Print_String("\n");
+#endif // TRACE_BLE
+ }
+
+ COMM_BLE_RequestState(COMM_BLE_ADVERTISING_AS_BROADCASTER);
+ }
+ break;
+
+ case COMM_BLE_STOP_ADVERTISING:
+ {
+ cy_en_ble_api_result_t apiResult = Cy_BLE_GAPC_StopScan();
+
+ if (apiResult != CY_BLE_SUCCESS)
+ {
+#ifdef TRACE_BLE
+ COMM_Console_Print_String("[BLE] Cy_BLE_GAPC_StopScan API Error: 0x");
+ COMM_Console_Print_UInt32AsHex(apiResult);
+ COMM_Console_Print_String("\n");
+#endif // TRACE_BLE
+ }
+
+ apiResult = Cy_BLE_GAPP_StopAdvertisement();
+
+ if (apiResult != CY_BLE_SUCCESS)
+ {
+#ifdef TRACE_BLE
+ COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_StopAdvertisement API Error: 0x");
+ COMM_Console_Print_UInt32AsHex(apiResult);
+ COMM_Console_Print_String("\n");
+#endif // TRACE_BLE
+ }
+
+ COMM_BLE_RequestState(COMM_BLE_SCANNING_FOR_KTAG_PACKETS);
+ }
+ break;
+
+ default:
+ // All other commands are ignored in this state.
+ break;
+ }
}
break;
}
@@ -326,20 +412,180 @@ SystemKResult_T BLE_GetMyAddress(uint8_t * BD_ADDR)
SystemKResult_T BLE_ScanAndAdvertise(void)
{
- COMM_BLE_Command_T command = { .ID = COMM_BLE_SCAN_AND_ADVERTISE, .Data = (void *)0x00 };
- xQueueSend(COMM_BLE_CommandQueue, &command, 0);
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "BLE_ScanAndAdvertise()");
+#endif // TRACE_BLE
+
+ if (Is_Quiet == false)
+ {
+ COMM_BLE_Command_T command = { .ID = COMM_BLE_SCAN_AND_ADVERTISE, .Data = (void *)0x00 };
+ xQueueSend(COMM_BLE_CommandQueue, &command, 0);
+ }
+ else
+ {
+ // If we are quiet, we don't want to advertise yet,
+ // but we will remember that we were asked to advertise.
+ Was_Advertising = true;
+ }
return SYSTEMK_RESULT_SUCCESS;
}
SystemKResult_T BLE_StopAdvertising(void)
{
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "BLE_StopAdvertising()");
+#endif // TRACE_BLE
+
COMM_BLE_Command_T command = { .ID = COMM_BLE_STOP_ADVERTISING, .Data = (void *)0x00 };
xQueueSend(COMM_BLE_CommandQueue, &command, 0);
return SYSTEMK_RESULT_SUCCESS;
}
+SystemKResult_T BLE_StopScanning(void)
+{
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "BLE_StopScanning()");
+#endif // TRACE_BLE
+
+ COMM_BLE_Command_T command = { .ID = COMM_BLE_STOP_SCANNING, .Data = (void *)0x00 };
+ xQueueSend(COMM_BLE_CommandQueue, &command, 0);
+
+ return SYSTEMK_RESULT_SUCCESS;
+}
+
+static void Unquiet_Timer_Callback(TimerHandle_t xTimer)
+{
+ KLOG_INFO(TAG, "Unquiet timer expired after %lu ms.", (xTimerGetPeriod(xTimer) / portTICK_PERIOD_MS));
+ BLE_Unquiet();
+}
+
+SystemKResult_T BLE_Quiet(uint32_t duration_ms)
+{
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "BLE_Quiet(%lu)", duration_ms);
+#endif // TRACE_BLE
+
+ SystemKResult_T result = SYSTEMK_RESULT_NOT_READY;
+
+ if (Is_Quiet == true)
+ {
+ // Already quiet; reset timer with new duration if duration_ms > 0.
+ if (duration_ms > 0)
+ {
+ // Stop and delete existing timer if it exists.
+ if (BLEUnquietTimer != NULL)
+ {
+ xTimerStop(BLEUnquietTimer, 0);
+ xTimerDelete(BLEUnquietTimer, 0);
+ BLEUnquietTimer = NULL;
+ }
+
+ // Create and start new timer with the new duration.
+ BLEUnquietTimer = xTimerCreateStatic(
+ "BLEUnquietTimer",
+ pdMS_TO_TICKS(duration_ms),
+ pdFALSE,
+ (void *)0,
+ Unquiet_Timer_Callback,
+ &xBLEUnquietTimerBuffer);
+
+ if (BLEUnquietTimer == NULL)
+ {
+ KLOG_ERROR(TAG, "Couldn't create the BLEUnquietTimer!");
+ result = SYSTEMK_RESULT_FAILED_TO_CREATE_RTOS_TIMER;
+ }
+ else
+ {
+ if (xTimerStart(BLEUnquietTimer, 0) != pdPASS)
+ {
+ KLOG_ERROR(TAG, "Couldn't start the BLEUnquietTimer!");
+ result = SYSTEMK_RESULT_FAILED_TO_START_RTOS_TIMER;
+ }
+ }
+ }
+ else
+ {
+ // If duration_ms is 0, stop and delete the timer to stay quiet indefinitely.
+ if (BLEUnquietTimer != NULL)
+ {
+ xTimerStop(BLEUnquietTimer, 0);
+ xTimerDelete(BLEUnquietTimer, 0);
+ BLEUnquietTimer = NULL;
+ }
+ }
+ result = SYSTEMK_RESULT_SUCCESS;
+ }
+ else
+ {
+ Is_Quiet = true;
+
+ if ((Current_State == COMM_BLE_SCANNING_AND_ADVERTISING) ||
+ (Current_State == COMM_BLE_ADVERTISING_AS_BROADCASTER))
+ {
+ result = BLE_StopAdvertising();
+ Was_Advertising = true;
+ }
+
+ if (duration_ms > 0)
+ {
+ // Set a timer to unquiet after the specified duration.
+ BLEUnquietTimer = xTimerCreateStatic(
+ "BLEUnquietTimer",
+ pdMS_TO_TICKS(duration_ms),
+ pdFALSE,
+ (void *)0,
+ Unquiet_Timer_Callback,
+ &xBLEUnquietTimerBuffer);
+
+ if (BLEUnquietTimer == NULL)
+ {
+ KLOG_ERROR(TAG, "Couldn't create the BLEUnquietTimer!");
+ result = SYSTEMK_RESULT_FAILED_TO_CREATE_RTOS_TIMER;
+ }
+ else
+ {
+ if (xTimerStart(BLEUnquietTimer, 0) != pdPASS)
+ {
+ KLOG_ERROR(TAG, "Couldn't start the BLEUnquietTimer!");
+ result = SYSTEMK_RESULT_FAILED_TO_START_RTOS_TIMER;
+ }
+ }
+ }
+ result = SYSTEMK_RESULT_SUCCESS;
+ }
+
+ return result;
+}
+
+SystemKResult_T BLE_Unquiet(void)
+{
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "BLE_Unquiet()");
+#endif // TRACE_BLE
+
+ SystemKResult_T result = SYSTEMK_RESULT_NOT_READY;
+
+ if (Is_Quiet == false)
+ {
+ // Already unquiet; no action needed.
+ return SYSTEMK_RESULT_SUCCESS;
+ }
+ else
+ {
+ Is_Quiet = false;
+ if (Was_Advertising == true)
+ {
+ BLE_ScanAndAdvertise();
+ Was_Advertising = false;
+ }
+ result = SYSTEMK_RESULT_SUCCESS;
+ }
+
+ return result;
+}
+
void COMM_BLE_RequestState(COMM_BLE_StateID_T state)
{
Next_State = state;
@@ -364,6 +610,10 @@ SystemKResult_T BLE_SetAdvertisingData(BLE_AdvertisingData_T * data)
Advertising_Data.advDataLen = BLE_KTAG_PACKET_TOTAL_SIZE;
memcpy(Advertising_Data.advData, data, BLE_KTAG_PACKET_TOTAL_SIZE);
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "Setting advertising data for packet type %u.", data->data[8]);
+#endif // TRACE_BLE
+
cy_en_ble_api_result_t result = Cy_BLE_GAPP_UpdateAdvScanData(&Advertising_Info);
if (result != CY_BLE_SUCCESS)
@@ -372,8 +622,14 @@ SystemKResult_T BLE_SetAdvertisingData(BLE_AdvertisingData_T * data)
COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_UpdateAdvScanData Error: 0x");
COMM_Console_Print_UInt32AsHex(result);
COMM_Console_Print_String("\n");
+
+ vTaskDelay(100);
#endif // TRACE_BLE
}
+
+ // Save a copy for later.
+ Cached_Advertising_Data.length = BLE_KTAG_PACKET_TOTAL_SIZE;
+ memcpy(&Cached_Advertising_Data, data, BLE_KTAG_PACKET_TOTAL_SIZE);
}
return result;
@@ -588,8 +844,8 @@ static void BLE_EventHandler(uint32_t event, void * eventParam)
COMM_Console_Print_String(" KTag 'Instigate Game' packet found!");
break;
- case BLE_PACKET_TYPE_JOIN_NOW:
- COMM_Console_Print_String(" KTag 'Join Now' packet found!");
+ case BLE_PACKET_TYPE_EVENT:
+ COMM_Console_Print_String(" KTag 'Event' packet found!");
break;
case BLE_PACKET_TYPE_TAG:
@@ -603,9 +859,17 @@ static void BLE_EventHandler(uint32_t event, void * eventParam)
case BLE_PACKET_TYPE_STATUS:
COMM_Console_Print_String(" KTag 'Status' packet found!");
break;
+
+ case BLE_PACKET_TYPE_PARAMETERS:
+ COMM_Console_Print_String(" KTag 'Parameters' packet found!");
+ break;
+
+ case BLE_PACKET_TYPE_HELLO:
+ COMM_Console_Print_String(" KTag 'Hello' packet found!");
+ break;
default:
- COMM_Console_Print_String(" Unknown KTag packet found!");
+ KLOG_ERROR(TAG, " Unknown KTag packet found: 0x%02X", packet->Generic.type);
break;
}
@@ -724,6 +988,30 @@ static void BLE_EventHandler(uint32_t event, void * eventParam)
COMM_Console_Print_String("\n");
#endif // TRACE_BLE
+ // Restore the previous;y set advertising packet.
+ if (Cy_BLE_GetAdvertisementState() == CY_BLE_ADV_STATE_ADVERTISING)
+ {
+ Advertising_Data.advDataLen = BLE_KTAG_PACKET_TOTAL_SIZE;
+ memcpy(Advertising_Data.advData, &Cached_Advertising_Data, BLE_KTAG_PACKET_TOTAL_SIZE);
+
+#ifdef TRACE_BLE
+ KLOG_TRACE(TAG, "Setting advertising data from cached copy for packet type %u.", Cached_Advertising_Data.data[8]);
+#endif // TRACE_BLE
+
+ cy_en_ble_api_result_t result = Cy_BLE_GAPP_UpdateAdvScanData(&Advertising_Info);
+
+ if (result != CY_BLE_SUCCESS)
+ {
+#ifdef TRACE_BLE
+ COMM_Console_Print_String("[BLE] Cy_BLE_GAPP_UpdateAdvScanData Error: 0x");
+ COMM_Console_Print_UInt32AsHex(result);
+ COMM_Console_Print_String("\n");
+
+ vTaskDelay(100);
+#endif // TRACE_BLE
+ }
+ }
+
#if 0
if (Cy_BLE_GetAdvertisementState() == CY_BLE_ADV_STATE_STOPPED)
{
diff --git a/2020TPCAppNoDFU.cydsn/COMM/BLE/COMM_BLE.h b/2020TPCAppNoDFU.cydsn/COMM/BLE/COMM_BLE.h
index 83701e6..e358b48 100644
--- a/2020TPCAppNoDFU.cydsn/COMM/BLE/COMM_BLE.h
+++ b/2020TPCAppNoDFU.cydsn/COMM/BLE/COMM_BLE.h
@@ -22,7 +22,7 @@ extern "C" {
//#define TRACE_BLE
//#define VERBOSE_BLE_TRACE
-#define COMM_BLE_TASK_STACK_SIZE_in_bytes 4096
+#define COMM_BLE_TASK_STACK_SIZE_in_bytes 6144
typedef enum
{
@@ -43,6 +43,7 @@ typedef enum
COMM_BLE_SCAN_FOR_KTAG_PACKETS,
COMM_BLE_ADVERTISE_AS_BROADCASTER,
COMM_BLE_ADVERTISE_AS_PERIPHERAL,
+ COMM_BLE_STOP_SCANNING,
COMM_BLE_STOP_ADVERTISING,
COMM_BLE_SCAN_AND_ADVERTISE,
// COMM_BLE_COMMAND_IS_OUT_OF_RANGE is one more than the last valid command.
diff --git a/2020TPCAppNoDFU.cydsn/SystemK b/2020TPCAppNoDFU.cydsn/SystemK
index 7aa8275..430aec5 160000
--- a/2020TPCAppNoDFU.cydsn/SystemK
+++ b/2020TPCAppNoDFU.cydsn/SystemK
@@ -1 +1 @@
-Subproject commit 7aa827563a00b9bfa74e89be60f8529259ddac99
+Subproject commit 430aec54b8d6edde82c3bc9240e34b6a9e31aa09