Hi,
I’m developing a BLE joystick with nrf52832 with a PCA10040 board
To make the development simple I’m using 16 input Buttons and 2 analog inputs with 8 bits each.
The data structure is the following:
static uint8_t rep_map_data[] =
{
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0x09, 0x05, /* USAGE (Joystick) */
0xa1, 0x01, /* COLLECTION (Application) */
0xa1, 0x03, /* COLLECTION (Report) */
0x85, 0x01, /* REPORT_ID (1) */
0x05, 0x09, /* USAGE_PAGE (Button) */
0x19, 0x01, /* USAGE_MINIMUM (Button 1) */
0x29, 0x10, /* USAGE_MAXIMUM (Button 16) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x95, 0x10, /* REPORT_COUNT (16) */
0x75, 0x01, /* REPORT_SIZE (1) */
0x81, 0x02, /* INPUT (Data,Var,Abs) */
0xa1, 0x00, /* COLLECTION (Physical) */
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0x09, 0x30, /* USAGE (X) */
0x09, 0x31, /* USAGE (Y) */
0x15, 0x81, /* LOGICAL_MINIMUM (-127) */
0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x95, 0x02, /* REPORT_COUNT (2) */
0x81, 0x01, /* INPUT (Data,Var,Abs) */
0xc0, /* END_COLLECTION */
0xc0, /* END_COLLECTION */
0xc0 /* END_COLLECTION */
};
For the data structure I have some doubts:
Should I define it as a JOYSTICK or a GAMEPAD?
I’m using “0x09, 0x05, /* USAGE (Joystick) */”
I’m not sure what is the value for INPUT (Data,Var,Abs), I presume that each Analog Input uses 1 byte, so I did put “0x81, 0x01, /* INPUT (Data,Var,Abs) */”
Is it ok?
With this data structure I presume that I have to send 4 bytes to update buttons and axes
#define INPUT_REP_LEN 4
#define INPUT_REP_INDEX 0
static void joystick_movement_send(uint8_t inputX, uint8_t inputY)
{
ret_code_t err_code;
uint8_t buffer[INPUT_REP_LEN];
if (m_in_boot_mode)
return;
NRF_LOG_INFO("HID X %d Y %d.", inputX, inputY);
APP_ERROR_CHECK_BOOL(INPUT_REP_LEN == 4);
buffer[0] = 0x81; // 1° and 8° buttons
buffer[1] = 0x81; // 9° and 16° buttons
buffer[2] = inputX;
buffer[3] = inputY;
err_code = ble_hids_inp_rep_send(&m_hids, INPUT_REP_INDEX, INPUT_REP_LEN, buffer, m_conn_handle);
if ((err_code != NRF_SUCCESS) &&
(err_code != NRF_ERROR_INVALID_STATE) &&
(err_code != NRF_ERROR_RESOURCES) &&
(err_code != NRF_ERROR_BUSY) &&
(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING))
{
APP_ERROR_HANDLER(err_code);
}
}
DATA FLASH SAVE
When the application runs, I noticed that there are 3 block addresses where the data is saved: 0x7D000, 0x7E000 and 0x7F000. I would like to know how I can change these addresses.
/* Linker script to configure memory regions. */
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
MEMORY
{
FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x5a000
RAM (rwx) : ORIGIN = 0x20002250, LENGTH = 0xddb0
}
SECTIONS
{
}
SECTIONS
{
. = ALIGN(4);
.mem_section_dummy_ram :
{
}
.cli_sorted_cmd_ptrs :
{
PROVIDE(__start_cli_sorted_cmd_ptrs = .);
KEEP(*(.cli_sorted_cmd_ptrs))
PROVIDE(__stop_cli_sorted_cmd_ptrs = .);
} > RAM
.fs_data :
{
PROVIDE(__start_fs_data = .);
KEEP(*(.fs_data))
PROVIDE(__stop_fs_data = .);
} > RAM
.log_dynamic_data :
{
PROVIDE(__start_log_dynamic_data = .);
KEEP(*(SORT(.log_dynamic_data*)))
PROVIDE(__stop_log_dynamic_data = .);
} > RAM
.log_filter_data :
{
PROVIDE(__start_log_filter_data = .);
KEEP(*(SORT(.log_filter_data*)))
PROVIDE(__stop_log_filter_data = .);
} > RAM
} INSERT AFTER .data;
SECTIONS
{
.mem_section_dummy_rom :
{
}
.sdh_soc_observers :
{
PROVIDE(__start_sdh_soc_observers = .);
KEEP(*(SORT(.sdh_soc_observers*)))
PROVIDE(__stop_sdh_soc_observers = .);
} > FLASH
.pwr_mgmt_data :
{
PROVIDE(__start_pwr_mgmt_data = .);
KEEP(*(SORT(.pwr_mgmt_data*)))
PROVIDE(__stop_pwr_mgmt_data = .);
} > FLASH
.sdh_ble_observers :
{
PROVIDE(__start_sdh_ble_observers = .);
KEEP(*(SORT(.sdh_ble_observers*)))
PROVIDE(__stop_sdh_ble_observers = .);
} > FLASH
.sdh_req_observers :
{
PROVIDE(__start_sdh_req_observers = .);
KEEP(*(SORT(.sdh_req_observers*)))
PROVIDE(__stop_sdh_req_observers = .);
} > FLASH
.sdh_state_observers :
{
PROVIDE(__start_sdh_state_observers = .);
KEEP(*(SORT(.sdh_state_observers*)))
PROVIDE(__stop_sdh_state_observers = .);
} > FLASH
.sdh_stack_observers :
{
PROVIDE(__start_sdh_stack_observers = .);
KEEP(*(SORT(.sdh_stack_observers*)))
PROVIDE(__stop_sdh_stack_observers = .);
} > FLASH
.nrf_queue :
{
PROVIDE(__start_nrf_queue = .);
KEEP(*(.nrf_queue))
PROVIDE(__stop_nrf_queue = .);
} > FLASH
.nrf_balloc :
{
PROVIDE(__start_nrf_balloc = .);
KEEP(*(.nrf_balloc))
PROVIDE(__stop_nrf_balloc = .);
} > FLASH
.cli_command :
{
PROVIDE(__start_cli_command = .);
KEEP(*(.cli_command))
PROVIDE(__stop_cli_command = .);
} > FLASH
.crypto_data :
{
PROVIDE(__start_crypto_data = .);
KEEP(*(SORT(.crypto_data*)))
PROVIDE(__stop_crypto_data = .);
} > FLASH
.log_const_data :
{
PROVIDE(__start_log_const_data = .);
KEEP(*(SORT(.log_const_data*)))
PROVIDE(__stop_log_const_data = .);
} > FLASH
.log_backends :
{
PROVIDE(__start_log_backends = .);
KEEP(*(SORT(.log_backends*)))
PROVIDE(__stop_log_backends = .);
} > FLASH
} INSERT AFTER .text
INCLUDE "nrf_common.ld"