Hi, this question could be ridiculous question due to my lack of data structure knowledge.
As you see in the HID keyboard example (SDK 7.2), there are several buffers.
typedef struct hid_key_buffer
{
uint8_t data_offset; /**< Max Data that can be buffered for all entries */
uint8_t data_len; /**< Total length of data */
uint8_t * p_data; /**< Scanned key pattern */
ble_hids_t * p_instance; /**< Identifies peer and service instance */
} buffer_entry_t; /** Abstracts buffer element */
#define MAX_BUFFER_ENTRIES 5 /**< Number of elements that can be enqueued */
typedef struct /** Circular buffer list */
{
buffer_entry_t buffer[MAX_BUFFER_ENTRIES]; /**< Maximum number of entries that can enqueued in the list */
uint8_t rp; /**< Index to the read location */
uint8_t wp; /**< Index to write location */
uint8_t count; /**< Number of elements in the list */
} buffer_list_t;
static uint8_t m_sample_key_press_scan_str[] ={
0x0b, 0x08, 0x0f, 0x0f, 0x12, 0x28 };
// each keys are h, e, l, l, o, Return
After sending keys (which is h, e, l, l, and o),
the program goes to on_ble_evt function since BLE_EVT_TX_COMPLETE has occurred.
static void on_ble_evt(ble_evt_t * p_ble_evt){ // I omitted other parts
switch (p_ble_evt->header.evt_id){
case BLE_EVT_TX_COMPLETE:
// Send next key event
(void) buffer_dequeue(true);
break;
}
}
#define BUFFER_LIST_FULL()\ /** Provide status of data list is full or not */
((MAX_BUFFER_ENTRIES == buffer_list.count - 1) ? true : false)
#define BUFFER_LIST_EMPTY()\ /** Provides status of buffer list is empty or not */
((0 == buffer_list.count) ? true : false)
#define BUFFER_ELEMENT_INIT(i)\
do \
{ \
buffer_list.buffer[(i)].p_data = NULL; \
} while (0)
static uint32_t buffer_dequeue(bool tx_flag)
{
buffer_entry_t * p_element;
uint32_t err_code = NRF_SUCCESS;
uint16_t actual_len;
if (BUFFER_LIST_EMPTY())
{
err_code = NRF_ERROR_NOT_FOUND;
}
else
{
bool remove_element = true;
p_element = &buffer_list.buffer[(buffer_list.rp)];
if (tx_flag)
{
err_code = send_key_scan_press_release(p_element->p_instance,
p_element->p_data,
p_element->data_len,
p_element->data_offset,
&actual_len);
// An additional notification is needed for release of all keys, therefore check
// is for actual_len <= element->data_len and not actual_len < element->data_len
if ((err_code == BLE_ERROR_NO_TX_BUFFERS) && (actual_len <= p_element->data_len))
{
// Transmission could not be completed, do not remove the entry, adjust next data to
// be transmitted
p_element->data_offset = actual_len;
remove_element = false;
}
}
if (remove_element)
{
BUFFER_ELEMENT_INIT(buffer_list.rp);
buffer_list.rp++;
buffer_list.count--;
if (buffer_list.rp == MAX_BUFFER_ENTRIES)
{
buffer_list.rp = 0;
}
}
}
return err_code;
}
Comparing with the HID mouse example, the mouse example did not had any buffers at all.
So my questions are,
- Why did the keyboard example implemented the circular buffer?
What does these buffers do?
(I hope this can help me to find the reason why the buffer needs dequeued
after every BLE_EVT_TX_COMPLETE event.)
- I want to manipulated the keyboard example.
If I don't dequeue every BLE_EVT_TX_COMPLETE event, does the HID key sending fails?
-Regards, Mango922