I have followed the Scheduler tutorial (https://devzone.nordicsemi.com/guides/short-range-guides/b/software-development-kit/posts/scheduler-tutorial) and was able to use it successfully in the case where I simply needed to call the scheduler-handler function without any arguments. This looks like:
app_sched_event_put(NULL, 0, (app_sched_event_handler_t)readConfigsHandler);
However, I can not get the Scheduler to work for my project when I need to actually pass data as arguments to a separate handler. For example, I am trying to run this code:
app_sched_event_put(p_evt, sizeof(p_evt), regWriteHandler);
When BLE data arrives to the nus_data_handler(), I can print it out and verify that the data does arrive correctly. However, when I next try to send the BLE event pointer, p_evt, to the correct handler via app_sched_event_put(), the data becomes all zeros and so the Register Write task fails every time. To be sure, this code works when I do NOT use the scheduler.
To give some context, I am calling these two app_sched_event_put() functions (one with args, one without) from within the standard nus_data_handler(). When my board receives BLE data, it reads the data and acts accordingly depending on the data received. Below, I am copy/pasting the code related to this issue, including the ble_nus_handler(), the regWriteHandler(), and the readConfigsHandler().
/**
* @brief Helper function to schedule RegWrite tasks
*/
void regWriteHandlerHelper(ble_nus_evt_t * p_evt)
{
uint32_t err_code;
uint16_t msg_len;
msg_len = (p_evt)->params.rx_data.length; // Data should look like --> "RegWrite,addr,reg,data", but its "" now
uint8_t msg[msg_len];
strcpy(msg, (p_evt)->params.rx_data.p_data);
NRF_LOG_INFO("Received %d bytes of data from BLE NUS: %s", msg_len, msg);
NRF_LOG_FLUSH();
char *token;
char *delim = ",";
token = strtok(msg, delim);
/* Access the first argument in RegWrite: (addr,reg,data) */
token = strtok(NULL, delim);
int address = (int)strtol(token, NULL, 16);
NRF_LOG_INFO("RegWrite Address: 0x%X\n", address);
/* Access the second argument in RegWrite: (addr,reg,data) */
token = strtok(NULL, delim);
int reg = (int)strtol(token, NULL, 16);
NRF_LOG_INFO("RegWrite Register: 0x%X\n", reg);
/* Access the third argument in RegWrite: (addr,reg,data) */
token = strtok(NULL, delim);
int d = (int)strtol(token, NULL, 16);
NRF_LOG_INFO("RegWrite Data: 0x%X\n", d);
const uint8_t dd[] = { (uint8_t) d};
if (address == (uint8_t) IQS572_ADDR) {
uint8_t buf[1];
uint16_t regs = (uint16_t) reg;
uint16_t addrs = (uint8_t) address;
twiRegRead16(addrs, regs, buf, 1); // NOTE: Dummy Read for expected NACK due to forced comms
err_code = twiRegWrite16(addrs, regs, dd, 1);
} else {
uint8_t add = (uint8_t) address;
uint8_t rgstr = (uint8_t) reg;
err_code = twiRegWrite(add, rgstr, dd, 1);
}
APP_ERROR_CHECK(err_code);
}
/**
* @brief Function to handle incoming BLE requests to write data to a register of a sensor IC
*/
void regWriteHandler(void * p_evt, uint16_t size)
{
regWriteHandlerHelper((ble_nus_evt_t *)p_evt);
}
/**
* @brief Function to handle incoming BLE requests to retreive sensor IC configuration data
*/
static void readConfigsHandler(void)
{
NRF_LOG_INFO("READ CONFIGS for HEPHAESTUS");
/* Send all config data <c,config_data_bytes> */
uint32_t err_code;
uint8_t dataPacket[BLE_CHARACTERISTIC_MAX_LENGTH];
uint8_t dataIndex = 0;
uint8_t id = 'c';
memcpy(dataPacket + dataIndex, &id, 1);
dataIndex = dataIndex + 1;
uint8_t sensitivity_configs[43] = {0};
// 2 Bytes for ATI Trackpad Target Value
// 1 Byte for Global ATI C value
// 40 Bytes for individual channel ATI adjustment values
capTouchSensitivityConfigs(sensitivity_configs);
memcpy(dataPacket + dataIndex, sensitivity_configs, 43);
dataIndex = dataIndex + 43;
displayConfigs(dataPacket, dataIndex);
err_code = nus_data_send(dataPacket, dataIndex);
if ((err_code != NRF_ERROR_INVALID_STATE) &&
(err_code != NRF_ERROR_RESOURCES) &&
(err_code != NRF_ERROR_NOT_FOUND))
{
APP_ERROR_CHECK(err_code);
}
}
/**@brief Function for handling the data from the Nordic UART Service.
*
* @details This function will process the data received from the Nordic UART BLE Service and send
* it to the UART module.
*
* @param[in] p_evt Nordic UART Service event.
*/
/**@snippet [Handling the data received over BLE] */
static void nus_data_handler(ble_nus_evt_t * p_evt)
{
if (p_evt->type == BLE_NUS_EVT_RX_DATA)
{
uint32_t err_code;
uint16_t msg_len;
msg_len = p_evt->params.rx_data.length;
uint8_t msg[msg_len];
strcpy(msg, p_evt->params.rx_data.p_data);
NRF_LOG_INFO("Received %d bytes of data from BLE NUS: %s", msg_len, msg);
NRF_LOG_FLUSH();
if(strstr(msg, "RegWrite"))
{
regWriteHandlerHelper(p_evt);
// TODO: Why wont data get passed through to the Scheduler Handler!
// app_sched_event_put(p_evt, sizeof(p_evt), regWriteHandler);
}
else if(strstr(msg, "ReadConfigs"))
{
app_sched_event_put(NULL, 0, (app_sched_event_handler_t)readConfigsHandler);
}
//else if(strstr(msg, "WriteConfigs"))
//{
//}
NRF_LOG_FLUSH();
}
}