初始版本
This commit is contained in:
549
components/serialization/common/ble_serialization.c
Normal file
549
components/serialization/common/ble_serialization.c
Normal file
@@ -0,0 +1,549 @@
|
||||
/**
|
||||
* Copyright (c) 2013 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "ble_serialization.h"
|
||||
#include "nrf_error.h"
|
||||
#include "app_util.h"
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
uint32_t ser_ble_cmd_rsp_status_code_enc(uint8_t op_code,
|
||||
uint32_t command_status,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t * const p_buf_len)
|
||||
{
|
||||
SER_ASSERT_NOT_NULL(p_buf);
|
||||
SER_ASSERT_NOT_NULL(p_buf_len);
|
||||
uint32_t index = 0;
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(SER_CMD_RSP_HEADER_SIZE, *p_buf_len);
|
||||
|
||||
//Encode Op Code.
|
||||
p_buf[index++] = op_code;
|
||||
|
||||
//Encode Status.
|
||||
index += uint32_encode(command_status, &(p_buf[index]));
|
||||
*p_buf_len = index;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ser_ble_cmd_rsp_result_code_dec(uint8_t const * const p_buf,
|
||||
uint32_t * const p_pos,
|
||||
uint32_t packet_len,
|
||||
uint8_t op_code,
|
||||
uint32_t * const p_result_code)
|
||||
{
|
||||
SER_ASSERT_NOT_NULL(p_buf);
|
||||
SER_ASSERT_NOT_NULL(p_pos);
|
||||
SER_ASSERT_NOT_NULL(p_result_code);
|
||||
|
||||
if (packet_len < SER_CMD_RSP_HEADER_SIZE)
|
||||
{
|
||||
return NRF_ERROR_DATA_SIZE;
|
||||
}
|
||||
|
||||
if (p_buf[(*p_pos)] != op_code)
|
||||
{
|
||||
return NRF_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
*p_result_code = uint32_decode(&(p_buf[(*p_pos) + SER_CMD_RSP_STATUS_CODE_POS]));
|
||||
*p_pos += SER_CMD_RSP_HEADER_SIZE;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ser_ble_cmd_rsp_dec(uint8_t const * const p_buf,
|
||||
uint32_t packet_len,
|
||||
uint8_t op_code,
|
||||
uint32_t * const p_result_code)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
uint32_t result_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, op_code,
|
||||
p_result_code);
|
||||
|
||||
if (result_code != NRF_SUCCESS)
|
||||
{
|
||||
return result_code;
|
||||
}
|
||||
|
||||
if (index != packet_len)
|
||||
{
|
||||
return NRF_ERROR_DATA_SIZE;
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t uint32_t_enc(void const * const p_field,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_ASSERT_NOT_NULL(p_buf);
|
||||
SER_ASSERT_NOT_NULL(p_field);
|
||||
SER_ASSERT_NOT_NULL(p_index);
|
||||
|
||||
uint32_t * p_uint32 = (uint32_t *)p_field;
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index);
|
||||
|
||||
*p_index += uint32_encode(*p_uint32, &p_buf[*p_index]);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t uint32_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * p_field)
|
||||
{
|
||||
SER_ASSERT_NOT_NULL(p_buf);
|
||||
SER_ASSERT_NOT_NULL(p_index);
|
||||
SER_ASSERT_NOT_NULL(p_field);
|
||||
|
||||
uint32_t * p_uint32 = (uint32_t *)p_field;
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(4, ((int32_t)buf_len - *p_index));
|
||||
|
||||
*p_uint32 = uint32_decode(&p_buf[*p_index]);
|
||||
*p_index += 4;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t uint16_t_enc(const void * const p_field,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
uint16_t * p_u16 = (uint16_t *)p_field;
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index);
|
||||
|
||||
*p_index += uint16_encode(*p_u16, &p_buf[*p_index]);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t uint16_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * p_field)
|
||||
{
|
||||
uint16_t * p_u16 = (uint16_t *)p_field;
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(2, ((int32_t)buf_len - *p_index));
|
||||
|
||||
*p_u16 = uint16_decode(&p_buf[*p_index]);
|
||||
*p_index += 2;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
void uint16_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const index,
|
||||
uint16_t * const value)
|
||||
{
|
||||
SER_ASSERT_VOID_RETURN(*index + 2 <= buf_len);
|
||||
*value = uint16_decode(&p_buf[*index]);
|
||||
*index += 2;
|
||||
}
|
||||
|
||||
uint32_t uint8_t_enc(const void * const p_field,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index);
|
||||
|
||||
uint8_t * p_u8 = (uint8_t *)p_field;
|
||||
p_buf[*p_index] = *p_u8;
|
||||
*p_index += 1;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t uint8_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * p_field)
|
||||
{
|
||||
uint8_t * p_u8 = (uint8_t *)p_field;
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(1, ((int32_t)buf_len - *p_index));
|
||||
*p_u8 = p_buf[*p_index];
|
||||
*p_index += 1;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
void uint8_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const index,
|
||||
uint8_t * const value)
|
||||
{
|
||||
SER_ASSERT_VOID_RETURN(*index + 1 <= buf_len);
|
||||
*value = p_buf[*index];
|
||||
*index += 1;
|
||||
}
|
||||
|
||||
|
||||
void int8_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const index,
|
||||
int8_t * const value)
|
||||
{
|
||||
SER_ASSERT_VOID_RETURN(*index + 1 <= buf_len);
|
||||
*value = p_buf[*index];
|
||||
*index += 1;
|
||||
}
|
||||
|
||||
uint32_t len8data_enc(uint8_t const * const p_data,
|
||||
uint8_t const dlen,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
err_code = uint8_t_enc(&dlen, p_buf, buf_len, p_index);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = buf_enc(p_data, dlen, p_buf, buf_len, p_index);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
uint32_t len8data_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint8_t * * const pp_data,
|
||||
uint8_t * const p_len)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
uint16_t out_buf_len = *p_len;
|
||||
|
||||
err_code = uint8_t_dec(p_buf, buf_len, p_index, p_len);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = buf_dec(p_buf, buf_len, p_index, pp_data, out_buf_len, *p_len);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
uint32_t len16data_enc(uint8_t const * const p_data,
|
||||
uint16_t const dlen,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
err_code = uint16_t_enc(&dlen, p_buf, buf_len, p_index);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = buf_enc(p_data, dlen, p_buf, buf_len, p_index);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
uint32_t len16data_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint8_t * * const pp_data,
|
||||
uint16_t * const p_dlen)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
uint16_t out_buf_len = *p_dlen;
|
||||
|
||||
err_code = uint16_t_dec(p_buf, buf_len, p_index, p_dlen);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = buf_dec(p_buf, buf_len, p_index, pp_data, out_buf_len, *p_dlen);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
uint32_t count16_cond_data16_enc(uint16_t const * const p_data,
|
||||
uint16_t const count,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(3, ((int32_t)buf_len - *p_index));
|
||||
*p_index += uint16_encode(count, &p_buf[*p_index]);
|
||||
|
||||
if (p_data)
|
||||
{
|
||||
SER_ASSERT_LENGTH_LEQ((int32_t)(2 * count + 1), ((int32_t)buf_len - (int32_t) * p_index));
|
||||
p_buf[*p_index] = SER_FIELD_PRESENT;
|
||||
*p_index += 1;
|
||||
|
||||
//memcpy may fail in case of Endianness difference between application and connectivity processor
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
*p_index += uint16_encode(p_data[i], &p_buf[*p_index]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SER_ASSERT_LENGTH_LEQ((1), ((int32_t)buf_len - *p_index));
|
||||
p_buf[*p_index] = SER_FIELD_NOT_PRESENT;
|
||||
*p_index += 1;
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t count16_cond_data16_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint16_t * * const pp_data,
|
||||
uint16_t * const p_count)
|
||||
|
||||
{
|
||||
uint16_t count = 0;
|
||||
uint8_t is_present = 0;
|
||||
uint16_t i;
|
||||
|
||||
SER_ASSERT_NOT_NULL(p_count);
|
||||
SER_ASSERT_NOT_NULL(pp_data);
|
||||
SER_ASSERT_NOT_NULL(*pp_data);
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(3, ((int32_t)buf_len - (*p_index)));
|
||||
|
||||
uint16_dec(p_buf, buf_len, p_index, &count);
|
||||
|
||||
if (count > *p_count)
|
||||
{
|
||||
return NRF_ERROR_DATA_SIZE;
|
||||
}
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(count, *p_count);
|
||||
|
||||
uint8_dec(p_buf, buf_len, p_index, &is_present);
|
||||
|
||||
if (!is_present)
|
||||
{
|
||||
*p_count = count;
|
||||
*pp_data = NULL;
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < count; i++ )
|
||||
{
|
||||
uint16_dec(p_buf, buf_len, p_index, &((&(**pp_data))[i]) );
|
||||
}
|
||||
*p_count = i;
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t cond_len16_cond_data_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint8_t * * const pp_data,
|
||||
uint16_t * * const pp_len)
|
||||
{
|
||||
SER_ASSERT_NOT_NULL(pp_len);
|
||||
SER_ASSERT_NOT_NULL(*pp_len);
|
||||
SER_ASSERT_NOT_NULL(pp_data);
|
||||
SER_ASSERT_NOT_NULL(*pp_data);
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(2, ((int32_t)buf_len - (*p_index)));
|
||||
uint8_t is_present = 0;
|
||||
|
||||
uint8_dec(p_buf, buf_len, p_index, &is_present);
|
||||
|
||||
if (!is_present)
|
||||
{
|
||||
*pp_len = NULL; //if length field is not present
|
||||
(*p_index)++; //then data can not be present
|
||||
*pp_data = NULL;
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return len16data_dec(p_buf, buf_len, p_index, pp_data, *pp_len);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t op_status_enc(uint8_t op_code,
|
||||
uint32_t return_code,
|
||||
uint8_t * const p_buff,
|
||||
uint32_t * const p_buff_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_ASSERT_NOT_NULL(p_buff);
|
||||
SER_ASSERT_NOT_NULL(p_buff_len);
|
||||
SER_ASSERT_NOT_NULL(p_index);
|
||||
SER_ASSERT_LENGTH_LEQ(SER_CMD_RSP_HEADER_SIZE, *p_buff_len - *p_index);
|
||||
|
||||
//Encode Op Code.
|
||||
p_buff[(*p_index)++] = op_code;
|
||||
//Encode Status.
|
||||
*p_index += uint32_encode(return_code, &(p_buff[*p_index]));
|
||||
//update size of used buffer
|
||||
*p_buff_len = *p_index;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t op_status_cond_uint16_enc(uint8_t op_code,
|
||||
uint32_t return_code,
|
||||
uint16_t value,
|
||||
uint8_t * const p_buff,
|
||||
uint32_t * const p_buff_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
uint32_t status_code;
|
||||
uint32_t init_buff_len = *p_buff_len;
|
||||
|
||||
status_code = op_status_enc(op_code, return_code, p_buff, p_buff_len, p_index);
|
||||
SER_ASSERT(status_code == NRF_SUCCESS, status_code);
|
||||
|
||||
if (return_code == NRF_SUCCESS) //Add 16bit value when return_code is a success
|
||||
{
|
||||
*p_buff_len = init_buff_len; //restore original value - it has been modified by op_status_enc
|
||||
status_code = uint16_t_enc(&value, p_buff, *p_buff_len, p_index);
|
||||
*p_buff_len = *p_index;
|
||||
SER_ASSERT(status_code == NRF_SUCCESS, status_code);
|
||||
}
|
||||
|
||||
return status_code;
|
||||
}
|
||||
|
||||
uint32_t buf_enc(uint8_t const * const p_data,
|
||||
uint16_t const dlen,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
uint8_t is_present = (p_data == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT;
|
||||
|
||||
err_code = uint8_t_enc(&is_present, p_buf, buf_len, p_index);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
if (p_data)
|
||||
{
|
||||
SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index));
|
||||
memcpy(&p_buf[*p_index], p_data, dlen);
|
||||
*p_index += dlen;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
uint32_t buf_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint8_t * * const pp_data,
|
||||
uint16_t data_len,
|
||||
uint16_t dlen)
|
||||
{
|
||||
uint8_t is_present = 0;
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(1, ((int32_t)buf_len - *p_index));
|
||||
uint8_dec(p_buf, buf_len, p_index, &is_present);
|
||||
|
||||
if (is_present == SER_FIELD_PRESENT)
|
||||
{
|
||||
SER_ASSERT_NOT_NULL(pp_data);
|
||||
SER_ASSERT_NOT_NULL(*pp_data);
|
||||
SER_ASSERT_LENGTH_LEQ(dlen, data_len);
|
||||
SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index));
|
||||
memcpy(*pp_data, &p_buf[*p_index], dlen);
|
||||
*p_index += dlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pp_data)
|
||||
{
|
||||
*pp_data = NULL;
|
||||
}
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t uint8_vector_enc(uint8_t const * const p_data,
|
||||
uint16_t const dlen,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
|
||||
SER_ASSERT_NOT_NULL(p_data);
|
||||
SER_ASSERT_NOT_NULL(p_buf);
|
||||
SER_ASSERT_NOT_NULL(p_index);
|
||||
SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index));
|
||||
memcpy(&p_buf[*p_index], p_data, dlen);
|
||||
*p_index += dlen;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t uint8_vector_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint8_t * const p_data,
|
||||
uint16_t dlen)
|
||||
{
|
||||
SER_ASSERT_NOT_NULL(p_data);
|
||||
SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index));
|
||||
memcpy(p_data, &p_buf[*p_index], dlen);
|
||||
*p_index += dlen;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
1103
components/serialization/common/ble_serialization.h
Normal file
1103
components/serialization/common/ble_serialization.h
Normal file
File diff suppressed because it is too large
Load Diff
101
components/serialization/common/cond_field_serialization.c
Normal file
101
components/serialization/common/cond_field_serialization.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "nrf_error.h"
|
||||
#include "cond_field_serialization.h"
|
||||
#include "ble_serialization.h"
|
||||
#include <stddef.h>
|
||||
|
||||
uint32_t cond_field_enc(void const * const p_field,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
field_encoder_handler_t fp_field_encoder)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(*p_index + 1, buf_len);
|
||||
p_buf[*p_index] = (p_field == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT;
|
||||
*p_index += 1;
|
||||
|
||||
if (p_field && (fp_field_encoder != NULL))
|
||||
{
|
||||
err_code = fp_field_encoder(p_field, p_buf, buf_len, p_index);
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
uint32_t cond_field_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * * const pp_field,
|
||||
field_decoder_handler_t fp_field_decoder)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
uint8_t is_present;
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index);
|
||||
uint8_dec(p_buf, buf_len, p_index, &is_present);
|
||||
|
||||
if (is_present == SER_FIELD_PRESENT)
|
||||
{
|
||||
SER_ASSERT_NOT_NULL(pp_field);
|
||||
SER_ASSERT_NOT_NULL(*pp_field);
|
||||
|
||||
if (fp_field_decoder != NULL)
|
||||
{
|
||||
err_code = fp_field_decoder(p_buf, buf_len, p_index, *pp_field);
|
||||
}
|
||||
}
|
||||
else if (is_present == SER_FIELD_NOT_PRESENT)
|
||||
{
|
||||
if (pp_field != NULL)
|
||||
{
|
||||
*pp_field = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
105
components/serialization/common/cond_field_serialization.h
Normal file
105
components/serialization/common/cond_field_serialization.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef COND_FIELD_SERIALIZATION_H__
|
||||
#define COND_FIELD_SERIALIZATION_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef uint32_t (*field_encoder_handler_t)(void const * const p_field,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
typedef uint32_t (*field_decoder_handler_t)(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * p_field);
|
||||
|
||||
/**@brief Function for safe encoding of a conditional field.
|
||||
*
|
||||
* Function sets a presence flag and checks if conditional field is provided. If the field is not NULL,
|
||||
* it calls the provided parser function which attempts to encode the field content to the buffer stream.
|
||||
*
|
||||
* @param[in] p_field Pointer to the input struct.
|
||||
* @param[in] p_buf Pointer to the beginning of the output buffer.
|
||||
* @param[in] buf_len Size of the buffer.
|
||||
* @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
|
||||
* \c out: Index in the buffer to the first byte after the encoded data.
|
||||
* @param[in] fp_field_encoder Pointer to the function which implements fields encoding.
|
||||
*
|
||||
* @return NRF_SUCCESS Fields encoded successfully.
|
||||
* @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
|
||||
*/
|
||||
uint32_t cond_field_enc(void const * const p_field,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
field_encoder_handler_t fp_field_encoder);
|
||||
|
||||
/**@brief Function for safe decoding of a conditional field.
|
||||
*
|
||||
* Function checks if conditional field is present in the input buffer. If it is set, it calls
|
||||
* the provided parser function which attempts to parse the buffer content to the known field.
|
||||
*
|
||||
* @param[in] p_buf Pointer to the beginning of the input buffer.
|
||||
* @param[in] buf_len Size of the buffer.
|
||||
* @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
|
||||
* \c out: Index in the buffer to the first byte after the decoded data.
|
||||
* @param[in] pp_field Pointer to output location.
|
||||
* @param[in] fp_field_decoder Pointer to the function which implements field decoding.
|
||||
*
|
||||
* @return NRF_SUCCESS Fields decoded successfully.
|
||||
* @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
|
||||
*/
|
||||
uint32_t cond_field_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * * const pp_field,
|
||||
field_decoder_handler_t fp_field_decoder);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // COND_FIELD_SERIALIZATION_H__
|
||||
130
components/serialization/common/ser_config.h
Normal file
130
components/serialization/common/ser_config.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef SER_CONFIG_H__
|
||||
#define SER_CONFIG_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nrf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***********************************************************************************************//**
|
||||
* General parameters configuration.
|
||||
**************************************************************************************************/
|
||||
|
||||
/** Value used as error code on SoftDevice stack dump. Can be used to identify stack location on
|
||||
* stack unwind.*/
|
||||
#define SER_SD_ERROR_CODE (0xDEADBEEFUL)
|
||||
|
||||
/** Value used as error code indicating warning - unusual situation but not critical so system
|
||||
* should NOT be reset. */
|
||||
#define SER_WARNING_CODE (0xBADDCAFEUL)
|
||||
|
||||
/***********************************************************************************************//**
|
||||
* HAL Transport layer configuration.
|
||||
**************************************************************************************************/
|
||||
|
||||
/** Max packets size in serialization HAL Transport layer (packets before adding PHY header i.e.
|
||||
* packet length). */
|
||||
#ifdef S112
|
||||
#define SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE (128UL)
|
||||
#define SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE (128UL)
|
||||
#else
|
||||
#define SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE (512UL)
|
||||
#define SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE (512UL)
|
||||
#endif
|
||||
|
||||
#define SER_HAL_TRANSPORT_MAX_PKT_SIZE ((SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE) >= \
|
||||
(SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE) \
|
||||
? \
|
||||
(SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE) : \
|
||||
(SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE))
|
||||
#ifdef SER_CONNECTIVITY
|
||||
#define SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE
|
||||
#define SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE
|
||||
|
||||
#else /* APPLICATION SIDE */
|
||||
#define SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE
|
||||
#define SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE
|
||||
#endif /* SER_CONNECTIVITY */
|
||||
|
||||
|
||||
/***********************************************************************************************//**
|
||||
* SER_PHY layer configuration.
|
||||
**************************************************************************************************/
|
||||
|
||||
#define SER_PHY_HEADER_SIZE 2
|
||||
|
||||
#define SER_PHY_HCI_SLIP_TX_BUF_SIZE 30
|
||||
|
||||
#define SER_PHY_SPI_FREQUENCY NRF_DRV_SPI_FREQ_1M
|
||||
|
||||
/** Max transfer unit for SPI MASTER and SPI SLAVE. */
|
||||
#define SER_PHY_SPI_MTU_SIZE 255
|
||||
|
||||
/** UART transmission parameters */
|
||||
#define SER_PHY_UART_FLOW_CTRL NRF_UART_HWFC_ENABLED
|
||||
#define SER_PHY_UART_PARITY NRF_UART_PARITY_INCLUDED
|
||||
#define SER_PHY_UART_BAUDRATE_VAL 1000000
|
||||
|
||||
#define SER_PHY_UART_BAUDRATE CONCAT_2(NRF_UART_BAUDRATE_,SER_PHY_UART_BAUDRATE_VAL)
|
||||
|
||||
/** Configuration timeouts of connectivity MCU. */
|
||||
#define CONN_CHIP_RESET_TIME 50 /**< Time to keep the reset line to the connectivity chip low (in milliseconds). */
|
||||
#define CONN_CHIP_WAKEUP_TIME 500 /**< Time for the connectivity chip to reset and become ready to receive serialized commands (in milliseconds). */
|
||||
|
||||
#ifdef S112
|
||||
#define SER_MAX_CONNECTIONS 2
|
||||
#else
|
||||
#define SER_MAX_CONNECTIONS 8
|
||||
#endif
|
||||
|
||||
#ifndef SER_MAX_ADV_DATA
|
||||
#define SER_MAX_ADV_DATA 256
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SER_CONFIG_H__ */
|
||||
320
components/serialization/common/ser_dbg_sd_str.c
Normal file
320
components/serialization/common/ser_dbg_sd_str.c
Normal file
@@ -0,0 +1,320 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "ser_dbg_sd_str.h"
|
||||
#include "nrf_soc.h"
|
||||
#include "nrf_log.h"
|
||||
#include <string.h>
|
||||
#include "sdk_common.h"
|
||||
|
||||
#ifdef BLE_STACK_SUPPORT_REQD
|
||||
#include "ble_ranges.h"
|
||||
#endif
|
||||
|
||||
#ifdef ANT_STACK_SUPPORT_REQD
|
||||
#include "ant_interface.h"
|
||||
#include "ant_parameters.h"
|
||||
#endif
|
||||
|
||||
#if NRF_MODULE_ENABLED(NRF_LOG) && defined(BLE_STACK_SUPPORT_REQD)
|
||||
static const char * sd_events[] = {
|
||||
"BLE_EVT_USER_MEM_REQUEST", /*0x01*/
|
||||
"BLE_EVT_USER_MEM_RELEASE", /*0x02*/
|
||||
"SD_EVT_UNKNOWN", /*0x03*/
|
||||
"SD_EVT_UNKNOWN", /*0x04*/
|
||||
"SD_EVT_UNKNOWN", /*0x05*/
|
||||
"SD_EVT_UNKNOWN", /*0x06*/
|
||||
"SD_EVT_UNKNOWN", /*0x07*/
|
||||
"SD_EVT_UNKNOWN", /*0x08*/
|
||||
"SD_EVT_UNKNOWN", /*0x09*/
|
||||
"SD_EVT_UNKNOWN", /*0x0a*/
|
||||
"SD_EVT_UNKNOWN", /*0x0b*/
|
||||
"SD_EVT_UNKNOWN", /*0x0c*/
|
||||
"SD_EVT_UNKNOWN", /*0x0d*/
|
||||
"SD_EVT_UNKNOWN", /*0x0e*/
|
||||
"SD_EVT_UNKNOWN", /*0x0f*/
|
||||
"BLE_GAP_EVT_CONNECTED", /*0x10*/
|
||||
"BLE_GAP_EVT_DISCONNECTED", /*0x11*/
|
||||
"BLE_GAP_EVT_CONN_PARAM_UPDATE", /*0x12*/
|
||||
"BLE_GAP_EVT_SEC_PARAMS_REQUEST", /*0x13*/
|
||||
"BLE_GAP_EVT_SEC_INFO_REQUEST", /*0x14*/
|
||||
"BLE_GAP_EVT_PASSKEY_DISPLAY", /*0x15*/
|
||||
"BLE_GAP_EVT_KEY_PRESSED", /*0x16*/
|
||||
"BLE_GAP_EVT_AUTH_KEY_REQUEST", /*0x17*/
|
||||
"BLE_GAP_EVT_LESC_DHKEY_REQUEST", /*0x18*/
|
||||
"BLE_GAP_EVT_AUTH_STATUS", /*0x19*/
|
||||
"BLE_GAP_EVT_CONN_SEC_UPDATE", /*0x1a*/
|
||||
"BLE_GAP_EVT_TIMEOUT", /*0x1b*/
|
||||
"BLE_GAP_EVT_RSSI_CHANGED", /*0x1c*/
|
||||
"BLE_GAP_EVT_ADV_REPORT", /*0x1d*/
|
||||
"BLE_GAP_EVT_SEC_REQUEST", /*0x1e*/
|
||||
"BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST", /*0x1f*/
|
||||
"BLE_GAP_EVT_SCAN_REQ_REPORT", /*0x20*/
|
||||
"BLE_GAP_EVT_PHY_UPDATE_REQUEST", /*0x21*/
|
||||
"BLE_GAP_EVT_PHY_UPDATE", /*0x22*/
|
||||
"BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST", /*0x23*/
|
||||
"BLE_GAP_EVT_DATA_LENGTH_UPDATE", /*0x24*/
|
||||
"BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT", /*0x25*/
|
||||
"BLE_GAP_EVT_ADV_SET_TERMINATED", /*0x26*/
|
||||
"SD_EVT_UNKNOWN", /*0x27*/
|
||||
"SD_EVT_UNKNOWN", /*0x28*/
|
||||
"SD_EVT_UNKNOWN", /*0x29*/
|
||||
"SD_EVT_UNKNOWN", /*0x2a*/
|
||||
"SD_EVT_UNKNOWN", /*0x2b*/
|
||||
"SD_EVT_UNKNOWN", /*0x2c*/
|
||||
"SD_EVT_UNKNOWN", /*0x2d*/
|
||||
"SD_EVT_UNKNOWN", /*0x2e*/
|
||||
"SD_EVT_UNKNOWN", /*0x2f*/
|
||||
"BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP", /*0x30*/
|
||||
"BLE_GATTC_EVT_REL_DISC_RSP", /*0x31*/
|
||||
"BLE_GATTC_EVT_CHAR_DISC_RSP", /*0x32*/
|
||||
"BLE_GATTC_EVT_DESC_DISC_RSP", /*0x33*/
|
||||
"BLE_GATTC_EVT_ATTR_INFO_DISC_RSP", /*0x34*/
|
||||
"BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP", /*0x35*/
|
||||
"BLE_GATTC_EVT_READ_RSP", /*0x36*/
|
||||
"BLE_GATTC_EVT_CHAR_VALS_READ_RSP", /*0x37*/
|
||||
"BLE_GATTC_EVT_WRITE_RSP", /*0x38*/
|
||||
"BLE_GATTC_EVT_HVX", /*0x39*/
|
||||
"BLE_GATTC_EVT_EXCHANGE_MTU_RSP", /*0x3a*/
|
||||
"BLE_GATTC_EVT_TIMEOUT", /*0x3b*/
|
||||
"BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE", /*0x3c*/
|
||||
"SD_EVT_UNKNOWN", /*0x3d*/
|
||||
"SD_EVT_UNKNOWN", /*0x3e*/
|
||||
"SD_EVT_UNKNOWN", /*0x3f*/
|
||||
"SD_EVT_UNKNOWN", /*0x40*/
|
||||
"SD_EVT_UNKNOWN", /*0x41*/
|
||||
"SD_EVT_UNKNOWN", /*0x42*/
|
||||
"SD_EVT_UNKNOWN", /*0x43*/
|
||||
"SD_EVT_UNKNOWN", /*0x44*/
|
||||
"SD_EVT_UNKNOWN", /*0x45*/
|
||||
"SD_EVT_UNKNOWN", /*0x46*/
|
||||
"SD_EVT_UNKNOWN", /*0x47*/
|
||||
"SD_EVT_UNKNOWN", /*0x48*/
|
||||
"SD_EVT_UNKNOWN", /*0x49*/
|
||||
"SD_EVT_UNKNOWN", /*0x4a*/
|
||||
"SD_EVT_UNKNOWN", /*0x4b*/
|
||||
"SD_EVT_UNKNOWN", /*0x4c*/
|
||||
"SD_EVT_UNKNOWN", /*0x4d*/
|
||||
"SD_EVT_UNKNOWN", /*0x4e*/
|
||||
"SD_EVT_UNKNOWN", /*0x4f*/
|
||||
"BLE_GATTS_EVT_WRITE", /*0x50*/
|
||||
"BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST", /*0x51*/
|
||||
"BLE_GATTS_EVT_SYS_ATTR_MISSING", /*0x52*/
|
||||
"BLE_GATTS_EVT_HVC", /*0x53*/
|
||||
"BLE_GATTS_EVT_SC_CONFIRM", /*0x54*/
|
||||
"BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST", /*0x55*/
|
||||
"BLE_GATTS_EVT_TIMEOUT", /*0x56*/
|
||||
"BLE_GATTS_EVT_HVN_TX_COMPLETE", /*0x57*/
|
||||
};
|
||||
|
||||
static const char * sd_functions[] = {
|
||||
/* 0x60 offset */
|
||||
"SD_BLE_ENABLE", /*0x60*/
|
||||
"SD_BLE_EVT_GET", /*0x61*/
|
||||
"SD_BLE_UUID_VS_ADD", /*0x62*/
|
||||
"SD_BLE_UUID_DECODE", /*0x63*/
|
||||
"SD_BLE_UUID_ENCODE", /*0x64*/
|
||||
"SD_BLE_VERSION_GET", /*0x65*/
|
||||
"SD_BLE_USER_MEM_REPLY", /*0x66*/
|
||||
"SD_BLE_OPT_SET", /*0x67*/
|
||||
"SD_BLE_OPT_GET", /*0x68*/
|
||||
"SD_BLE_CFG_SET", /*0x69*/
|
||||
"SD_BLE_UUID_VS_REMOVE", /*0x6A*/
|
||||
"SD_UNKNOWN", /*0x6B*/
|
||||
"SD_BLE_GAP_ADDR_SET" , /*0x6C*/
|
||||
"SD_BLE_GAP_ADDR_GET" , /*0x6D*/
|
||||
"SD_BLE_GAP_WHITELIST_SET" , /*0x6E*/
|
||||
"SD_BLE_GAP_DEVICE_IDENTITIES_SET" , /*0x6F*/
|
||||
"SD_BLE_GAP_PRIVACY_SET" , /*0x70*/
|
||||
"SD_BLE_GAP_PRIVACY_GET" , /*0x71*/
|
||||
"SD_BLE_GAP_ADV_SET_CONFIGURE" , /*0x72*/
|
||||
"SD_BLE_GAP_ADV_START" , /*0x73*/
|
||||
"SD_BLE_GAP_ADV_STOP" , /*0x74*/
|
||||
"SD_BLE_GAP_CONN_PARAM_UPDATE" , /*0x75*/
|
||||
"SD_BLE_GAP_DISCONNECT" , /*0x76*/
|
||||
"SD_BLE_GAP_TX_POWER_SET" , /*0x77*/
|
||||
"SD_BLE_GAP_APPEARANCE_SET" , /*0x78*/
|
||||
"SD_BLE_GAP_APPEARANCE_GET" , /*0x79*/
|
||||
"SD_BLE_GAP_PPCP_SET" , /*0x7a*/
|
||||
"SD_BLE_GAP_PPCP_GET" , /*0x7b*/
|
||||
"SD_BLE_GAP_DEVICE_NAME_SET" , /*0x7c*/
|
||||
"SD_BLE_GAP_DEVICE_NAME_GET" , /*0x7d*/
|
||||
"SD_BLE_GAP_AUTHENTICATE" , /*0x7e*/
|
||||
"SD_BLE_GAP_SEC_PARAMS_REPLY" , /*0x7f*/
|
||||
"SD_BLE_GAP_AUTH_KEY_REPLY" , /*0x80*/
|
||||
"SD_BLE_GAP_LESC_DHKEY_REPLY" , /*0x81*/
|
||||
"SD_BLE_GAP_KEYPRESS_NOTIFY" , /*0x82*/
|
||||
"SD_BLE_GAP_LESC_OOB_DATA_GET" , /*0x83*/
|
||||
"SD_BLE_GAP_LESC_OOB_DATA_SET" , /*0x84*/
|
||||
"SD_BLE_GAP_ENCRYPT" , /*0x85*/
|
||||
"SD_BLE_GAP_SEC_INFO_REPLY" , /*0x86*/
|
||||
"SD_BLE_GAP_CONN_SEC_GET" , /*0x87*/
|
||||
"SD_BLE_GAP_RSSI_START" , /*0x88*/
|
||||
"SD_BLE_GAP_RSSI_STOP" , /*0x89*/
|
||||
"SD_BLE_GAP_SCAN_START" , /*0x8a*/
|
||||
"SD_BLE_GAP_SCAN_STOP" , /*0x8b*/
|
||||
"SD_BLE_GAP_CONNECT" , /*0x8c*/
|
||||
"SD_BLE_GAP_CONNECT_CANCEL " , /*0x8d*/
|
||||
"SD_BLE_GAP_RSSI_GET" , /*0x8e*/
|
||||
"SD_BLE_GAP_PHY_UPDATE" , /*0x8f*/
|
||||
"SD_BLE_GAP_DATA_LENGTH_UPDATE" , /*0x90*/
|
||||
"SD_BLE_GAP_QOS_CHANNEL_SURVEY_START", /*0x91*/
|
||||
"SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP" , /*0x92*/
|
||||
"SD_UNKNOWN", /*0x93*/
|
||||
"SD_UNKNOWN", /*0x94*/
|
||||
"SD_UNKNOWN", /*0x95*/
|
||||
"SD_UNKNOWN", /*0x96*/
|
||||
"SD_UNKNOWN", /*0x97*/
|
||||
"SD_UNKNOWN", /*0x98*/
|
||||
"SD_UNKNOWN", /*0x99*/
|
||||
"SD_UNKNOWN", /*0x9A*/
|
||||
"SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER", /*0x9B*/
|
||||
"SD_BLE_GATTC_RELATIONSHIPS_DISCOVER", /*0x9C*/
|
||||
"SD_BLE_GATTC_CHARACTERISTICS_DISCOVER", /*0x9D*/
|
||||
"SD_BLE_GATTC_DESCRIPTORS_DISCOVER", /*0x9E*/
|
||||
"SD_BLE_GATTC_ATTR_INFO_DISCOVER", /*0x9F*/
|
||||
"SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ", /*0xA0*/
|
||||
"SD_BLE_GATTC_READ", /*0xA1*/
|
||||
"SD_BLE_GATTC_CHAR_VALUES_READ", /*0xA2*/
|
||||
"SD_BLE_GATTC_WRITE", /*0xA3*/
|
||||
"SD_BLE_GATTC_HV_CONFIRM", /*0xA4*/
|
||||
"SD_BLE_GATTC_EXCHANGE_MTU_REQUEST", /*0xA5*/
|
||||
"SD_UNKNOWN", /*0xA6*/
|
||||
"SD_UNKNOWN", /*0xA7*/
|
||||
"SD_BLE_GATTS_SERVICE_ADD", /*0xA8*/
|
||||
"SD_BLE_GATTS_INCLUDE_ADD", /*0xA9*/
|
||||
"SD_BLE_GATTS_CHARACTERISTIC_ADD", /*0xAA*/
|
||||
"SD_BLE_GATTS_DESCRIPTOR_ADD", /*0xAB*/
|
||||
"SD_BLE_GATTS_VALUE_SET", /*0xAC*/
|
||||
"SD_BLE_GATTS_VALUE_GET", /*0xAD*/
|
||||
"SD_BLE_GATTS_HVX", /*0xAE*/
|
||||
"SD_BLE_GATTS_SERVICE_CHANGED", /*0xAF*/
|
||||
"SD_BLE_GATTS_RW_AUTHORIZE_REPLY", /*0xB0*/
|
||||
"SD_BLE_GATTS_SYS_ATTR_SET", /*0xB1*/
|
||||
"SD_BLE_GATTS_SYS_ATTR_GET", /*0xB2*/
|
||||
"SD_BLE_GATTS_INITIAL_USER_HANDLE_GET", /*0xB3*/
|
||||
"SD_BLE_GATTS_ATTR_GET", /*0xB4*/
|
||||
"SD_BLE_GATTS_EXCHANGE_MTU_REPLY", /*0xB5*/
|
||||
};
|
||||
#endif // NRF_MODULE_ENABLED(NRF_LOG) && defined(BLE_STACK_SUPPORT_REQD)
|
||||
|
||||
#ifdef ANT_STACK_SUPPORT_REQD
|
||||
const char * string[] =
|
||||
{
|
||||
"ANT SVC",
|
||||
"ANT_EVT",
|
||||
};
|
||||
#endif // ANT_STACK_SUPPORT_REQD
|
||||
|
||||
const char * ser_dbg_sd_call_str_get(uint8_t opcode)
|
||||
{
|
||||
#if NRF_MODULE_ENABLED(NRF_LOG)
|
||||
const char * p_str = "SD_CALL_UNKNOWN";
|
||||
#ifdef BLE_STACK_SUPPORT_REQD
|
||||
if (opcode >= BLE_SVC_BASE && opcode <= BLE_GATTS_SVC_LAST)
|
||||
{
|
||||
uint32_t idx = opcode-BLE_SVC_BASE;
|
||||
if (idx < ARRAY_SIZE(sd_functions) )
|
||||
{
|
||||
p_str = sd_functions[idx];
|
||||
}
|
||||
}
|
||||
#endif // BLE_STACK_SUPPORT_REQD
|
||||
|
||||
#ifdef ANT_STACK_SUPPORT_REQD
|
||||
// Check if opcode is within the range of the ANT Stack API SVC numbers
|
||||
#ifdef BLE_STACK_SUPPORT_REQD
|
||||
else if (opcode >= STK_SVC_BASE_2)
|
||||
#else
|
||||
if (opcode >= STK_SVC_BASE_2)
|
||||
#endif // BLE_STACK_SUPPORT_REQD
|
||||
{
|
||||
p_str = string[0];
|
||||
}
|
||||
#endif // ANT_STACK_SUPPORT_REQD
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case SD_ECB_BLOCK_ENCRYPT:
|
||||
p_str = "SD_ECB_BLOCK_ENCRYPT";
|
||||
break;
|
||||
case SD_TEMP_GET:
|
||||
p_str = "SD_TEMP_GET";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return p_str;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char * ser_dbg_sd_evt_str_get(uint16_t opcode)
|
||||
{
|
||||
#if NRF_MODULE_ENABLED(NRF_LOG)
|
||||
const char * p_str = "SD_EVT_UNKNOWN";
|
||||
#ifdef BLE_STACK_SUPPORT_REQD
|
||||
if (opcode >= BLE_EVT_BASE && opcode <= BLE_GATTS_EVT_LAST)
|
||||
{
|
||||
uint32_t idx = opcode - BLE_EVT_BASE;
|
||||
if (idx < ARRAY_SIZE(sd_events))
|
||||
{
|
||||
p_str = sd_events[idx];
|
||||
}
|
||||
}
|
||||
#endif // BLE_STACK_SUPPORT_REQD
|
||||
|
||||
#ifdef ANT_STACK_SUPPORT_REQD
|
||||
// Check if opcode is within the range of the ANT Stack API SVC numbers
|
||||
#ifdef BLE_STACK_SUPPORT_REQD
|
||||
else if (opcode <= EVENT_BLOCKED)
|
||||
#else
|
||||
if (opcode <= EVENT_BLOCKED)
|
||||
#endif // BLE_STACK_SUPPORT_REQD
|
||||
{
|
||||
p_str = string[1];
|
||||
}
|
||||
#endif
|
||||
return p_str;
|
||||
#else
|
||||
return NULL;
|
||||
#endif // NRF_MODULE_ENABLED(NRF_LOG)
|
||||
}
|
||||
45
components/serialization/common/ser_dbg_sd_str.h
Normal file
45
components/serialization/common/ser_dbg_sd_str.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef SER_DBG_SD_STR_H
|
||||
#define SER_DBG_SD_STR_H
|
||||
#include <stdint.h>
|
||||
const char * ser_dbg_sd_call_str_get(uint8_t opcode);
|
||||
const char * ser_dbg_sd_evt_str_get(uint16_t opcode);
|
||||
#endif //SER_DBG_SD_STR_H
|
||||
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ant_interface.h"
|
||||
#include "ant_struct_serialization.h"
|
||||
#include "nrf_sdh_ant.h"
|
||||
#include "ble_serialization.h"
|
||||
#include "app_util.h"
|
||||
#include "cond_field_serialization.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
uint32_t ANT_ENABLE_enc(void const * const p_void_enable_params,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_ASSERT_NOT_NULL(p_buf);
|
||||
SER_ASSERT_NOT_NULL(p_index);
|
||||
SER_ASSERT_NOT_NULL(p_void_enable_params);
|
||||
|
||||
ANT_ENABLE * p_enable_params = (ANT_ENABLE *)p_void_enable_params;
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
err_code = uint8_t_enc(&p_enable_params->ucTotalNumberOfChannels, p_buf, buf_len, p_index);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = uint8_t_enc(&p_enable_params->ucNumberOfEncryptedChannels, p_buf, buf_len, p_index);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = uint16_t_enc(&p_enable_params->usNumberOfEvents, p_buf, buf_len, p_index);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = uint32_t_enc(&p_enable_params->pucMemoryBlockStartLocation, p_buf, buf_len, p_index);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = uint16_t_enc(&p_enable_params->usMemoryBlockByteSize, p_buf, buf_len, p_index);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ANT_ENABLE_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_enable_params)
|
||||
|
||||
{
|
||||
SER_ASSERT_NOT_NULL(p_buf);
|
||||
SER_ASSERT_NOT_NULL(p_index);
|
||||
SER_ASSERT_NOT_NULL(p_void_enable_params);
|
||||
|
||||
ANT_ENABLE * p_enable_params = (ANT_ENABLE *)p_void_enable_params;
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
err_code = uint8_t_dec(p_buf, buf_len, p_index, &p_enable_params->ucTotalNumberOfChannels);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = uint8_t_dec(p_buf, buf_len, p_index, &p_enable_params->ucNumberOfEncryptedChannels);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = uint16_t_dec(p_buf, buf_len, p_index, &p_enable_params->usNumberOfEvents);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = uint32_t_dec(p_buf, buf_len, p_index, &p_enable_params->pucMemoryBlockStartLocation);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = uint16_t_dec(p_buf, buf_len, p_index, &p_enable_params->usMemoryBlockByteSize);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
uint32_t ant_evt_t_enc(void const * const p_void_ant_evt,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_ASSERT_NOT_NULL(p_buf);
|
||||
SER_ASSERT_NOT_NULL(p_index);
|
||||
SER_ASSERT_NOT_NULL(p_void_ant_evt);
|
||||
|
||||
ant_evt_t * p_ant_evt = (ant_evt_t *)p_void_ant_evt;
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
memcpy(&p_buf[*p_index], p_ant_evt->message.aucMessage, MESG_BUFFER_SIZE); // Size + sizeof(size) & sizeof(msg id)
|
||||
*p_index += MESG_BUFFER_SIZE;
|
||||
|
||||
err_code = uint8_t_enc(&p_ant_evt->event, p_buf, buf_len, p_index);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = uint8_t_enc(&p_ant_evt->channel, p_buf, buf_len, p_index);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
return(err_code);
|
||||
}
|
||||
|
||||
uint32_t ant_evt_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_ant_evt)
|
||||
|
||||
{
|
||||
SER_ASSERT_NOT_NULL(p_buf);
|
||||
SER_ASSERT_NOT_NULL(p_index);
|
||||
SER_ASSERT_NOT_NULL(p_void_ant_evt);
|
||||
|
||||
ant_evt_t * p_ant_evt = (ant_evt_t *)p_void_ant_evt;
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
memcpy(p_ant_evt->message.aucMessage, &p_buf[*p_index], MESG_BUFFER_SIZE); // Size + sizeof(size) & sizeof(msg id)
|
||||
*p_index += MESG_BUFFER_SIZE;
|
||||
|
||||
err_code = uint8_t_dec(p_buf, buf_len, p_index, &p_ant_evt->event);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
err_code = uint8_t_dec(p_buf, buf_len, p_index, &p_ant_evt->channel);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ANT_STRUCT_SERIALIZATION_
|
||||
#define _ANT_STRUCT_SERIALIZATION_
|
||||
|
||||
/**@brief Function for safe encoding of an ANT_ENABLE struct.
|
||||
*
|
||||
* Safe decoding of an ANT_ENABLE struct. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
|
||||
*
|
||||
* @param[in] p_void_enable_params An ANT_ENABLE struct to be encoded.
|
||||
* @param[out] p_buf Buffer containing the struct.
|
||||
* @param[in] buf_len Size of the buffer.
|
||||
* @param[in,out] p_index \c in: Index to the start of the ANT_ENABLE struct in the buffer.
|
||||
* \c out: Index in the buffer to the first byte after the decoded struct.
|
||||
*
|
||||
* @return NRF_SUCCESS Fields decoded successfully.
|
||||
* @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
|
||||
*/
|
||||
uint32_t ANT_ENABLE_enc( void const * const p_void_enable_params,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
/**@brief Function for safe decoding of an ANT_ENABLE struct.
|
||||
*
|
||||
* Safe decoding of a ANT_ENABLE struct. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
|
||||
*
|
||||
* @param[in] p_buf Buffer containing the struct.
|
||||
* @param[in] buf_len Size of the buffer.
|
||||
* @param[in,out] p_index \c in: Index to the start of the ANT_ENABLE struct in the buffer.
|
||||
* \c out: Index in the buffer to the first byte after the decoded struct.
|
||||
* @param[out] p_void_enable_params Decoded ANT_ENABLE struct.
|
||||
*/
|
||||
uint32_t ANT_ENABLE_dec( uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_enable_params);
|
||||
|
||||
/**@brief Function for safe encoding of an ant_evt_t struct.
|
||||
*
|
||||
* Safe decoding of an ant_evt_t struct. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
|
||||
*
|
||||
* @param[in] p_void_ant_evt An ant_evt_t struct to be encoded.
|
||||
* @param[out] p_buf Buffer containing the struct.
|
||||
* @param[in] buf_len Size of the buffer.
|
||||
* @param[in,out] p_index \c in: Index to the start of the ant_evt_t struct in the buffer.
|
||||
* \c out: Index in the buffer to the first byte after the decoded struct.
|
||||
*
|
||||
* @return NRF_SUCCESS Fields decoded successfully.
|
||||
* @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
|
||||
*/
|
||||
uint32_t ant_evt_t_enc( void const * const p_void_ant_evt,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
/**@brief Function for safe decoding of an ant_evt_t struct.
|
||||
*
|
||||
* Safe decoding of a ant_evt_t struct. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
|
||||
*
|
||||
* @param[in] p_buf Buffer containing the struct.
|
||||
* @param[in] buf_len Size of the buffer.
|
||||
* @param[in,out] p_index \c in: Index to the start of the ant_evt_t struct in the buffer.
|
||||
* \c out: Index in the buffer to the first byte after the decoded struct.
|
||||
* @param[out] p_void_ant_evt Decoded ant_evt_t struct.
|
||||
*/
|
||||
uint32_t ant_evt_t_dec( uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_ant_evt);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,612 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef BLE_GAP_STRUCT_SERIALIZATION_H__
|
||||
#define BLE_GAP_STRUCT_SERIALIZATION_H__
|
||||
|
||||
#include "ble_gap.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t ble_gap_evt_adv_report_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_evt_adv_report_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_irk_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_irk_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_addr_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_addr_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_sec_levels_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_sec_levels_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_sec_keys_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_sec_keys_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_enc_info_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_enc_info_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_sign_info_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_sign_info_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_evt_auth_status_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_conn_sec_mode_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_conn_sec_mode_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_conn_sec_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_evt_conn_sec_update_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_evt_sec_info_request_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_evt_connected_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_sec_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_sec_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_evt_sec_params_request_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_evt_sec_params_request_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_conn_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_conn_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_evt_conn_param_update_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_evt_conn_param_update_request_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_evt_disconnected_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_scan_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_scan_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_data);
|
||||
|
||||
uint32_t ble_gap_master_id_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_master_id_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_enc_key_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_enc_key_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_id_key_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_id_key_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_sec_keyset_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_sec_keyset_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_evt_sec_request_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_evt_sec_request_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_sec_kdist_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_sec_kdist_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_opt_ch_map_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_opt_local_conn_latency_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_opt_passkey_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_opt_scan_req_report_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_opt_scan_req_report_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
|
||||
uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_opt_compat_mode_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#endif
|
||||
uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_adv_ch_mask_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_enable_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_enable_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_lesc_p256_pk_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_lesc_p256_pk_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_lesc_dhkey_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_lesc_dhkey_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_lesc_oob_data_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_lesc_oob_data_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_adv_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_adv_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
|
||||
uint32_t ble_gap_opt_ext_len_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_opt_ext_len_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#endif
|
||||
|
||||
uint32_t ble_gap_opt_auth_payload_timeout_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_opt_auth_payload_timeout_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
|
||||
uint32_t ble_gap_device_name_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_device_name_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#else
|
||||
uint32_t ble_gap_cfg_device_name_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_cfg_device_name_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#endif
|
||||
|
||||
uint32_t ble_gap_privacy_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_privacy_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
#if NRF_SD_BLE_API_VERSION >= 4
|
||||
uint32_t ble_gap_opt_compat_mode_1_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_opt_compat_mode_1_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_opt_compat_mode_2_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_opt_compat_mode_2_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
uint32_t ble_gap_opt_slave_latency_disable_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_opt_slave_latency_disable_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_conn_cfg_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_conn_cfg_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_cfg_role_count_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_cfg_role_count_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_data_length_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_data_length_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_data_length_limitation_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_data_length_limitation_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#endif
|
||||
|
||||
#if NRF_SD_BLE_API_VERSION >= 5
|
||||
uint32_t ble_gap_phys_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_phys_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#endif
|
||||
|
||||
#if NRF_SD_BLE_API_VERSION > 5
|
||||
uint32_t ble_gap_adv_properties_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_adv_properties_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_adv_report_type_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_adv_report_type_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_aux_pointer_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_aux_pointer_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_adv_data_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_adv_data_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gap_evt_adv_set_terminated_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gap_evt_adv_set_terminated_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BLE_GAP_STRUCT_SERIALIZATION_H__
|
||||
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "ble_serialization.h"
|
||||
#include "ble_struct_serialization.h"
|
||||
#include "ble_gatt_struct_serialization.h"
|
||||
#include "cond_field_serialization.h"
|
||||
#include "app_util.h"
|
||||
#include "ble_gatt.h"
|
||||
#include <string.h>
|
||||
|
||||
uint32_t ble_gatt_char_props_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatt_char_props_t);
|
||||
|
||||
uint8_t ser_data = (p_struct->broadcast & 0x01)
|
||||
| ((p_struct->read & 0x01) << 1)
|
||||
| ((p_struct->write_wo_resp & 0x01) << 2)
|
||||
| ((p_struct->write & 0x01) << 3)
|
||||
| ((p_struct->notify & 0x01) << 4)
|
||||
| ((p_struct->indicate & 0x01) << 5)
|
||||
| ((p_struct->auth_signed_wr & 0x01) << 6);
|
||||
SER_PUSH_uint8(&ser_data);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatt_char_props_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatt_char_props_t);
|
||||
|
||||
uint8_t ser_data;
|
||||
SER_PULL_uint8(&ser_data);
|
||||
p_struct->broadcast = ser_data & 0x01;
|
||||
p_struct->read = (ser_data >> 1) & 0x01;
|
||||
p_struct->write_wo_resp = (ser_data >> 2) & 0x01;
|
||||
p_struct->write = (ser_data >> 3) & 0x01;
|
||||
p_struct->notify = (ser_data >> 4) & 0x01;
|
||||
p_struct->indicate = (ser_data >> 5) & 0x01;
|
||||
p_struct->auth_signed_wr = (ser_data >> 6) & 0x01;
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatt_char_ext_props_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatt_char_ext_props_t);
|
||||
|
||||
uint8_t ser_data = (p_struct->reliable_wr & 0x01)
|
||||
| ((p_struct->wr_aux & 0x01) << 1);
|
||||
SER_PUSH_uint8(&ser_data);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatt_char_ext_props_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatt_char_ext_props_t);
|
||||
|
||||
uint8_t ser_data;
|
||||
SER_PULL_uint8(&ser_data);
|
||||
p_struct->reliable_wr = ser_data & 0x01;
|
||||
p_struct->wr_aux = (ser_data >> 1) & 0x01;
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
|
||||
uint32_t ble_gatt_enable_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatt_enable_params_t);
|
||||
SER_PUSH_uint16(&p_struct->att_mtu);
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_gatt_enable_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatt_enable_params_t);
|
||||
SER_PULL_uint16(&p_struct->att_mtu);
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
#else
|
||||
uint32_t ble_gatt_conn_cfg_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatt_conn_cfg_t);
|
||||
SER_PUSH_uint16(&p_struct->att_mtu);
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_gatt_conn_cfg_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatt_conn_cfg_t);
|
||||
SER_PULL_uint16(&p_struct->att_mtu);
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef BLE_GATT_STRUCT_SERIALIZATION_H
|
||||
#define BLE_GATT_STRUCT_SERIALIZATION_H
|
||||
|
||||
#include "ble_gatt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t ble_gatt_char_props_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatt_char_props_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatt_char_ext_props_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatt_char_ext_props_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
|
||||
uint32_t ble_gatt_enable_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatt_enable_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#else
|
||||
uint32_t ble_gatt_conn_cfg_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatt_conn_cfg_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*BLE_GATT_STRUCT_SERIALIZATION_H*/
|
||||
@@ -0,0 +1,715 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "ble_gatt_struct_serialization.h"
|
||||
#include "ble_gattc_struct_serialization.h"
|
||||
#include "ble_struct_serialization.h"
|
||||
#include "ble_serialization.h"
|
||||
#include "app_util.h"
|
||||
#include "ble_gattc.h"
|
||||
#include "cond_field_serialization.h"
|
||||
#include <string.h>
|
||||
|
||||
uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_evt_char_val_by_uuid_read_rsp_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->count);
|
||||
SER_PUSH_uint16(&p_struct->value_len);
|
||||
|
||||
// Copy the whole packed list.
|
||||
uint16_t list_length = (p_struct->value_len + sizeof(uint16_t)) * p_struct->count;
|
||||
SER_PUSH_uint8array(p_struct->handle_value, list_length);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_evt_char_val_by_uuid_read_rsp_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->count);
|
||||
SER_PULL_uint16(&p_struct->value_len);
|
||||
|
||||
uint16_t list_length = (p_struct->value_len + sizeof(uint16_t)) * p_struct->count;
|
||||
SER_ASSERT_LENGTH_LEQ(list_length, *p_ext_len);
|
||||
SER_PULL_uint8array(p_struct->handle_value, list_length);
|
||||
*p_ext_len = list_length;
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_evt_char_vals_read_rsp_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->len);
|
||||
SER_PUSH_uint8array(p_struct->values, p_struct->len);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_evt_char_vals_read_rsp_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->len);
|
||||
|
||||
SER_ASSERT_LENGTH_LEQ(p_struct->len, *p_ext_len);
|
||||
SER_PULL_uint8array(p_struct->values, p_struct->len);
|
||||
*p_ext_len = p_struct->len;
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_handle_range_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->start_handle);
|
||||
SER_PUSH_uint16(&p_struct->end_handle);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_handle_range_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->start_handle);
|
||||
SER_PULL_uint16(&p_struct->end_handle);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_gattc_service_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_service_t);
|
||||
|
||||
SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc);
|
||||
SER_PUSH_FIELD(&p_struct->handle_range, ble_gattc_handle_range_t_enc);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_service_t);
|
||||
|
||||
SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec);
|
||||
SER_PULL_FIELD(&p_struct->handle_range, ble_gattc_handle_range_t_dec);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_include_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_include_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->handle);
|
||||
SER_PUSH_FIELD(&p_struct->included_srvc, ble_gattc_service_t_enc);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_include_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->handle);
|
||||
SER_PULL_FIELD(&p_struct->included_srvc, ble_gattc_service_t_dec);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_evt_rel_disc_rsp_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->count);
|
||||
|
||||
ble_gattc_include_t * p_include = &(p_struct->includes[0]);
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < p_struct->count; i++)
|
||||
{
|
||||
SER_PUSH_FIELD(p_include, ble_gattc_include_t_enc);
|
||||
++p_include;
|
||||
}
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_evt_rel_disc_rsp_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->count);
|
||||
|
||||
uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_include_t));
|
||||
SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
|
||||
|
||||
ble_gattc_include_t * p_include = &(p_struct->includes[0]);
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < p_struct->count; i++)
|
||||
{
|
||||
SER_PULL_FIELD(p_include, ble_gattc_include_t_dec);
|
||||
++p_include;
|
||||
}
|
||||
|
||||
*p_ext_len = data_len;
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_write_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_write_params_t);
|
||||
|
||||
SER_PUSH_uint8(&p_struct->write_op);
|
||||
SER_PUSH_uint8(&p_struct->flags);
|
||||
SER_PUSH_uint16(&p_struct->handle);
|
||||
SER_PUSH_uint16(&p_struct->offset);
|
||||
SER_PUSH_len16data(p_struct->p_value, p_struct->len);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_write_params_t);
|
||||
|
||||
SER_PULL_uint8(&p_struct->write_op);
|
||||
SER_PULL_uint8(&p_struct->flags);
|
||||
SER_PULL_uint16(&p_struct->handle);
|
||||
SER_PULL_uint16(&p_struct->offset);
|
||||
SER_PULL_len16data((uint8_t **) &p_struct->p_value, &p_struct->len);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_attr_info16_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_attr_info16_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->handle);
|
||||
SER_PUSH_FIELD(&(p_struct->uuid), ble_uuid_t_enc);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_attr_info16_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_attr_info16_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->handle);
|
||||
SER_PULL_FIELD(&(p_struct->uuid), ble_uuid_t_dec);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_attr_info128_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_attr_info128_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->handle);
|
||||
SER_PUSH_FIELD(&(p_struct->uuid), ble_uuid128_t_enc);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_attr_info128_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_attr_info128_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->handle);
|
||||
SER_PULL_FIELD(&(p_struct->uuid), ble_uuid128_t_dec);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_attr_info_disc_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_evt_attr_info_disc_rsp_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->count);
|
||||
SER_PUSH_uint8(&p_struct->format);
|
||||
|
||||
field_encoder_handler_t fp_encoder = (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) ?
|
||||
ble_gattc_attr_info16_t_enc : ble_gattc_attr_info128_t_enc;
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0; i < p_struct->count; ++i)
|
||||
{
|
||||
void * uuid_struct;
|
||||
uuid_struct = (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) ?
|
||||
(void *)&(p_struct->info.attr_info16[i]) : (void *)&(p_struct->info.attr_info128[i]);
|
||||
SER_PUSH_FIELD(uuid_struct, fp_encoder);
|
||||
}
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_attr_info_disc_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_evt_attr_info_disc_rsp_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->count);
|
||||
SER_PULL_uint8(&p_struct->format);
|
||||
|
||||
uint32_t i;
|
||||
uint32_t data_len;
|
||||
field_decoder_handler_t fp_decoder;
|
||||
if (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT)
|
||||
{
|
||||
fp_decoder = ble_gattc_attr_info16_t_dec;
|
||||
data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_attr_info16_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_decoder = ble_gattc_attr_info128_t_dec;
|
||||
data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_attr_info128_t));
|
||||
}
|
||||
SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
|
||||
|
||||
for (i = 0; i < p_struct->count; i++)
|
||||
{
|
||||
void * uuid_struct;
|
||||
uuid_struct = (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) ?
|
||||
(void *)&(p_struct->info.attr_info16[i]) : (void *)&(p_struct->info.attr_info128[i]);
|
||||
SER_PULL_FIELD(uuid_struct, fp_decoder);
|
||||
}
|
||||
|
||||
*p_ext_len = data_len;
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_char_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_char_t);
|
||||
|
||||
uint8_t ser_data;
|
||||
SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc);
|
||||
SER_PUSH_FIELD(&p_struct->char_props, ble_gatt_char_props_t_enc);
|
||||
ser_data = p_struct->char_ext_props & 0x01;
|
||||
SER_PUSH_uint8(&ser_data);
|
||||
SER_PUSH_uint16(&p_struct->handle_decl);
|
||||
SER_PUSH_uint16(&p_struct->handle_value);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_char_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_char_t);
|
||||
|
||||
uint8_t ser_data;
|
||||
SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec);
|
||||
SER_PULL_FIELD(&p_struct->char_props, ble_gatt_char_props_t_dec);
|
||||
SER_PULL_uint8(&ser_data);
|
||||
p_struct->char_ext_props = ser_data & 0x01;
|
||||
SER_PULL_uint16(&p_struct->handle_decl);
|
||||
SER_PULL_uint16(&p_struct->handle_value);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_char_disc_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_evt_char_disc_rsp_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->count);
|
||||
SER_PUSH_FIELD_ARRAY(p_struct->chars, ble_gattc_char_t_enc, p_struct->count);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_char_disc_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_evt_char_disc_rsp_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->count);
|
||||
uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_char_t));
|
||||
SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
|
||||
|
||||
SER_PULL_FIELD_ARRAY(p_struct->chars, ble_gattc_char_t_dec, p_struct->count);
|
||||
|
||||
*p_ext_len = data_len;
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_desc_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_desc_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->handle);
|
||||
SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_desc_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_desc_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->handle);
|
||||
SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_desc_disc_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_evt_desc_disc_rsp_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->count);
|
||||
SER_PUSH_FIELD_ARRAY(p_struct->descs, ble_gattc_desc_t_enc, p_struct->count);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_desc_disc_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_evt_desc_disc_rsp_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->count);
|
||||
uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_desc_t));
|
||||
SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
|
||||
|
||||
SER_PULL_FIELD_ARRAY(p_struct->descs, ble_gattc_desc_t_dec, p_struct->count);
|
||||
|
||||
*p_ext_len = data_len;
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_hvx_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_evt_hvx_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->handle);
|
||||
SER_PUSH_uint8(&p_struct->type);
|
||||
SER_PUSH_uint16(&p_struct->len);
|
||||
SER_PUSH_uint8array(p_struct->data, p_struct->len);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_hvx_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_evt_hvx_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->handle);
|
||||
SER_PULL_uint8(&p_struct->type);
|
||||
SER_PULL_uint16(&p_struct->len);
|
||||
|
||||
uint32_t data_len = (SUB1(p_struct->len));
|
||||
SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
|
||||
|
||||
SER_PULL_uint8array(p_struct->data, p_struct->len);
|
||||
|
||||
*p_ext_len = data_len;
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_evt_prim_srvc_disc_rsp_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->count);
|
||||
SER_PUSH_FIELD_ARRAY(p_struct->services, ble_gattc_service_t_enc, p_struct->count);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_evt_prim_srvc_disc_rsp_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->count);
|
||||
uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_service_t));
|
||||
SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
|
||||
|
||||
SER_PULL_FIELD_ARRAY(p_struct->services, ble_gattc_service_t_dec, p_struct->count);
|
||||
|
||||
*p_ext_len = data_len;
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_read_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_evt_read_rsp_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->handle);
|
||||
SER_PUSH_uint16(&p_struct->offset);
|
||||
SER_PUSH_uint16(&p_struct->len);
|
||||
SER_PUSH_uint8array(p_struct->data, p_struct->len);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_read_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_evt_read_rsp_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->handle);
|
||||
SER_PULL_uint16(&p_struct->offset);
|
||||
SER_PULL_uint16(&p_struct->len);
|
||||
|
||||
uint32_t data_len = (SUB1(p_struct->len));
|
||||
SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
|
||||
|
||||
SER_PULL_uint8array(p_struct->data, p_struct->len);
|
||||
|
||||
*p_ext_len = data_len;
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_timeout_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_evt_timeout_t);
|
||||
SER_PUSH_uint8(&p_struct->src);
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_timeout_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_evt_timeout_t);
|
||||
SER_PULL_uint8(&p_struct->src);
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_write_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_evt_write_rsp_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->handle);
|
||||
SER_PUSH_uint8(&p_struct->write_op);
|
||||
SER_PUSH_uint16(&p_struct->offset);
|
||||
SER_PUSH_uint16(&p_struct->len);
|
||||
SER_PUSH_uint8array(p_struct->data, p_struct->len);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_write_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_evt_write_rsp_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->handle);
|
||||
SER_PULL_uint8(&p_struct->write_op);
|
||||
SER_PULL_uint16(&p_struct->offset);
|
||||
SER_PULL_uint16(&p_struct->len);
|
||||
|
||||
uint32_t data_len = (SUB1(p_struct->len));
|
||||
SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
|
||||
|
||||
SER_PULL_uint8array(p_struct->data, p_struct->len);
|
||||
|
||||
*p_ext_len = data_len;
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_exchange_mtu_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_evt_exchange_mtu_rsp_t);
|
||||
SER_PUSH_uint16(&p_struct->server_rx_mtu);
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_evt_exchange_mtu_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_evt_exchange_mtu_rsp_t);
|
||||
SER_PULL_uint16(&p_struct->server_rx_mtu);
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
#if NRF_SD_BLE_API_VERSION >= 4
|
||||
uint32_t ble_gattc_conn_cfg_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gattc_conn_cfg_t);
|
||||
SER_PUSH_uint8(&p_struct->write_cmd_tx_queue_size);
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gattc_conn_cfg_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gattc_conn_cfg_t);
|
||||
SER_PULL_uint8(&p_struct->write_cmd_tx_queue_size);
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,293 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef BLE_GATTC_STRUCT_SERIALIZATION_H
|
||||
#define BLE_GATTC_STRUCT_SERIALIZATION_H
|
||||
|
||||
#include "ble_gattc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_service_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_include_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_write_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_attr_info16_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_attr_info16_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_attr_info128_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_attr_info128_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_evt_attr_info_disc_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_evt_attr_info_disc_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatt_char_props_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatt_char_props_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatt_char_ext_props_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatt_char_ext_props_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_char_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_char_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_evt_char_disc_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_evt_char_disc_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_desc_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_desc_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_evt_desc_disc_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_evt_desc_disc_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_evt_hvx_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_evt_hvx_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_evt_read_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_evt_read_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_evt_timeout_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_evt_timeout_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_evt_write_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_evt_write_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gattc_evt_exchange_mtu_rsp_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_evt_exchange_mtu_rsp_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#if NRF_SD_BLE_API_VERSION >= 4
|
||||
uint32_t ble_gattc_conn_cfg_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gattc_conn_cfg_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*BLE_GATTC_STRUCT_SERIALIZATION_H*/
|
||||
@@ -0,0 +1,689 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "ble_gatt_struct_serialization.h"
|
||||
#include "ble_gatts_struct_serialization.h"
|
||||
#include "ble_gap_struct_serialization.h"
|
||||
#include "ble_struct_serialization.h"
|
||||
#include "ble_serialization.h"
|
||||
#include "app_util.h"
|
||||
#include "ble_gatts.h"
|
||||
#include "cond_field_serialization.h"
|
||||
#include <string.h>
|
||||
|
||||
uint32_t ble_gatts_char_pf_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_char_pf_t);
|
||||
|
||||
SER_PUSH_uint8(&p_struct->format);
|
||||
SER_PUSH_int8(&p_struct->exponent);
|
||||
SER_PUSH_uint16(&p_struct->unit);
|
||||
SER_PUSH_uint8(&p_struct->name_space);
|
||||
SER_PUSH_uint16(&p_struct->desc);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_char_pf_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_char_pf_t);
|
||||
|
||||
SER_PULL_uint8(&p_struct->format);
|
||||
SER_PULL_int8(&p_struct->exponent);
|
||||
SER_PULL_uint16(&p_struct->unit);
|
||||
SER_PULL_uint8(&p_struct->name_space);
|
||||
SER_PULL_uint16(&p_struct->desc);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_attr_md_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_attr_md_t);
|
||||
|
||||
SER_PUSH_FIELD(&p_struct->read_perm, ble_gap_conn_sec_mode_t_enc);
|
||||
SER_PUSH_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_enc);
|
||||
uint8_t ser_data = (p_struct->vlen & 0x01)
|
||||
| ((p_struct->vloc & 0x03) << 1)
|
||||
| ((p_struct->rd_auth & 0x01) << 3)
|
||||
| ((p_struct->wr_auth & 0x01) << 4);
|
||||
SER_PUSH_uint8(&ser_data);
|
||||
|
||||
// Serializer does not support attributes on stack.
|
||||
if (p_struct->vloc != BLE_GATTS_VLOC_STACK)
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_attr_md_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_attr_md_t);
|
||||
|
||||
uint8_t ser_data;
|
||||
SER_PULL_FIELD(&p_struct->read_perm, ble_gap_conn_sec_mode_t_dec);
|
||||
SER_PULL_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_dec);
|
||||
SER_PULL_uint8(&ser_data);
|
||||
|
||||
p_struct->vlen = ser_data & 0x01;
|
||||
p_struct->vloc = (ser_data >> 1) & 0x03;
|
||||
p_struct->rd_auth = (ser_data >> 3) & 0x01;
|
||||
p_struct->wr_auth = (ser_data >> 4) & 0x01;
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_char_md_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_char_md_t);
|
||||
|
||||
SER_PUSH_FIELD(&p_struct->char_props, ble_gatt_char_props_t_enc);
|
||||
SER_PUSH_FIELD(&p_struct->char_ext_props, ble_gatt_char_ext_props_t_enc);
|
||||
SER_PUSH_uint16(&p_struct->char_user_desc_max_size);
|
||||
SER_ERROR_CHECK(p_struct->char_user_desc_size <= BLE_GATTS_VAR_ATTR_LEN_MAX,
|
||||
NRF_ERROR_INVALID_PARAM);
|
||||
SER_PUSH_len16data(p_struct->p_char_user_desc, p_struct->char_user_desc_size);
|
||||
SER_PUSH_COND(p_struct->p_char_pf, ble_gatts_char_pf_t_enc);
|
||||
SER_PUSH_COND(p_struct->p_user_desc_md, ble_gatts_attr_md_t_enc);
|
||||
SER_PUSH_COND(p_struct->p_cccd_md, ble_gatts_attr_md_t_enc);
|
||||
SER_PUSH_COND(p_struct->p_sccd_md, ble_gatts_attr_md_t_enc);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_char_md_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_char_md_t);
|
||||
|
||||
SER_PULL_FIELD(&p_struct->char_props, ble_gatt_char_props_t_dec);
|
||||
SER_PULL_FIELD(&p_struct->char_ext_props, ble_gatt_char_ext_props_t_dec);
|
||||
SER_PULL_uint16(&p_struct->char_user_desc_max_size);
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
|
||||
SER_PULL_len16data(&p_struct->p_char_user_desc, &p_struct->char_user_desc_size);
|
||||
#else
|
||||
SER_PULL_len16data((uint8_t * * )&p_struct->p_char_user_desc, &p_struct->char_user_desc_size);
|
||||
#endif
|
||||
SER_PULL_COND(&p_struct->p_char_pf, ble_gatts_char_pf_t_dec);
|
||||
SER_PULL_COND(&p_struct->p_user_desc_md, ble_gatts_attr_md_t_dec);
|
||||
SER_PULL_COND(&p_struct->p_cccd_md, ble_gatts_attr_md_t_dec);
|
||||
SER_PULL_COND(&p_struct->p_sccd_md, ble_gatts_attr_md_t_dec);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_attr_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_attr_t);
|
||||
|
||||
SER_PUSH_COND(p_struct->p_uuid, ble_uuid_t_enc);
|
||||
SER_PUSH_COND(p_struct->p_attr_md, ble_gatts_attr_md_t_enc);
|
||||
SER_PUSH_uint16(&p_struct->init_offs);
|
||||
SER_PUSH_uint16(&p_struct->max_len);
|
||||
SER_ERROR_CHECK(p_struct->init_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM);
|
||||
SER_PUSH_len16data(p_struct->p_value, p_struct->init_len);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_attr_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_attr_t);
|
||||
|
||||
SER_PULL_COND(&p_struct->p_uuid, ble_uuid_t_dec);
|
||||
SER_PULL_COND(&p_struct->p_attr_md, ble_gatts_attr_md_t_dec);
|
||||
SER_PULL_uint16(&p_struct->init_offs);
|
||||
SER_PULL_uint16(&p_struct->max_len);
|
||||
SER_PULL_len16data(&p_struct->p_value, &p_struct->init_len);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_char_handles_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_char_handles_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->value_handle);
|
||||
SER_PUSH_uint16(&p_struct->user_desc_handle);
|
||||
SER_PUSH_uint16(&p_struct->cccd_handle);
|
||||
SER_PUSH_uint16(&p_struct->sccd_handle);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_char_handles_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_char_handles_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->value_handle);
|
||||
SER_PULL_uint16(&p_struct->user_desc_handle);
|
||||
SER_PULL_uint16(&p_struct->cccd_handle);
|
||||
SER_PULL_uint16(&p_struct->sccd_handle);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_hvx_params_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->handle);
|
||||
SER_PUSH_uint8(&p_struct->type);
|
||||
SER_PUSH_uint16(&p_struct->offset);
|
||||
SER_PUSH_COND(p_struct->p_len, uint16_t_enc);
|
||||
if (p_struct->p_len)
|
||||
{
|
||||
SER_PUSH_buf(p_struct->p_data, *p_struct->p_len);
|
||||
}
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_hvx_params_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->handle);
|
||||
SER_PULL_uint8(&p_struct->type);
|
||||
SER_PULL_uint16(&p_struct->offset);
|
||||
SER_PULL_COND(&p_struct->p_len, uint16_t_dec);
|
||||
if (p_struct->p_len)
|
||||
{
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
|
||||
SER_PULL_buf(&p_struct->p_data, *p_struct->p_len, *p_struct->p_len);
|
||||
#else
|
||||
SER_PULL_buf((uint8_t**)&p_struct->p_data, *p_struct->p_len, *p_struct->p_len);
|
||||
#endif
|
||||
}
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_evt_write_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->handle);
|
||||
SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc);
|
||||
SER_PUSH_uint8(&p_struct->op);
|
||||
SER_PUSH_uint8(&p_struct->auth_required);
|
||||
SER_PUSH_uint16(&p_struct->offset);
|
||||
SER_PUSH_uint16(&p_struct->len);
|
||||
SER_PUSH_uint8array(p_struct->data, p_struct->len);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_evt_write_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->handle);
|
||||
SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec);
|
||||
SER_PULL_uint8(&p_struct->op);
|
||||
SER_PULL_uint8(&p_struct->auth_required);
|
||||
SER_PULL_uint16(&p_struct->offset);
|
||||
SER_PULL_uint16(&p_struct->len);
|
||||
|
||||
// Data field is defined as 1-element array, so the first element
|
||||
// is always allocated in the structure.
|
||||
SER_ASSERT_LENGTH_LEQ(p_struct->len, *p_ext_len + 1);
|
||||
SER_PULL_uint8array(p_struct->data, p_struct->len);
|
||||
*p_ext_len = (p_struct->len > 1) ? p_struct->len - 1 : 0;
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_evt_read_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->handle);
|
||||
SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc);
|
||||
SER_PUSH_uint16(&p_struct->offset);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_evt_read_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->handle);
|
||||
SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec);
|
||||
SER_PULL_uint16(&p_struct->offset);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_evt_rw_authorize_request_t);
|
||||
|
||||
SER_PUSH_uint8(&p_struct->type);
|
||||
|
||||
switch (p_struct->type)
|
||||
{
|
||||
case BLE_GATTS_AUTHORIZE_TYPE_READ:
|
||||
SER_PUSH_FIELD(&p_struct->request.read, ble_gatts_evt_read_t_enc);
|
||||
break;
|
||||
|
||||
case BLE_GATTS_AUTHORIZE_TYPE_WRITE:
|
||||
SER_PUSH_FIELD(&p_struct->request.write, ble_gatts_evt_write_t_enc);
|
||||
break;
|
||||
|
||||
default:
|
||||
case BLE_GATTS_AUTHORIZE_TYPE_INVALID:
|
||||
err_code = NRF_ERROR_INVALID_PARAM;
|
||||
break;
|
||||
}
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_evt_rw_authorize_request_t);
|
||||
|
||||
SER_PULL_uint8(&p_struct->type);
|
||||
|
||||
switch (p_struct->type)
|
||||
{
|
||||
case BLE_GATTS_AUTHORIZE_TYPE_READ:
|
||||
SER_PULL_FIELD(&p_struct->request.read, ble_gatts_evt_read_t_dec);
|
||||
break;
|
||||
|
||||
case BLE_GATTS_AUTHORIZE_TYPE_WRITE:
|
||||
err_code = ble_gatts_evt_write_t_dec(p_buf,
|
||||
buf_len,
|
||||
p_index,
|
||||
p_ext_len,
|
||||
&p_struct->request.write);
|
||||
SER_ASSERT(err_code == NRF_SUCCESS, err_code);
|
||||
break;
|
||||
|
||||
default:
|
||||
case BLE_GATTS_AUTHORIZE_TYPE_INVALID:
|
||||
return NRF_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_authorize_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_authorize_params_t);
|
||||
|
||||
uint8_t ser_data = p_struct->update & 0x01;
|
||||
SER_PUSH_uint16(&p_struct->gatt_status);
|
||||
SER_PUSH_uint8(&ser_data);
|
||||
SER_PUSH_uint16(&p_struct->offset);
|
||||
SER_PUSH_len16data(p_struct->p_data, p_struct->len);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_authorize_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_authorize_params_t);
|
||||
|
||||
uint8_t ser_data;
|
||||
SER_PULL_uint16(&p_struct->gatt_status);
|
||||
SER_PULL_uint8(&ser_data);
|
||||
SER_PULL_uint16(&p_struct->offset);
|
||||
SER_PULL_len16data((uint8_t **) &p_struct->p_data, &p_struct->len);
|
||||
|
||||
p_struct->update = ser_data & 0x01;
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_rw_authorize_reply_params_t);
|
||||
|
||||
SER_PUSH_uint8(&p_struct->type);
|
||||
if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_READ)
|
||||
{
|
||||
SER_PUSH_FIELD(&p_struct->params.read, ble_gatts_authorize_params_t_enc);
|
||||
}
|
||||
else if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
|
||||
{
|
||||
SER_PUSH_FIELD(&p_struct->params.write, ble_gatts_authorize_params_t_enc);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_rw_authorize_reply_params_t);
|
||||
|
||||
SER_PULL_uint8(&p_struct->type);
|
||||
if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_READ)
|
||||
{
|
||||
SER_PULL_FIELD(&p_struct->params.read, ble_gatts_authorize_params_t_dec);
|
||||
}
|
||||
else if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
|
||||
{
|
||||
SER_PULL_FIELD(&p_struct->params.write, ble_gatts_authorize_params_t_dec);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
|
||||
uint32_t ble_gatts_enable_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_enable_params_t);
|
||||
|
||||
uint8_t ser_data = p_struct->service_changed & 0x01;
|
||||
SER_PUSH_uint8(&ser_data);
|
||||
SER_PUSH_uint32(&p_struct->attr_tab_size);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_enable_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_enable_params_t);
|
||||
|
||||
uint8_t ser_data;
|
||||
SER_PULL_uint8(&ser_data);
|
||||
SER_PULL_uint32(&p_struct->attr_tab_size);
|
||||
|
||||
p_struct->service_changed = ser_data & 0x01;
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t ble_gatts_value_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_value_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->offset);
|
||||
SER_PUSH_len16data(p_struct->p_value, p_struct->len);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_value_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->offset);
|
||||
SER_PULL_len16data(&p_struct->p_value, &p_struct->len);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_exchange_mtu_request_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_evt_exchange_mtu_request_t);
|
||||
SER_PUSH_uint16(&p_struct->client_rx_mtu);
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_exchange_mtu_request_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_evt_exchange_mtu_request_t);
|
||||
SER_PULL_uint16(&p_struct->client_rx_mtu);
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_hvc_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_evt_hvc_t);
|
||||
SER_PUSH_uint16(&p_struct->handle);
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_hvc_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_evt_hvc_t);
|
||||
SER_PULL_uint16(&p_struct->handle);
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_sys_attr_missing_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_evt_sys_attr_missing_t);
|
||||
SER_PUSH_uint8(&p_struct->hint);
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_sys_attr_missing_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_evt_sys_attr_missing_t);
|
||||
SER_PULL_uint8(&p_struct->hint);
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_timeout_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_evt_timeout_t);
|
||||
SER_PUSH_uint8(&p_struct->src);
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_evt_timeout_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_evt_timeout_t);
|
||||
SER_PULL_uint8(&p_struct->src);
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
#if NRF_SD_BLE_API_VERSION >= 4
|
||||
uint32_t ble_gatts_conn_cfg_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_conn_cfg_t);
|
||||
SER_PUSH_uint8(&p_struct->hvn_tx_queue_size);
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_conn_cfg_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_conn_cfg_t);
|
||||
SER_PULL_uint8(&p_struct->hvn_tx_queue_size);
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_cfg_service_changed_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_cfg_service_changed_t);
|
||||
uint8_t service_changed = p_struct->service_changed;
|
||||
SER_PUSH_uint8(&service_changed);
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_cfg_service_changed_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_cfg_service_changed_t);
|
||||
uint8_t service_changed;
|
||||
SER_PULL_uint8(&service_changed);
|
||||
p_struct->service_changed = service_changed;
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
uint32_t ble_gatts_cfg_attr_tab_size_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_gatts_cfg_attr_tab_size_t);
|
||||
SER_PUSH_uint32(&p_struct->attr_tab_size);
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_gatts_cfg_attr_tab_size_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_gatts_cfg_attr_tab_size_t);
|
||||
SER_PULL_uint32(&p_struct->attr_tab_size);
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,259 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef BLE_GATTS_STRUCT_SERIALIZATION_H
|
||||
#define BLE_GATTS_STRUCT_SERIALIZATION_H
|
||||
|
||||
#include "ble_gatts.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t ble_gatts_char_pf_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_char_pf_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_attr_md_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_attr_md_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_char_md_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_char_md_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_attr_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_attr_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_char_handles_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_char_handles_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_authorize_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_authorize_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
|
||||
uint32_t ble_gatts_enable_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_enable_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#endif
|
||||
|
||||
uint32_t ble_gatts_value_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_evt_exchange_mtu_request_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_evt_exchange_mtu_request_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_evt_hvc_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_evt_hvc_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_evt_sys_attr_missing_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_evt_sys_attr_missing_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_evt_timeout_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_evt_timeout_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
#if NRF_SD_BLE_API_VERSION >= 4
|
||||
uint32_t ble_gatts_conn_cfg_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_conn_cfg_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_cfg_service_changed_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_cfg_service_changed_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_gatts_cfg_attr_tab_size_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_gatts_cfg_attr_tab_size_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BLE_GATTS_STRUCT_SERIALIZATION_H */
|
||||
@@ -0,0 +1,227 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "ble_l2cap_struct_serialization.h"
|
||||
#include "ble_struct_serialization.h"
|
||||
#include "ble_serialization.h"
|
||||
#include "app_util.h"
|
||||
#include "cond_field_serialization.h"
|
||||
#include <string.h>
|
||||
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
|
||||
uint32_t ble_l2cap_header_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_l2cap_header_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->len);
|
||||
SER_PUSH_uint16(&p_struct->cid);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_l2cap_header_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->len);
|
||||
SER_PULL_uint16(&p_struct->cid);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_l2cap_evt_rx_t);
|
||||
|
||||
SER_PUSH_FIELD(&p_struct->header, ble_l2cap_header_t_enc);
|
||||
SER_PUSH_uint8array(p_struct->data, p_struct->header.len);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_l2cap_evt_rx_t);
|
||||
|
||||
SER_PULL_FIELD(&p_struct->header, ble_l2cap_header_t_dec);
|
||||
|
||||
uint32_t data_len = (SUB1(p_struct->header.len));
|
||||
SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
|
||||
|
||||
SER_PULL_uint8array(p_struct->data, p_struct->header.len);
|
||||
|
||||
*p_ext_len = data_len;
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NRF_SD_BLE_API_VERSION >= 5
|
||||
uint32_t ble_l2cap_conn_cfg_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_l2cap_conn_cfg_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->rx_mps);
|
||||
SER_PUSH_uint16(&p_struct->tx_mps);
|
||||
SER_PUSH_uint8(&p_struct->rx_queue_size);
|
||||
SER_PUSH_uint8(&p_struct->tx_queue_size);
|
||||
SER_PUSH_uint8(&p_struct->ch_count);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_l2cap_conn_cfg_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_l2cap_conn_cfg_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->rx_mps);
|
||||
SER_PULL_uint16(&p_struct->tx_mps);
|
||||
SER_PULL_uint8(&p_struct->rx_queue_size);
|
||||
SER_PULL_uint8(&p_struct->tx_queue_size);
|
||||
SER_PULL_uint8(&p_struct->ch_count);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_l2cap_ch_rx_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_l2cap_ch_rx_params_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->rx_mtu);
|
||||
SER_PUSH_uint16(&p_struct->rx_mps);
|
||||
SER_PUSH_uint16(&p_struct->sdu_buf.len);
|
||||
SER_PUSH_uint32(&p_struct->sdu_buf.p_data);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_l2cap_ch_rx_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_l2cap_ch_rx_params_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->rx_mtu);
|
||||
SER_PULL_uint16(&p_struct->rx_mps);
|
||||
SER_PULL_uint16(&p_struct->sdu_buf.len);
|
||||
SER_PULL_uint32(&p_struct->sdu_buf.p_data);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_l2cap_ch_setup_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_l2cap_ch_setup_params_t);
|
||||
|
||||
SER_PUSH_FIELD(&p_struct->rx_params, ble_l2cap_ch_rx_params_t_enc);
|
||||
SER_PUSH_uint16(&p_struct->le_psm);
|
||||
SER_PUSH_uint16(&p_struct->status);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_l2cap_ch_setup_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_l2cap_ch_setup_params_t);
|
||||
|
||||
SER_PULL_FIELD(&p_struct->rx_params, ble_l2cap_ch_rx_params_t_dec);
|
||||
SER_PULL_uint16(&p_struct->le_psm);
|
||||
SER_PULL_uint16(&p_struct->status);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_l2cap_ch_tx_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_l2cap_ch_tx_params_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->tx_mtu);
|
||||
SER_PUSH_uint16(&p_struct->peer_mps);
|
||||
SER_PUSH_uint16(&p_struct->tx_mps);
|
||||
SER_PUSH_uint16(&p_struct->credits);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_l2cap_ch_tx_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_l2cap_ch_tx_params_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->tx_mtu);
|
||||
SER_PULL_uint16(&p_struct->peer_mps);
|
||||
SER_PULL_uint16(&p_struct->tx_mps);
|
||||
SER_PULL_uint16(&p_struct->credits);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
#endif //NRF_SD_BLE_API_VERSION >= 5
|
||||
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef BLE_L2CAP_STRUCT_SERIALIZATION_H
|
||||
#define BLE_L2CAP_STRUCT_SERIALIZATION_H
|
||||
|
||||
#ifndef S112
|
||||
#include "ble_l2cap.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
|
||||
uint32_t ble_l2cap_header_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
uint32_t * const p_ext_len,
|
||||
void * const p_void_struct);
|
||||
#endif
|
||||
|
||||
#if NRF_SD_BLE_API_VERSION >= 5
|
||||
uint32_t ble_l2cap_conn_cfg_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_l2cap_conn_cfg_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_l2cap_ch_rx_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_l2cap_ch_rx_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_l2cap_ch_setup_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_l2cap_ch_setup_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_l2cap_ch_tx_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_l2cap_ch_tx_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*BLE_L2CAP_STRUCT_SERIALIZATION_H*/
|
||||
@@ -0,0 +1,545 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "ble_struct_serialization.h"
|
||||
#include "ble_gap_struct_serialization.h"
|
||||
#include "ble_gatt_struct_serialization.h"
|
||||
#include "ble_gatts_struct_serialization.h"
|
||||
#include "ble_serialization.h"
|
||||
#include "app_util.h"
|
||||
#include "ble_types.h"
|
||||
#include "ble.h"
|
||||
#include "cond_field_serialization.h"
|
||||
#include "ser_config.h"
|
||||
#include <string.h>
|
||||
|
||||
#if NRF_SD_BLE_API_VERSION > 5
|
||||
#ifdef UNIT_TEST
|
||||
#include "conn_ble_gap_sec_keys.h"
|
||||
#include "app_ble_gap_sec_keys.h"
|
||||
bool serialization_connectivity_role = true;
|
||||
#elif defined(SER_CONNECTIVITY)
|
||||
#include "conn_ble_gap_sec_keys.h"
|
||||
#else
|
||||
#include "app_ble_gap_sec_keys.h"
|
||||
#endif /* UNIT_TEST */
|
||||
#endif /* NRF_SD_BLE_API_VERSION > 5 */
|
||||
|
||||
|
||||
uint32_t ble_uuid_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_uuid_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->uuid);
|
||||
SER_PUSH_uint8(&p_struct->type);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_uuid_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_uuid_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->uuid);
|
||||
SER_PULL_uint8(&p_struct->type);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_uuid128_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_uuid128_t);
|
||||
SER_PUSH_uint8array(p_struct->uuid128, sizeof (p_struct->uuid128));
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_uuid128_t);
|
||||
SER_PULL_uint8array(p_struct->uuid128, sizeof (p_struct->uuid128));
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
|
||||
uint32_t ble_enable_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_enable_params_t);
|
||||
|
||||
SER_PUSH_FIELD(&p_struct->common_enable_params, ble_common_enable_params_t_enc);
|
||||
SER_PUSH_FIELD(&p_struct->gap_enable_params, ble_gap_enable_params_t_enc);
|
||||
SER_PUSH_FIELD(&p_struct->gatt_enable_params, ble_gatt_enable_params_t_enc);
|
||||
SER_PUSH_FIELD(&p_struct->gatts_enable_params, ble_gatts_enable_params_t_enc);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_enable_params_t);
|
||||
|
||||
SER_PULL_FIELD(&p_struct->common_enable_params, ble_common_enable_params_t_dec);
|
||||
SER_PULL_FIELD(&p_struct->gap_enable_params, ble_gap_enable_params_t_dec);
|
||||
SER_PULL_FIELD(&p_struct->gatt_enable_params, ble_gatt_enable_params_t_dec);
|
||||
SER_PULL_FIELD(&p_struct->gatts_enable_params, ble_gatts_enable_params_t_dec);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_conn_bw_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_conn_bw_t);
|
||||
|
||||
SER_PUSH_uint8(&p_struct->conn_bw_rx);
|
||||
SER_PUSH_uint8(&p_struct->conn_bw_tx);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_conn_bw_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_conn_bw_t);
|
||||
|
||||
SER_PULL_uint8(&p_struct->conn_bw_rx);
|
||||
SER_PULL_uint8(&p_struct->conn_bw_tx);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_common_opt_conn_bw_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_common_opt_conn_bw_t);
|
||||
|
||||
SER_PUSH_uint8(&p_struct->role);
|
||||
SER_PUSH_FIELD(&p_struct->conn_bw, ble_conn_bw_t_enc);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_common_opt_conn_bw_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_common_opt_conn_bw_t);
|
||||
|
||||
SER_PULL_uint8(&p_struct->role);
|
||||
SER_PULL_FIELD(&p_struct->conn_bw, ble_conn_bw_t_dec);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_conn_bw_count_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_conn_bw_count_t);
|
||||
|
||||
SER_PUSH_uint8(&p_struct->high_count);
|
||||
SER_PUSH_uint8(&p_struct->mid_count);
|
||||
SER_PUSH_uint8(&p_struct->low_count);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_conn_bw_count_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_conn_bw_count_t);
|
||||
|
||||
SER_PULL_uint8(&p_struct->high_count);
|
||||
SER_PULL_uint8(&p_struct->mid_count);
|
||||
SER_PULL_uint8(&p_struct->low_count);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_conn_bw_counts_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_conn_bw_counts_t);
|
||||
|
||||
SER_PUSH_FIELD(&p_struct->tx_counts, ble_conn_bw_count_t_enc);
|
||||
SER_PUSH_FIELD(&p_struct->rx_counts, ble_conn_bw_count_t_enc);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_conn_bw_counts_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_conn_bw_counts_t);
|
||||
|
||||
SER_PULL_FIELD(&p_struct->tx_counts, ble_conn_bw_count_t_dec);
|
||||
SER_PULL_FIELD(&p_struct->rx_counts, ble_conn_bw_count_t_dec);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_common_enable_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_common_enable_params_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->vs_uuid_count);
|
||||
SER_PUSH_COND(p_struct->p_conn_bw_counts, ble_conn_bw_counts_t_enc);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_common_enable_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_common_enable_params_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->vs_uuid_count);
|
||||
SER_PULL_COND(&p_struct->p_conn_bw_counts, ble_conn_bw_counts_t_dec);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
#endif
|
||||
uint32_t ble_common_opt_pa_lna_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_common_opt_pa_lna_t);
|
||||
|
||||
SER_PUSH_FIELD(&p_struct->pa_cfg, ble_pa_lna_cfg_t_enc);
|
||||
SER_PUSH_FIELD(&p_struct->lna_cfg, ble_pa_lna_cfg_t_enc);
|
||||
SER_PUSH_uint8(&p_struct->ppi_ch_id_set);
|
||||
SER_PUSH_uint8(&p_struct->ppi_ch_id_clr);
|
||||
SER_PUSH_uint8(&p_struct->gpiote_ch_id);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_common_opt_pa_lna_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_common_opt_pa_lna_t);
|
||||
|
||||
SER_PULL_FIELD(&p_struct->pa_cfg, ble_pa_lna_cfg_t_dec);
|
||||
SER_PULL_FIELD(&p_struct->lna_cfg, ble_pa_lna_cfg_t_dec);
|
||||
SER_PULL_uint8(&p_struct->ppi_ch_id_set);
|
||||
SER_PULL_uint8(&p_struct->ppi_ch_id_clr);
|
||||
SER_PULL_uint8(&p_struct->gpiote_ch_id);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_pa_lna_cfg_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_pa_lna_cfg_t);
|
||||
|
||||
uint8_t ser_data = (p_struct->enable & 0x01)
|
||||
| ((p_struct->active_high & 0x01) << 1)
|
||||
| ((p_struct->gpio_pin & 0x3F) << 2);
|
||||
SER_PUSH_uint8(&ser_data);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_pa_lna_cfg_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_pa_lna_cfg_t);
|
||||
|
||||
uint8_t ser_data;
|
||||
SER_PULL_uint8(&ser_data);
|
||||
p_struct->enable = ser_data & 0x01;
|
||||
p_struct->active_high = (ser_data >> 1) & 0x01;
|
||||
p_struct->gpio_pin = (ser_data >> 2) & 0x3F;
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_user_mem_block_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_user_mem_block_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->len);
|
||||
SER_PUSH_COND(p_struct->p_mem, NULL);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_user_mem_block_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_user_mem_block_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->len);
|
||||
SER_PULL_COND(&p_struct->p_mem, NULL);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_version_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_version_t);
|
||||
|
||||
SER_PUSH_uint8(&p_struct->version_number);
|
||||
SER_PUSH_uint16(&p_struct->company_id);
|
||||
SER_PUSH_uint16(&p_struct->subversion_number);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_version_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_version_t);
|
||||
|
||||
SER_PULL_uint8(&p_struct->version_number);
|
||||
SER_PULL_uint16(&p_struct->company_id);
|
||||
SER_PULL_uint16(&p_struct->subversion_number);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
|
||||
uint32_t ble_evt_data_length_changed_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_evt_data_length_changed_t);
|
||||
|
||||
SER_PUSH_uint16(&p_struct->max_tx_octets);
|
||||
SER_PUSH_uint16(&p_struct->max_tx_time);
|
||||
SER_PUSH_uint16(&p_struct->max_rx_octets);
|
||||
SER_PUSH_uint16(&p_struct->max_rx_time);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_evt_data_length_changed_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_evt_data_length_changed_t);
|
||||
|
||||
SER_PULL_uint16(&p_struct->max_tx_octets);
|
||||
SER_PULL_uint16(&p_struct->max_tx_time);
|
||||
SER_PULL_uint16(&p_struct->max_rx_octets);
|
||||
SER_PULL_uint16(&p_struct->max_rx_time);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
#endif
|
||||
uint32_t ble_common_opt_conn_evt_ext_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_common_opt_conn_evt_ext_t);
|
||||
|
||||
uint8_t ser_data = p_struct->enable & 0x01;
|
||||
SER_PUSH_uint8(&ser_data);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_common_opt_conn_evt_ext_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_common_opt_conn_evt_ext_t);
|
||||
|
||||
uint8_t ser_data;
|
||||
SER_PULL_uint8(&ser_data);
|
||||
p_struct->enable = ser_data & 0x01;
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
#if NRF_SD_BLE_API_VERSION >= 4
|
||||
uint32_t ble_common_cfg_vs_uuid_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_common_cfg_vs_uuid_t);
|
||||
|
||||
SER_PUSH_uint8(&p_struct->vs_uuid_count);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_common_cfg_vs_uuid_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_common_cfg_vs_uuid_t);
|
||||
|
||||
SER_PULL_uint8(&p_struct->vs_uuid_count);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 4
|
||||
uint32_t ble_data_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(ble_data_t);
|
||||
|
||||
int buf_id = 0;
|
||||
#if NRF_SD_BLE_API_VERSION > 5
|
||||
#ifdef UNIT_TEST
|
||||
if (serialization_connectivity_role)
|
||||
{
|
||||
buf_id = conn_ble_gap_ble_data_buf_free(p_struct->p_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf_id = app_ble_gap_adv_buf_register(p_struct->p_data);
|
||||
SER_ASSERT(buf_id >= 0, NRF_ERROR_NO_MEM);
|
||||
}
|
||||
#elif defined(SER_CONNECTIVITY)
|
||||
buf_id = conn_ble_gap_ble_data_buf_free(p_struct->p_data);
|
||||
#else
|
||||
buf_id = app_ble_gap_adv_buf_register(p_struct->p_data);
|
||||
SER_ASSERT(buf_id >= 0, NRF_ERROR_NO_MEM);
|
||||
#endif
|
||||
#endif /* NRF_SD_BLE_API_VERSION > 5 */
|
||||
SER_PUSH_uint32((uint32_t *)&buf_id);
|
||||
SER_PUSH_len16data(p_struct->p_data, p_struct->len);
|
||||
|
||||
SER_STRUCT_ENC_END;
|
||||
}
|
||||
|
||||
uint32_t ble_data_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(ble_data_t);
|
||||
|
||||
uint32_t buf_id;
|
||||
SER_PULL_uint32(&buf_id);
|
||||
p_struct->len = SER_MAX_ADV_DATA;
|
||||
#if NRF_SD_BLE_API_VERSION > 5
|
||||
#ifdef UNIT_TEST
|
||||
if (serialization_connectivity_role)
|
||||
{
|
||||
if (buf_id && (p_struct->p_data == NULL))
|
||||
{
|
||||
p_struct->p_data = conn_ble_gap_ble_data_buf_alloc(buf_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p_struct->p_data = app_ble_gap_adv_buf_unregister((int)buf_id, true);
|
||||
}
|
||||
#elif defined(SER_CONNECTIVITY)
|
||||
if (buf_id && (p_struct->p_data == NULL))
|
||||
{
|
||||
p_struct->p_data = conn_ble_gap_ble_data_buf_alloc(buf_id);
|
||||
}
|
||||
#else
|
||||
p_struct->p_data = app_ble_gap_adv_buf_unregister(buf_id, true);
|
||||
#endif
|
||||
#endif /* NRF_SD_BLE_API_VERSION > 5*/
|
||||
SER_PULL_len16data(&p_struct->p_data, &p_struct->len);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,217 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef BLE_STRUCT_SERIALIZATION_H__
|
||||
#define BLE_STRUCT_SERIALIZATION_H__
|
||||
|
||||
#include "ble_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
uint32_t ble_uuid_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_uuid_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_uuid128_t_enc(const void * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_enable_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_conn_bw_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_conn_bw_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_common_opt_conn_bw_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_common_opt_conn_bw_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_conn_bw_count_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_conn_bw_count_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_conn_bw_counts_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_conn_bw_counts_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_common_enable_params_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_common_enable_params_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_common_opt_pa_lna_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_common_opt_pa_lna_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_pa_lna_cfg_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_pa_lna_cfg_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_user_mem_block_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_user_mem_block_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_version_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_version_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_evt_data_length_changed_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_evt_data_length_changed_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t ble_common_opt_conn_evt_ext_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_common_opt_conn_evt_ext_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#if NRF_SD_BLE_API_VERSION >= 4
|
||||
uint32_t ble_common_cfg_vs_uuid_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_common_cfg_vs_uuid_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 4
|
||||
uint32_t ble_data_t_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t ble_data_t_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BLE_STRUCT_SERIALIZATION_H__
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "nrf_soc_struct_serialization.h"
|
||||
#include "ble_serialization.h"
|
||||
#include "cond_field_serialization.h"
|
||||
#include "app_util.h"
|
||||
#include "string.h"
|
||||
|
||||
uint32_t nrf_ecb_hal_data_t_in_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(nrf_ecb_hal_data_t);
|
||||
|
||||
SER_PUSH_uint8array(p_struct->key, SOC_ECB_KEY_LENGTH);
|
||||
SER_PUSH_uint8array(p_struct->cleartext, SOC_ECB_CLEARTEXT_LENGTH);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t nrf_ecb_hal_data_t_in_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(nrf_ecb_hal_data_t);
|
||||
|
||||
SER_PULL_uint8array(p_struct->key, SOC_ECB_KEY_LENGTH);
|
||||
SER_PULL_uint8array(p_struct->cleartext, SOC_ECB_CLEARTEXT_LENGTH);
|
||||
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t nrf_ecb_hal_data_t_out_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index)
|
||||
{
|
||||
SER_STRUCT_ENC_BEGIN(nrf_ecb_hal_data_t);
|
||||
SER_PUSH_uint8array(p_struct->ciphertext, SOC_ECB_CIPHERTEXT_LENGTH);
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
|
||||
uint32_t nrf_ecb_hal_data_t_out_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct)
|
||||
{
|
||||
SER_STRUCT_DEC_BEGIN(nrf_ecb_hal_data_t);
|
||||
SER_PULL_uint8array(p_struct->ciphertext, SOC_ECB_CIPHERTEXT_LENGTH);
|
||||
SER_STRUCT_DEC_END;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef NRF_SOC_STRUCT_SERIALIZATION_H__
|
||||
#define NRF_SOC_STRUCT_SERIALIZATION_H__
|
||||
|
||||
#include "nrf_soc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t nrf_ecb_hal_data_t_in_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t nrf_ecb_hal_data_t_in_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
uint32_t nrf_ecb_hal_data_t_out_enc(void const * const p_void_struct,
|
||||
uint8_t * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index);
|
||||
|
||||
uint32_t nrf_ecb_hal_data_t_out_dec(uint8_t const * const p_buf,
|
||||
uint32_t buf_len,
|
||||
uint32_t * const p_index,
|
||||
void * const p_void_struct);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF_SOC_STRUCT_SERIALIZATION_H__
|
||||
93
components/serialization/common/transport/dtm_uart_params.h
Normal file
93
components/serialization/common/transport/dtm_uart_params.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Copyright (c) 2013 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef DTM_UART_PARAMS_H__
|
||||
#define DTM_UART_PARAMS_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @ingroup ble_dtm_app
|
||||
*/
|
||||
|
||||
|
||||
/**@brief Enumeration of supported baud rates. */
|
||||
typedef enum
|
||||
{
|
||||
UART_BAUD_RATE_1200, /**< Baud rate 1200. */
|
||||
UART_BAUD_RATE_2400, /**< Baud rate 2400. */
|
||||
UART_BAUD_RATE_4800, /**< Baud rate 4800. */
|
||||
UART_BAUD_RATE_9600, /**< Baud rate 9600. */
|
||||
UART_BAUD_RATE_14400, /**< Baud rate 14400. */
|
||||
UART_BAUD_RATE_19200, /**< Baud rate 19200. */
|
||||
UART_BAUD_RATE_28800, /**< Baud rate 28800. */
|
||||
UART_BAUD_RATE_38400, /**< Baud rate 38400. */
|
||||
UART_BAUD_RATE_57600, /**< Baud rate 57600. */
|
||||
UART_BAUD_RATE_76800, /**< Baud rate 76800. */
|
||||
UART_BAUD_RATE_115200, /**< Baud rate 115200. */
|
||||
UART_BAUD_RATE_230400, /**< Baud rate 230400. */
|
||||
UART_BAUD_RATE_250000, /**< Baud rate 250000. */
|
||||
UART_BAUD_RATE_460800, /**< Baud rate 460800. */
|
||||
UART_BAUD_RATE_921600, /**< Baud rate 921600. */
|
||||
UART_BAUD_RATE_1000000, /**< Baud rate 1000000. */
|
||||
UART_BAUD_RATE_MAX /**< Enumeration upper bound. */
|
||||
} app_uart_stream_baud_rate_t;
|
||||
|
||||
/**@brief UART communication structure holding configuration settings for the peripheral.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t rx_pin_no; /**< RX pin number. */
|
||||
uint8_t tx_pin_no; /**< TX pin number. */
|
||||
uint8_t rts_pin_no; /**< RTS pin number, only used if flow control is enabled. */
|
||||
uint8_t cts_pin_no; /**< CTS pin number, only used if flow control is enabled. */
|
||||
bool use_parity; /**< Even parity if TRUE, no parity if FALSE. */
|
||||
app_uart_stream_baud_rate_t baud_rate; /**< Baud rate configuration. */
|
||||
} app_uart_stream_comm_params_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // DTM_UART_PARAMS_H__
|
||||
514
components/serialization/common/transport/ser_hal_transport.c
Normal file
514
components/serialization/common/transport/ser_hal_transport.c
Normal file
@@ -0,0 +1,514 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "app_error.h"
|
||||
#include "sdk_config.h"
|
||||
#include "ser_config.h"
|
||||
#include "ser_phy.h"
|
||||
#include "ser_hal_transport.h"
|
||||
#if defined(APP_SCHEDULER_WITH_PAUSE) && APP_SCHEDULER_WITH_PAUSE
|
||||
#include "app_scheduler.h"
|
||||
#endif
|
||||
#define NRF_LOG_MODULE_NAME ser_hal_transport
|
||||
#if SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED
|
||||
#define NRF_LOG_LEVEL SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL
|
||||
#define NRF_LOG_INFO_COLOR SER_HAL_TRANSPORT_CONFIG_INFO_COLOR
|
||||
#define NRF_LOG_DEBUG_COLOR SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR
|
||||
#else //SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED
|
||||
#define NRF_LOG_LEVEL 0
|
||||
#endif //SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED
|
||||
#include "nrf_log.h"
|
||||
NRF_LOG_MODULE_REGISTER();
|
||||
|
||||
/**
|
||||
* @brief States of the RX state machine.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_TRANSP_RX_STATE_CLOSED = 0,
|
||||
HAL_TRANSP_RX_STATE_IDLE,
|
||||
HAL_TRANSP_RX_STATE_RECEIVING,
|
||||
HAL_TRANSP_RX_STATE_DROPPING,
|
||||
HAL_TRANSP_RX_STATE_RECEIVED,
|
||||
HAL_TRANSP_RX_STATE_RECEIVED_PENDING_BUF_REQ,
|
||||
HAL_TRANSP_RX_STATE_RECEIVED_DROPPING,
|
||||
HAL_TRANSP_RX_STATE_MAX
|
||||
}ser_hal_transp_rx_states_t;
|
||||
|
||||
/**
|
||||
* @brief States of the TX state machine.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_TRANSP_TX_STATE_CLOSED = 0,
|
||||
HAL_TRANSP_TX_STATE_IDLE,
|
||||
HAL_TRANSP_TX_STATE_TX_ALLOCATED,
|
||||
HAL_TRANSP_TX_STATE_TRANSMITTING,
|
||||
HAL_TRANSP_TX_STATE_TRANSMITTED,
|
||||
HAL_TRANSP_TX_STATE_MAX
|
||||
}ser_hal_transp_tx_states_t;
|
||||
|
||||
/**
|
||||
* @brief RX state.
|
||||
*/
|
||||
static ser_hal_transp_rx_states_t m_rx_state = HAL_TRANSP_RX_STATE_CLOSED;
|
||||
/**
|
||||
* @brief TX state.
|
||||
*/
|
||||
static ser_hal_transp_tx_states_t m_tx_state = HAL_TRANSP_TX_STATE_CLOSED;
|
||||
|
||||
/**
|
||||
* @brief Transmission buffer.
|
||||
*/
|
||||
static uint8_t m_tx_buffer[SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE];
|
||||
/**
|
||||
* @brief Reception buffer.
|
||||
*/
|
||||
static uint8_t m_rx_buffer[SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE];
|
||||
|
||||
/**
|
||||
* @brief Callback function handler for Serialization HAL Transport layer events.
|
||||
*/
|
||||
static ser_hal_transport_events_handler_t m_events_handler = NULL;
|
||||
|
||||
|
||||
/**
|
||||
* @brief A callback function to be used to handle a PHY module events. This function is called in
|
||||
* an interrupt context.
|
||||
*/
|
||||
static void phy_events_handler(ser_phy_evt_t phy_event)
|
||||
{
|
||||
uint32_t err_code = 0;
|
||||
ser_hal_transport_evt_t hal_transp_event;
|
||||
|
||||
memset(&hal_transp_event, 0, sizeof (ser_hal_transport_evt_t));
|
||||
hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_TYPE_MAX;
|
||||
|
||||
NRF_LOG_INFO("phy evt:%d", phy_event.evt_type);
|
||||
switch (phy_event.evt_type)
|
||||
{
|
||||
case SER_PHY_EVT_TX_PKT_SENT:
|
||||
{
|
||||
if (HAL_TRANSP_TX_STATE_TRANSMITTING == m_tx_state)
|
||||
{
|
||||
m_tx_state = HAL_TRANSP_TX_STATE_TRANSMITTED;
|
||||
NRF_LOG_INFO("tx free");
|
||||
err_code = ser_hal_transport_tx_pkt_free(m_tx_buffer);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
/* An event to an upper layer that a packet has been transmitted. */
|
||||
hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_TX_PKT_SENT;
|
||||
m_events_handler(hal_transp_event);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Lower layer should not generate this event in current state. */
|
||||
APP_ERROR_CHECK_BOOL(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SER_PHY_EVT_RX_BUF_REQUEST:
|
||||
{
|
||||
/* An event to an upper layer that a packet is being scheduled to receive or to drop. */
|
||||
hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_RX_PKT_RECEIVING;
|
||||
|
||||
/* Receive or drop a packet. */
|
||||
if (phy_event.evt_params.rx_buf_request.num_of_bytes <= sizeof (m_rx_buffer))
|
||||
{
|
||||
if (HAL_TRANSP_RX_STATE_IDLE == m_rx_state)
|
||||
{
|
||||
m_events_handler(hal_transp_event);
|
||||
err_code = ser_phy_rx_buf_set(m_rx_buffer);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_RECEIVING;
|
||||
}
|
||||
else if (HAL_TRANSP_RX_STATE_RECEIVED == m_rx_state)
|
||||
{
|
||||
/* It is OK to get know higher layer at this point that we are going to receive
|
||||
* a new packet even though we will start receiving when rx buffer is freed. */
|
||||
m_events_handler(hal_transp_event);
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED_PENDING_BUF_REQ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Lower layer should not generate this event in current state. */
|
||||
APP_ERROR_CHECK_BOOL(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There is not enough memory but packet has to be received to dummy location. */
|
||||
if (HAL_TRANSP_RX_STATE_IDLE == m_rx_state)
|
||||
{
|
||||
m_events_handler(hal_transp_event);
|
||||
err_code = ser_phy_rx_buf_set(NULL);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_DROPPING;
|
||||
}
|
||||
else if (HAL_TRANSP_RX_STATE_RECEIVED == m_rx_state)
|
||||
{
|
||||
m_events_handler(hal_transp_event);
|
||||
err_code = ser_phy_rx_buf_set(NULL);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED_DROPPING;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Lower layer should not generate this event in current state. */
|
||||
APP_ERROR_CHECK_BOOL(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SER_PHY_EVT_RX_PKT_RECEIVED:
|
||||
{
|
||||
if (HAL_TRANSP_RX_STATE_RECEIVING == m_rx_state)
|
||||
{
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED;
|
||||
/* Generate the event to an upper layer. */
|
||||
hal_transp_event.evt_type =
|
||||
SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED;
|
||||
hal_transp_event.evt_params.rx_pkt_received.p_buffer =
|
||||
phy_event.evt_params.rx_pkt_received.p_buffer;
|
||||
hal_transp_event.evt_params.rx_pkt_received.num_of_bytes =
|
||||
phy_event.evt_params.rx_pkt_received.num_of_bytes;
|
||||
m_events_handler(hal_transp_event);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Lower layer should not generate this event in current state. */
|
||||
APP_ERROR_CHECK_BOOL(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SER_PHY_EVT_RX_PKT_DROPPED:
|
||||
{
|
||||
if (HAL_TRANSP_RX_STATE_DROPPING == m_rx_state)
|
||||
{
|
||||
/* Generate the event to an upper layer. */
|
||||
hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_RX_PKT_DROPPED;
|
||||
m_events_handler(hal_transp_event);
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_IDLE;
|
||||
}
|
||||
else if (HAL_TRANSP_RX_STATE_RECEIVED_DROPPING == m_rx_state)
|
||||
{
|
||||
/* Generate the event to an upper layer. */
|
||||
hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_RX_PKT_DROPPED;
|
||||
m_events_handler(hal_transp_event);
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Lower layer should not generate this event in current state. */
|
||||
APP_ERROR_CHECK_BOOL(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SER_PHY_EVT_RX_OVERFLOW_ERROR:
|
||||
{
|
||||
/* Generate the event to an upper layer. */
|
||||
hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_PHY_ERROR;
|
||||
hal_transp_event.evt_params.phy_error.error_type =
|
||||
SER_HAL_TRANSP_PHY_ERROR_RX_OVERFLOW;
|
||||
m_events_handler(hal_transp_event);
|
||||
break;
|
||||
}
|
||||
|
||||
case SER_PHY_EVT_TX_OVERREAD_ERROR:
|
||||
{
|
||||
/* Generate the event to an upper layer. */
|
||||
hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_PHY_ERROR;
|
||||
hal_transp_event.evt_params.phy_error.error_type =
|
||||
SER_HAL_TRANSP_PHY_ERROR_TX_OVERREAD;
|
||||
m_events_handler(hal_transp_event);
|
||||
break;
|
||||
}
|
||||
|
||||
case SER_PHY_EVT_HW_ERROR:
|
||||
{
|
||||
/* Generate the event to an upper layer. */
|
||||
hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_PHY_ERROR;
|
||||
hal_transp_event.evt_params.phy_error.error_type =
|
||||
SER_HAL_TRANSP_PHY_ERROR_HW_ERROR;
|
||||
hal_transp_event.evt_params.phy_error.hw_error_code =
|
||||
phy_event.evt_params.hw_error.error_code;
|
||||
if (HAL_TRANSP_TX_STATE_TRANSMITTING == m_tx_state)
|
||||
{
|
||||
m_tx_state = HAL_TRANSP_TX_STATE_TRANSMITTED;
|
||||
err_code = ser_hal_transport_tx_pkt_free(phy_event.evt_params.hw_error.p_buffer);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
#if defined(APP_SCHEDULER_WITH_PAUSE) && APP_SCHEDULER_WITH_PAUSE
|
||||
app_sched_resume();
|
||||
#endif
|
||||
/* An event to an upper layer that a packet has been transmitted. */
|
||||
}
|
||||
else if (HAL_TRANSP_RX_STATE_RECEIVING == m_rx_state)
|
||||
{
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED;
|
||||
err_code = ser_hal_transport_rx_pkt_free(phy_event.evt_params.hw_error.p_buffer);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
m_events_handler(hal_transp_event);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
APP_ERROR_CHECK_BOOL(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ser_hal_transport_reset(void)
|
||||
{
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_IDLE;
|
||||
m_tx_state = HAL_TRANSP_TX_STATE_IDLE;
|
||||
}
|
||||
|
||||
uint32_t ser_hal_transport_open(ser_hal_transport_events_handler_t events_handler)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
if ((HAL_TRANSP_RX_STATE_CLOSED != m_rx_state) || (HAL_TRANSP_TX_STATE_CLOSED != m_tx_state))
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
else if (NULL == events_handler)
|
||||
{
|
||||
err_code = NRF_ERROR_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We have to change states before calling lower layer because ser_phy_open() function is
|
||||
* going to enable interrupts. On success an event from PHY layer can be emitted immediately
|
||||
* after return from ser_phy_open(). */
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_IDLE;
|
||||
m_tx_state = HAL_TRANSP_TX_STATE_IDLE;
|
||||
|
||||
m_events_handler = events_handler;
|
||||
|
||||
/* Initialize a PHY module. */
|
||||
err_code = ser_phy_open(phy_events_handler);
|
||||
|
||||
if (NRF_SUCCESS != err_code)
|
||||
{
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_CLOSED;
|
||||
m_tx_state = HAL_TRANSP_TX_STATE_CLOSED;
|
||||
m_events_handler = NULL;
|
||||
|
||||
if (NRF_ERROR_INVALID_PARAM != err_code)
|
||||
{
|
||||
err_code = NRF_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
void ser_hal_transport_close(void)
|
||||
{
|
||||
/* Reset generic handler for all events, reset internal states and close PHY module. */
|
||||
ser_phy_interrupts_disable();
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_CLOSED;
|
||||
m_tx_state = HAL_TRANSP_TX_STATE_CLOSED;
|
||||
|
||||
m_events_handler = NULL;
|
||||
|
||||
ser_phy_close();
|
||||
}
|
||||
|
||||
|
||||
uint32_t ser_hal_transport_rx_pkt_free(uint8_t * p_buffer)
|
||||
{
|
||||
|
||||
NRF_LOG_INFO("rx pkt free:%d", p_buffer);
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
ser_phy_interrupts_disable();
|
||||
|
||||
if (NULL == p_buffer)
|
||||
{
|
||||
err_code = NRF_ERROR_NULL;
|
||||
}
|
||||
else if (p_buffer != m_rx_buffer)
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_ADDR;
|
||||
}
|
||||
else if (HAL_TRANSP_RX_STATE_RECEIVED == m_rx_state)
|
||||
{
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_IDLE;
|
||||
}
|
||||
else if (HAL_TRANSP_RX_STATE_RECEIVED_DROPPING == m_rx_state)
|
||||
{
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_DROPPING;
|
||||
}
|
||||
else if (HAL_TRANSP_RX_STATE_RECEIVED_PENDING_BUF_REQ == m_rx_state)
|
||||
{
|
||||
err_code = ser_phy_rx_buf_set(m_rx_buffer);
|
||||
|
||||
if (NRF_SUCCESS == err_code)
|
||||
{
|
||||
m_rx_state = HAL_TRANSP_RX_STATE_RECEIVING;
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Upper layer should not call this function in current state. */
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
ser_phy_interrupts_enable();
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ser_hal_transport_tx_pkt_alloc(uint8_t * * pp_memory, uint16_t * p_num_of_bytes)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
if ((NULL == pp_memory) || (NULL == p_num_of_bytes))
|
||||
{
|
||||
err_code = NRF_ERROR_NULL;
|
||||
}
|
||||
else if (HAL_TRANSP_TX_STATE_CLOSED == m_tx_state)
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
else if (HAL_TRANSP_TX_STATE_IDLE == m_tx_state)
|
||||
{
|
||||
m_tx_state = HAL_TRANSP_TX_STATE_TX_ALLOCATED;
|
||||
*pp_memory = &m_tx_buffer[0];
|
||||
*p_num_of_bytes = (uint16_t)sizeof (m_tx_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ser_hal_transport_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
/* The buffer provided to this function must be allocated through ser_hal_transport_tx_alloc()
|
||||
* function - this assures correct state and that correct memory buffer is used. */
|
||||
if (NULL == p_buffer)
|
||||
{
|
||||
err_code = NRF_ERROR_NULL;
|
||||
}
|
||||
else if (0 == num_of_bytes)
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
else if (p_buffer != m_tx_buffer)
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_ADDR;
|
||||
}
|
||||
else if (num_of_bytes > sizeof (m_tx_buffer))
|
||||
{
|
||||
err_code = NRF_ERROR_DATA_SIZE;
|
||||
}
|
||||
else if (HAL_TRANSP_TX_STATE_TX_ALLOCATED == m_tx_state)
|
||||
{
|
||||
ser_phy_interrupts_disable();
|
||||
err_code = ser_phy_tx_pkt_send(p_buffer, num_of_bytes);
|
||||
|
||||
if (NRF_SUCCESS == err_code)
|
||||
{
|
||||
m_tx_state = HAL_TRANSP_TX_STATE_TRANSMITTING;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NRF_ERROR_BUSY != err_code)
|
||||
{
|
||||
err_code = NRF_ERROR_INTERNAL;
|
||||
}
|
||||
}
|
||||
ser_phy_interrupts_enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ser_hal_transport_tx_pkt_free(uint8_t * p_buffer)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
if (NULL == p_buffer)
|
||||
{
|
||||
err_code = NRF_ERROR_NULL;
|
||||
}
|
||||
else if (p_buffer != m_tx_buffer)
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_ADDR;
|
||||
}
|
||||
else if ((HAL_TRANSP_TX_STATE_TX_ALLOCATED == m_tx_state) ||
|
||||
(HAL_TRANSP_TX_STATE_TRANSMITTED == m_tx_state))
|
||||
{
|
||||
/* Release TX buffer for use. */
|
||||
m_tx_state = HAL_TRANSP_TX_STATE_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
268
components/serialization/common/transport/ser_hal_transport.h
Normal file
268
components/serialization/common/transport/ser_hal_transport.h
Normal file
@@ -0,0 +1,268 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/** @file
|
||||
*
|
||||
* @defgroup ser_hal_transport Serialization HAL Transport
|
||||
* @{
|
||||
* @ingroup ble_sdk_lib_serialization
|
||||
*
|
||||
* @brief HAL Transport layer for serialization.
|
||||
*
|
||||
* @details The @ref ser_hal_transport declares functions and typedefs used as API of the HAL
|
||||
* transport layer for serialization. This layer is fully hardware-independent.
|
||||
* Currently, the HAL transport layer is responsible for controlling the PHY layer and
|
||||
* memory management. In the future, more features might be added to it, such as CRC
|
||||
* or retransmission.
|
||||
*
|
||||
* \n \n
|
||||
* \image html ser_hal_transport_rx_state_machine.svg "RX state machine"
|
||||
* \n \n
|
||||
* \image html ser_hal_transport_tx_state_machine.svg "TX state machine"
|
||||
* \n
|
||||
*/
|
||||
|
||||
#ifndef SER_HAL_TRANSPORT_H__
|
||||
#define SER_HAL_TRANSPORT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**@brief Serialization HAL Transport layer event types. */
|
||||
typedef enum
|
||||
{
|
||||
SER_HAL_TRANSP_EVT_TX_PKT_SENT = 0, /**< An event indicating that TX packet has been
|
||||
transmitted. */
|
||||
SER_HAL_TRANSP_EVT_RX_PKT_RECEIVING, /**< An event indicating that RX packet is being
|
||||
scheduled to receive or to drop. */
|
||||
SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED, /**< An event indicating that RX packet is ready for
|
||||
read. */
|
||||
SER_HAL_TRANSP_EVT_RX_PKT_DROPPED, /**< An event indicating that RX packet was dropped
|
||||
because it was longer than available buffer. */
|
||||
SER_HAL_TRANSP_EVT_PHY_ERROR, /**< An event indicating error on PHY layer. */
|
||||
SER_HAL_TRANSP_EVT_TYPE_MAX /**< Enumeration upper bound. */
|
||||
} ser_hal_transport_evt_type_t;
|
||||
|
||||
|
||||
/**@brief Serialization PHY layer error types. */
|
||||
typedef enum
|
||||
{
|
||||
SER_HAL_TRANSP_PHY_ERROR_RX_OVERFLOW = 0, /**< An error indicating that more information has
|
||||
been transmitted than the PHY module could handle. */
|
||||
SER_HAL_TRANSP_PHY_ERROR_TX_OVERREAD, /**< An error indicating that the PHY module was forced to
|
||||
transmit more information than possessed. */
|
||||
SER_HAL_TRANSP_PHY_ERROR_HW_ERROR, /**< An error indicating a hardware error in the PHY
|
||||
module. */
|
||||
SER_HAL_TRANSP_PHY_ERROR_TYPE_MAX /**< Enumeration upper bound. */
|
||||
} ser_hal_transport_phy_error_type_t;
|
||||
|
||||
|
||||
/**@brief Struct containing parameters of event of type
|
||||
* @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t * p_buffer; /**< Pointer to a buffer containing a packet to read. */
|
||||
uint16_t num_of_bytes; /**< Length of a received packet in octets. */
|
||||
} ser_hal_transport_evt_rx_pkt_received_params_t;
|
||||
|
||||
|
||||
/**@brief Struct containing parameters of event of type @ref SER_HAL_TRANSP_EVT_PHY_ERROR. */
|
||||
typedef struct
|
||||
{
|
||||
ser_hal_transport_phy_error_type_t error_type; /**< Type of the PHY error. */
|
||||
uint32_t hw_error_code; /**< Hardware error code - specific for a microcontroller. Parameter
|
||||
is valid only for the PHY error of type
|
||||
@ref SER_HAL_TRANSP_PHY_ERROR_HW_ERROR. */
|
||||
} ser_hal_transport_evt_phy_error_params_t;
|
||||
|
||||
|
||||
/**@brief Struct containing events from the Serialization HAL Transport layer.
|
||||
*
|
||||
* @note Some events do not have parameters, then the whole information is contained in the evt_type.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ser_hal_transport_evt_type_t evt_type; /**< Type of event. */
|
||||
union /**< Union alternative identified by evt_type in the enclosing struct. */
|
||||
{
|
||||
ser_hal_transport_evt_rx_pkt_received_params_t rx_pkt_received; /**< Parameters of event of type @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED. */
|
||||
ser_hal_transport_evt_phy_error_params_t phy_error; /**< Parameters of event of type @ref SER_HAL_TRANSP_EVT_PHY_ERROR. */
|
||||
} evt_params;
|
||||
} ser_hal_transport_evt_t;
|
||||
|
||||
|
||||
/**@brief Generic callback function type to be used by all Serialization HAL Transport layer
|
||||
* events.
|
||||
*
|
||||
* @param[in] event Serialization HAL Transport layer event.
|
||||
*/
|
||||
typedef void (*ser_hal_transport_events_handler_t)(ser_hal_transport_evt_t event);
|
||||
|
||||
|
||||
/**@brief Function for opening and initializing the Serialization HAL Transport layer.
|
||||
*
|
||||
* @note The function opens the transport channel, initializes a PHY layer, and registers the callback
|
||||
* function to be used by all Serialization HAL Transport layer events.
|
||||
*
|
||||
* @warning If the function has been already called, the function @ref ser_hal_transport_close has
|
||||
* to be called before ser_hal_transport_open can be called again.
|
||||
*
|
||||
* @param[in] events_handler Generic callback function to be used by all Serialization HAL
|
||||
* Transport layer events.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success.
|
||||
* @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
|
||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. Hardware initialization parameters taken from
|
||||
* the configuration file are wrong.
|
||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called. To call
|
||||
* it again the function @ref ser_hal_transport_close has to be
|
||||
* called first.
|
||||
* @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred.
|
||||
*/
|
||||
uint32_t ser_hal_transport_open(ser_hal_transport_events_handler_t events_handler);
|
||||
|
||||
/**@brief Function for reseting ser_hal_transport. */
|
||||
void ser_hal_transport_reset(void);
|
||||
|
||||
/**@brief Function for closing a transport channel.
|
||||
*
|
||||
* @note The function disables the hardware, resets internal module states, and unregisters the events
|
||||
* callback function. Can be called multiple times, also for a channel that is not opened.
|
||||
*/
|
||||
void ser_hal_transport_close(void);
|
||||
|
||||
|
||||
/**@brief Function for freeing memory allocated for an RX packet.
|
||||
*
|
||||
* @note The function should be called as a response to an event of type
|
||||
* @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED when the received data has beed processed. The function
|
||||
* frees the RX memory pointed by p_buffer. The memory, immediately or at a later time, is
|
||||
* reused by the underlying transport layer.
|
||||
*
|
||||
* @param[in] p_buffer A pointer to the beginning of the buffer that has been processed (has to be
|
||||
* the same address as provided in the event of type
|
||||
* @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED).
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success.
|
||||
* @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
|
||||
* @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer (provided address is not
|
||||
* the starting address of a buffer managed by HAL Transport layer).
|
||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. The function should be called as a response
|
||||
* to an event of type @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED.
|
||||
* @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred.
|
||||
*/
|
||||
uint32_t ser_hal_transport_rx_pkt_free(uint8_t * p_buffer);
|
||||
|
||||
|
||||
/**@brief Function for allocating memory for a TX packet.
|
||||
*
|
||||
* @param[out] pp_memory A pointer to pointer to which an address of the beginning of the
|
||||
* allocated buffer is written.
|
||||
* @param[out] p_num_of_bytes A pointer to a variable to which size in octets of the allocated
|
||||
* buffer is written.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success. Memory was allocated.
|
||||
* @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
|
||||
* @retval NRF_ERROR_NO_MEM Operation failure. No memory available.
|
||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. The function was called before calling
|
||||
* @ref ser_hal_transport_open function.
|
||||
*/
|
||||
uint32_t ser_hal_transport_tx_pkt_alloc(uint8_t ** pp_memory, uint16_t * p_num_of_bytes);
|
||||
|
||||
/**@brief Function for transmitting a packet.
|
||||
*
|
||||
* @note The function adds a packet pointed by the p_buffer parameter to a transmission queue. A buffer
|
||||
* provided to this function must be allocated by the @ref ser_hal_transport_tx_pkt_alloc function.
|
||||
*
|
||||
* @warning Completion of this method does not guarantee that actual peripheral transmission will be completed.
|
||||
*
|
||||
* @param[in] p_buffer Pointer to the buffer to transmit.
|
||||
* @param[in] num_of_bytes Number of octets to transmit. Must be more than 0.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue.
|
||||
* @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
|
||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. num_of_bytes is equal to 0.
|
||||
* @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer (provided address is not
|
||||
* the starting address of a buffer managed by HAL Transport layer).
|
||||
* @retval NRF_ERROR_DATA_SIZE Operation failure. Packet size exceeds limit.
|
||||
* @retval NRF_ERROR_BUSY Operation failure. Transmission queue is full so packet was not
|
||||
* added to the transmission queue.
|
||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. Transmittion channel was not opened by
|
||||
* @ref ser_hal_transport_open function or provided buffer was not
|
||||
* allocated by @ref ser_hal_transport_tx_pkt_alloc function.
|
||||
* @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred.
|
||||
*/
|
||||
uint32_t ser_hal_transport_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes);
|
||||
|
||||
|
||||
/**@brief Function for freeing memory allocated for a TX packet.
|
||||
*
|
||||
* @note The function frees the TX memory pointed by p_buffer. Freeing a TX buffer is possible only if
|
||||
* the buffer was allocated by @ref ser_hal_transport_tx_pkt_alloc function and transmittion
|
||||
* is not in progress. When transmittion has finished, this function is automatically called by
|
||||
* the Serialization HAL Transport layer, so the only case when this function should be used
|
||||
* from outside is when a TX buffer was allocated but a transmittion has not been started
|
||||
* (@ref ser_hal_transport_tx_pkt_send function has not been called).
|
||||
*
|
||||
* @param[in] p_buffer Pointer to the beginning of a buffer that has been allocated by
|
||||
* @ref ser_hal_transport_tx_pkt_alloc function.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success. Memory was freed.
|
||||
* @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
|
||||
* @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer (provided address is not
|
||||
* the starting address of a buffer managed by HAL Transport layer).
|
||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. Freeing a TX buffer is possible only if the
|
||||
* buffer was allocated by @ref ser_hal_transport_tx_pkt_alloc
|
||||
* function and transmittion is not in progress.
|
||||
*/
|
||||
uint32_t ser_hal_transport_tx_pkt_free(uint8_t * p_buffer);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SER_HAL_TRANSPORT_H__ */
|
||||
/** @} */
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef SER_CONFIG_5W_APP_H__
|
||||
#define SER_CONFIG_5W_APP_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SER_CONFIG_5W_APP_H__
|
||||
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef SER_PHY_CONFIG_APP_H__
|
||||
#define SER_PHY_CONFIG_APP_H__
|
||||
|
||||
#include "boards.h"
|
||||
#include "ser_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(SPI_MASTER_0_ENABLE)
|
||||
#define SER_PHY_SPI_MASTER SPI_MASTER_0
|
||||
#endif
|
||||
#if defined(SPI_MASTER_1_ENABLE)
|
||||
#define SER_PHY_SPI_MASTER SPI_MASTER_1
|
||||
#endif
|
||||
#if defined(SPI_MASTER_2_ENABLE)
|
||||
#define SER_PHY_SPI_MASTER SPI_MASTER_2
|
||||
#endif
|
||||
|
||||
#if (defined(SPI0_ENABLED) && (SPI0_ENABLED == 1)) || defined(SPI_MASTER_0_ENABLE)
|
||||
|
||||
#define SER_PHY_SPI_MASTER_INSTANCE NRF_DRV_SPI_INSTANCE(0)
|
||||
#define SER_PHY_SPI_MASTER_PIN_SCK SER_APP_SPIM0_SCK_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_MISO SER_APP_SPIM0_MISO_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_MOSI SER_APP_SPIM0_MOSI_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT SER_APP_SPIM0_SS_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST SER_APP_SPIM0_REQ_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_SLAVE_READY SER_APP_SPIM0_RDY_PIN
|
||||
|
||||
#elif (defined(SPI1_ENABLED) && (SPI1_ENABLED == 1)) || defined(SPI_MASTER_1_ENABLE)
|
||||
|
||||
#define SER_PHY_SPI_MASTER_INSTANCE NRF_DRV_SPI_INSTANCE(1)
|
||||
#define SER_PHY_SPI_MASTER_PIN_SCK SER_APP_SPIM1_SCK_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_MISO SER_APP_SPIM1_MISO_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_MOSI SER_APP_SPIM1_MOSI_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT SER_APP_SPIM1_SS_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST SER_APP_SPIM1_REQ_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_SLAVE_READY SER_APP_SPIM1_RDY_PIN
|
||||
|
||||
#elif (defined(SPI2_ENABLED) && (SPI2_ENABLED == 1)) || defined(SPI_MASTER_2_ENABLE)
|
||||
|
||||
#define SER_PHY_SPI_MASTER_INSTANCE NRF_DRV_SPI_INSTANCE(2)
|
||||
#define SER_PHY_SPI_MASTER_PIN_SCK SER_APP_SPIM2_SCK_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_MISO SER_APP_SPIM2_MISO_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_MOSI SER_APP_SPIM2_MOSI_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT SER_APP_SPIM2_SS_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST SER_APP_SPIM2_REQ_PIN
|
||||
#define SER_PHY_SPI_MASTER_PIN_SLAVE_READY SER_APP_SPIM2_RDY_PIN
|
||||
|
||||
#endif
|
||||
|
||||
#define CONN_CHIP_RESET_PIN_NO SER_CONN_CHIP_RESET_PIN /**< Pin used for reseting the connectivity. */
|
||||
|
||||
/* UART configuration */
|
||||
#define UART_IRQ_PRIORITY APP_IRQ_PRIORITY_MID
|
||||
#define SER_PHY_UART_RX SER_APP_RX_PIN
|
||||
#define SER_PHY_UART_TX SER_APP_TX_PIN
|
||||
#define SER_PHY_UART_CTS SER_APP_CTS_PIN
|
||||
#define SER_PHY_UART_RTS SER_APP_RTS_PIN
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SER_PHY_CONFIG_APP_H__
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef SER_PHY_CONFIG_CONN_H__
|
||||
#define SER_PHY_CONFIG_CONN_H__
|
||||
|
||||
#include "boards.h"
|
||||
#include "ser_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***********************************************************************************************//**
|
||||
* SER_PHY layer configuration.
|
||||
**************************************************************************************************/
|
||||
#define SER_PHY_SPI_PPI_RDY_CH 0
|
||||
#define SER_PHY_SPI_GPIOTE_RDY_CH 0
|
||||
|
||||
#ifdef NRF_SPIS0
|
||||
#define SER_PHY_SPI_SLAVE_INSTANCE 0
|
||||
#else
|
||||
#define SER_PHY_SPI_SLAVE_INSTANCE 1
|
||||
#endif
|
||||
|
||||
#define SER_PHY_SPI_SLAVE_REQ_PIN SER_CON_SPIS_REQ_PIN
|
||||
#define SER_PHY_SPI_SLAVE_RDY_PIN SER_CON_SPIS_RDY_PIN
|
||||
#define SER_PHY_SPI_SLAVE_SCK_PIN SER_CON_SPIS_SCK_PIN
|
||||
#define SER_PHY_SPI_SLAVE_MISO_PIN SER_CON_SPIS_MISO_PIN
|
||||
#define SER_PHY_SPI_SLAVE_MOSI_PIN SER_CON_SPIS_MOSI_PIN
|
||||
#define SER_PHY_SPI_SLAVE_SS_PIN SER_CON_SPIS_CSN_PIN
|
||||
|
||||
/* UART configuration */
|
||||
#define UART_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST
|
||||
|
||||
#define SER_PHY_UART_RX SER_CON_RX_PIN
|
||||
#define SER_PHY_UART_TX SER_CON_TX_PIN
|
||||
#define SER_PHY_UART_CTS SER_CON_CTS_PIN
|
||||
#define SER_PHY_UART_RTS SER_CON_RTS_PIN
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SER_PHY_CONFIG_CONN_H__
|
||||
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef SER_PHY_DEBUG_APP_H__
|
||||
#define SER_PHY_DEBUG_APP_H__
|
||||
|
||||
#ifndef SER_PHY_DEBUG_APP_ENABLE
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_REQUEST(data)
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_READY(data)
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_XFER_DONE(data)
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_API_CALL(data)
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE(data)
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_REQUEST_EDGE(data)
|
||||
#define DEBUG_EVT_SPI_MASTER_PHY_TX_PKT_SENT(data)
|
||||
#define DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_DROPPED(data)
|
||||
#define DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_RECEIVED(data)
|
||||
#define DEBUG_EVT_SPI_MASTER_PHY_BUF_REQUEST(data)
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(data)
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_XFER_PASSED(data)
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_XFER_ABORTED(data)
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_XFER_RESTARTED(data)
|
||||
|
||||
#else
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//Low level hardware events
|
||||
typedef enum
|
||||
{
|
||||
SPI_MASTER_RAW_READY,
|
||||
SPI_MASTER_RAW_REQUEST,
|
||||
SPI_MASTER_RAW_XFER_DONE,
|
||||
SPI_MASTER_RAW_API_CALL,
|
||||
SPI_MASTER_RAW_READY_EDGE,
|
||||
SPI_MASTER_RAW_REQUEST_EDGE,
|
||||
SPI_MASTER_RAW_XFER_STARTED,
|
||||
SPI_MASTER_RAW_XFER_GUARDED,
|
||||
SPI_MASTER_RAW_XFER_PASSED,
|
||||
SPI_MASTER_RAW_XFER_ABORTED,
|
||||
SPI_MASTER_RAW_XFER_RESTARTED,
|
||||
SPI_MASTER_PHY_TX_PKT_SENT,
|
||||
SPI_MASTER_PHY_BUF_REQUEST,
|
||||
SPI_MASTER_PHY_RX_PKT_RECEIVED,
|
||||
SPI_MASTER_PHY_RX_PKT_DROPPED,
|
||||
SPI_MASTER_EVT_MAX
|
||||
} spi_master_raw_evt_type_t;
|
||||
|
||||
|
||||
//Low level hardware event definition
|
||||
typedef struct
|
||||
{
|
||||
spi_master_raw_evt_type_t evt;
|
||||
uint32_t data;
|
||||
} spi_master_raw_evt_t;
|
||||
|
||||
typedef void (*spi_master_raw_callback_t)(spi_master_raw_evt_t event);
|
||||
|
||||
void debug_init(spi_master_raw_callback_t spi_master_raw_evt_callback);
|
||||
|
||||
void debug_evt(spi_master_raw_evt_type_t evt, uint32_t data);
|
||||
|
||||
|
||||
#define DEBUG_EVT(evt, data) \
|
||||
do { \
|
||||
debug_evt(evt, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_REQUEST(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_RAW_REQUEST, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_READY(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_RAW_READY, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_XFER_DONE(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_RAW_XFER_DONE, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_API_CALL(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_RAW_API_CALL, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_RAW_READY_EDGE, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_REQUEST_EDGE(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_RAW_REQUEST_EDGE, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_PHY_TX_PKT_SENT(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_PHY_TX_PKT_SENT, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_DROPPED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_PHY_RX_PKT_DROPPED, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_RECEIVED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_PHY_RX_PKT_RECEIVED, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_PHY_BUF_REQUEST(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_PHY_BUF_REQUEST, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_RAW_XFER_GUARDED, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_XFER_PASSED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_RAW_XFER_PASSED, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_XFER_ABORTED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_RAW_XFER_ABORTED, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_SPI_MASTER_RAW_XFER_RESTARTED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_MASTER_RAW_XFER_RESTARTED, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //SER_PHY_DEBUG_APP_H__
|
||||
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef SER_PHY_DEBUG_CONN_H__
|
||||
#define SER_PHY_DEBUG_CONN_H__
|
||||
|
||||
#ifndef SER_PHY_DEBUG_CONN_ENABLE
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(data);
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(data);
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(data);
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(data);
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_RAW_REQ_CLEARED(data);
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_PHY_BUF_REQUEST(data);
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_RECEIVED(data);
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_DROPPED(data);
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_SENT(data);
|
||||
|
||||
#else
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// low level hardware event types
|
||||
typedef enum
|
||||
{
|
||||
SPI_SLAVE_RAW_BUFFERS_SET,
|
||||
SPI_SLAVE_RAW_RX_XFER_DONE,
|
||||
SPI_SLAVE_RAW_TX_XFER_DONE,
|
||||
SPI_SLAVE_RAW_REQ_SET,
|
||||
SPI_SLAVE_RAW_REQ_CLEARED,
|
||||
SPI_SLAVE_PHY_BUF_REQUEST,
|
||||
SPI_SLAVE_PHY_PKT_SENT,
|
||||
SPI_SLAVE_PHY_PKT_RECEIVED,
|
||||
SPI_SLAVE_PHY_PKT_DROPPED,
|
||||
SPI_SLAVE_RAW_EVT_TYPE_MAX
|
||||
} spi_slave_raw_evt_type_t;
|
||||
|
||||
// low level hardware event definition
|
||||
typedef struct
|
||||
{
|
||||
spi_slave_raw_evt_type_t evt_type;
|
||||
uint32_t data;
|
||||
} spi_slave_raw_evt_t;
|
||||
|
||||
typedef void (*spi_slave_raw_callback_t)(spi_slave_raw_evt_t event);
|
||||
|
||||
void debug_init(spi_slave_raw_callback_t spi_slave_raw_evt_callback);
|
||||
|
||||
void debug_evt(spi_slave_raw_evt_type_t evt_type, uint32_t data);
|
||||
|
||||
#define DEBUG_EVT(evt, data) \
|
||||
do { \
|
||||
debug_evt(evt, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_SLAVE_RAW_RX_XFER_DONE, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_SLAVE_RAW_TX_XFER_DONE, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_SLAVE_RAW_BUFFERS_SET, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_SLAVE_RAW_REQ_SET, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_RAW_REQ_CLEARED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_SLAVE_RAW_REQ_CLEARED, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_PHY_BUF_REQUEST(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_SLAVE_PHY_BUF_REQUEST, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_RECEIVED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_SLAVE_PHY_PKT_RECEIVED, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_DROPPED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_SLAVE_PHY_PKT_DROPPED, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_SENT(data) \
|
||||
do { \
|
||||
DEBUG_EVT(SPI_SLAVE_PHY_PKT_SENT, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //SER_PHY_DEBUG_CONN_H__
|
||||
88
components/serialization/common/transport/ser_phy/ser_phy.c
Normal file
88
components/serialization/common/transport/ser_phy/ser_phy.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "ser_phy.h"
|
||||
#include "app_error.h"
|
||||
|
||||
|
||||
__weak uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
|
||||
{
|
||||
/* A function stub. Function should be implemented according to ser_phy.h API. */
|
||||
APP_ERROR_CHECK_BOOL(false);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
__weak uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
|
||||
{
|
||||
/* A function stub. Function should be implemented according to ser_phy.h API. */
|
||||
APP_ERROR_CHECK_BOOL(false);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
__weak uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
|
||||
{
|
||||
/* A function stub. Function should be implemented according to ser_phy.h API. */
|
||||
APP_ERROR_CHECK_BOOL(false);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
__weak void ser_phy_close(void)
|
||||
{
|
||||
/* A function stub. Function should be implemented according to ser_phy.h API. */
|
||||
APP_ERROR_CHECK_BOOL(false);
|
||||
}
|
||||
|
||||
|
||||
__weak void ser_phy_interrupts_enable(void)
|
||||
{
|
||||
/* A function stub. Function should be implemented according to ser_phy.h API. */
|
||||
APP_ERROR_CHECK_BOOL(false);
|
||||
}
|
||||
|
||||
|
||||
__weak void ser_phy_interrupts_disable(void)
|
||||
{
|
||||
/* A function stub. Function should be implemented according to ser_phy.h API. */
|
||||
APP_ERROR_CHECK_BOOL(false);
|
||||
}
|
||||
|
||||
|
||||
308
components/serialization/common/transport/ser_phy/ser_phy.h
Normal file
308
components/serialization/common/transport/ser_phy/ser_phy.h
Normal file
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/** @file
|
||||
*
|
||||
* @defgroup ser_phy Serialization PHY
|
||||
* @{
|
||||
* @ingroup ble_sdk_lib_serialization
|
||||
*
|
||||
* @brief PHY layer for serialization.
|
||||
*
|
||||
* @details The @ref ser_phy library declares functions and definitions of data structures and
|
||||
* identifiers (typedef enum) that are used as API of the serialization PHY layer.
|
||||
*
|
||||
* \par Rationale
|
||||
* Each specific PHY layer (SPI, I2C, UART, low power UART etc.) should provide the same API. This
|
||||
* allows the layer above (the HAL Transport layer), which is responsible for controlling the PHY
|
||||
* layer, memory management, CRC, retransmission etc., to be hardware independent.
|
||||
*
|
||||
*
|
||||
* \par Interlayer communication and control
|
||||
* The PHY layer is controlled by the HAL transport layer by calling functions declared in
|
||||
* the @ref ser_phy library.
|
||||
*
|
||||
* @par
|
||||
* The PHY layer communicates events to the HAL transport layer by calling a callback function.
|
||||
* A handler to this function is passed in the @ref ser_phy_open function. This callback function
|
||||
* should be called with a parameter of type @ref ser_phy_evt_t, filled accordingly to an event to be
|
||||
* passed. Types of supported events are defined in @ref ser_phy_evt_type_t.
|
||||
*
|
||||
* @par
|
||||
* For example, to pass an event indicating that an RX packet has been successfully received, first a
|
||||
* struct of type @ref ser_phy_evt_t must be filled:
|
||||
* @code
|
||||
* ser_phy_evt_t phy_evt;
|
||||
* phy_evt.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
|
||||
* phy_evt.evt_params.rx_pkt_received.p_buffer = (pointer to the RX buffer);
|
||||
* phy_evt.evt_params.rx_pkt_received.num_of_bytes = (number of received bytes);
|
||||
* @endcode
|
||||
* Then, the callback function must be called:
|
||||
* @code
|
||||
* events_handler(phy_evt);
|
||||
* @endcode
|
||||
* All functions declared in the @ref ser_phy file (ser_phy.h) must be implemented. Some events specified in
|
||||
* @ref ser_phy_evt_type_t are optional to implement.
|
||||
*
|
||||
* \par Transmitting a packet
|
||||
* Each PHY layer is responsible for adding the PHY header to a packet to be sent. This header
|
||||
* consists of a 16-bit field that carries the packet length (the uint16_encode function defined in
|
||||
* app_util.h should be used to ensure endianness independence). A pointer to a packet to be sent
|
||||
* and length of the packet are parameters of the @ref ser_phy_tx_pkt_send function. When a packet
|
||||
* has been transmitted, an event of type @ref SER_PHY_EVT_TX_PKT_SENT should be emitted.
|
||||
*
|
||||
* \image html ser_phy_transport_tx.svg "TX - interlayer communication"
|
||||
*
|
||||
* \par Receiving a packet
|
||||
* The PHY layer should be able to store only the PHY header (16-bit field carrying the packet
|
||||
* length). After the PHY header has been received, the transmission is stopped and the PHY
|
||||
* layer must send a request to the HAL transport layer for memory to store the packet - an event
|
||||
* of type @ref SER_PHY_EVT_RX_BUF_REQUEST with event parameters defined in
|
||||
* @ref ser_phy_evt_rx_buf_request_params_t (the uint16_decode function defined in app_util.h should
|
||||
* be used for header decoding to ensure endianness independence). The transmission should be
|
||||
* resumed when the @ref ser_phy_rx_buf_set function has been called.
|
||||
*
|
||||
* @par
|
||||
* When the @ref ser_phy_rx_buf_set function parameter equals NULL, there is not
|
||||
* enough memory to store the packet. However, the packet will be received to a dummy location to
|
||||
* ensure continuous communication. After receiving has finished, an event of type
|
||||
* @ref SER_PHY_EVT_RX_PKT_DROPPED is generated.
|
||||
*
|
||||
* \image html ser_phy_transport_rx_dropped.svg "RX dropping - interlayer communication"
|
||||
*
|
||||
* @par
|
||||
* When the @ref ser_phy_rx_buf_set function parameter is different than NULL, the packet is
|
||||
* received to a buffer pointed to by it. After receiving has finished, an event of type
|
||||
* @ref SER_PHY_EVT_RX_PKT_RECEIVED is generated with event parameters defined in
|
||||
* @ref ser_phy_evt_rx_pkt_received_params_t.
|
||||
*
|
||||
* \image html ser_phy_transport_rx_received.svg "RX - interlayer communication"
|
||||
*
|
||||
* \par PHY layer errors
|
||||
* PHY layer errors can be signaled by an event of type @ref SER_PHY_EVT_RX_OVERFLOW_ERROR or
|
||||
* @ref SER_PHY_EVT_TX_OVERREAD_ERROR or @ref SER_PHY_EVT_HW_ERROR with event parameters defined in
|
||||
* @ref ser_phy_evt_hw_error_params_t.
|
||||
*
|
||||
* @par Available PHY layers
|
||||
* The following PHY layers are available:
|
||||
* - @ref ser_phy_spi_page
|
||||
* - @ref ser_phy_spi_5W_page
|
||||
* - @ref ser_phy_uart_page
|
||||
* - @ref ser_phy_uart_hci_page
|
||||
* <!-- - @ref ser_phy_usb_hci_page -->
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SER_PHY_H__
|
||||
#define SER_PHY_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@brief Serialization PHY module event types. */
|
||||
typedef enum
|
||||
{
|
||||
SER_PHY_EVT_TX_PKT_SENT = 0, /**< Obligatory to implement. An event indicating that a TX packet
|
||||
* has been transmitted. */
|
||||
SER_PHY_EVT_RX_BUF_REQUEST, /**< Obligatory to implement. An event indicating that the PHY layer
|
||||
* needs a buffer for an RX packet. The PHY flow should be blocked
|
||||
* until the @ref ser_phy_rx_buf_set function is called. */
|
||||
SER_PHY_EVT_RX_PKT_RECEIVED, /**< Obligatory to implement. An event indicating that an RX packet
|
||||
* has been successfully received. */
|
||||
SER_PHY_EVT_RX_PKT_DROPPED, /**< Obligatory to implement. An event indicating that the RX packet
|
||||
* receiving has been finished but the packet was discarded because
|
||||
* it was longer than available the buffer. */
|
||||
|
||||
SER_PHY_EVT_RX_OVERFLOW_ERROR, /**< Optional to implement. An event indicating that more
|
||||
* information has been transmitted than the PHY module could
|
||||
* handle. */
|
||||
SER_PHY_EVT_TX_OVERREAD_ERROR, /**< Optional to implement. An event indicating that the PHY module
|
||||
* was forced to transmit more information than possessed. */
|
||||
SER_PHY_EVT_HW_ERROR, /**< Optional to implement. An event indicating a hardware error
|
||||
* in the PHY module. */
|
||||
SER_PHY_EVT_TYPE_MAX /**< Enumeration upper bound. */
|
||||
} ser_phy_evt_type_t;
|
||||
|
||||
|
||||
/**@brief A struct containing parameters of event of type @ref SER_PHY_EVT_RX_BUF_REQUEST. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t num_of_bytes; /**< Length of a buffer in octets that the layer above the PHY module should
|
||||
* deliver, so that the PHY module can receive a packet. */
|
||||
} ser_phy_evt_rx_buf_request_params_t;
|
||||
|
||||
|
||||
/**@brief A struct containing parameters of event of type @ref SER_PHY_EVT_RX_PKT_RECEIVED. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t * p_buffer; /**< Pointer to a buffer containing the received packet. */
|
||||
uint16_t num_of_bytes; /**< Length of the received packet in octets. */
|
||||
} ser_phy_evt_rx_pkt_received_params_t;
|
||||
|
||||
|
||||
/**@brief A struct containing parameters of event of type @ref SER_PHY_EVT_HW_ERROR. */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t error_code; /**< Hardware error code - specific for a microcontroller. */
|
||||
uint8_t * p_buffer; /**< Pointer to the buffer that was processed when error occured. */
|
||||
} ser_phy_evt_hw_error_params_t;
|
||||
|
||||
|
||||
/**@brief A struct containing events from a Serialization PHY module.
|
||||
*
|
||||
* @note Some events do not have parameters, then whole information is contained in the evt_type.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ser_phy_evt_type_t evt_type; /**< Type of event. */
|
||||
|
||||
union /**< Union alternative identified by evt_type in enclosing struct. */
|
||||
{
|
||||
/** Parameters of event of type @ref SER_PHY_EVT_RX_BUF_REQUEST. */
|
||||
ser_phy_evt_rx_buf_request_params_t rx_buf_request;
|
||||
/** Parameters of event of type @ref SER_PHY_EVT_RX_PKT_RECEIVED. */
|
||||
ser_phy_evt_rx_pkt_received_params_t rx_pkt_received;
|
||||
/** Parameters of the event of type @ref SER_PHY_EVT_HW_ERROR. */
|
||||
ser_phy_evt_hw_error_params_t hw_error;
|
||||
} evt_params;
|
||||
} ser_phy_evt_t;
|
||||
|
||||
|
||||
/**@brief A type of generic callback function handler to be used by all PHY module events.
|
||||
*
|
||||
* @param[in] event Serialization PHY module event.
|
||||
*/
|
||||
typedef void (*ser_phy_events_handler_t)(ser_phy_evt_t event);
|
||||
|
||||
|
||||
/**@brief Function for opening and initializing the PHY module.
|
||||
*
|
||||
* @note The function initializes hardware and internal module states, and registers callback
|
||||
* function to be used by all PHY module events.
|
||||
*
|
||||
* @warning If the function has been already called, the function @ref ser_phy_close has to be
|
||||
* called before ser_phy_open can be called again.
|
||||
*
|
||||
* @param[in] events_handler Generic callback function handler to be used by all PHY module
|
||||
* events.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success.
|
||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called.
|
||||
* To call it again, the function @ref ser_phy_close has to be
|
||||
* called first.
|
||||
* @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
|
||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. Hardware initialization parameters are not
|
||||
* supported.
|
||||
*/
|
||||
uint32_t ser_phy_open(ser_phy_events_handler_t events_handler);
|
||||
|
||||
|
||||
/**@brief Function for transmitting a packet.
|
||||
*
|
||||
* @note The function adds a packet pointed by p_buffer parameter to a transmission queue and
|
||||
* schedules generation of an event of type @ref SER_PHY_EVT_TX_PKT_SENT upon transmission
|
||||
* completion.
|
||||
*
|
||||
* @param[in] p_buffer Pointer to a buffer to transmit.
|
||||
* @param[in] num_of_bytes Number of octets to transmit. Must be more than 0.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue
|
||||
* and event will be send upon transmission completion.
|
||||
* @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
|
||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. The num_of_bytes parameter equal to 0.
|
||||
* @retval NRF_ERROR_BUSY Operation failure. Transmitting of a packet in progress.
|
||||
*/
|
||||
uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes);
|
||||
|
||||
|
||||
/**@brief Function for setting an RX buffer and enabling reception of data (the PHY flow).
|
||||
*
|
||||
* @note The function has to be called as a response to an event of type
|
||||
* @ref SER_PHY_EVT_RX_BUF_REQUEST. The function sets an RX buffer and enables reception of
|
||||
* data (enables the PHY flow).
|
||||
* Size of a buffer pointed by the p_buffer parameter should be at least equal to the
|
||||
* num_of_bytes parameter passed within the event (@ref ser_phy_evt_rx_buf_request_params_t),
|
||||
* or p_buffer should be equal to NULL if there is not enough memory.
|
||||
* When p_buffer is different from NULL and num_of_bytes octets have been received, an event of
|
||||
* type @ref SER_PHY_EVT_RX_PKT_RECEIVED is generated
|
||||
* (@ref ser_phy_evt_rx_pkt_received_params_t).
|
||||
* When p_buffer is equal to NULL, data is received to dummy location to ensure continuous
|
||||
* communication. Then, if num_of_bytes octets have been received, an event of type
|
||||
* @ref SER_PHY_EVT_RX_PKT_DROPPED is generated.
|
||||
*
|
||||
* @param[in] p_buffer Pointer to an RX buffer in which to receive.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success.
|
||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. A buffer was set without request.
|
||||
*/
|
||||
uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer);
|
||||
|
||||
|
||||
/**@brief Function for closing the PHY module.
|
||||
*
|
||||
* @note The function disables hardware, resets internal module states, and unregisters the events
|
||||
* callback function.
|
||||
*/
|
||||
void ser_phy_close(void);
|
||||
|
||||
|
||||
/**@brief Function for enabling the PHY module interrupts.
|
||||
*
|
||||
* @note The function enables all interrupts that are used by the PHY module (and only those).
|
||||
*/
|
||||
void ser_phy_interrupts_enable(void);
|
||||
|
||||
|
||||
/**@brief Function for disabling the PHY module interrupts.
|
||||
*
|
||||
* @note The function disables all interrupts that are used by the PHY module (and only those).
|
||||
*/
|
||||
void ser_phy_interrupts_disable(void);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SER_PHY_H__ */
|
||||
/** @} */
|
||||
1768
components/serialization/common/transport/ser_phy/ser_phy_hci.c
Normal file
1768
components/serialization/common/transport/ser_phy/ser_phy_hci.c
Normal file
File diff suppressed because it is too large
Load Diff
185
components/serialization/common/transport/ser_phy/ser_phy_hci.h
Normal file
185
components/serialization/common/transport/ser_phy/ser_phy_hci.h
Normal file
@@ -0,0 +1,185 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/** @file
|
||||
*
|
||||
* @defgroup ser_phy_hci HCI Serialization PHY
|
||||
* @{
|
||||
* @ingroup ble_sdk_lib_serialization
|
||||
*
|
||||
* @brief HCI PHY layer for serialization.
|
||||
*
|
||||
* @details This file contains declarations of functions and definitions of data structures and
|
||||
* identifiers (typedef enum) used as API of the serialization HCI PHY layer.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SER_PHY_HCI_H__
|
||||
#define SER_PHY_HCI_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@brief Serialization PHY HCI module events types. */
|
||||
typedef enum
|
||||
{
|
||||
SER_PHY_HCI_SLIP_EVT_PKT_SENT = 0, /**< An event indicating that packet has been transmitted. */
|
||||
SER_PHY_HCI_SLIP_EVT_ACK_SENT, /**< An event indicating that ack packet has been transmitted. */
|
||||
SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED, /**< An event indicating that packet has been received. */
|
||||
SER_PHY_HCI_SLIP_EVT_HW_ERROR, /**< An event indicating a hardware error in PHY HCI module. */
|
||||
SER_PHY_HCI_SLIP_EVT_TYPE_MAX /**< Enumeration upper bound. */
|
||||
} ser_phy_hci_slip_evt_type_t;
|
||||
|
||||
/**@brief Struct representing a PHY HCI packet. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t * p_buffer; /**< Pointer to a buffer containing a packet. */
|
||||
uint16_t num_of_bytes; /**< Length of a packet in octets. */
|
||||
} ser_phy_hci_pkt_params_t;
|
||||
|
||||
|
||||
/**@brief Struct containing parameters of event of type @ref SER_PHY_HCI_SLIP_EVT_HW_ERROR. */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t error_code; /**< Hardware error code - specific for a microcontroller. */
|
||||
} ser_phy_hci_evt_hw_error_params_t;
|
||||
|
||||
|
||||
/**@brief Struct containing events from the Serialization PHY module.
|
||||
*
|
||||
* @note Some events do not have parameters, then the whole information is contained in the evt_type.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ser_phy_hci_slip_evt_type_t evt_type; /**< Type of an event. */
|
||||
union /**< Union alternative identified by evt_type in the enclosing struct. */
|
||||
{
|
||||
/** Parameters of event of type @ref SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED. */
|
||||
ser_phy_hci_pkt_params_t received_pkt;
|
||||
/** Parameters of event of type @ref SER_PHY_HCI_SLIP_EVT_HW_ERROR. */
|
||||
ser_phy_hci_evt_hw_error_params_t hw_error;
|
||||
} evt_params;
|
||||
} ser_phy_hci_slip_evt_t;
|
||||
|
||||
|
||||
/**@brief Type of generic callback function handler to be used by all PHY HCI events.
|
||||
*
|
||||
* @param[in] event Serialization PHY HCI module event.
|
||||
*/
|
||||
typedef void (*ser_phy_hci_slip_event_handler_t)(ser_phy_hci_slip_evt_t *p_event);
|
||||
|
||||
/**@brief Function for opening and initializing a HCI SLIP PHY module.
|
||||
*
|
||||
* @note The function initializes hardware and internal module states and registers callback
|
||||
* function to be used by all PHY HCI module events.
|
||||
*
|
||||
* @warning If the function has been already called, the function @ref ser_phy_hci_slip_close has to be
|
||||
* called before ser_phy_hci_slip_open can be called again.
|
||||
*
|
||||
* @param[in] events_handler Generic callback function handler to be used by all PHY HCI module
|
||||
* events.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success.
|
||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called.
|
||||
* To call it again, the function @ref ser_phy_hci_slip_close has to
|
||||
* be called first.
|
||||
* @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
|
||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. Hardware initialization parameters are not
|
||||
* supported.
|
||||
*/
|
||||
uint32_t ser_phy_hci_slip_open(ser_phy_hci_slip_event_handler_t events_handler);
|
||||
|
||||
/**@brief Function for resetting the module.*/
|
||||
void ser_phy_hci_slip_reset(void);
|
||||
|
||||
/**@brief A function for transmitting a HCI SLIP packet.
|
||||
*
|
||||
* @note The function adds a packet pointed by p_buffer parameter to a transmission queue and
|
||||
* schedules generation of an event of type @ref SER_PHY_HCI_SLIP_EVT_PKT_SENT upon transmission
|
||||
* completion.
|
||||
*
|
||||
* @param[in] p_header Pointer to ser_phy_hci_pkt_params_t structure representing packet header.
|
||||
* @param[in] p_payload Pointer to ser_phy_hci_pkt_params_t structure representing packet payload.
|
||||
* @param[in] p_crc Pointer to ser_phy_hci_pkt_params_t structure representing packet crc.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue
|
||||
* and event will be sent upon transmission completion.
|
||||
* @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied in p_header parameter.
|
||||
* NULL pointer is allowed for p_payload and p_crc parameters.
|
||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. Number of bytes to be sent equals 0.
|
||||
* @retval NRF_ERROR_BUSY Operation failure. Transmitting of a packet in progress.
|
||||
*/
|
||||
uint32_t ser_phy_hci_slip_tx_pkt_send(const ser_phy_hci_pkt_params_t * p_header,
|
||||
const ser_phy_hci_pkt_params_t * p_payload,
|
||||
const ser_phy_hci_pkt_params_t * p_crc);
|
||||
|
||||
|
||||
/**@brief A function for freeing an RX buffer.
|
||||
*
|
||||
* @note The function has to be called as a response to event @ref SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED
|
||||
* when an RX packet has been processed. The function frees the RX buffer and therefore enables
|
||||
* reception of next incoming data.
|
||||
|
||||
* @param[in] p_buffer Pointer to an RX buffer which must be freed.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success.
|
||||
* @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
|
||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. A buffer was already free.
|
||||
*/
|
||||
uint32_t ser_phy_hci_slip_rx_buf_free(uint8_t * p_buffer);
|
||||
|
||||
|
||||
/**@brief A function for closing a PHY HCI module.
|
||||
*
|
||||
* @note The function disables hardware, resets internal module states, and unregisters the events
|
||||
* callback function.
|
||||
*/
|
||||
void ser_phy_hci_slip_close(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SER_PHY_HCI_H__ */
|
||||
/** @} */
|
||||
@@ -0,0 +1,702 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "ser_phy_hci.h"
|
||||
#include "ser_config.h"
|
||||
#ifdef SER_CONNECTIVITY
|
||||
#include "ser_phy_config_conn.h"
|
||||
#else
|
||||
#include "ser_phy_config_app.h"
|
||||
#endif
|
||||
#include "nrf_drv_uart.h"
|
||||
#include "app_error.h"
|
||||
#include "app_util_platform.h"
|
||||
|
||||
#define APP_SLIP_END 0xC0 /**< SLIP code for identifying the beginning and end of a packet frame.. */
|
||||
#define APP_SLIP_ESC 0xDB /**< SLIP escape code. This code is used to specify that the following character is specially encoded. */
|
||||
#define APP_SLIP_ESC_END 0xDC /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xC0.. */
|
||||
#define APP_SLIP_ESC_ESC 0xDD /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xDB. */
|
||||
|
||||
#define HDR_SIZE 4
|
||||
#define CRC_SIZE 2
|
||||
#define PKT_SIZE (SER_HAL_TRANSPORT_MAX_PKT_SIZE + HDR_SIZE + CRC_SIZE)
|
||||
|
||||
static const nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0);
|
||||
static const nrf_drv_uart_config_t m_uart_config = {
|
||||
.pseltxd = SER_PHY_UART_TX,
|
||||
.pselrxd = SER_PHY_UART_RX,
|
||||
.pselrts = SER_PHY_UART_RTS,
|
||||
.pselcts = SER_PHY_UART_CTS,
|
||||
.p_context = NULL,
|
||||
.interrupt_priority = UART_IRQ_PRIORITY,
|
||||
#if defined(UARTE_PRESENT) && defined(UART_PRESENT)
|
||||
.use_easy_dma = true,
|
||||
#endif
|
||||
// These values are common for application and connectivity, they are
|
||||
// defined in "ser_config.h".
|
||||
.hwfc = SER_PHY_UART_FLOW_CTRL,
|
||||
.parity = SER_PHY_UART_PARITY,
|
||||
.baudrate = (nrf_uart_baudrate_t)SER_PHY_UART_BAUDRATE
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
ser_phy_hci_pkt_params_t header;
|
||||
ser_phy_hci_pkt_params_t payload;
|
||||
ser_phy_hci_pkt_params_t crc;
|
||||
} ser_phy_hci_slip_pkt_t;
|
||||
static ser_phy_hci_slip_pkt_t m_tx_curr_packet;
|
||||
static ser_phy_hci_slip_pkt_t m_tx_next_packet;
|
||||
|
||||
static ser_phy_hci_slip_evt_t m_ser_phy_hci_slip_event;
|
||||
static ser_phy_hci_slip_event_handler_t m_ser_phy_hci_slip_event_handler; /**< Event handler for upper layer */
|
||||
|
||||
static uint8_t m_tx_buf0[SER_PHY_HCI_SLIP_TX_BUF_SIZE];
|
||||
static uint8_t m_tx_buf1[SER_PHY_HCI_SLIP_TX_BUF_SIZE];
|
||||
static uint8_t * mp_tx_buf;
|
||||
static uint8_t m_tx_bytes;
|
||||
static enum {
|
||||
PHASE_BEGIN,
|
||||
PHASE_HEADER,
|
||||
PHASE_PAYLOAD,
|
||||
PHASE_CRC,
|
||||
PHASE_ACK_END,
|
||||
// The following three elements have to have consecutive values,
|
||||
// 'tx_buf_fill()' relies on this.
|
||||
PHASE_PACKET_END,
|
||||
PHASE_PRE_IDLE = PHASE_PACKET_END + 1,
|
||||
PHASE_IDLE = PHASE_PRE_IDLE + 1
|
||||
} volatile m_tx_phase;
|
||||
static bool volatile m_tx_in_progress;
|
||||
static bool volatile m_tx_pending;
|
||||
|
||||
#define NO_EVENT SER_PHY_HCI_SLIP_EVT_TYPE_MAX
|
||||
static ser_phy_hci_slip_evt_type_t m_tx_evt_type;
|
||||
static ser_phy_hci_slip_evt_type_t m_tx_pending_evt_type;
|
||||
|
||||
static uint8_t m_small_buffer[HDR_SIZE];
|
||||
static uint8_t m_big_buffer[PKT_SIZE];
|
||||
|
||||
static uint8_t * mp_small_buffer = NULL;
|
||||
static uint8_t * mp_big_buffer = NULL;
|
||||
static uint8_t * mp_buffer = NULL;
|
||||
|
||||
static uint8_t m_rx_buf[1];
|
||||
static bool m_rx_escape;
|
||||
|
||||
|
||||
// The function returns false to signal that no more bytes can be passed to be
|
||||
// sent (put into the TX buffer) until UART transmission is done.
|
||||
static bool tx_buf_put(uint8_t data_byte)
|
||||
{
|
||||
ASSERT(m_tx_bytes < SER_PHY_HCI_SLIP_TX_BUF_SIZE);
|
||||
|
||||
mp_tx_buf[m_tx_bytes] = data_byte;
|
||||
++m_tx_bytes;
|
||||
|
||||
bool flush = false;
|
||||
ser_phy_hci_slip_evt_type_t slip_evt_type = NO_EVENT;
|
||||
if (m_tx_phase == PHASE_ACK_END)
|
||||
{
|
||||
// Send buffer, then signal that an acknowledge packet has been sent.
|
||||
flush = true;
|
||||
slip_evt_type = SER_PHY_HCI_SLIP_EVT_ACK_SENT;
|
||||
}
|
||||
else if (m_tx_phase == PHASE_PACKET_END)
|
||||
{
|
||||
// Send buffer, then signal that a packet with payload has been sent.
|
||||
flush = true;
|
||||
slip_evt_type = SER_PHY_HCI_SLIP_EVT_PKT_SENT;
|
||||
}
|
||||
else if (m_tx_bytes >= SER_PHY_HCI_SLIP_TX_BUF_SIZE)
|
||||
{
|
||||
// Send buffer (because it is filled up), but don't signal anything,
|
||||
// since the packet sending is not complete yet.
|
||||
flush = true;
|
||||
}
|
||||
|
||||
if (flush)
|
||||
{
|
||||
// If some TX transfer is being done at the moment, a new one cannot be
|
||||
// started, it must be scheduled to be performed later.
|
||||
if (m_tx_in_progress)
|
||||
{
|
||||
m_tx_pending_evt_type = slip_evt_type;
|
||||
m_tx_pending = true;
|
||||
// No more buffers available, can't continue filling.
|
||||
return false;
|
||||
}
|
||||
|
||||
m_tx_in_progress = true;
|
||||
m_tx_evt_type = slip_evt_type;
|
||||
APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, mp_tx_buf, m_tx_bytes));
|
||||
|
||||
// Switch to the second buffer.
|
||||
mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0;
|
||||
m_tx_bytes = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tx_buf_fill(void)
|
||||
{
|
||||
static ser_phy_hci_pkt_params_t * mp_tx_data = NULL;
|
||||
static uint32_t m_tx_index;
|
||||
bool can_continue = true;
|
||||
|
||||
do {
|
||||
static uint8_t tx_escaped_data = 0;
|
||||
|
||||
if (tx_escaped_data != 0)
|
||||
{
|
||||
can_continue = tx_buf_put(tx_escaped_data);
|
||||
tx_escaped_data = 0;
|
||||
++m_tx_index;
|
||||
}
|
||||
else switch (m_tx_phase)
|
||||
{
|
||||
case PHASE_BEGIN:
|
||||
can_continue = tx_buf_put(APP_SLIP_END);
|
||||
mp_tx_data = &m_tx_curr_packet.header;
|
||||
m_tx_index = 0;
|
||||
m_tx_phase = PHASE_HEADER;
|
||||
tx_escaped_data = 0;
|
||||
break;
|
||||
|
||||
case PHASE_ACK_END:
|
||||
case PHASE_PACKET_END:
|
||||
can_continue = tx_buf_put(APP_SLIP_END);
|
||||
|
||||
// [this is needed for the '++m_tx_phase;' below]
|
||||
m_tx_phase = PHASE_PACKET_END;
|
||||
// no break, intentional fall-through
|
||||
|
||||
case PHASE_PRE_IDLE:
|
||||
// In PHASE_PRE_IDLE the sending process is almost finished, only
|
||||
// the NRF_DRV_UART_EVT_TX_DONE event is needed before it can switch
|
||||
// to PHASE_IDLE. But during this waiting a new packet may appear
|
||||
// (i.e. 'ser_phy_hci_slip_tx_pkt_send()' may be called), hence
|
||||
// the following pointer must be checked before switching the phase,
|
||||
// just like right after writing whole packet to buffer (i.e. in
|
||||
// PHASE_PACKET_END). Therefore, the following code is common for
|
||||
// these two cases.
|
||||
if (m_tx_next_packet.header.p_buffer != NULL)
|
||||
{
|
||||
m_tx_curr_packet = m_tx_next_packet;
|
||||
m_tx_next_packet.header.p_buffer = NULL;
|
||||
|
||||
m_tx_phase = PHASE_BEGIN;
|
||||
break;
|
||||
}
|
||||
// Go to the next phase:
|
||||
// PHASE_PACKET_END -> PHASE_PRE_IDLE
|
||||
// PHASE_PRE_IDLE -> PHASE_IDLE
|
||||
++m_tx_phase;
|
||||
return;
|
||||
|
||||
default:
|
||||
if (m_tx_index < mp_tx_data->num_of_bytes)
|
||||
{
|
||||
ASSERT(mp_tx_data->p_buffer != NULL);
|
||||
uint8_t data = mp_tx_data->p_buffer[m_tx_index];
|
||||
|
||||
if (data == APP_SLIP_END)
|
||||
{
|
||||
data = APP_SLIP_ESC;
|
||||
tx_escaped_data = APP_SLIP_ESC_END;
|
||||
}
|
||||
else if (data == APP_SLIP_ESC)
|
||||
{
|
||||
tx_escaped_data = APP_SLIP_ESC_ESC;
|
||||
}
|
||||
else
|
||||
{
|
||||
++m_tx_index;
|
||||
}
|
||||
can_continue = tx_buf_put(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
mp_tx_data->p_buffer = NULL;
|
||||
|
||||
if (m_tx_phase == PHASE_HEADER)
|
||||
{
|
||||
if (m_tx_curr_packet.payload.p_buffer == NULL)
|
||||
{
|
||||
// No payload -> ACK packet.
|
||||
m_tx_phase = PHASE_ACK_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
mp_tx_data = &m_tx_curr_packet.payload;
|
||||
m_tx_index = 0;
|
||||
m_tx_phase = PHASE_PAYLOAD;
|
||||
}
|
||||
}
|
||||
else if (m_tx_phase == PHASE_PAYLOAD)
|
||||
{
|
||||
if (m_tx_curr_packet.crc.p_buffer == NULL)
|
||||
{
|
||||
// Packet without CRC.
|
||||
m_tx_phase = PHASE_PACKET_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
mp_tx_data = &m_tx_curr_packet.crc;
|
||||
m_tx_index = 0;
|
||||
m_tx_phase = PHASE_CRC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(m_tx_phase == PHASE_CRC);
|
||||
m_tx_phase = PHASE_PACKET_END;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (can_continue);
|
||||
}
|
||||
|
||||
uint32_t ser_phy_hci_slip_tx_pkt_send(const ser_phy_hci_pkt_params_t * p_header,
|
||||
const ser_phy_hci_pkt_params_t * p_payload,
|
||||
const ser_phy_hci_pkt_params_t * p_crc)
|
||||
{
|
||||
if (p_header == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
CRITICAL_REGION_ENTER();
|
||||
|
||||
// If some packet is already transmitted, schedule this new one to be sent
|
||||
// as next. A critical region is needed here to ensure that the transmission
|
||||
// won't finish before the following assignments are done.
|
||||
if (m_tx_phase != PHASE_IDLE)
|
||||
{
|
||||
m_tx_next_packet.header = *p_header;
|
||||
|
||||
if (p_payload == NULL)
|
||||
{
|
||||
m_tx_next_packet.payload.p_buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tx_next_packet.payload = *p_payload;
|
||||
}
|
||||
|
||||
if (p_crc == NULL)
|
||||
{
|
||||
m_tx_next_packet.crc.p_buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tx_next_packet.crc = *p_crc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tx_curr_packet.header = *p_header;
|
||||
|
||||
if (p_payload == NULL)
|
||||
{
|
||||
m_tx_curr_packet.payload.p_buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tx_curr_packet.payload = *p_payload;
|
||||
}
|
||||
|
||||
if (p_crc == NULL)
|
||||
{
|
||||
m_tx_curr_packet.crc.p_buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tx_curr_packet.crc = *p_crc;
|
||||
}
|
||||
|
||||
m_tx_phase = PHASE_BEGIN;
|
||||
tx_buf_fill();
|
||||
}
|
||||
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
/* Function returns false when last byte in packet is detected.*/
|
||||
static bool slip_decode(uint8_t * p_received_byte)
|
||||
{
|
||||
switch (*p_received_byte)
|
||||
{
|
||||
case APP_SLIP_END:
|
||||
return false;
|
||||
|
||||
case APP_SLIP_ESC:
|
||||
m_rx_escape = true;
|
||||
break;
|
||||
|
||||
case APP_SLIP_ESC_END:
|
||||
|
||||
if (m_rx_escape == true)
|
||||
{
|
||||
m_rx_escape = false;
|
||||
*p_received_byte = APP_SLIP_END;
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_SLIP_ESC_ESC:
|
||||
|
||||
if (m_rx_escape == true)
|
||||
{
|
||||
m_rx_escape = false;
|
||||
*p_received_byte = APP_SLIP_ESC;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Normal character - decoding not needed*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void ser_phi_hci_rx_byte(uint8_t rx_byte)
|
||||
{
|
||||
static bool rx_sync = false;
|
||||
uint8_t received_byte = rx_byte;
|
||||
static bool big_buff_in_use = false;
|
||||
static uint32_t m_rx_index;
|
||||
/* Test received byte for SLIP packet start: 0xC0*/
|
||||
if (!rx_sync)
|
||||
{
|
||||
if (received_byte == APP_SLIP_END)
|
||||
{
|
||||
m_rx_index = 0;
|
||||
rx_sync = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Additional check needed in case rx_sync flag was set by end of previous packet*/
|
||||
if ((m_rx_index) == 0 && (received_byte == APP_SLIP_END))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if small (ACK) buffer is available*/
|
||||
if ((mp_small_buffer != NULL) && (big_buff_in_use == false))
|
||||
{
|
||||
if (m_rx_index == 0)
|
||||
{
|
||||
mp_buffer = mp_small_buffer;
|
||||
}
|
||||
|
||||
/* Check if switch between small and big buffer is needed*/
|
||||
if (m_rx_index == sizeof (m_small_buffer) && received_byte != APP_SLIP_END)
|
||||
{
|
||||
/* Check if big (PKT) buffer is available*/
|
||||
if (mp_big_buffer != NULL)
|
||||
{
|
||||
/* Switch to big buffer*/
|
||||
memcpy(m_big_buffer, m_small_buffer, sizeof (m_small_buffer));
|
||||
mp_buffer = m_big_buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Small buffer is too small and big buffer not available - cannot continue reception*/
|
||||
rx_sync = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if big buffer is full */
|
||||
if ((m_rx_index >= PKT_SIZE) && (received_byte != APP_SLIP_END))
|
||||
{
|
||||
/* Do not notify upper layer - the packet is too big and cannot be handled by slip */
|
||||
rx_sync = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Decode byte. Will return false when it is 0xC0 - end of packet*/
|
||||
if (slip_decode(&received_byte))
|
||||
{
|
||||
/* Write Rx byte only if it is not escape char */
|
||||
if (!m_rx_escape)
|
||||
{
|
||||
mp_buffer[m_rx_index++] = received_byte;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset pointers to signalise buffers are locked waiting for upper layer */
|
||||
if (mp_buffer == mp_small_buffer)
|
||||
{
|
||||
mp_small_buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
mp_big_buffer = NULL;
|
||||
}
|
||||
/* Report packet reception end*/
|
||||
m_ser_phy_hci_slip_event.evt_type =
|
||||
SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED;
|
||||
m_ser_phy_hci_slip_event.evt_params.received_pkt.p_buffer = mp_buffer;
|
||||
m_ser_phy_hci_slip_event.evt_params.received_pkt.num_of_bytes = m_rx_index;
|
||||
m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
|
||||
|
||||
rx_sync = false;
|
||||
}
|
||||
}
|
||||
else if (mp_big_buffer != NULL)
|
||||
{
|
||||
big_buff_in_use = true;
|
||||
mp_buffer = mp_big_buffer;
|
||||
|
||||
/* Check if big buffer is full */
|
||||
if ((m_rx_index >= PKT_SIZE) && (received_byte != APP_SLIP_END))
|
||||
{
|
||||
/* Do not notify upper layer - the packet is too big and cannot be handled by slip */
|
||||
rx_sync = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Decode byte*/
|
||||
if (slip_decode(&received_byte))
|
||||
{
|
||||
/* Write Rx byte only if it is not escape char */
|
||||
if (!m_rx_escape)
|
||||
{
|
||||
mp_buffer[m_rx_index++] = received_byte;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Mark the big buffer as locked (it should be freed by the upper
|
||||
// layer).
|
||||
mp_big_buffer = NULL;
|
||||
big_buff_in_use = false;
|
||||
|
||||
/* Report packet reception end*/
|
||||
m_ser_phy_hci_slip_event.evt_type =
|
||||
SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED;
|
||||
m_ser_phy_hci_slip_event.evt_params.received_pkt.p_buffer = mp_buffer;
|
||||
m_ser_phy_hci_slip_event.evt_params.received_pkt.num_of_bytes = m_rx_index;
|
||||
m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
|
||||
|
||||
rx_sync = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Both buffers are not available - cannot continue reception*/
|
||||
rx_sync = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t ser_phy_hci_slip_rx_buf_free(uint8_t * p_buffer)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
if (p_buffer == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
else if (p_buffer == m_small_buffer)
|
||||
{
|
||||
/* Free small buffer*/
|
||||
if (mp_small_buffer == NULL)
|
||||
{
|
||||
mp_small_buffer = m_small_buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
else if (p_buffer == m_big_buffer)
|
||||
{
|
||||
/* Free big buffer*/
|
||||
if (mp_big_buffer == NULL)
|
||||
{
|
||||
mp_big_buffer = m_big_buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
static void uart_event_handler(nrf_drv_uart_event_t * p_event,
|
||||
void * p_context)
|
||||
{
|
||||
(void)p_context;
|
||||
|
||||
switch (p_event->type)
|
||||
{
|
||||
case NRF_DRV_UART_EVT_ERROR:
|
||||
// Process the error only if this is a parity or overrun error.
|
||||
// Break and framing errors will always occur before the other
|
||||
// side becomes active.
|
||||
if (p_event->data.error.error_mask &
|
||||
(NRF_UART_ERROR_PARITY_MASK | NRF_UART_ERROR_OVERRUN_MASK))
|
||||
{
|
||||
// Pass error source to upper layer
|
||||
m_ser_phy_hci_slip_event.evt_type =
|
||||
SER_PHY_HCI_SLIP_EVT_HW_ERROR;
|
||||
m_ser_phy_hci_slip_event.evt_params.hw_error.error_code =
|
||||
p_event->data.error.error_mask;
|
||||
m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
|
||||
}
|
||||
APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_buf, 1));
|
||||
break;
|
||||
|
||||
case NRF_DRV_UART_EVT_TX_DONE:
|
||||
// If there is a pending transfer (the second buffer is ready to
|
||||
// be sent), start it immediately.
|
||||
if (m_tx_pending)
|
||||
{
|
||||
APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, mp_tx_buf, m_tx_bytes));
|
||||
|
||||
// Switch to the buffer that has just been sent completely
|
||||
// and now can be filled again.
|
||||
mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0;
|
||||
m_tx_bytes = 0;
|
||||
|
||||
m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type;
|
||||
m_tx_evt_type = m_tx_pending_evt_type;
|
||||
|
||||
m_tx_pending = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tx_in_progress = false;
|
||||
m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type;
|
||||
}
|
||||
// If needed, notify the upper layer that the packet transfer is
|
||||
// complete (note that this notification may result in another
|
||||
// packet send request, so everything must be cleaned up above).
|
||||
if (m_ser_phy_hci_slip_event.evt_type != NO_EVENT)
|
||||
{
|
||||
m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
|
||||
}
|
||||
// And if the sending process is not yet finished, look what is
|
||||
// to be done next.
|
||||
if (m_tx_phase != PHASE_IDLE)
|
||||
{
|
||||
tx_buf_fill();
|
||||
}
|
||||
break;
|
||||
|
||||
case NRF_DRV_UART_EVT_RX_DONE:
|
||||
{
|
||||
uint8_t rx_byte = m_rx_buf[0];
|
||||
APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_buf, 1));
|
||||
if (p_event->data.rxtx.bytes)
|
||||
{
|
||||
ser_phi_hci_rx_byte(rx_byte);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
|
||||
}
|
||||
}
|
||||
|
||||
void ser_phy_hci_slip_reset(void)
|
||||
{
|
||||
mp_tx_buf = m_tx_buf0;
|
||||
m_tx_bytes = 0;
|
||||
m_tx_phase = PHASE_IDLE;
|
||||
m_tx_in_progress = false;
|
||||
m_tx_pending = false;
|
||||
|
||||
m_rx_escape = false;
|
||||
mp_small_buffer = m_small_buffer;
|
||||
mp_big_buffer = m_big_buffer;
|
||||
}
|
||||
|
||||
uint32_t ser_phy_hci_slip_open(ser_phy_hci_slip_event_handler_t events_handler)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
if (events_handler == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
// Check if function was not called before.
|
||||
if (m_ser_phy_hci_slip_event_handler != NULL)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
m_ser_phy_hci_slip_event_handler = events_handler;
|
||||
|
||||
err_code = nrf_drv_uart_init(&m_uart, &m_uart_config, uart_event_handler);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ser_phy_hci_slip_reset();
|
||||
|
||||
APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_buf, 1));
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void ser_phy_hci_slip_close(void)
|
||||
{
|
||||
nrf_drv_uart_uninit(&m_uart);
|
||||
m_ser_phy_hci_slip_event_handler = NULL;
|
||||
}
|
||||
@@ -0,0 +1,737 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "ser_phy_hci.h"
|
||||
#include "ser_config.h"
|
||||
#ifdef SER_CONNECTIVITY
|
||||
#include "ser_phy_config_conn.h"
|
||||
#else
|
||||
#include "ser_phy_config_app.h"
|
||||
#endif
|
||||
#include "app_usbd_cdc_acm.h"
|
||||
#include "nrf_drv_clock.h"
|
||||
#include "app_error.h"
|
||||
#include "app_util_platform.h"
|
||||
|
||||
#define NRF_LOG_MODULE_NAME sphy_cdc
|
||||
#include "nrf_log.h"
|
||||
NRF_LOG_MODULE_REGISTER();
|
||||
|
||||
#define APP_SLIP_END 0xC0 /**< SLIP code for identifying the beginning and end of a packet frame.. */
|
||||
#define APP_SLIP_ESC 0xDB /**< SLIP escape code. This code is used to specify that the following character is specially encoded. */
|
||||
#define APP_SLIP_ESC_END 0xDC /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xC0.. */
|
||||
#define APP_SLIP_ESC_ESC 0xDD /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xDB. */
|
||||
|
||||
#define HDR_SIZE 4
|
||||
#define CRC_SIZE 2
|
||||
#define PKT_SIZE (SER_HAL_TRANSPORT_MAX_PKT_SIZE + HDR_SIZE + CRC_SIZE)
|
||||
|
||||
static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
|
||||
app_usbd_cdc_acm_user_event_t event);
|
||||
|
||||
#define CDC_ACM_COMM_INTERFACE 0
|
||||
#define CDC_ACM_COMM_EPIN NRF_DRV_USBD_EPIN2
|
||||
|
||||
#define CDC_ACM_DATA_INTERFACE 1
|
||||
#define CDC_ACM_DATA_EPIN NRF_DRV_USBD_EPIN1
|
||||
#define CDC_ACM_DATA_EPOUT NRF_DRV_USBD_EPOUT1
|
||||
|
||||
APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm,
|
||||
cdc_acm_user_ev_handler,
|
||||
CDC_ACM_COMM_INTERFACE,
|
||||
CDC_ACM_DATA_INTERFACE,
|
||||
CDC_ACM_COMM_EPIN,
|
||||
CDC_ACM_DATA_EPIN,
|
||||
CDC_ACM_DATA_EPOUT,
|
||||
APP_USBD_CDC_COMM_PROTOCOL_NONE
|
||||
);
|
||||
|
||||
static bool volatile m_port_open;
|
||||
|
||||
typedef struct {
|
||||
ser_phy_hci_pkt_params_t header;
|
||||
ser_phy_hci_pkt_params_t payload;
|
||||
ser_phy_hci_pkt_params_t crc;
|
||||
} ser_phy_hci_slip_pkt_t;
|
||||
static ser_phy_hci_slip_pkt_t m_tx_curr_packet;
|
||||
static ser_phy_hci_slip_pkt_t m_tx_next_packet;
|
||||
|
||||
static ser_phy_hci_slip_evt_t m_ser_phy_hci_slip_event;
|
||||
static ser_phy_hci_slip_event_handler_t m_ser_phy_hci_slip_event_handler; /**< Event handler for upper layer */
|
||||
|
||||
static uint8_t m_tx_buf0[NRF_DRV_USBD_EPSIZE];
|
||||
static uint8_t m_tx_buf1[NRF_DRV_USBD_EPSIZE];
|
||||
static uint8_t * mp_tx_buf;
|
||||
static uint8_t m_tx_bytes;
|
||||
|
||||
static enum {
|
||||
PHASE_BEGIN,
|
||||
PHASE_HEADER,
|
||||
PHASE_PAYLOAD,
|
||||
PHASE_CRC,
|
||||
PHASE_ACK_END,
|
||||
// The following three elements have to have consecutive values,
|
||||
// 'tx_buf_fill()' relies on this.
|
||||
PHASE_PACKET_END,
|
||||
PHASE_PRE_IDLE = PHASE_PACKET_END + 1,
|
||||
PHASE_IDLE = PHASE_PRE_IDLE + 1
|
||||
} volatile m_tx_phase;
|
||||
|
||||
static bool volatile m_tx_in_progress;
|
||||
static bool volatile m_tx_pending;
|
||||
|
||||
#define NO_EVENT SER_PHY_HCI_SLIP_EVT_TYPE_MAX
|
||||
static ser_phy_hci_slip_evt_type_t m_tx_evt_type;
|
||||
static ser_phy_hci_slip_evt_type_t m_tx_pending_evt_type;
|
||||
|
||||
static ser_phy_hci_pkt_params_t * mp_tx_data = NULL;
|
||||
static uint32_t m_tx_index;
|
||||
|
||||
static uint8_t m_small_buffer[HDR_SIZE];
|
||||
static uint8_t m_big_buffer[PKT_SIZE];
|
||||
|
||||
static uint8_t * mp_small_buffer = NULL;
|
||||
static uint8_t * mp_big_buffer = NULL;
|
||||
static uint8_t * mp_buffer = NULL;
|
||||
static uint32_t m_rx_index;
|
||||
|
||||
static uint8_t m_rx_byte;
|
||||
static bool m_rx_escape;
|
||||
|
||||
|
||||
// The function returns false to signal that no more bytes can be passed to be
|
||||
// sent (put into the TX buffer) until UART transmission is done.
|
||||
static bool tx_buf_put(uint8_t data_byte)
|
||||
{
|
||||
ASSERT(m_tx_bytes < SER_PHY_HCI_SLIP_TX_BUF_SIZE);
|
||||
mp_tx_buf[m_tx_bytes] = data_byte;
|
||||
++m_tx_bytes;
|
||||
|
||||
bool flush = false;
|
||||
ser_phy_hci_slip_evt_type_t slip_evt_type = NO_EVENT;
|
||||
if (m_tx_phase == PHASE_ACK_END)
|
||||
{
|
||||
// Send buffer, then signal that an acknowledge packet has been sent.
|
||||
flush = true;
|
||||
slip_evt_type = SER_PHY_HCI_SLIP_EVT_ACK_SENT;
|
||||
}
|
||||
else if (m_tx_phase == PHASE_PACKET_END)
|
||||
{
|
||||
// Send buffer, then signal that a packet with payload has been sent.
|
||||
flush = true;
|
||||
slip_evt_type = SER_PHY_HCI_SLIP_EVT_PKT_SENT;
|
||||
}
|
||||
else if (m_tx_bytes >= SER_PHY_HCI_SLIP_TX_BUF_SIZE)
|
||||
{
|
||||
// Send buffer (because it is filled up), but don't signal anything,
|
||||
// since the packet sending is not complete yet.
|
||||
flush = true;
|
||||
}
|
||||
|
||||
if (flush)
|
||||
{
|
||||
// If some TX transfer is being done at the moment, a new one cannot be
|
||||
// started, it must be scheduled to be performed later.
|
||||
if (m_tx_in_progress)
|
||||
{
|
||||
m_tx_pending_evt_type = slip_evt_type;
|
||||
m_tx_pending = true;
|
||||
// No more buffers available, can't continue filling.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_port_open)
|
||||
{
|
||||
m_tx_in_progress = true;
|
||||
m_tx_evt_type = slip_evt_type;
|
||||
APP_ERROR_CHECK(app_usbd_cdc_acm_write(&m_app_cdc_acm,
|
||||
mp_tx_buf, m_tx_bytes));
|
||||
}
|
||||
|
||||
// Switch to the second buffer.
|
||||
mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0;
|
||||
m_tx_bytes = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tx_buf_fill(void)
|
||||
{
|
||||
bool can_continue = true;
|
||||
do {
|
||||
static uint8_t tx_escaped_data = 0;
|
||||
|
||||
if (tx_escaped_data != 0)
|
||||
{
|
||||
can_continue = tx_buf_put(tx_escaped_data);
|
||||
tx_escaped_data = 0;
|
||||
++m_tx_index;
|
||||
}
|
||||
else switch (m_tx_phase)
|
||||
{
|
||||
case PHASE_BEGIN:
|
||||
can_continue = tx_buf_put(APP_SLIP_END);
|
||||
mp_tx_data = &m_tx_curr_packet.header;
|
||||
m_tx_index = 0;
|
||||
m_tx_phase = PHASE_HEADER;
|
||||
tx_escaped_data = 0;
|
||||
break;
|
||||
|
||||
case PHASE_ACK_END:
|
||||
case PHASE_PACKET_END:
|
||||
can_continue = tx_buf_put(APP_SLIP_END);
|
||||
|
||||
// [this is needed for the '++m_tx_phase;' below]
|
||||
m_tx_phase = PHASE_PACKET_END;
|
||||
// no break, intentional fall-through
|
||||
|
||||
case PHASE_PRE_IDLE:
|
||||
// In PHASE_PRE_IDLE the sending process is almost finished, only
|
||||
// the NRF_DRV_UART_EVT_TX_DONE event is needed before it can switch
|
||||
// to PHASE_IDLE. But during this waiting a new packet may appear
|
||||
// (i.e. 'ser_phy_hci_slip_tx_pkt_send()' may be called), hence
|
||||
// the following pointer must be checked before switching the phase,
|
||||
// just like right after writing whole packet to buffer (i.e. in
|
||||
// PHASE_PACKET_END). Therefore, the following code is common for
|
||||
// these two cases.
|
||||
if (m_tx_next_packet.header.p_buffer != NULL)
|
||||
{
|
||||
m_tx_curr_packet = m_tx_next_packet;
|
||||
m_tx_next_packet.header.p_buffer = NULL;
|
||||
|
||||
m_tx_phase = PHASE_BEGIN;
|
||||
break;
|
||||
}
|
||||
// Go to the next phase:
|
||||
// PHASE_PACKET_END -> PHASE_PRE_IDLE
|
||||
// PHASE_PRE_IDLE -> PHASE_IDLE
|
||||
++m_tx_phase;
|
||||
return;
|
||||
|
||||
default:
|
||||
ASSERT(mp_tx_data->p_buffer != NULL);
|
||||
if (m_tx_index < mp_tx_data->num_of_bytes)
|
||||
{
|
||||
uint8_t data = mp_tx_data->p_buffer[m_tx_index];
|
||||
|
||||
if (data == APP_SLIP_END)
|
||||
{
|
||||
data = APP_SLIP_ESC;
|
||||
tx_escaped_data = APP_SLIP_ESC_END;
|
||||
}
|
||||
else if (data == APP_SLIP_ESC)
|
||||
{
|
||||
tx_escaped_data = APP_SLIP_ESC_ESC;
|
||||
}
|
||||
else
|
||||
{
|
||||
++m_tx_index;
|
||||
}
|
||||
can_continue = tx_buf_put(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
mp_tx_data->p_buffer = NULL;
|
||||
|
||||
if (m_tx_phase == PHASE_HEADER)
|
||||
{
|
||||
if (m_tx_curr_packet.payload.p_buffer == NULL)
|
||||
{
|
||||
// No payload -> ACK packet.
|
||||
m_tx_phase = PHASE_ACK_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
mp_tx_data = &m_tx_curr_packet.payload;
|
||||
m_tx_index = 0;
|
||||
m_tx_phase = PHASE_PAYLOAD;
|
||||
}
|
||||
}
|
||||
else if (m_tx_phase == PHASE_PAYLOAD)
|
||||
{
|
||||
if (m_tx_curr_packet.crc.p_buffer == NULL)
|
||||
{
|
||||
// Packet without CRC.
|
||||
m_tx_phase = PHASE_PACKET_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
mp_tx_data = &m_tx_curr_packet.crc;
|
||||
m_tx_index = 0;
|
||||
m_tx_phase = PHASE_CRC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(m_tx_phase == PHASE_CRC);
|
||||
m_tx_phase = PHASE_PACKET_END;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (can_continue);
|
||||
}
|
||||
|
||||
uint32_t ser_phy_hci_slip_tx_pkt_send(const ser_phy_hci_pkt_params_t * p_header,
|
||||
const ser_phy_hci_pkt_params_t * p_payload,
|
||||
const ser_phy_hci_pkt_params_t * p_crc)
|
||||
{
|
||||
if (p_header == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
if (!m_port_open)
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
CRITICAL_REGION_ENTER();
|
||||
|
||||
// If some packet is already transmitted, schedule this new one to be sent
|
||||
// as next. A critical region is needed here to ensure that the transmission
|
||||
// won't finish before the following assignments are done.
|
||||
if (m_tx_phase != PHASE_IDLE)
|
||||
{
|
||||
m_tx_next_packet.header = *p_header;
|
||||
|
||||
if (p_payload == NULL)
|
||||
{
|
||||
m_tx_next_packet.payload.p_buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tx_next_packet.payload = *p_payload;
|
||||
}
|
||||
|
||||
if (p_crc == NULL)
|
||||
{
|
||||
m_tx_next_packet.crc.p_buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tx_next_packet.crc = *p_crc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tx_curr_packet.header = *p_header;
|
||||
|
||||
if (p_payload == NULL)
|
||||
{
|
||||
m_tx_curr_packet.payload.p_buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tx_curr_packet.payload = *p_payload;
|
||||
}
|
||||
|
||||
if (p_crc == NULL)
|
||||
{
|
||||
m_tx_curr_packet.crc.p_buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tx_curr_packet.crc = *p_crc;
|
||||
}
|
||||
|
||||
m_tx_phase = PHASE_BEGIN;
|
||||
tx_buf_fill();
|
||||
}
|
||||
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
/* Function returns false when last byte in packet is detected.*/
|
||||
static bool slip_decode(uint8_t * p_received_byte)
|
||||
{
|
||||
switch (*p_received_byte)
|
||||
{
|
||||
case APP_SLIP_END:
|
||||
return false;
|
||||
|
||||
case APP_SLIP_ESC:
|
||||
m_rx_escape = true;
|
||||
break;
|
||||
|
||||
case APP_SLIP_ESC_END:
|
||||
|
||||
if (m_rx_escape == true)
|
||||
{
|
||||
m_rx_escape = false;
|
||||
*p_received_byte = APP_SLIP_END;
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_SLIP_ESC_ESC:
|
||||
|
||||
if (m_rx_escape == true)
|
||||
{
|
||||
m_rx_escape = false;
|
||||
*p_received_byte = APP_SLIP_ESC;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Normal character - decoding not needed*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void ser_phi_hci_rx_byte(uint8_t rx_byte)
|
||||
{
|
||||
static bool rx_sync = false;
|
||||
uint8_t received_byte = rx_byte;
|
||||
static bool big_buff_in_use = false;
|
||||
|
||||
/* Test received byte for SLIP packet start: 0xC0*/
|
||||
if (!rx_sync)
|
||||
{
|
||||
if (received_byte == APP_SLIP_END)
|
||||
{
|
||||
m_rx_index = 0;
|
||||
rx_sync = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Additional check needed in case rx_sync flag was set by end of previous packet*/
|
||||
if ((m_rx_index) == 0 && (received_byte == APP_SLIP_END))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if small (ACK) buffer is available*/
|
||||
if ((mp_small_buffer != NULL) && (big_buff_in_use == false))
|
||||
{
|
||||
if (m_rx_index == 0)
|
||||
{
|
||||
mp_buffer = mp_small_buffer;
|
||||
}
|
||||
|
||||
/* Check if switch between small and big buffer is needed*/
|
||||
if (m_rx_index == sizeof (m_small_buffer) /*NEW!!!*/ && received_byte != APP_SLIP_END)
|
||||
{
|
||||
/* Check if big (PKT) buffer is available*/
|
||||
if (mp_big_buffer != NULL)
|
||||
{
|
||||
/* Switch to big buffer*/
|
||||
memcpy(m_big_buffer, m_small_buffer, sizeof (m_small_buffer));
|
||||
mp_buffer = m_big_buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Small buffer is too small and big buffer not available - cannot continue reception*/
|
||||
rx_sync = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if big buffer is full */
|
||||
if ((m_rx_index >= PKT_SIZE) && (received_byte != APP_SLIP_END))
|
||||
{
|
||||
/* Do not notify upper layer - the packet is too big and cannot be handled by slip */
|
||||
rx_sync = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Decode byte. Will return false when it is 0xC0 - end of packet*/
|
||||
if (slip_decode(&received_byte))
|
||||
{
|
||||
/* Write Rx byte only if it is not escape char */
|
||||
if (!m_rx_escape)
|
||||
{
|
||||
mp_buffer[m_rx_index++] = received_byte;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset pointers to signalise buffers are locked waiting for upper layer */
|
||||
if (mp_buffer == mp_small_buffer)
|
||||
{
|
||||
mp_small_buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
mp_big_buffer = NULL;
|
||||
}
|
||||
/* Report packet reception end*/
|
||||
m_ser_phy_hci_slip_event.evt_type =
|
||||
SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED;
|
||||
m_ser_phy_hci_slip_event.evt_params.received_pkt.p_buffer = mp_buffer;
|
||||
m_ser_phy_hci_slip_event.evt_params.received_pkt.num_of_bytes = m_rx_index;
|
||||
m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
|
||||
|
||||
rx_sync = false;
|
||||
}
|
||||
}
|
||||
else if (mp_big_buffer != NULL)
|
||||
{
|
||||
big_buff_in_use = true;
|
||||
mp_buffer = mp_big_buffer;
|
||||
|
||||
/* Check if big buffer is full */
|
||||
if ((m_rx_index >= PKT_SIZE) && (received_byte != APP_SLIP_END))
|
||||
{
|
||||
/* Do not notify upper layer - the packet is too big and cannot be handled by slip */
|
||||
rx_sync = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Decode byte*/
|
||||
if (slip_decode(&received_byte))
|
||||
{
|
||||
/* Write Rx byte only if it is not escape char */
|
||||
if (!m_rx_escape)
|
||||
{
|
||||
mp_buffer[m_rx_index++] = received_byte;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Mark the big buffer as locked (it should be freed by the upper
|
||||
// layer).
|
||||
mp_big_buffer = NULL;
|
||||
big_buff_in_use = false;
|
||||
|
||||
/* Report packet reception end*/
|
||||
m_ser_phy_hci_slip_event.evt_type =
|
||||
SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED;
|
||||
m_ser_phy_hci_slip_event.evt_params.received_pkt.p_buffer = mp_buffer;
|
||||
m_ser_phy_hci_slip_event.evt_params.received_pkt.num_of_bytes = m_rx_index;
|
||||
m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
|
||||
|
||||
rx_sync = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Both buffers are not available - cannot continue reception*/
|
||||
rx_sync = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t ser_phy_hci_slip_rx_buf_free(uint8_t * p_buffer)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
if (p_buffer == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
else if (p_buffer == m_small_buffer)
|
||||
{
|
||||
/* Free small buffer*/
|
||||
if (mp_small_buffer == NULL)
|
||||
{
|
||||
mp_small_buffer = m_small_buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
else if (p_buffer == m_big_buffer)
|
||||
{
|
||||
/* Free big buffer*/
|
||||
if (mp_big_buffer == NULL)
|
||||
{
|
||||
mp_big_buffer = m_big_buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
|
||||
app_usbd_cdc_acm_user_event_t event)
|
||||
{
|
||||
app_usbd_cdc_acm_t const * p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst);
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
|
||||
NRF_LOG_DEBUG("EVT_PORT_OPEN");
|
||||
if (!m_port_open)
|
||||
{
|
||||
ret_code_t ret_code;
|
||||
|
||||
m_port_open = true;
|
||||
|
||||
do {
|
||||
ret_code = app_usbd_cdc_acm_read(p_cdc_acm, &m_rx_byte, 1);
|
||||
if (ret_code == NRF_SUCCESS)
|
||||
{
|
||||
ser_phi_hci_rx_byte(m_rx_byte);
|
||||
}
|
||||
else if (ret_code != NRF_ERROR_IO_PENDING)
|
||||
{
|
||||
APP_ERROR_CHECK(ret_code);
|
||||
}
|
||||
} while (ret_code == NRF_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
|
||||
NRF_LOG_DEBUG("EVT_PORT_CLOSE");
|
||||
if (m_tx_in_progress)
|
||||
{
|
||||
m_ser_phy_hci_slip_event.evt_type = SER_PHY_HCI_SLIP_EVT_PKT_SENT;
|
||||
m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
|
||||
m_tx_in_progress = false;
|
||||
}
|
||||
m_port_open = false;
|
||||
break;
|
||||
|
||||
case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
|
||||
// If there is a pending transfer (the second buffer is ready to
|
||||
// be sent), start it immediately.
|
||||
if (m_tx_pending)
|
||||
{
|
||||
APP_ERROR_CHECK(app_usbd_cdc_acm_write(p_cdc_acm,
|
||||
mp_tx_buf, m_tx_bytes));
|
||||
|
||||
// Switch to the buffer that has just been sent completely
|
||||
// and now can be filled again.
|
||||
mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0;
|
||||
m_tx_bytes = 0;
|
||||
|
||||
m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type;
|
||||
m_tx_evt_type = m_tx_pending_evt_type;
|
||||
|
||||
m_tx_pending = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tx_in_progress = false;
|
||||
m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type;
|
||||
}
|
||||
// If needed, notify the upper layer that the packet transfer is
|
||||
// complete (note that this notification may result in another
|
||||
// packet send request, so everything must be cleaned up above).
|
||||
if (m_ser_phy_hci_slip_event.evt_type != NO_EVENT)
|
||||
{
|
||||
m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
|
||||
}
|
||||
// And if the sending process is not yet finished, look what is
|
||||
// to be done next.
|
||||
if (m_tx_phase != PHASE_IDLE)
|
||||
{
|
||||
tx_buf_fill();
|
||||
}
|
||||
break;
|
||||
|
||||
case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
|
||||
{
|
||||
ret_code_t ret_code;
|
||||
do
|
||||
{
|
||||
ser_phi_hci_rx_byte(m_rx_byte);
|
||||
|
||||
ret_code = app_usbd_cdc_acm_read(p_cdc_acm, &m_rx_byte, 1);
|
||||
} while (ret_code == NRF_SUCCESS);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ser_phy_hci_slip_reset(void)
|
||||
{
|
||||
mp_tx_buf = m_tx_buf0;
|
||||
m_tx_bytes = 0;
|
||||
m_tx_phase = PHASE_IDLE;
|
||||
m_tx_in_progress = false;
|
||||
m_tx_pending = false;
|
||||
|
||||
m_rx_escape = false;
|
||||
mp_small_buffer = m_small_buffer;
|
||||
mp_big_buffer = m_big_buffer;
|
||||
}
|
||||
|
||||
uint32_t ser_phy_hci_slip_open(ser_phy_hci_slip_event_handler_t events_handler)
|
||||
{
|
||||
if (events_handler == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
// Check if function was not called before.
|
||||
if (m_ser_phy_hci_slip_event_handler != NULL)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
ret_code_t ret = app_usbd_class_append(
|
||||
app_usbd_cdc_acm_class_inst_get(&m_app_cdc_acm));
|
||||
if (ret != NRF_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
m_ser_phy_hci_slip_event_handler = events_handler;
|
||||
|
||||
ser_phy_hci_slip_reset();
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void ser_phy_hci_slip_close(void)
|
||||
{
|
||||
m_ser_phy_hci_slip_event_handler = NULL;
|
||||
}
|
||||
@@ -0,0 +1,382 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/**@file
|
||||
*
|
||||
* @defgroup ser_phy_spi_phy_driver_slave ser_phy_nrf51_spi_slave.c
|
||||
* @{
|
||||
* @ingroup ser_phy_spi_phy_driver_slave
|
||||
*
|
||||
* @brief SPI_RAW PHY slave driver.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "app_error.h"
|
||||
#include "app_util.h"
|
||||
#include "app_util_platform.h"
|
||||
#include "app_timer.h"
|
||||
#include "ser_phy.h"
|
||||
#include "ser_phy_hci.h"
|
||||
#include "crc16.h"
|
||||
#include "nrf_soc.h"
|
||||
|
||||
#include "ser_phy_debug_comm.h"
|
||||
|
||||
static bool m_flag_nohci_init = false;
|
||||
static bool m_flag_expect_ack;
|
||||
static bool m_flag_buffer_reqested = false;
|
||||
|
||||
static uint16_t m_rx_packet_length;
|
||||
static uint8_t * m_p_rx_packet;
|
||||
|
||||
static uint16_t m_rx_pending_packet_length;
|
||||
static uint8_t * m_p_rx_pending_packet;
|
||||
|
||||
static uint16_t m_rx_allocated_packet_length;
|
||||
static uint8_t * m_p_rx_allocated_packet;
|
||||
|
||||
static uint8_t * m_p_tx_packet = NULL;
|
||||
static uint16_t m_tx_packet_length;
|
||||
|
||||
static ser_phy_events_handler_t m_ser_phy_callback = NULL;
|
||||
|
||||
#define PKT_HDR_SIZE 4 /**< Packet header size in number of bytes. */
|
||||
#define PKT_CRC_SIZE 2 /**< Packet CRC size in number of bytes. */
|
||||
|
||||
static void ser_phy_nohci_assert(bool cond)
|
||||
{
|
||||
APP_ERROR_CHECK_BOOL(cond);
|
||||
}
|
||||
|
||||
|
||||
static void ser_phy_event_callback(ser_phy_evt_t event)
|
||||
{
|
||||
if (m_ser_phy_callback)
|
||||
{
|
||||
m_ser_phy_callback(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void memory_request_callback(uint16_t size)
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
DEBUG_EVT_HCI_PHY_EVT_BUF_REQUEST(0);
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
|
||||
event.evt_params.rx_buf_request.num_of_bytes = size;
|
||||
ser_phy_event_callback(event);
|
||||
}
|
||||
|
||||
|
||||
static void packet_received_callback(uint8_t * pBuffer, uint16_t size)
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
DEBUG_EVT_HCI_PHY_EVT_RX_PKT_RECEIVED(0);
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
|
||||
event.evt_params.rx_pkt_received.num_of_bytes = size;
|
||||
event.evt_params.rx_pkt_received.p_buffer = pBuffer;
|
||||
ser_phy_event_callback(event);
|
||||
}
|
||||
|
||||
|
||||
static void packet_dropped_callback(void)
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
DEBUG_EVT_HCI_PHY_EVT_RX_PKT_DROPPED(0);
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED;
|
||||
ser_phy_event_callback(event);
|
||||
}
|
||||
|
||||
|
||||
static void packet_transmitted_callback(void)
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
DEBUG_EVT_HCI_PHY_EVT_TX_PKT_SENT(0);
|
||||
|
||||
event.evt_type = SER_PHY_EVT_TX_PKT_SENT;
|
||||
ser_phy_event_callback(event);
|
||||
}
|
||||
|
||||
|
||||
static void hci_slip_event_handler(ser_phy_hci_slip_evt_t * p_event)
|
||||
{
|
||||
if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_PKT_SENT )
|
||||
{
|
||||
DEBUG_EVT_SLIP_PACKET_TXED(0);
|
||||
|
||||
if (!m_flag_expect_ack)
|
||||
{
|
||||
m_p_tx_packet = NULL;
|
||||
packet_transmitted_callback();
|
||||
}
|
||||
else
|
||||
{
|
||||
ser_phy_nohci_assert(false); // packet was send as a ACK packet, callback should be with ACK_SENT
|
||||
}
|
||||
|
||||
}
|
||||
else if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_ACK_SENT )
|
||||
{
|
||||
DEBUG_EVT_SLIP_ACK_TXED(0);
|
||||
|
||||
if (m_flag_expect_ack)
|
||||
{
|
||||
m_p_tx_packet = NULL;
|
||||
packet_transmitted_callback();
|
||||
}
|
||||
else
|
||||
{
|
||||
ser_phy_nohci_assert(false); // packet was send as a normal packet, callback should be with PKT_SENT
|
||||
}
|
||||
|
||||
}
|
||||
else if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED )
|
||||
{
|
||||
CRITICAL_REGION_ENTER();
|
||||
|
||||
if (m_p_rx_packet == NULL)
|
||||
{
|
||||
m_p_rx_packet = p_event->evt_params.received_pkt.p_buffer;
|
||||
m_rx_packet_length = p_event->evt_params.received_pkt.num_of_bytes;
|
||||
m_p_rx_allocated_packet = m_p_rx_packet;
|
||||
m_rx_allocated_packet_length = m_rx_packet_length;
|
||||
m_flag_buffer_reqested = true;
|
||||
memory_request_callback(m_rx_allocated_packet_length);
|
||||
}
|
||||
else if (m_p_rx_pending_packet == NULL)
|
||||
{
|
||||
m_p_rx_pending_packet = p_event->evt_params.received_pkt.p_buffer;
|
||||
m_rx_pending_packet_length = p_event->evt_params.received_pkt.num_of_bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
// both buffers are not released; this is fault
|
||||
ser_phy_nohci_assert(false);
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
}
|
||||
else
|
||||
{
|
||||
// no other callbacks are expected
|
||||
ser_phy_nohci_assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_interrupts_enable(void)
|
||||
{
|
||||
|
||||
NVIC_EnableIRQ(UART0_IRQn);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_interrupts_disable(void)
|
||||
{
|
||||
NVIC_DisableIRQ(UART0_IRQn);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
|
||||
{
|
||||
uint32_t status = NRF_SUCCESS;
|
||||
|
||||
if (m_flag_buffer_reqested)
|
||||
{
|
||||
m_flag_buffer_reqested = false;
|
||||
|
||||
if (p_buffer)
|
||||
{
|
||||
memcpy(p_buffer, m_p_rx_allocated_packet, m_rx_allocated_packet_length);
|
||||
packet_received_callback(p_buffer, m_rx_allocated_packet_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_dropped_callback();
|
||||
}
|
||||
|
||||
CRITICAL_REGION_ENTER();
|
||||
|
||||
if (m_p_rx_allocated_packet == m_p_rx_packet && (m_p_rx_pending_packet == NULL))
|
||||
{
|
||||
// packet is copied and there is no pending packet
|
||||
(void) ser_phy_hci_slip_rx_buf_free(m_p_rx_packet);
|
||||
m_p_rx_packet = NULL;
|
||||
m_p_rx_allocated_packet = NULL;
|
||||
}
|
||||
else if (m_p_rx_allocated_packet == m_p_rx_packet && (m_p_rx_pending_packet != NULL))
|
||||
{
|
||||
// there is a pending packet - request memory for it
|
||||
m_p_rx_allocated_packet = m_p_rx_pending_packet;
|
||||
m_rx_allocated_packet_length = m_rx_pending_packet_length;
|
||||
m_flag_buffer_reqested = true;
|
||||
}
|
||||
else if (m_p_rx_allocated_packet == m_p_rx_pending_packet )
|
||||
{
|
||||
// the pending packet was serviced - release both
|
||||
m_p_rx_allocated_packet = NULL;
|
||||
(void) ser_phy_hci_slip_rx_buf_free(m_p_rx_packet);
|
||||
m_p_rx_packet = NULL;
|
||||
(void) ser_phy_hci_slip_rx_buf_free(m_p_rx_pending_packet);
|
||||
m_p_rx_pending_packet = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no other calls are expected
|
||||
ser_phy_nohci_assert(false);
|
||||
}
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
// request memory for a pending
|
||||
if (m_p_rx_allocated_packet)
|
||||
{
|
||||
memory_request_callback(m_rx_allocated_packet_length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NRF_ERROR_BUSY;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
|
||||
{
|
||||
uint32_t status = NRF_SUCCESS;
|
||||
uint32_t err_code;
|
||||
|
||||
if ( p_buffer == NULL || num_of_bytes == 0)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
if ( m_p_tx_packet == NULL)
|
||||
{
|
||||
m_tx_packet_length = num_of_bytes;
|
||||
m_p_tx_packet = (uint8_t *)p_buffer;
|
||||
|
||||
if (m_tx_packet_length <= PKT_HDR_SIZE + PKT_CRC_SIZE)
|
||||
{
|
||||
ser_phy_hci_pkt_params_t pkt; // all packets smaller than 6 goes as ACK
|
||||
|
||||
m_flag_expect_ack = true;
|
||||
pkt.p_buffer = (uint8_t *)m_p_tx_packet;
|
||||
pkt.num_of_bytes = m_tx_packet_length;
|
||||
DEBUG_EVT_SLIP_ACK_TX(0);
|
||||
err_code = ser_phy_hci_slip_tx_pkt_send(&pkt, NULL, NULL); // this will look like ACK for slip
|
||||
ser_phy_nohci_assert(err_code == NRF_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
ser_phy_hci_pkt_params_t header; // this is fake header - just first 4 bytes
|
||||
ser_phy_hci_pkt_params_t crc; // this is fake header - just last 2 bytes
|
||||
ser_phy_hci_pkt_params_t payload; // this is fake payload - all except for header and crc
|
||||
|
||||
m_flag_expect_ack = false;
|
||||
header.p_buffer = (uint8_t *)m_p_tx_packet;
|
||||
header.num_of_bytes = PKT_HDR_SIZE;
|
||||
crc.p_buffer = (uint8_t *)m_p_tx_packet + m_tx_packet_length - PKT_CRC_SIZE;
|
||||
crc.num_of_bytes = PKT_CRC_SIZE;
|
||||
payload.p_buffer = (uint8_t *)m_p_tx_packet + PKT_HDR_SIZE;
|
||||
payload.num_of_bytes = m_tx_packet_length - PKT_HDR_SIZE - PKT_CRC_SIZE;
|
||||
DEBUG_EVT_SLIP_PACKET_TX(0);
|
||||
err_code = ser_phy_hci_slip_tx_pkt_send(&header, &payload, &crc); // this will look like normal packet for slip
|
||||
ser_phy_nohci_assert(err_code == NRF_SUCCESS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NRF_ERROR_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
if (m_flag_nohci_init)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (events_handler == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
err_code = ser_phy_hci_slip_open(hci_slip_event_handler);
|
||||
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
|
||||
m_ser_phy_callback = events_handler;
|
||||
m_flag_nohci_init = true;
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_close(void)
|
||||
{
|
||||
m_ser_phy_callback = NULL;
|
||||
ser_phy_hci_slip_close();
|
||||
m_flag_nohci_init = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,823 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/**@file
|
||||
*
|
||||
* @defgroup ser_phy_spi_5W_phy_driver_master ser_phy_nrf51_spi_5W_master.c
|
||||
* @{
|
||||
* @ingroup ser_phy_spi_5W_phy_driver_master
|
||||
*
|
||||
* @brief SPI_5W_RAW PHY master driver.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "app_util.h"
|
||||
#include "app_util_platform.h"
|
||||
#include "boards.h"
|
||||
#include "nrf_error.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_drv_gpiote.h"
|
||||
#include "ser_config.h"
|
||||
#include "ser_config_5W_app.h"
|
||||
#include "ser_phy.h"
|
||||
#include "ser_phy_config_app.h"
|
||||
#include "spi_5W_master.h"
|
||||
#include "ser_phy_debug_app.h"
|
||||
#include "app_error.h"
|
||||
#define notUSE_PendSV
|
||||
|
||||
#ifdef USE_PendSV
|
||||
#define SW_IRQn PendSV_IRQn
|
||||
#define SW_IRQ_Handler() PendSV_Handler()
|
||||
#define SET_Pend_SW_IRQ() SCB->ICSR = SCB->ICSR | SCB_ICSR_PENDSVSET_Msk //NVIC_SetPendingIRQ(PendSV_IRQn) - PendSV_IRQn is a negative - does not work with CMSIS
|
||||
#else
|
||||
#define SW_IRQn SWI3_IRQn
|
||||
#define SW_IRQ_Handler() SWI3_IRQHandler()
|
||||
#define SET_Pend_SW_IRQ() NVIC_SetPendingIRQ(SWI3_IRQn)
|
||||
#endif
|
||||
|
||||
#define SER_PHY_SPI_5W_MTU_SIZE SER_PHY_SPI_MTU_SIZE
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SER_PHY_STATE_IDLE = 0,
|
||||
SER_PHY_STATE_TX_HEADER,
|
||||
SER_PHY_STATE_TX_WAIT_FOR_RDY,
|
||||
SER_PHY_STATE_TX_PAYLOAD,
|
||||
SER_PHY_STATE_RX_WAIT_FOR_RDY,
|
||||
SER_PHY_STATE_TX_ZERO_HEADER,
|
||||
SER_PHY_STATE_RX_HEADER,
|
||||
SER_PHY_STATE_MEMORY_REQUEST,
|
||||
SER_PHY_STATE_RX_PAYLOAD,
|
||||
SER_PHY_STATE_DISABLED
|
||||
} ser_phy_spi_master_state_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SER_PHY_EVT_GPIO_RDY = 0,
|
||||
SER_PHY_EVT_GPIO_REQ,
|
||||
SER_PHY_EVT_SPI_TRANSFER_DONE,
|
||||
SER_PHY_EVT_TX_API_CALL,
|
||||
SER_PHY_EVT_RX_API_CALL
|
||||
} ser_phy_event_source_t;
|
||||
|
||||
#define _static static
|
||||
|
||||
_static uint8_t * mp_tx_buffer = NULL;
|
||||
_static uint16_t m_tx_buf_len = 0;
|
||||
|
||||
_static uint8_t * mp_rx_buffer = NULL;
|
||||
_static uint16_t m_rx_buf_len = 0;
|
||||
_static uint8_t m_recv_buffer[SER_PHY_SPI_5W_MTU_SIZE];
|
||||
_static uint8_t m_len_buffer[SER_PHY_HEADER_SIZE + 1] = { 0 }; //len is asymmetric for 5W, there is a 1 byte guard when receiving
|
||||
|
||||
_static uint16_t m_tx_packet_length = 0;
|
||||
_static uint16_t m_accumulated_tx_packet_length = 0;
|
||||
_static uint16_t m_current_tx_packet_length = 0;
|
||||
|
||||
_static uint16_t m_rx_packet_length = 0;
|
||||
_static uint16_t m_accumulated_rx_packet_length = 0;
|
||||
_static uint16_t m_current_rx_packet_length = 0;
|
||||
|
||||
_static volatile bool m_pend_req_flag = 0;
|
||||
_static volatile bool m_pend_rdy_flag = 0;
|
||||
_static volatile bool m_pend_xfer_flag = 0;
|
||||
_static volatile bool m_pend_rx_api_flag = 0;
|
||||
_static volatile bool m_pend_tx_api_flag = 0;
|
||||
|
||||
_static volatile bool m_slave_ready_flag = false;
|
||||
_static volatile bool m_slave_request_flag = false;
|
||||
|
||||
|
||||
_static ser_phy_events_handler_t m_callback_events_handler = NULL;
|
||||
_static ser_phy_spi_master_state_t m_spi_master_state = SER_PHY_STATE_DISABLED;
|
||||
|
||||
static void ser_phy_switch_state(ser_phy_event_source_t evt_src);
|
||||
|
||||
static void spi_master_raw_assert(bool cond)
|
||||
{
|
||||
APP_ERROR_CHECK_BOOL(cond);
|
||||
}
|
||||
|
||||
void SW_IRQ_Handler()
|
||||
{
|
||||
if (m_pend_req_flag)
|
||||
{
|
||||
m_pend_req_flag = false;
|
||||
DEBUG_EVT_SPI_MASTER_RAW_REQUEST(0);
|
||||
ser_phy_switch_state(SER_PHY_EVT_GPIO_REQ);
|
||||
}
|
||||
|
||||
if (m_pend_rdy_flag)
|
||||
{
|
||||
m_pend_rdy_flag = false;
|
||||
DEBUG_EVT_SPI_MASTER_RAW_READY(0);
|
||||
ser_phy_switch_state(SER_PHY_EVT_GPIO_RDY);
|
||||
}
|
||||
|
||||
if (m_pend_xfer_flag)
|
||||
{
|
||||
m_pend_xfer_flag = false;
|
||||
DEBUG_EVT_SPI_MASTER_RAW_XFER_DONE(0);
|
||||
ser_phy_switch_state(SER_PHY_EVT_SPI_TRANSFER_DONE);
|
||||
}
|
||||
|
||||
if (m_pend_rx_api_flag)
|
||||
{
|
||||
m_pend_rx_api_flag = false;
|
||||
DEBUG_EVT_SPI_MASTER_RAW_API_CALL(0);
|
||||
ser_phy_switch_state(SER_PHY_EVT_RX_API_CALL);
|
||||
}
|
||||
|
||||
if (m_pend_tx_api_flag)
|
||||
{
|
||||
m_pend_tx_api_flag = false;
|
||||
DEBUG_EVT_SPI_MASTER_RAW_API_CALL(0);
|
||||
ser_phy_switch_state(SER_PHY_EVT_TX_API_CALL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifndef _SPI_5W_
|
||||
static void ser_phy_spi_master_ready(nrf_drv_gpiote_pin_t pin,
|
||||
nrf_gpiote_polarity_t action)
|
||||
{
|
||||
if (nrf_gpio_pin_read(pin) == 0)
|
||||
{
|
||||
m_slave_ready_flag = true;
|
||||
m_pend_rdy_flag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_slave_ready_flag = false;
|
||||
}
|
||||
|
||||
DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE((uint32_t) !m_slave_ready_flag);
|
||||
SET_Pend_SW_IRQ();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ser_phy_spi_master_request(nrf_drv_gpiote_pin_t pin,
|
||||
nrf_gpiote_polarity_t action)
|
||||
{
|
||||
if (nrf_gpio_pin_read(pin) == 0)
|
||||
{
|
||||
m_slave_request_flag = true;
|
||||
m_pend_req_flag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_slave_request_flag = false;
|
||||
}
|
||||
|
||||
DEBUG_EVT_SPI_MASTER_RAW_REQUEST_EDGE((uint32_t) !m_slave_request_flag);
|
||||
SET_Pend_SW_IRQ();
|
||||
}
|
||||
|
||||
/* Send event SER_PHY_EVT_TX_PKT_SENT */
|
||||
static __INLINE void callback_packet_sent()
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
event.evt_type = SER_PHY_EVT_TX_PKT_SENT;
|
||||
m_callback_events_handler(event);
|
||||
}
|
||||
|
||||
/* Send event SER_PHY_EVT_RX_PKT_DROPPED */
|
||||
static __INLINE void callback_packet_dropped()
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED;
|
||||
m_callback_events_handler(event);
|
||||
}
|
||||
|
||||
/* Send event SER_PHY_EVT_RX_PKT_RECEIVED */
|
||||
static __INLINE void callback_packet_received()
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
|
||||
event.evt_params.rx_pkt_received.p_buffer = mp_rx_buffer;
|
||||
event.evt_params.rx_pkt_received.num_of_bytes = m_rx_buf_len;
|
||||
m_callback_events_handler(event);
|
||||
}
|
||||
|
||||
/* Send event SER_PHY_EVT_RX_BUF_REQUEST */
|
||||
static __INLINE void callback_mem_request()
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
|
||||
event.evt_params.rx_buf_request.num_of_bytes = m_rx_buf_len;
|
||||
m_callback_events_handler(event);
|
||||
}
|
||||
|
||||
static __INLINE void copy_buff(uint8_t * const p_dest, uint8_t const * const p_src, uint16_t len)
|
||||
{
|
||||
uint16_t index;
|
||||
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
p_dest[index] = p_src[index];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static __INLINE void buffer_release(uint8_t * * const pp_buffer, uint16_t * const p_buf_len)
|
||||
{
|
||||
*pp_buffer = NULL;
|
||||
*p_buf_len = 0;
|
||||
}
|
||||
|
||||
static uint16_t compute_current_packet_length(const uint16_t packet_length,
|
||||
const uint16_t accumulated_packet_length)
|
||||
{
|
||||
uint16_t current_packet_length = packet_length - accumulated_packet_length;
|
||||
|
||||
if (current_packet_length > SER_PHY_SPI_5W_MTU_SIZE)
|
||||
{
|
||||
current_packet_length = SER_PHY_SPI_5W_MTU_SIZE;
|
||||
}
|
||||
|
||||
return current_packet_length;
|
||||
}
|
||||
|
||||
static __INLINE uint32_t header_send(const uint16_t length)
|
||||
{
|
||||
uint16_t buf_len_size = uint16_encode(length, m_len_buffer);
|
||||
|
||||
return spi_master_send_recv(SER_PHY_SPI_MASTER, m_len_buffer, buf_len_size, NULL, 0);
|
||||
}
|
||||
|
||||
static __INLINE uint32_t frame_send()
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_current_tx_packet_length = compute_current_packet_length(m_tx_packet_length,
|
||||
m_accumulated_tx_packet_length);
|
||||
err_code =
|
||||
spi_master_send_recv(SER_PHY_SPI_MASTER,
|
||||
&mp_tx_buffer[m_accumulated_tx_packet_length],
|
||||
m_current_tx_packet_length,
|
||||
NULL,
|
||||
0);
|
||||
m_accumulated_tx_packet_length += m_current_tx_packet_length;
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static __INLINE uint32_t header_get()
|
||||
{
|
||||
return spi_master_send_recv(SER_PHY_SPI_MASTER, NULL, 0, m_len_buffer, SER_PHY_HEADER_SIZE + 1); //add 0 byte guard when receiving
|
||||
}
|
||||
|
||||
static __INLINE uint32_t frame_get()
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_current_rx_packet_length = compute_current_packet_length(m_rx_packet_length,
|
||||
m_accumulated_rx_packet_length);
|
||||
|
||||
if (m_current_rx_packet_length < SER_PHY_SPI_5W_MTU_SIZE)
|
||||
{
|
||||
m_current_rx_packet_length++; //take into account guard byte when receiving
|
||||
}
|
||||
err_code = spi_master_send_recv(SER_PHY_SPI_MASTER,
|
||||
NULL,
|
||||
0,
|
||||
m_recv_buffer,
|
||||
m_current_rx_packet_length);
|
||||
return err_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Master driver main state machine
|
||||
* Executed only in the context of PendSV_Handler()
|
||||
* For UML graph, please refer to SDK documentation
|
||||
*/
|
||||
|
||||
static void ser_phy_switch_state(ser_phy_event_source_t evt_src)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
static bool m_waitForReadyFlag = false; //local scheduling flag to defer RDY events
|
||||
|
||||
switch (m_spi_master_state)
|
||||
{
|
||||
|
||||
case SER_PHY_STATE_IDLE:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_GPIO_REQ)
|
||||
{
|
||||
m_waitForReadyFlag = false;
|
||||
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
|
||||
err_code = header_send(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY;
|
||||
}
|
||||
}
|
||||
else if (evt_src == SER_PHY_EVT_TX_API_CALL)
|
||||
{
|
||||
spi_master_raw_assert(mp_tx_buffer != NULL); //api event with tx_buffer == NULL has no sense
|
||||
m_waitForReadyFlag = false;
|
||||
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_HEADER;
|
||||
err_code = header_send(m_tx_buf_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_TX_WAIT_FOR_RDY:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_GPIO_RDY)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_HEADER;
|
||||
err_code = header_send(m_tx_buf_len);
|
||||
}
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_RX_WAIT_FOR_RDY:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_GPIO_RDY)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
|
||||
err_code = header_send(0);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_TX_HEADER:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
|
||||
{
|
||||
m_tx_packet_length = m_tx_buf_len;
|
||||
m_accumulated_tx_packet_length = 0;
|
||||
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD;
|
||||
err_code = frame_send();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_waitForReadyFlag = true;
|
||||
}
|
||||
}
|
||||
else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag)
|
||||
{
|
||||
m_waitForReadyFlag = false;
|
||||
m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD;
|
||||
err_code = frame_send();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_TX_PAYLOAD:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
|
||||
{
|
||||
if (m_accumulated_tx_packet_length < m_tx_packet_length)
|
||||
{
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
err_code = frame_send();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_waitForReadyFlag = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_master_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length);
|
||||
//Release TX buffer
|
||||
buffer_release(&mp_tx_buffer, &m_tx_buf_len);
|
||||
callback_packet_sent();
|
||||
|
||||
if ( m_slave_request_flag)
|
||||
{
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
|
||||
err_code = header_send(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_IDLE; //m_Tx_buffer is NULL - have to wait for API event
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag )
|
||||
{
|
||||
m_waitForReadyFlag = false;
|
||||
err_code = frame_send();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_TX_ZERO_HEADER:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
|
||||
{
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_RX_HEADER;
|
||||
err_code = header_get();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_waitForReadyFlag = true;
|
||||
}
|
||||
}
|
||||
else if ( (evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag)
|
||||
{
|
||||
m_waitForReadyFlag = false;
|
||||
m_spi_master_state = SER_PHY_STATE_RX_HEADER;
|
||||
err_code = header_get();
|
||||
}
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_RX_HEADER:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_MEMORY_REQUEST;
|
||||
m_rx_buf_len = uint16_decode(&(m_len_buffer[1])); //skip guard when receiving
|
||||
m_rx_packet_length = m_rx_buf_len;
|
||||
callback_mem_request();
|
||||
}
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_MEMORY_REQUEST:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_RX_API_CALL)
|
||||
{
|
||||
m_accumulated_rx_packet_length = 0;
|
||||
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD;
|
||||
err_code = frame_get();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_waitForReadyFlag = true;
|
||||
}
|
||||
}
|
||||
else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag)
|
||||
{
|
||||
m_waitForReadyFlag = false;
|
||||
m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD;
|
||||
err_code = frame_get();
|
||||
}
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_RX_PAYLOAD:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
|
||||
{
|
||||
if (mp_rx_buffer)
|
||||
{
|
||||
copy_buff(&(mp_rx_buffer[m_accumulated_rx_packet_length]),
|
||||
&(m_recv_buffer[1]),
|
||||
m_current_rx_packet_length - 1); //skip guard byte when receiving
|
||||
}
|
||||
m_accumulated_rx_packet_length += (m_current_rx_packet_length - 1);
|
||||
|
||||
if (m_accumulated_rx_packet_length < m_rx_packet_length)
|
||||
{
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
err_code = frame_get();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_waitForReadyFlag = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_master_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length);
|
||||
|
||||
if (mp_rx_buffer == NULL)
|
||||
{
|
||||
callback_packet_dropped();
|
||||
}
|
||||
else
|
||||
{
|
||||
callback_packet_received();
|
||||
}
|
||||
//Release RX buffer
|
||||
buffer_release(&mp_rx_buffer, &m_rx_buf_len);
|
||||
|
||||
if ((mp_tx_buffer != NULL)) //mp_tx_buffer !=NULL, this means that API_EVT was scheduled
|
||||
{
|
||||
if (m_slave_ready_flag )
|
||||
{
|
||||
err_code = header_send(m_tx_buf_len);
|
||||
m_spi_master_state = SER_PHY_STATE_TX_HEADER;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY;
|
||||
}
|
||||
}
|
||||
else if (m_slave_request_flag)
|
||||
{
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
|
||||
err_code = header_send(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( evt_src == SER_PHY_EVT_GPIO_RDY && m_waitForReadyFlag)
|
||||
{
|
||||
m_waitForReadyFlag = false;
|
||||
err_code = frame_get();
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
(void)err_code;
|
||||
}
|
||||
}
|
||||
|
||||
/* SPI master event handler */
|
||||
static void ser_phy_spi_master_event_handler(spi_master_evt_t spi_master_evt)
|
||||
{
|
||||
switch (spi_master_evt.type)
|
||||
{
|
||||
case SPI_MASTER_EVT_TRANSFER_COMPLETED:
|
||||
|
||||
/* Switch state */
|
||||
m_pend_xfer_flag = true;
|
||||
SET_Pend_SW_IRQ();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ser_phy_init_pendSV(void)
|
||||
{
|
||||
NVIC_SetPriority(SW_IRQn, APP_IRQ_PRIORITY_MID);
|
||||
NVIC_EnableIRQ(SW_IRQn);
|
||||
}
|
||||
|
||||
static void ser_phy_init_gpiote(void)
|
||||
{
|
||||
if (!nrf_drv_gpiote_is_init())
|
||||
{
|
||||
(void)nrf_drv_gpiote_init();
|
||||
}
|
||||
NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH);
|
||||
|
||||
nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
|
||||
/* Enable pullup to ensure high state while connectivity device is reset */
|
||||
config.pull = NRF_GPIO_PIN_PULLUP;
|
||||
(void)nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST, &config,
|
||||
ser_phy_spi_master_request);
|
||||
nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST,true);
|
||||
m_slave_request_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST));
|
||||
|
||||
#ifdef _SPI_5W_
|
||||
m_slave_ready_flag = true;
|
||||
#else
|
||||
(void)nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_READY, &config,
|
||||
ser_phy_spi_master_ready);
|
||||
nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_READY,true);
|
||||
m_slave_ready_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_READY));
|
||||
#endif
|
||||
|
||||
NVIC_ClearPendingIRQ(SW_IRQn);
|
||||
}
|
||||
|
||||
static void ser_phy_deinit_gpiote(void)
|
||||
{
|
||||
nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST);
|
||||
#ifndef _SPI_5W_
|
||||
nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_READY);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
|
||||
{
|
||||
if (p_buffer == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
if (num_of_bytes == 0)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (mp_tx_buffer != NULL)
|
||||
{
|
||||
return NRF_ERROR_BUSY;
|
||||
}
|
||||
|
||||
//ser_phy_interrupts_disable();
|
||||
CRITICAL_REGION_ENTER();
|
||||
mp_tx_buffer = (uint8_t *)p_buffer;
|
||||
m_tx_buf_len = num_of_bytes;
|
||||
m_pend_tx_api_flag = true;
|
||||
SET_Pend_SW_IRQ();
|
||||
//ser_phy_interrupts_enable();
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
|
||||
{
|
||||
if (m_spi_master_state != SER_PHY_STATE_MEMORY_REQUEST)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
//ser_phy_interrupts_disable();
|
||||
CRITICAL_REGION_ENTER();
|
||||
mp_rx_buffer = p_buffer;
|
||||
m_pend_rx_api_flag = true;
|
||||
SET_Pend_SW_IRQ();
|
||||
//ser_phy_interrupts_enable();
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
|
||||
{
|
||||
|
||||
if (m_spi_master_state != SER_PHY_STATE_DISABLED)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (events_handler == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
m_spi_master_state = SER_PHY_STATE_IDLE;
|
||||
m_callback_events_handler = events_handler;
|
||||
ser_phy_init_gpiote();
|
||||
|
||||
/* Configure SPI Master driver */
|
||||
spi_master_config_t spi_master_config;
|
||||
spi_master_config.SPI_Freq = SPI_FREQUENCY_FREQUENCY_M1;
|
||||
spi_master_config.SPI_Pin_SCK = SER_PHY_SPI_MASTER_PIN_SCK;
|
||||
spi_master_config.SPI_Pin_MISO = SER_PHY_SPI_MASTER_PIN_MISO;
|
||||
spi_master_config.SPI_Pin_MOSI = SER_PHY_SPI_MASTER_PIN_MOSI;
|
||||
spi_master_config.SPI_Pin_SS = SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT;
|
||||
spi_master_config.SPI_ORDER = SPI_CONFIG_ORDER_LsbFirst;
|
||||
spi_master_config.SPI_CPOL = SPI_CONFIG_CPOL_ActiveHigh;
|
||||
spi_master_config.SPI_CPHA = SPI_CONFIG_CPHA_Leading;
|
||||
|
||||
err_code = spi_master_open(SER_PHY_SPI_MASTER, &spi_master_config);
|
||||
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
#ifdef _SPI_5W_
|
||||
spi_5W_master_evt_handler_reg(SER_PHY_SPI_MASTER, ser_phy_spi_master_event_handler);
|
||||
#else
|
||||
spi_master_evt_handler_reg(SER_PHY_SPI_MASTER, ser_phy_spi_master_event_handler);
|
||||
#endif
|
||||
ser_phy_init_pendSV();
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_close(void)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_DISABLED;
|
||||
|
||||
m_callback_events_handler = NULL;
|
||||
|
||||
buffer_release(&mp_tx_buffer, &m_tx_buf_len);
|
||||
buffer_release(&mp_rx_buffer, &m_rx_buf_len);
|
||||
m_tx_packet_length = 0;
|
||||
m_accumulated_tx_packet_length = 0;
|
||||
m_current_tx_packet_length = 0;
|
||||
m_rx_packet_length = 0;
|
||||
m_accumulated_rx_packet_length = 0;
|
||||
m_current_rx_packet_length = 0;
|
||||
ser_phy_deinit_gpiote();
|
||||
spi_master_close(SER_PHY_SPI_MASTER);
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_interrupts_enable(void)
|
||||
{
|
||||
NVIC_EnableIRQ(SW_IRQn);
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_interrupts_disable(void)
|
||||
{
|
||||
NVIC_DisableIRQ(SW_IRQn);
|
||||
}
|
||||
|
||||
|
||||
#ifdef SER_PHY_DEBUG_APP_ENABLE
|
||||
|
||||
static spi_master_raw_callback_t m_spi_master_raw_evt_callback;
|
||||
|
||||
void debug_evt(spi_master_raw_evt_type_t evt, uint32_t data)
|
||||
{
|
||||
if (m_spi_master_raw_evt_callback)
|
||||
{
|
||||
spi_master_raw_evt_t e;
|
||||
e.evt = evt;
|
||||
e.data = data;
|
||||
m_spi_master_raw_evt_callback(e);
|
||||
}
|
||||
}
|
||||
|
||||
void debug_init(spi_master_raw_callback_t spi_master_raw_evt_callback)
|
||||
{
|
||||
m_spi_master_raw_evt_callback = spi_master_raw_evt_callback;
|
||||
}
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
@@ -0,0 +1,644 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/**@file
|
||||
*
|
||||
* @defgroup ser_phy_spi_5W_phy_driver_slave ser_phy_nrf51_spi_5W_slave.c
|
||||
* @{
|
||||
* @ingroup ser_phy_spi_5W_phy_driver_slave
|
||||
*
|
||||
* @brief SPI_5W_RAW PHY slave driver.
|
||||
*/
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "boards.h"
|
||||
#include "nrf_drv_spis.h"
|
||||
#include "ser_phy.h"
|
||||
#include "ser_config.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_gpiote.h"
|
||||
#include "nrf_soc.h"
|
||||
#include "app_error.h"
|
||||
#include "app_util.h"
|
||||
#include "ser_phy_config_conn.h"
|
||||
#include "ser_phy_debug_conn.h"
|
||||
#include "app_error.h"
|
||||
|
||||
#define _static static
|
||||
|
||||
#define SER_PHY_SPI_5W_MTU_SIZE SER_PHY_SPI_MTU_SIZE
|
||||
|
||||
#define SER_PHY_SPI_DEF_CHARACTER 0xFF //SPI default character. Character clocked out in case of an ignored transaction
|
||||
#define SER_PHY_SPI_ORC_CHARACTER 0xFF //SPI over-read character. Character clocked out after an over-read of the transmit buffer
|
||||
|
||||
static nrf_drv_spis_t m_spis = NRF_DRV_SPIS_INSTANCE(SER_PHY_SPI_SLAVE_INSTANCE);
|
||||
|
||||
#define _SPI_5W_
|
||||
|
||||
//SPI raw peripheral device configuration data
|
||||
typedef struct
|
||||
{
|
||||
int32_t pin_req; //SPI /REQ pin. -1 for not using
|
||||
int32_t pin_rdy; //SPI /RDY pin. -1 for not using
|
||||
int32_t ppi_rdy_ch; //SPI /RDY ppi ready channel
|
||||
int32_t gpiote_rdy_ch; //SPI /RDY pin ready channel
|
||||
} spi_slave_raw_trasp_cfg_t;
|
||||
|
||||
/**@brief States of the SPI transaction state machine. */
|
||||
typedef enum
|
||||
{
|
||||
SPI_RAW_STATE_UNKNOWN,
|
||||
SPI_RAW_STATE_SETUP_HEADER,
|
||||
SPI_RAW_STATE_RX_HEADER,
|
||||
SPI_RAW_STATE_MEM_REQUESTED,
|
||||
SPI_RAW_STATE_RX_PAYLOAD,
|
||||
SPI_RAW_STATE_TX_HEADER,
|
||||
SPI_RAW_STATE_TX_PAYLOAD,
|
||||
} trans_state_t;
|
||||
|
||||
_static spi_slave_raw_trasp_cfg_t m_spi_slave_raw_config;
|
||||
|
||||
_static uint16_t m_accumulated_rx_packet_length;
|
||||
_static uint16_t m_rx_packet_length;
|
||||
_static uint16_t m_current_rx_frame_length;
|
||||
|
||||
_static uint16_t m_accumulated_tx_packet_length;
|
||||
_static uint16_t m_tx_packet_length;
|
||||
_static uint16_t m_current_tx_frame_length;
|
||||
|
||||
_static uint8_t m_header_rx_buffer[SER_PHY_HEADER_SIZE + 1]; // + 1 for '0' guard in SPI_5W
|
||||
_static uint8_t m_header_tx_buffer[SER_PHY_HEADER_SIZE + 1]; // + 1 for '0' guard in SPI_5W
|
||||
|
||||
_static uint8_t m_tx_frame_buffer[SER_PHY_SPI_5W_MTU_SIZE];
|
||||
_static uint8_t m_rx_frame_buffer[SER_PHY_SPI_5W_MTU_SIZE];
|
||||
_static uint8_t m_zero_buff[SER_PHY_SPI_5W_MTU_SIZE] = { 0 }; //ROM'able declaration - all guard bytes
|
||||
|
||||
_static uint8_t * volatile m_p_rx_buffer = NULL;
|
||||
_static const uint8_t * volatile m_p_tx_buffer = NULL;
|
||||
|
||||
_static bool m_trash_payload_flag;
|
||||
_static bool m_buffer_reqested_flag;
|
||||
|
||||
_static trans_state_t m_trans_state = SPI_RAW_STATE_UNKNOWN;
|
||||
_static ser_phy_events_handler_t m_ser_phy_callback = NULL;
|
||||
|
||||
static void spi_slave_raw_assert(bool cond)
|
||||
{
|
||||
APP_ERROR_CHECK_BOOL(cond);
|
||||
}
|
||||
|
||||
static void callback_ser_phy_event(ser_phy_evt_t event)
|
||||
{
|
||||
if (m_ser_phy_callback)
|
||||
{
|
||||
m_ser_phy_callback(event);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void callback_memory_request(uint16_t size)
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
|
||||
event.evt_params.rx_buf_request.num_of_bytes = size;
|
||||
callback_ser_phy_event(event);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
static void callback_packet_received(uint8_t * pBuffer, uint16_t size)
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
|
||||
event.evt_params.rx_pkt_received.num_of_bytes = size;
|
||||
event.evt_params.rx_pkt_received.p_buffer = pBuffer;
|
||||
callback_ser_phy_event(event);
|
||||
return;
|
||||
}
|
||||
|
||||
static void callback_packet_dropped()
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED;
|
||||
callback_ser_phy_event(event);
|
||||
return;
|
||||
}
|
||||
|
||||
static void callback_packet_transmitted(void)
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
event.evt_type = SER_PHY_EVT_TX_PKT_SENT;
|
||||
callback_ser_phy_event(event);
|
||||
return;
|
||||
}
|
||||
|
||||
static void copy_buff(uint8_t * const p_dest, uint8_t const * const p_src, uint16_t len)
|
||||
{
|
||||
uint16_t index;
|
||||
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
p_dest[index] = p_src[index];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Function computes current packet length */
|
||||
static uint16_t compute_current_frame_length(const uint16_t packet_length,
|
||||
const uint16_t accumulated_packet_length)
|
||||
{
|
||||
uint16_t current_packet_length = packet_length - accumulated_packet_length;
|
||||
|
||||
if (current_packet_length > SER_PHY_SPI_5W_MTU_SIZE)
|
||||
{
|
||||
current_packet_length = SER_PHY_SPI_5W_MTU_SIZE;
|
||||
}
|
||||
|
||||
return current_packet_length;
|
||||
}
|
||||
|
||||
static uint32_t header_get()
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
err_code = nrf_drv_spis_buffers_set(&m_spis,
|
||||
(uint8_t *) m_zero_buff,
|
||||
SER_PHY_HEADER_SIZE,
|
||||
m_header_rx_buffer,
|
||||
SER_PHY_HEADER_SIZE);
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static uint32_t frame_get()
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_current_rx_frame_length = compute_current_frame_length(m_rx_packet_length,
|
||||
m_accumulated_rx_packet_length);
|
||||
|
||||
if (!m_trash_payload_flag)
|
||||
{
|
||||
err_code =
|
||||
nrf_drv_spis_buffers_set(&m_spis,
|
||||
(uint8_t *) m_zero_buff,
|
||||
m_current_rx_frame_length,
|
||||
&(m_p_rx_buffer[m_accumulated_rx_packet_length]),
|
||||
m_current_rx_frame_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = nrf_drv_spis_buffers_set(&m_spis,
|
||||
(uint8_t *) m_zero_buff,
|
||||
m_current_rx_frame_length,
|
||||
m_rx_frame_buffer,
|
||||
m_current_rx_frame_length);
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static uint32_t header_send(uint16_t len)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_header_tx_buffer[0] = (uint8_t) 0; //this is guard byte
|
||||
(void)uint16_encode(len, &(m_header_tx_buffer[1]));
|
||||
err_code = nrf_drv_spis_buffers_set(&m_spis,
|
||||
m_header_tx_buffer,
|
||||
SER_PHY_HEADER_SIZE + 1,
|
||||
m_header_rx_buffer,
|
||||
SER_PHY_HEADER_SIZE + 1);
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static uint32_t frame_send()
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_current_tx_frame_length = compute_current_frame_length(m_tx_packet_length,
|
||||
m_accumulated_tx_packet_length);
|
||||
|
||||
if (m_current_tx_frame_length == SER_PHY_SPI_5W_MTU_SIZE)
|
||||
{
|
||||
m_current_tx_frame_length -= 1; //extra space for guard byte must be taken into account for MTU
|
||||
}
|
||||
m_tx_frame_buffer[0] = 0; //guard byte
|
||||
copy_buff(&(m_tx_frame_buffer[1]),
|
||||
&(m_p_tx_buffer[m_accumulated_tx_packet_length]),
|
||||
m_current_tx_frame_length);
|
||||
err_code = nrf_drv_spis_buffers_set(&m_spis,
|
||||
m_tx_frame_buffer,
|
||||
m_current_tx_frame_length + 1,
|
||||
m_rx_frame_buffer,
|
||||
m_current_tx_frame_length + 1);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static void set_ready_line(void)
|
||||
{
|
||||
#ifndef _SPI_5W_
|
||||
//toggle - this should go high - but toggle is unsafe
|
||||
uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.gpiote_rdy_ch);
|
||||
*(uint32_t *)rdy_task = 1;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static void set_request_line(void)
|
||||
{
|
||||
//active low logic - set is 0
|
||||
nrf_gpio_pin_clear(m_spi_slave_raw_config.pin_req);
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(0);
|
||||
return;
|
||||
}
|
||||
|
||||
static void clear_request_line(void)
|
||||
{
|
||||
//active low logic - clear is 1
|
||||
nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req);
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_REQ_CLEARED(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Slave driver main state machine
|
||||
* For UML graph, please refer to SDK documentation
|
||||
*/
|
||||
static void spi_slave_event_handle(nrf_drv_spis_event_t event)
|
||||
{
|
||||
static uint32_t err_code = NRF_SUCCESS;
|
||||
static uint16_t packetLength;
|
||||
|
||||
switch (m_trans_state)
|
||||
{
|
||||
case SPI_RAW_STATE_SETUP_HEADER:
|
||||
m_trans_state = SPI_RAW_STATE_RX_HEADER;
|
||||
err_code = header_get();
|
||||
break;
|
||||
|
||||
case SPI_RAW_STATE_RX_HEADER:
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
|
||||
set_ready_line();
|
||||
}
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount);
|
||||
spi_slave_raw_assert(event.rx_amount == SER_PHY_HEADER_SIZE);
|
||||
packetLength = uint16_decode(m_header_rx_buffer);
|
||||
|
||||
if (packetLength != 0 )
|
||||
{
|
||||
m_trans_state = SPI_RAW_STATE_MEM_REQUESTED;
|
||||
m_buffer_reqested_flag = true;
|
||||
m_rx_packet_length = packetLength;
|
||||
callback_memory_request(packetLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_p_tx_buffer)
|
||||
{
|
||||
clear_request_line();
|
||||
m_trans_state = SPI_RAW_STATE_TX_HEADER;
|
||||
err_code = header_send(m_tx_packet_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
//there is nothing to send - zero response facilitates pooling - but perhaps, it should be assert
|
||||
err_code = header_send(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SPI_RAW_STATE_MEM_REQUESTED:
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_EVT_TYPE_MAX) //This is API dummy event
|
||||
{
|
||||
m_buffer_reqested_flag = false;
|
||||
m_trans_state = SPI_RAW_STATE_RX_PAYLOAD;
|
||||
m_accumulated_rx_packet_length = 0;
|
||||
err_code = frame_get();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SPI_RAW_STATE_RX_PAYLOAD:
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
|
||||
set_ready_line();
|
||||
}
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount);
|
||||
spi_slave_raw_assert(event.rx_amount == m_current_rx_frame_length);
|
||||
m_accumulated_rx_packet_length += m_current_rx_frame_length;
|
||||
|
||||
if (m_accumulated_rx_packet_length < m_rx_packet_length )
|
||||
{
|
||||
err_code = frame_get();
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_slave_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length);
|
||||
m_trans_state = SPI_RAW_STATE_RX_HEADER;
|
||||
err_code = header_get();
|
||||
|
||||
if (!m_trash_payload_flag)
|
||||
{
|
||||
callback_packet_received(m_p_rx_buffer, m_accumulated_rx_packet_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback_packet_dropped();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SPI_RAW_STATE_TX_HEADER:
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
|
||||
set_ready_line();
|
||||
}
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount);
|
||||
spi_slave_raw_assert(event.tx_amount == SER_PHY_HEADER_SIZE + 1);
|
||||
m_trans_state = SPI_RAW_STATE_TX_PAYLOAD;
|
||||
m_accumulated_tx_packet_length = 0;
|
||||
err_code = frame_send();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SPI_RAW_STATE_TX_PAYLOAD:
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
|
||||
set_ready_line();
|
||||
}
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount);
|
||||
spi_slave_raw_assert(event.tx_amount == m_current_tx_frame_length + 1);
|
||||
m_accumulated_tx_packet_length += m_current_tx_frame_length;
|
||||
|
||||
if ( m_accumulated_tx_packet_length < m_tx_packet_length )
|
||||
{
|
||||
err_code = frame_send();
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_slave_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length);
|
||||
//clear pointer before callback
|
||||
m_p_tx_buffer = NULL;
|
||||
callback_packet_transmitted();
|
||||
//spi slave TX transfer is possible only when RX is ready, so return to waiting for a header
|
||||
m_trans_state = SPI_RAW_STATE_RX_HEADER;
|
||||
err_code = header_get();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
|
||||
#ifndef _SPI_5W_
|
||||
static void spi_slave_gpiote_init(void)
|
||||
{
|
||||
if (!nrf_drv_gpiote_is_init())
|
||||
{
|
||||
(void)nrf_drv_gpiote_init();
|
||||
}
|
||||
nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
|
||||
(void)nrf_drv_gpiote_out_init(m_spi_slave_raw_config.gpiote_rdy_ch, &config);
|
||||
return;
|
||||
}
|
||||
|
||||
static void spi_slave_ppi_init(void)
|
||||
{
|
||||
uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.gpiote_rdy_ch);
|
||||
//Configure PPI channel to clear /RDY line
|
||||
NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].EEP = (uint32_t)(&NRF_SPIS1->EVENTS_END);
|
||||
NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].TEP = rdy_task;
|
||||
|
||||
//this works only for channels 0..15 - but soft device is using 8-15 anyway
|
||||
NRF_PPI->CHEN |= (1 << m_spi_slave_raw_config.ppi_rdy_ch);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void spi_slave_gpio_init(void)
|
||||
{
|
||||
nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req);
|
||||
nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_req);
|
||||
#ifndef _SPI_5W_
|
||||
nrf_gpio_pin_set(m_spi_slave_raw_config.pin_rdy);
|
||||
nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_rdy);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_interrupts_enable(void)
|
||||
{
|
||||
NVIC_EnableIRQ(nrfx_get_irq_number(m_spis.p_reg));
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_interrupts_disable(void)
|
||||
{
|
||||
NVIC_DisableIRQ(nrfx_get_irq_number(m_spis.p_reg));
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
|
||||
{
|
||||
uint32_t status = NRF_SUCCESS;
|
||||
nrf_drv_spis_event_t event;
|
||||
|
||||
ser_phy_interrupts_disable();
|
||||
|
||||
if (m_buffer_reqested_flag && (m_trans_state == SPI_RAW_STATE_MEM_REQUESTED))
|
||||
{
|
||||
m_p_rx_buffer = p_buffer;
|
||||
|
||||
if (m_p_rx_buffer)
|
||||
{
|
||||
m_trash_payload_flag = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_trash_payload_flag = true;
|
||||
}
|
||||
|
||||
event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition with dummy event
|
||||
event.rx_amount = 0;
|
||||
event.tx_amount = 0;
|
||||
spi_slave_event_handle(event);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NRF_ERROR_BUSY;
|
||||
}
|
||||
ser_phy_interrupts_enable();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
|
||||
{
|
||||
uint32_t status = NRF_SUCCESS;
|
||||
|
||||
if ( p_buffer == NULL || num_of_bytes == 0)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
ser_phy_interrupts_disable();
|
||||
|
||||
if ( m_p_tx_buffer == NULL)
|
||||
{
|
||||
m_tx_packet_length = num_of_bytes;
|
||||
m_p_tx_buffer = p_buffer;
|
||||
set_request_line();
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NRF_ERROR_BUSY;
|
||||
}
|
||||
ser_phy_interrupts_enable();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
|
||||
{
|
||||
uint32_t err_code;
|
||||
nrf_drv_spis_config_t spi_slave_config;
|
||||
nrf_drv_spis_event_t event;
|
||||
|
||||
if (m_trans_state != SPI_RAW_STATE_UNKNOWN)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (events_handler == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
//one ppi channel and one gpiote channel are used to drive RDY line
|
||||
m_spi_slave_raw_config.pin_req = SER_PHY_SPI_SLAVE_REQ_PIN;
|
||||
m_spi_slave_raw_config.pin_rdy = SER_PHY_SPI_SLAVE_RDY_PIN;
|
||||
m_spi_slave_raw_config.ppi_rdy_ch = SER_PHY_SPI_PPI_RDY_CH;
|
||||
m_spi_slave_raw_config.gpiote_rdy_ch = SER_PHY_SPI_GPIOTE_RDY_CH;
|
||||
|
||||
spi_slave_gpio_init();
|
||||
#ifndef _SPI_5W_
|
||||
spi_slave_gpiote_init();
|
||||
spi_slave_ppi_init();
|
||||
#endif
|
||||
|
||||
spi_slave_config.miso_pin = SER_CON_SPIS_MISO_PIN;
|
||||
spi_slave_config.mosi_pin = SER_CON_SPIS_MOSI_PIN;
|
||||
spi_slave_config.sck_pin = SER_CON_SPIS_SCK_PIN;
|
||||
spi_slave_config.csn_pin = SER_CON_SPIS_CSN_PIN;
|
||||
spi_slave_config.mode = NRF_DRV_SPIS_MODE_0;
|
||||
spi_slave_config.bit_order = NRF_DRV_SPIS_BIT_ORDER_LSB_FIRST;
|
||||
spi_slave_config.def = SER_PHY_SPI_DEF_CHARACTER;
|
||||
spi_slave_config.orc = SER_PHY_SPI_ORC_CHARACTER;
|
||||
spi_slave_config.csn_pullup = NRF_GPIO_PIN_PULLUP;
|
||||
spi_slave_config.irq_priority = APP_IRQ_PRIORITY_LOWEST;
|
||||
|
||||
//keep /CS high when init
|
||||
nrf_gpio_cfg_input(spi_slave_config.csn_pin, NRF_GPIO_PIN_PULLUP);
|
||||
|
||||
err_code = nrf_drv_spis_init(&m_spis, &spi_slave_config, spi_slave_event_handle);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
m_ser_phy_callback = events_handler;
|
||||
|
||||
m_trans_state = SPI_RAW_STATE_SETUP_HEADER;
|
||||
event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition for dummy event
|
||||
event.rx_amount = 0;
|
||||
event.tx_amount = 0;
|
||||
spi_slave_event_handle(event);
|
||||
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_close(void)
|
||||
{
|
||||
nrf_drv_spis_uninit(&m_spis);
|
||||
m_ser_phy_callback = NULL;
|
||||
m_trans_state = SPI_RAW_STATE_UNKNOWN;
|
||||
}
|
||||
@@ -0,0 +1,804 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/**@file
|
||||
*
|
||||
* @defgroup ser_phy_spi_phy_driver_master ser_phy_nrf51_spi_master.c
|
||||
* @{
|
||||
* @ingroup ser_phy_spi_phy_driver_master
|
||||
*
|
||||
* @brief SPI_RAW PHY master driver.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "nrf_drv_gpiote.h"
|
||||
#include "nrf_drv_spi.h"
|
||||
#include "ser_phy.h"
|
||||
#include "ser_config.h"
|
||||
#include "app_util.h"
|
||||
#include "app_util_platform.h"
|
||||
#include "app_error.h"
|
||||
#include "nrf_error.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_gpiote.h"
|
||||
#include "boards.h"
|
||||
#include "app_error.h"
|
||||
#include "ser_phy_config_app.h"
|
||||
#include "ser_phy_debug_app.h"
|
||||
|
||||
#define notUSE_PendSV
|
||||
|
||||
#ifdef USE_PendSV
|
||||
|
||||
#define SW_IRQn PendSV_IRQn
|
||||
#define SW_IRQ_Handler() PendSV_Handler()
|
||||
#define SET_Pend_SW_IRQ() SCB->ICSR = SCB->ICSR | SCB_ICSR_PENDSVSET_Msk //NVIC_SetPendingIRQ(PendSV_IRQn) - PendSV_IRQn is a negative - does not work with CMSIS
|
||||
|
||||
#else
|
||||
|
||||
#define SW_IRQn SWI3_IRQn
|
||||
#define SW_IRQ_Handler() SWI3_IRQHandler()
|
||||
#define SET_Pend_SW_IRQ() NVIC_SetPendingIRQ(SWI3_IRQn)
|
||||
#endif /* USE_PendSV */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SER_PHY_STATE_IDLE = 0,
|
||||
SER_PHY_STATE_TX_HEADER,
|
||||
SER_PHY_STATE_TX_WAIT_FOR_RDY,
|
||||
SER_PHY_STATE_TX_PAYLOAD,
|
||||
SER_PHY_STATE_RX_WAIT_FOR_RDY,
|
||||
SER_PHY_STATE_TX_ZERO_HEADER,
|
||||
SER_PHY_STATE_RX_HEADER,
|
||||
SER_PHY_STATE_MEMORY_REQUEST,
|
||||
SER_PHY_STATE_RX_PAYLOAD,
|
||||
SER_PHY_STATE_DISABLED
|
||||
} ser_phy_spi_master_state_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SER_PHY_EVT_GPIO_RDY = 0,
|
||||
SER_PHY_EVT_GPIO_REQ,
|
||||
SER_PHY_EVT_SPI_TRANSFER_DONE,
|
||||
SER_PHY_EVT_TX_API_CALL,
|
||||
SER_PHY_EVT_RX_API_CALL
|
||||
} ser_phy_event_source_t;
|
||||
|
||||
#define _static static
|
||||
|
||||
_static uint8_t * mp_tx_buffer = NULL;
|
||||
_static uint16_t m_tx_buf_len = 0;
|
||||
|
||||
_static uint8_t * mp_rx_buffer = NULL;
|
||||
_static uint16_t m_rx_buf_len = 0;
|
||||
_static uint8_t m_frame_buffer[SER_PHY_SPI_MTU_SIZE];
|
||||
_static uint8_t m_header_buffer[SER_PHY_HEADER_SIZE] = { 0 };
|
||||
|
||||
_static uint16_t m_tx_packet_length = 0;
|
||||
_static uint16_t m_accumulated_tx_packet_length = 0;
|
||||
_static uint16_t m_current_tx_packet_length = 0;
|
||||
|
||||
_static uint16_t m_rx_packet_length = 0;
|
||||
_static uint16_t m_accumulated_rx_packet_length = 0;
|
||||
_static uint16_t m_current_rx_packet_length = 0;
|
||||
|
||||
_static volatile bool m_pend_req_flag = 0;
|
||||
_static volatile bool m_pend_rdy_flag = 0;
|
||||
_static volatile bool m_pend_xfer_flag = 0;
|
||||
_static volatile bool m_pend_rx_api_flag = 0;
|
||||
_static volatile bool m_pend_tx_api_flag = 0;
|
||||
|
||||
_static volatile bool m_slave_ready_flag = false;
|
||||
_static volatile bool m_slave_request_flag = false;
|
||||
|
||||
_static ser_phy_events_handler_t m_callback_events_handler = NULL;
|
||||
_static ser_phy_spi_master_state_t m_spi_master_state = SER_PHY_STATE_DISABLED;
|
||||
|
||||
_static const nrf_drv_spi_t m_spi_master = SER_PHY_SPI_MASTER_INSTANCE;
|
||||
|
||||
static void ser_phy_switch_state(ser_phy_event_source_t evt_src);
|
||||
|
||||
static void spi_master_raw_assert(bool cond)
|
||||
{
|
||||
APP_ERROR_CHECK_BOOL(cond);
|
||||
}
|
||||
|
||||
void SW_IRQ_Handler()
|
||||
{
|
||||
if (m_pend_req_flag)
|
||||
{
|
||||
m_pend_req_flag = false;
|
||||
DEBUG_EVT_SPI_MASTER_RAW_REQUEST(0);
|
||||
ser_phy_switch_state(SER_PHY_EVT_GPIO_REQ);
|
||||
}
|
||||
|
||||
if (m_pend_rdy_flag)
|
||||
{
|
||||
m_pend_rdy_flag = false;
|
||||
DEBUG_EVT_SPI_MASTER_RAW_READY(0);
|
||||
ser_phy_switch_state(SER_PHY_EVT_GPIO_RDY);
|
||||
}
|
||||
|
||||
if (m_pend_xfer_flag)
|
||||
{
|
||||
m_pend_xfer_flag = false;
|
||||
DEBUG_EVT_SPI_MASTER_RAW_XFER_DONE(0);
|
||||
ser_phy_switch_state(SER_PHY_EVT_SPI_TRANSFER_DONE);
|
||||
}
|
||||
|
||||
if (m_pend_rx_api_flag)
|
||||
{
|
||||
m_pend_rx_api_flag = false;
|
||||
DEBUG_EVT_SPI_MASTER_RAW_API_CALL(0);
|
||||
ser_phy_switch_state(SER_PHY_EVT_RX_API_CALL);
|
||||
}
|
||||
|
||||
if (m_pend_tx_api_flag)
|
||||
{
|
||||
m_pend_tx_api_flag = false;
|
||||
DEBUG_EVT_SPI_MASTER_RAW_API_CALL(0);
|
||||
ser_phy_switch_state(SER_PHY_EVT_TX_API_CALL);
|
||||
}
|
||||
}
|
||||
|
||||
static void ser_phy_spi_master_ready(nrf_drv_gpiote_pin_t pin,
|
||||
nrf_gpiote_polarity_t action)
|
||||
{
|
||||
if (nrf_gpio_pin_read(pin) == 0)
|
||||
{
|
||||
m_slave_ready_flag = true;
|
||||
m_pend_rdy_flag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_slave_ready_flag = false;
|
||||
}
|
||||
|
||||
DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE((uint32_t) !m_slave_ready_flag);
|
||||
SET_Pend_SW_IRQ();
|
||||
}
|
||||
|
||||
static void ser_phy_spi_master_request(nrf_drv_gpiote_pin_t pin,
|
||||
nrf_gpiote_polarity_t action)
|
||||
{
|
||||
if (nrf_gpio_pin_read(pin) == 0)
|
||||
{
|
||||
m_slave_request_flag = true;
|
||||
m_pend_req_flag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_slave_request_flag = false;
|
||||
}
|
||||
|
||||
DEBUG_EVT_SPI_MASTER_RAW_REQUEST_EDGE((uint32_t) !m_slave_request_flag);
|
||||
SET_Pend_SW_IRQ();
|
||||
}
|
||||
|
||||
/* Send event SER_PHY_EVT_TX_PKT_SENT */
|
||||
static __INLINE void callback_packet_sent()
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
DEBUG_EVT_SPI_MASTER_PHY_TX_PKT_SENT(0);
|
||||
|
||||
event.evt_type = SER_PHY_EVT_TX_PKT_SENT;
|
||||
m_callback_events_handler(event);
|
||||
}
|
||||
|
||||
/* Send event SER_PHY_EVT_RX_PKT_DROPPED */
|
||||
static __INLINE void callback_packet_dropped()
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_DROPPED(0);
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED;
|
||||
m_callback_events_handler(event);
|
||||
}
|
||||
|
||||
/* Send event SER_PHY_EVT_RX_PKT_RECEIVED */
|
||||
static __INLINE void callback_packet_received()
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_RECEIVED(0);
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
|
||||
event.evt_params.rx_pkt_received.p_buffer = mp_rx_buffer;
|
||||
event.evt_params.rx_pkt_received.num_of_bytes = m_rx_buf_len;
|
||||
m_callback_events_handler(event);
|
||||
}
|
||||
|
||||
/* Send event SER_PHY_EVT_RX_BUF_REQUEST */
|
||||
static __INLINE void callback_mem_request()
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
DEBUG_EVT_SPI_MASTER_PHY_BUF_REQUEST(0);
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
|
||||
event.evt_params.rx_buf_request.num_of_bytes = m_rx_buf_len;
|
||||
m_callback_events_handler(event);
|
||||
}
|
||||
|
||||
/* Release buffer */
|
||||
static __INLINE void buffer_release(uint8_t * * const pp_buffer,
|
||||
uint16_t * const p_buf_len)
|
||||
{
|
||||
*pp_buffer = NULL;
|
||||
*p_buf_len = 0;
|
||||
}
|
||||
|
||||
/* Function computes current packet length */
|
||||
static uint16_t compute_current_packet_length(const uint16_t packet_length,
|
||||
const uint16_t accumulated_packet_length)
|
||||
{
|
||||
uint16_t current_packet_length = packet_length - accumulated_packet_length;
|
||||
|
||||
if (current_packet_length > SER_PHY_SPI_MTU_SIZE)
|
||||
{
|
||||
current_packet_length = SER_PHY_SPI_MTU_SIZE;
|
||||
}
|
||||
|
||||
return current_packet_length;
|
||||
}
|
||||
|
||||
static __INLINE uint32_t header_send(const uint16_t length)
|
||||
{
|
||||
uint8_t buf_len_size = uint16_encode(length, m_header_buffer);
|
||||
|
||||
return nrf_drv_spi_transfer(&m_spi_master, m_header_buffer, buf_len_size, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
static __INLINE uint32_t frame_send()
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_current_tx_packet_length = compute_current_packet_length(m_tx_packet_length,
|
||||
m_accumulated_tx_packet_length);
|
||||
err_code =
|
||||
nrf_drv_spi_transfer(&m_spi_master,
|
||||
&mp_tx_buffer[m_accumulated_tx_packet_length],
|
||||
m_current_tx_packet_length,
|
||||
NULL,
|
||||
0);
|
||||
m_accumulated_tx_packet_length += m_current_tx_packet_length;
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static __INLINE uint32_t header_get()
|
||||
{
|
||||
return nrf_drv_spi_transfer(&m_spi_master, NULL, 0, m_header_buffer, SER_PHY_HEADER_SIZE);
|
||||
}
|
||||
|
||||
static __INLINE uint32_t frame_get()
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_current_rx_packet_length = compute_current_packet_length(m_rx_packet_length,
|
||||
m_accumulated_rx_packet_length);
|
||||
|
||||
if (mp_rx_buffer)
|
||||
{
|
||||
err_code = nrf_drv_spi_transfer(&m_spi_master,
|
||||
NULL,
|
||||
0,
|
||||
&(mp_rx_buffer[m_accumulated_rx_packet_length]),
|
||||
m_current_rx_packet_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = nrf_drv_spi_transfer(&m_spi_master,
|
||||
NULL,
|
||||
0,
|
||||
m_frame_buffer,
|
||||
m_current_rx_packet_length);
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Master driver main state machine
|
||||
* Executed only in the context of PendSV_Handler()
|
||||
* For UML graph, please refer to SDK documentation
|
||||
*/
|
||||
static void ser_phy_switch_state(ser_phy_event_source_t evt_src)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
static bool m_wait_for_ready_flag = false; //local scheduling flag to defer RDY events
|
||||
|
||||
switch (m_spi_master_state)
|
||||
{
|
||||
|
||||
case SER_PHY_STATE_IDLE:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_GPIO_REQ)
|
||||
{
|
||||
m_wait_for_ready_flag = false;
|
||||
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
|
||||
err_code = header_send(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY;
|
||||
}
|
||||
}
|
||||
else if (evt_src == SER_PHY_EVT_TX_API_CALL)
|
||||
{
|
||||
spi_master_raw_assert(mp_tx_buffer != NULL); //api event with tx_buffer == NULL has no sense
|
||||
m_wait_for_ready_flag = false;
|
||||
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_HEADER;
|
||||
err_code = header_send(m_tx_buf_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_TX_WAIT_FOR_RDY:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_GPIO_RDY)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_HEADER;
|
||||
err_code = header_send(m_tx_buf_len);
|
||||
}
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_RX_WAIT_FOR_RDY:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_GPIO_RDY)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
|
||||
err_code = header_send(0);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_TX_HEADER:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
|
||||
{
|
||||
m_tx_packet_length = m_tx_buf_len;
|
||||
m_accumulated_tx_packet_length = 0;
|
||||
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD;
|
||||
err_code = frame_send();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_wait_for_ready_flag = true;
|
||||
}
|
||||
}
|
||||
else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_wait_for_ready_flag)
|
||||
{
|
||||
m_wait_for_ready_flag = false;
|
||||
m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD;
|
||||
err_code = frame_send();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_TX_PAYLOAD:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
|
||||
{
|
||||
if (m_accumulated_tx_packet_length < m_tx_packet_length)
|
||||
{
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
err_code = frame_send();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_wait_for_ready_flag = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_master_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length);
|
||||
buffer_release(&mp_tx_buffer, &m_tx_buf_len);
|
||||
callback_packet_sent();
|
||||
if ( m_slave_request_flag)
|
||||
{
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
|
||||
err_code = header_send(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_IDLE; //m_Tx_buffer is NULL - have to wait for API event
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_wait_for_ready_flag )
|
||||
{
|
||||
m_wait_for_ready_flag = false;
|
||||
err_code = frame_send();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_TX_ZERO_HEADER:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
|
||||
{
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_RX_HEADER;
|
||||
err_code = header_get();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_wait_for_ready_flag = true;
|
||||
}
|
||||
}
|
||||
else if ( (evt_src == SER_PHY_EVT_GPIO_RDY) && m_wait_for_ready_flag)
|
||||
{
|
||||
m_wait_for_ready_flag = false;
|
||||
m_spi_master_state = SER_PHY_STATE_RX_HEADER;
|
||||
err_code = header_get();
|
||||
}
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_RX_HEADER:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_MEMORY_REQUEST;
|
||||
m_rx_buf_len = uint16_decode(m_header_buffer);
|
||||
m_rx_packet_length = m_rx_buf_len;
|
||||
callback_mem_request();
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_MEMORY_REQUEST:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_RX_API_CALL)
|
||||
{
|
||||
m_accumulated_rx_packet_length = 0;
|
||||
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD;
|
||||
err_code = frame_get();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_wait_for_ready_flag = true;
|
||||
}
|
||||
}
|
||||
else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_wait_for_ready_flag)
|
||||
{
|
||||
m_wait_for_ready_flag = false;
|
||||
m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD;
|
||||
err_code = frame_get();
|
||||
}
|
||||
break;
|
||||
|
||||
case SER_PHY_STATE_RX_PAYLOAD:
|
||||
|
||||
if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
|
||||
{
|
||||
m_accumulated_rx_packet_length += m_current_rx_packet_length;
|
||||
|
||||
if (m_accumulated_rx_packet_length < m_rx_packet_length)
|
||||
{
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
err_code = frame_get();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_wait_for_ready_flag = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_master_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length);
|
||||
|
||||
if (mp_rx_buffer == NULL)
|
||||
{
|
||||
callback_packet_dropped();
|
||||
}
|
||||
else
|
||||
{
|
||||
callback_packet_received();
|
||||
}
|
||||
buffer_release(&mp_rx_buffer, &m_rx_buf_len);
|
||||
if (mp_tx_buffer != NULL) //mp_tx_buffer !=NULL, this means that API_EVT was scheduled
|
||||
{
|
||||
if (m_slave_ready_flag )
|
||||
{
|
||||
err_code = header_send(m_tx_buf_len);
|
||||
m_spi_master_state = SER_PHY_STATE_TX_HEADER;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY;
|
||||
}
|
||||
}
|
||||
else if (m_slave_request_flag)
|
||||
{
|
||||
if (m_slave_ready_flag)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
|
||||
err_code = header_send(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_IDLE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if ( evt_src == SER_PHY_EVT_GPIO_RDY && m_wait_for_ready_flag)
|
||||
{
|
||||
m_wait_for_ready_flag = false;
|
||||
err_code = frame_get();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
(void)err_code;
|
||||
}
|
||||
}
|
||||
|
||||
static void ser_phy_spi_master_event_handler(nrf_drv_spi_evt_t const * p_event,
|
||||
void * p_context)
|
||||
{
|
||||
switch (p_event->type)
|
||||
{
|
||||
case NRF_DRV_SPI_EVENT_DONE:
|
||||
|
||||
/* Switch state */
|
||||
m_pend_xfer_flag = true;
|
||||
SET_Pend_SW_IRQ();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ser_phy_init_PendSV(void)
|
||||
{
|
||||
NVIC_SetPriority(SW_IRQn, APP_IRQ_PRIORITY_MID);
|
||||
NVIC_EnableIRQ(SW_IRQn);
|
||||
}
|
||||
|
||||
static ret_code_t ser_phy_init_gpiote(void)
|
||||
{
|
||||
if (!nrf_drv_gpiote_is_init())
|
||||
{
|
||||
(void)nrf_drv_gpiote_init();
|
||||
}
|
||||
NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH);
|
||||
|
||||
nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
|
||||
/* Enable pullup to ensure high state while connectivity device is reset */
|
||||
config.pull = NRF_GPIO_PIN_PULLUP;
|
||||
ret_code_t err_code = nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST,
|
||||
&config, ser_phy_spi_master_request);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST,true);
|
||||
|
||||
err_code = nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_READY,
|
||||
&config, ser_phy_spi_master_ready);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_READY,true);
|
||||
|
||||
m_slave_request_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST));
|
||||
m_slave_ready_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_READY));
|
||||
|
||||
NVIC_ClearPendingIRQ(SW_IRQn);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
static void ser_phy_deinit_gpiote(void)
|
||||
{
|
||||
nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST);
|
||||
nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_READY);
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
|
||||
{
|
||||
if (p_buffer == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
if (num_of_bytes == 0)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (mp_tx_buffer != NULL)
|
||||
{
|
||||
return NRF_ERROR_BUSY;
|
||||
}
|
||||
|
||||
//ser_phy_interrupts_disable();
|
||||
CRITICAL_REGION_ENTER();
|
||||
mp_tx_buffer = (uint8_t *)p_buffer;
|
||||
m_tx_buf_len = num_of_bytes;
|
||||
m_pend_tx_api_flag = true;
|
||||
SET_Pend_SW_IRQ();
|
||||
//ser_phy_interrupts_enable();
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
|
||||
{
|
||||
if (m_spi_master_state != SER_PHY_STATE_MEMORY_REQUEST)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
//ser_phy_interrupts_disable();
|
||||
CRITICAL_REGION_ENTER();
|
||||
mp_rx_buffer = p_buffer;
|
||||
m_pend_rx_api_flag = true;
|
||||
SET_Pend_SW_IRQ();
|
||||
//ser_phy_interrupts_enable();
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
|
||||
{
|
||||
if (m_spi_master_state != SER_PHY_STATE_DISABLED)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (events_handler == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
|
||||
m_spi_master_state = SER_PHY_STATE_IDLE;
|
||||
m_callback_events_handler = events_handler;
|
||||
nrf_drv_spi_config_t spi_master_config = {
|
||||
.sck_pin = SER_PHY_SPI_MASTER_PIN_SCK,
|
||||
.mosi_pin = SER_PHY_SPI_MASTER_PIN_MOSI,
|
||||
.miso_pin = SER_PHY_SPI_MASTER_PIN_MISO,
|
||||
.ss_pin = SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT,
|
||||
.irq_priority = APP_IRQ_PRIORITY_MID,
|
||||
.orc = 0,
|
||||
.frequency = SER_PHY_SPI_FREQUENCY,
|
||||
.mode = NRF_DRV_SPI_MODE_0,
|
||||
.bit_order = NRF_DRV_SPI_BIT_ORDER_LSB_FIRST,
|
||||
};
|
||||
err_code = nrf_drv_spi_init(&m_spi_master,
|
||||
&spi_master_config,
|
||||
ser_phy_spi_master_event_handler,
|
||||
NULL);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
|
||||
err_code = ser_phy_init_gpiote();
|
||||
ser_phy_init_PendSV();
|
||||
return err_code;
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_close(void)
|
||||
{
|
||||
m_spi_master_state = SER_PHY_STATE_DISABLED;
|
||||
|
||||
m_callback_events_handler = NULL;
|
||||
|
||||
buffer_release(&mp_tx_buffer, &m_tx_buf_len);
|
||||
buffer_release(&mp_rx_buffer, &m_rx_buf_len);
|
||||
|
||||
m_tx_packet_length = 0;
|
||||
m_accumulated_tx_packet_length = 0;
|
||||
m_current_tx_packet_length = 0;
|
||||
|
||||
m_rx_packet_length = 0;
|
||||
m_accumulated_rx_packet_length = 0;
|
||||
m_current_rx_packet_length = 0;
|
||||
|
||||
ser_phy_deinit_gpiote();
|
||||
nrf_drv_spi_uninit(&m_spi_master);
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
/* only PendSV may interact with ser_phy layer, other interrupts are internal */
|
||||
void ser_phy_interrupts_enable(void)
|
||||
{
|
||||
NVIC_EnableIRQ(SW_IRQn);
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_interrupts_disable(void)
|
||||
{
|
||||
NVIC_DisableIRQ(SW_IRQn);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,613 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/**@file
|
||||
*
|
||||
* @defgroup ser_phy_spi_phy_driver_slave ser_phy_nrf51_spi_slave.c
|
||||
* @{
|
||||
* @ingroup ser_phy_spi_phy_driver_slave
|
||||
*
|
||||
* @brief SPI_RAW PHY slave driver.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "app_error.h"
|
||||
#include "app_util.h"
|
||||
#include "boards.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_drv_gpiote.h"
|
||||
#include "nrf_soc.h"
|
||||
#include "nrf_drv_spis.h"
|
||||
#include "ser_config.h"
|
||||
#include "ser_phy.h"
|
||||
#include "ser_phy_config_conn.h"
|
||||
#include "ser_phy_debug_conn.h"
|
||||
|
||||
#define SER_PHY_SPI_DEF_CHARACTER 0xFF //SPI default character. Character clocked out in case of an ignored transaction
|
||||
#define SER_PHY_SPI_ORC_CHARACTER 0xFF //SPI over-read character. Character clocked out after an over-read of the transmit buffer
|
||||
|
||||
static nrf_drv_spis_t m_spis = NRF_DRV_SPIS_INSTANCE(SER_PHY_SPI_SLAVE_INSTANCE);
|
||||
|
||||
#ifdef NRF_SPIS0
|
||||
#define SPI_SLAVE_REG NRF_SPIS0
|
||||
#else
|
||||
#define SPI_SLAVE_REG NRF_SPIS1
|
||||
#endif
|
||||
|
||||
//SPI raw peripheral device configuration data
|
||||
typedef struct
|
||||
{
|
||||
int32_t pin_req; //SPI /REQ pin. -1 for not using
|
||||
int32_t pin_rdy; //SPI /RDY pin. -1 for not using
|
||||
int32_t ppi_rdy_ch; //SPI /RDY ppi ready channel
|
||||
int32_t gpiote_rdy_ch; //SPI /RDY pin ready channel
|
||||
} spi_slave_raw_trasp_cfg_t;
|
||||
|
||||
/**@brief States of the SPI transaction state machine. */
|
||||
typedef enum
|
||||
{
|
||||
SPI_RAW_STATE_UNKNOWN,
|
||||
SPI_RAW_STATE_SETUP_HEADER,
|
||||
SPI_RAW_STATE_RX_HEADER,
|
||||
SPI_RAW_STATE_MEM_REQUESTED,
|
||||
SPI_RAW_STATE_RX_PAYLOAD,
|
||||
SPI_RAW_STATE_TX_HEADER,
|
||||
SPI_RAW_STATE_TX_PAYLOAD,
|
||||
} trans_state_t;
|
||||
|
||||
#define _static static
|
||||
|
||||
static spi_slave_raw_trasp_cfg_t m_spi_slave_raw_config;
|
||||
|
||||
_static uint16_t m_accumulated_rx_packet_length;
|
||||
_static uint16_t m_rx_packet_length;
|
||||
_static uint16_t m_current_rx_frame_length;
|
||||
|
||||
_static uint16_t m_accumulated_tx_packet_length;
|
||||
_static uint16_t m_tx_packet_length;
|
||||
_static uint16_t m_current_tx_frame_length;
|
||||
|
||||
_static uint8_t m_header_rx_buffer[SER_PHY_HEADER_SIZE];
|
||||
_static uint8_t m_header_tx_buffer[SER_PHY_HEADER_SIZE];
|
||||
|
||||
_static uint8_t m_frame_buffer[SER_PHY_SPI_MTU_SIZE]; //trash storage
|
||||
_static uint8_t m_zero_buffer[SER_PHY_SPI_MTU_SIZE] = { 0 }; //ROM'able declaration
|
||||
|
||||
_static uint8_t * volatile m_p_rx_buffer = NULL;
|
||||
_static const uint8_t * volatile m_p_tx_buffer = NULL;
|
||||
|
||||
_static bool m_trash_payload_flag;
|
||||
_static bool m_buffer_reqested_flag;
|
||||
|
||||
_static trans_state_t m_trans_state = SPI_RAW_STATE_UNKNOWN;
|
||||
_static ser_phy_events_handler_t m_ser_phy_callback = NULL;
|
||||
|
||||
static void spi_slave_raw_assert(bool cond)
|
||||
{
|
||||
APP_ERROR_CHECK_BOOL(cond);
|
||||
}
|
||||
|
||||
static void callback_ser_phy_event(ser_phy_evt_t event)
|
||||
{
|
||||
if (m_ser_phy_callback)
|
||||
{
|
||||
m_ser_phy_callback(event);
|
||||
}
|
||||
}
|
||||
|
||||
static void callback_memory_request(uint16_t size)
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
DEBUG_EVT_SPI_SLAVE_PHY_BUF_REQUEST(0);
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
|
||||
event.evt_params.rx_buf_request.num_of_bytes = size;
|
||||
callback_ser_phy_event(event);
|
||||
}
|
||||
|
||||
static void callback_packet_received(uint8_t * pBuffer, uint16_t size)
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
DEBUG_EVT_SPI_SLAVE_PHY_PKT_RECEIVED(0);
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
|
||||
event.evt_params.rx_pkt_received.num_of_bytes = size;
|
||||
event.evt_params.rx_pkt_received.p_buffer = pBuffer;
|
||||
callback_ser_phy_event(event);
|
||||
}
|
||||
|
||||
static void callback_packet_dropped()
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
DEBUG_EVT_SPI_SLAVE_PHY_PKT_DROPPED(0);
|
||||
|
||||
event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED;
|
||||
callback_ser_phy_event(event);
|
||||
}
|
||||
|
||||
static void callback_packet_transmitted(void)
|
||||
{
|
||||
ser_phy_evt_t event;
|
||||
|
||||
DEBUG_EVT_SPI_SLAVE_PHY_PKT_SENT(0);
|
||||
|
||||
event.evt_type = SER_PHY_EVT_TX_PKT_SENT;
|
||||
callback_ser_phy_event(event);
|
||||
}
|
||||
|
||||
/* Function computes current packet length */
|
||||
static uint16_t compute_current_frame_length(const uint16_t packet_length,
|
||||
const uint16_t accumulated_packet_length)
|
||||
{
|
||||
uint16_t current_packet_length = packet_length - accumulated_packet_length;
|
||||
|
||||
if (current_packet_length > SER_PHY_SPI_MTU_SIZE)
|
||||
{
|
||||
current_packet_length = SER_PHY_SPI_MTU_SIZE;
|
||||
}
|
||||
|
||||
return current_packet_length;
|
||||
}
|
||||
|
||||
static uint32_t header_get()
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
err_code = nrf_drv_spis_buffers_set(&m_spis,
|
||||
(uint8_t *) m_zero_buffer,
|
||||
SER_PHY_HEADER_SIZE,
|
||||
m_header_rx_buffer,
|
||||
SER_PHY_HEADER_SIZE);
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static uint32_t frame_get()
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_current_rx_frame_length = compute_current_frame_length(m_rx_packet_length,
|
||||
m_accumulated_rx_packet_length);
|
||||
|
||||
if (!m_trash_payload_flag)
|
||||
{
|
||||
err_code =
|
||||
nrf_drv_spis_buffers_set(&m_spis,
|
||||
(uint8_t *) m_zero_buffer,
|
||||
m_current_rx_frame_length,
|
||||
&(m_p_rx_buffer[m_accumulated_rx_packet_length]),
|
||||
m_current_rx_frame_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = nrf_drv_spis_buffers_set(&m_spis,
|
||||
(uint8_t *) m_zero_buffer,
|
||||
m_current_rx_frame_length,
|
||||
m_frame_buffer,
|
||||
m_current_rx_frame_length);
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static uint32_t header_send(uint16_t len)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
(void) uint16_encode(len, m_header_tx_buffer);
|
||||
err_code =
|
||||
nrf_drv_spis_buffers_set(&m_spis,
|
||||
m_header_tx_buffer,
|
||||
sizeof (m_header_tx_buffer),
|
||||
m_header_rx_buffer,
|
||||
sizeof (m_header_tx_buffer));
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static uint32_t frame_send()
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_current_tx_frame_length = compute_current_frame_length(m_tx_packet_length,
|
||||
m_accumulated_tx_packet_length);
|
||||
err_code =
|
||||
nrf_drv_spis_buffers_set(&m_spis,
|
||||
(uint8_t *) &(m_p_tx_buffer[m_accumulated_tx_packet_length]),
|
||||
m_current_tx_frame_length,
|
||||
m_frame_buffer,
|
||||
m_current_tx_frame_length);
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static void set_ready_line(void)
|
||||
{
|
||||
//toggle - this should go high - but toggle is unsafe
|
||||
uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.pin_rdy);
|
||||
*(uint32_t *)rdy_task = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
static void set_request_line(void)
|
||||
{
|
||||
//active low logic - set is 0
|
||||
nrf_gpio_pin_clear(m_spi_slave_raw_config.pin_req);
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(0);
|
||||
}
|
||||
|
||||
static void clear_request_line(void)
|
||||
{
|
||||
//active low logic - clear is 1
|
||||
nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req);
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Slave driver main state machine
|
||||
* For UML graph, please refer to SDK documentation
|
||||
*/
|
||||
static void spi_slave_event_handle(nrf_drv_spis_event_t event)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
static uint16_t packetLength;
|
||||
|
||||
switch (m_trans_state)
|
||||
{
|
||||
case SPI_RAW_STATE_SETUP_HEADER:
|
||||
m_trans_state = SPI_RAW_STATE_RX_HEADER;
|
||||
err_code = header_get();
|
||||
break;
|
||||
|
||||
case SPI_RAW_STATE_RX_HEADER:
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
|
||||
set_ready_line();
|
||||
}
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount);
|
||||
spi_slave_raw_assert(event.rx_amount == SER_PHY_HEADER_SIZE);
|
||||
packetLength = uint16_decode(m_header_rx_buffer);
|
||||
|
||||
if (packetLength != 0 )
|
||||
{
|
||||
m_trans_state = SPI_RAW_STATE_MEM_REQUESTED;
|
||||
m_buffer_reqested_flag = true;
|
||||
m_rx_packet_length = packetLength;
|
||||
callback_memory_request(packetLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_p_tx_buffer)
|
||||
{
|
||||
clear_request_line();
|
||||
m_trans_state = SPI_RAW_STATE_TX_HEADER;
|
||||
err_code = header_send(m_tx_packet_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
//there is nothing to send - zero response facilitates pooling - but perhaps, it should be assert
|
||||
err_code = header_send(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SPI_RAW_STATE_MEM_REQUESTED:
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_EVT_TYPE_MAX) //This is API dummy event
|
||||
{
|
||||
m_buffer_reqested_flag = false;
|
||||
m_trans_state = SPI_RAW_STATE_RX_PAYLOAD;
|
||||
m_accumulated_rx_packet_length = 0;
|
||||
err_code = frame_get();
|
||||
}
|
||||
break;
|
||||
|
||||
case SPI_RAW_STATE_RX_PAYLOAD:
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
|
||||
set_ready_line();
|
||||
}
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount);
|
||||
spi_slave_raw_assert(event.rx_amount == m_current_rx_frame_length);
|
||||
m_accumulated_rx_packet_length += m_current_rx_frame_length;
|
||||
|
||||
if (m_accumulated_rx_packet_length < m_rx_packet_length )
|
||||
{
|
||||
err_code = frame_get();
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_slave_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length);
|
||||
m_trans_state = SPI_RAW_STATE_RX_HEADER;
|
||||
err_code = header_get();
|
||||
|
||||
if (!m_trash_payload_flag)
|
||||
{
|
||||
callback_packet_received(m_p_rx_buffer, m_accumulated_rx_packet_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback_packet_dropped();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SPI_RAW_STATE_TX_HEADER:
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
|
||||
set_ready_line();
|
||||
}
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount);
|
||||
spi_slave_raw_assert(event.tx_amount == SER_PHY_HEADER_SIZE);
|
||||
m_trans_state = SPI_RAW_STATE_TX_PAYLOAD;
|
||||
m_accumulated_tx_packet_length = 0;
|
||||
err_code = frame_send();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SPI_RAW_STATE_TX_PAYLOAD:
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
|
||||
set_ready_line();
|
||||
}
|
||||
|
||||
if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
|
||||
{
|
||||
DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount);
|
||||
spi_slave_raw_assert(event.tx_amount == m_current_tx_frame_length);
|
||||
m_accumulated_tx_packet_length += m_current_tx_frame_length;
|
||||
|
||||
if ( m_accumulated_tx_packet_length < m_tx_packet_length )
|
||||
{
|
||||
err_code = frame_send();
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_slave_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length);
|
||||
//clear pointer before callback
|
||||
m_p_tx_buffer = NULL;
|
||||
callback_packet_transmitted();
|
||||
//spi slave TX transfer is possible only when RX is ready, so return to waiting for a header
|
||||
m_trans_state = SPI_RAW_STATE_RX_HEADER;
|
||||
err_code = header_get();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
|
||||
static void spi_slave_gpiote_init(void)
|
||||
{
|
||||
if (!nrf_drv_gpiote_is_init())
|
||||
{
|
||||
(void)nrf_drv_gpiote_init();
|
||||
}
|
||||
nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
|
||||
(void) nrf_drv_gpiote_out_init(m_spi_slave_raw_config.pin_rdy, &config);
|
||||
(void) nrf_drv_gpiote_out_task_enable(m_spi_slave_raw_config.pin_rdy);
|
||||
return;
|
||||
}
|
||||
|
||||
static void spi_slave_ppi_init(void)
|
||||
{
|
||||
uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.pin_rdy);
|
||||
//Configure PPI channel to clear /RDY line
|
||||
NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].EEP = (uint32_t)(&SPI_SLAVE_REG->EVENTS_END);
|
||||
NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].TEP = rdy_task;
|
||||
|
||||
//this works only for channels 0..15 - but soft device is using 8-15 anyway
|
||||
NRF_PPI->CHEN |= (1 << m_spi_slave_raw_config.ppi_rdy_ch);
|
||||
return;
|
||||
}
|
||||
|
||||
static void spi_slave_gpio_init(void)
|
||||
{
|
||||
nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req);
|
||||
nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_req);
|
||||
nrf_gpio_pin_set(m_spi_slave_raw_config.pin_rdy);
|
||||
nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_rdy);
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_interrupts_enable(void)
|
||||
{
|
||||
(void)sd_nvic_EnableIRQ(nrfx_get_irq_number(m_spis.p_reg));
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_interrupts_disable(void)
|
||||
{
|
||||
(void)sd_nvic_DisableIRQ(nrfx_get_irq_number(m_spis.p_reg));
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
|
||||
{
|
||||
uint32_t status = NRF_SUCCESS;
|
||||
nrf_drv_spis_event_t event;
|
||||
|
||||
ser_phy_interrupts_disable();
|
||||
|
||||
if (m_buffer_reqested_flag && (m_trans_state == SPI_RAW_STATE_MEM_REQUESTED))
|
||||
{
|
||||
m_p_rx_buffer = p_buffer;
|
||||
|
||||
if (m_p_rx_buffer)
|
||||
{
|
||||
m_trash_payload_flag = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_trash_payload_flag = true;
|
||||
}
|
||||
event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition with dummy event
|
||||
event.rx_amount = 0;
|
||||
event.tx_amount = 0;
|
||||
spi_slave_event_handle(event);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NRF_ERROR_BUSY;
|
||||
}
|
||||
ser_phy_interrupts_enable();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
|
||||
{
|
||||
uint32_t status = NRF_SUCCESS;
|
||||
|
||||
if ( p_buffer == NULL || num_of_bytes == 0)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
ser_phy_interrupts_disable();
|
||||
|
||||
if ( m_p_tx_buffer == NULL)
|
||||
{
|
||||
m_tx_packet_length = num_of_bytes;
|
||||
m_p_tx_buffer = p_buffer;
|
||||
set_request_line();
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NRF_ERROR_BUSY;
|
||||
}
|
||||
ser_phy_interrupts_enable();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
|
||||
{
|
||||
uint32_t err_code;
|
||||
nrf_drv_spis_config_t spi_slave_config;
|
||||
nrf_drv_spis_event_t event;
|
||||
|
||||
if (m_trans_state != SPI_RAW_STATE_UNKNOWN)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (events_handler == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
//one ppi channel and one gpiote channel are used to drive RDY line
|
||||
m_spi_slave_raw_config.pin_req = SER_PHY_SPI_SLAVE_REQ_PIN;
|
||||
m_spi_slave_raw_config.pin_rdy = SER_PHY_SPI_SLAVE_RDY_PIN;
|
||||
m_spi_slave_raw_config.ppi_rdy_ch = SER_PHY_SPI_PPI_RDY_CH;
|
||||
m_spi_slave_raw_config.gpiote_rdy_ch = SER_PHY_SPI_GPIOTE_RDY_CH;
|
||||
|
||||
spi_slave_gpio_init();
|
||||
spi_slave_gpiote_init();
|
||||
spi_slave_ppi_init();
|
||||
|
||||
spi_slave_config.miso_pin = SER_PHY_SPI_SLAVE_MISO_PIN;
|
||||
spi_slave_config.mosi_pin = SER_PHY_SPI_SLAVE_MOSI_PIN;
|
||||
spi_slave_config.sck_pin = SER_PHY_SPI_SLAVE_SCK_PIN;
|
||||
spi_slave_config.csn_pin = SER_PHY_SPI_SLAVE_SS_PIN;
|
||||
spi_slave_config.mode = NRF_DRV_SPIS_MODE_0;
|
||||
spi_slave_config.bit_order = NRF_DRV_SPIS_BIT_ORDER_LSB_FIRST;
|
||||
spi_slave_config.def = SER_PHY_SPI_DEF_CHARACTER;
|
||||
spi_slave_config.orc = SER_PHY_SPI_ORC_CHARACTER;
|
||||
spi_slave_config.irq_priority = APP_IRQ_PRIORITY_LOWEST;
|
||||
spi_slave_config.miso_drive = NRF_DRV_SPIS_DEFAULT_MISO_DRIVE;
|
||||
//use /CS pullup because state of the line might be undefined when master redefines PIO lines
|
||||
spi_slave_config.csn_pullup = NRF_GPIO_PIN_PULLUP;
|
||||
|
||||
//keep /CS high when init
|
||||
nrf_gpio_cfg_input(spi_slave_config.csn_pin, NRF_GPIO_PIN_PULLUP);
|
||||
|
||||
err_code = nrf_drv_spis_init(&m_spis, &spi_slave_config, spi_slave_event_handle);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
m_ser_phy_callback = events_handler;
|
||||
|
||||
m_trans_state = SPI_RAW_STATE_SETUP_HEADER;
|
||||
event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition for dummy event
|
||||
event.rx_amount = 0;
|
||||
event.tx_amount = 0;
|
||||
spi_slave_event_handle(event);
|
||||
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
/* ser_phy API function */
|
||||
void ser_phy_close(void)
|
||||
{
|
||||
nrf_drv_spis_uninit(&m_spis);
|
||||
m_ser_phy_callback = NULL;
|
||||
m_trans_state = SPI_RAW_STATE_UNKNOWN;
|
||||
}
|
||||
363
components/serialization/common/transport/ser_phy/ser_phy_uart.c
Normal file
363
components/serialization/common/transport/ser_phy/ser_phy_uart.c
Normal file
@@ -0,0 +1,363 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "ser_phy.h"
|
||||
#include "ser_config.h"
|
||||
#ifdef SER_CONNECTIVITY
|
||||
#include "ser_phy_config_conn.h"
|
||||
#else
|
||||
#include "ser_phy_config_app.h"
|
||||
#endif
|
||||
#include "nrf_drv_uart.h"
|
||||
#include "app_error.h"
|
||||
#include "app_util.h"
|
||||
#include "app_util_platform.h"
|
||||
|
||||
#define UART_TRANSFER_MAX 255
|
||||
|
||||
static const nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0);
|
||||
static const nrf_drv_uart_config_t m_uart_config = {
|
||||
.pseltxd = SER_PHY_UART_TX,
|
||||
.pselrxd = SER_PHY_UART_RX,
|
||||
.pselrts = SER_PHY_UART_RTS,
|
||||
.pselcts = SER_PHY_UART_CTS,
|
||||
.p_context = NULL,
|
||||
.interrupt_priority = UART_IRQ_PRIORITY,
|
||||
#if defined(NRF_DRV_UART_WITH_UARTE) && defined(NRF_DRV_UART_WITH_UART)
|
||||
.use_easy_dma = true,
|
||||
#endif
|
||||
// These values are common for application and connectivity, they are
|
||||
// defined in "ser_config.h".
|
||||
.hwfc = SER_PHY_UART_FLOW_CTRL,
|
||||
.parity = SER_PHY_UART_PARITY,
|
||||
.baudrate = (nrf_uart_baudrate_t)SER_PHY_UART_BAUDRATE
|
||||
};
|
||||
|
||||
static bool volatile m_tx_in_progress;
|
||||
static uint8_t m_tx_header_buf[SER_PHY_HEADER_SIZE];
|
||||
static uint16_t m_bytes_to_transmit;
|
||||
static uint8_t const * mp_tx_buffer;
|
||||
|
||||
static uint8_t m_rx_header_buf[SER_PHY_HEADER_SIZE];
|
||||
static uint16_t m_bytes_to_receive;
|
||||
static uint8_t m_rx_drop_buf[1];
|
||||
|
||||
static ser_phy_events_handler_t m_ser_phy_event_handler;
|
||||
static ser_phy_evt_t m_ser_phy_rx_event;
|
||||
|
||||
|
||||
static void packet_sent_callback(void)
|
||||
{
|
||||
static ser_phy_evt_t const event = {
|
||||
.evt_type = SER_PHY_EVT_TX_PKT_SENT,
|
||||
};
|
||||
m_ser_phy_event_handler(event);
|
||||
}
|
||||
|
||||
static void buffer_request_callback(uint16_t num_of_bytes)
|
||||
{
|
||||
m_ser_phy_rx_event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
|
||||
m_ser_phy_rx_event.evt_params.rx_buf_request.num_of_bytes = num_of_bytes;
|
||||
m_ser_phy_event_handler(m_ser_phy_rx_event);
|
||||
}
|
||||
|
||||
static void packet_received_callback(void)
|
||||
{
|
||||
m_ser_phy_event_handler(m_ser_phy_rx_event);
|
||||
}
|
||||
|
||||
static void packet_dropped_callback(void)
|
||||
{
|
||||
static ser_phy_evt_t const event = {
|
||||
.evt_type = SER_PHY_EVT_RX_PKT_DROPPED,
|
||||
};
|
||||
m_ser_phy_event_handler(event);
|
||||
}
|
||||
|
||||
static void hardware_error_callback(uint32_t hw_error)
|
||||
{
|
||||
ser_phy_evt_t event = {
|
||||
.evt_type = SER_PHY_EVT_HW_ERROR,
|
||||
.evt_params.hw_error.error_code = hw_error,
|
||||
};
|
||||
m_ser_phy_event_handler(event);
|
||||
}
|
||||
|
||||
static void packet_rx_start(void)
|
||||
{
|
||||
APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_header_buf,
|
||||
SER_PHY_HEADER_SIZE));
|
||||
}
|
||||
|
||||
static void packet_byte_drop(void)
|
||||
{
|
||||
APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_drop_buf, 1));
|
||||
}
|
||||
|
||||
static void uart_event_handler(nrf_drv_uart_event_t * p_event,
|
||||
void * p_context)
|
||||
{
|
||||
(void)p_context;
|
||||
|
||||
switch (p_event->type)
|
||||
{
|
||||
case NRF_DRV_UART_EVT_ERROR:
|
||||
// Process the error only if this is a parity or overrun error.
|
||||
// Break and framing errors will always occur before the other
|
||||
// side becomes active.
|
||||
if (p_event->data.error.error_mask &
|
||||
(NRF_UART_ERROR_PARITY_MASK | NRF_UART_ERROR_OVERRUN_MASK))
|
||||
{
|
||||
// Pass error source to upper layer.
|
||||
hardware_error_callback(p_event->data.error.error_mask);
|
||||
}
|
||||
|
||||
packet_rx_start();
|
||||
break;
|
||||
|
||||
case NRF_DRV_UART_EVT_TX_DONE:
|
||||
if (p_event->data.rxtx.p_data == m_tx_header_buf)
|
||||
{
|
||||
#if (SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
|
||||
if (m_bytes_to_transmit > UART_TRANSFER_MAX)
|
||||
{
|
||||
APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, mp_tx_buffer,
|
||||
UART_TRANSFER_MAX));
|
||||
}
|
||||
else
|
||||
#endif // (SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
|
||||
{
|
||||
APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, mp_tx_buffer,
|
||||
m_bytes_to_transmit));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
|
||||
ASSERT(p_event->data.rxtx.bytes <= m_bytes_to_transmit);
|
||||
m_bytes_to_transmit -= p_event->data.rxtx.bytes;
|
||||
if (m_bytes_to_transmit != 0)
|
||||
{
|
||||
APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart,
|
||||
p_event->data.rxtx.p_data + p_event->data.rxtx.bytes,
|
||||
m_bytes_to_transmit < UART_TRANSFER_MAX ?
|
||||
m_bytes_to_transmit : UART_TRANSFER_MAX));
|
||||
}
|
||||
else
|
||||
#endif // (SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
|
||||
{
|
||||
m_tx_in_progress = false;
|
||||
packet_sent_callback();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NRF_DRV_UART_EVT_RX_DONE:
|
||||
if (p_event->data.rxtx.p_data == m_rx_header_buf)
|
||||
{
|
||||
m_bytes_to_receive = uint16_decode(m_rx_header_buf);
|
||||
buffer_request_callback(m_bytes_to_receive);
|
||||
}
|
||||
else if (p_event->data.rxtx.p_data == m_rx_drop_buf)
|
||||
{
|
||||
--m_bytes_to_receive;
|
||||
if (m_bytes_to_receive != 0)
|
||||
{
|
||||
packet_byte_drop();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_dropped_callback();
|
||||
|
||||
packet_rx_start();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
|
||||
ASSERT(p_event->data.rxtx.bytes <= m_bytes_to_receive);
|
||||
m_bytes_to_receive -= p_event->data.rxtx.bytes;
|
||||
if (m_bytes_to_receive != 0)
|
||||
{
|
||||
APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart,
|
||||
p_event->data.rxtx.p_data + p_event->data.rxtx.bytes,
|
||||
m_bytes_to_receive < UART_TRANSFER_MAX ?
|
||||
m_bytes_to_receive : UART_TRANSFER_MAX));
|
||||
}
|
||||
else
|
||||
#endif // (SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
|
||||
{
|
||||
packet_received_callback();
|
||||
|
||||
packet_rx_start();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
|
||||
}
|
||||
}
|
||||
|
||||
/** API FUNCTIONS */
|
||||
|
||||
uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
if (events_handler == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
// Check if function was not called before.
|
||||
if (m_ser_phy_event_handler != NULL)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
err_code = nrf_drv_uart_init(&m_uart, &m_uart_config, uart_event_handler);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
m_ser_phy_event_handler = events_handler;
|
||||
|
||||
packet_rx_start();
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
|
||||
{
|
||||
if (p_buffer == NULL)
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
else if (num_of_bytes == 0)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
bool busy;
|
||||
|
||||
CRITICAL_REGION_ENTER();
|
||||
busy = m_tx_in_progress;
|
||||
m_tx_in_progress = true;
|
||||
CRITICAL_REGION_EXIT();
|
||||
|
||||
if (busy)
|
||||
{
|
||||
return NRF_ERROR_BUSY;
|
||||
}
|
||||
|
||||
(void)uint16_encode(num_of_bytes, m_tx_header_buf);
|
||||
mp_tx_buffer = p_buffer;
|
||||
m_bytes_to_transmit = num_of_bytes;
|
||||
APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, m_tx_header_buf,
|
||||
SER_PHY_HEADER_SIZE));
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
|
||||
{
|
||||
|
||||
if (m_ser_phy_rx_event.evt_type != SER_PHY_EVT_RX_BUF_REQUEST)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
m_ser_phy_rx_event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
|
||||
m_ser_phy_rx_event.evt_params.rx_pkt_received.p_buffer = p_buffer;
|
||||
m_ser_phy_rx_event.evt_params.rx_pkt_received.num_of_bytes =
|
||||
m_bytes_to_receive;
|
||||
|
||||
// If there is not enough memory to receive the packet (no buffer was
|
||||
// provided), drop its data byte by byte (using an internal 1-byte buffer).
|
||||
if (p_buffer == NULL)
|
||||
{
|
||||
packet_byte_drop();
|
||||
}
|
||||
#if (SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
|
||||
else if (m_bytes_to_receive > UART_TRANSFER_MAX)
|
||||
{
|
||||
APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, p_buffer, UART_TRANSFER_MAX));
|
||||
}
|
||||
#endif // (SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
|
||||
else
|
||||
{
|
||||
APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, p_buffer, m_bytes_to_receive));
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void ser_phy_close(void)
|
||||
{
|
||||
nrf_drv_uart_uninit(&m_uart);
|
||||
m_ser_phy_event_handler = NULL;
|
||||
}
|
||||
|
||||
|
||||
void ser_phy_interrupts_enable(void)
|
||||
{
|
||||
IRQn_Type irqn;
|
||||
#if defined(NRF_DRV_UART_WITH_UARTE)
|
||||
irqn = nrfx_get_irq_number(m_uart.uarte.p_reg);
|
||||
#else
|
||||
irqn = nrfx_get_irq_number(m_uart.uart.p_reg);
|
||||
#endif
|
||||
NVIC_EnableIRQ(irqn);
|
||||
}
|
||||
|
||||
|
||||
void ser_phy_interrupts_disable(void)
|
||||
{
|
||||
IRQn_Type irqn;
|
||||
#if defined(NRF_DRV_UART_WITH_UARTE)
|
||||
irqn = nrfx_get_irq_number(m_uart.uarte.p_reg);
|
||||
#else
|
||||
irqn = nrfx_get_irq_number(m_uart.uart.p_reg);
|
||||
#endif
|
||||
NVIC_DisableIRQ(irqn);
|
||||
}
|
||||
203
components/serialization/common/transport/ser_phy_debug_comm.h
Normal file
203
components/serialization/common/transport/ser_phy_debug_comm.h
Normal file
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef SER_PHY_DEBUG_COMM_H__
|
||||
#define SER_PHY_DEBUG_COMM_H__
|
||||
|
||||
#ifndef SER_PHY_HCI_DEBUG_ENABLE
|
||||
|
||||
// empty definitions here
|
||||
#define DEBUG_EVT_HCI_PHY_EVT_TX_PKT_SENT(data)
|
||||
#define DEBUG_EVT_HCI_PHY_EVT_BUF_REQUEST(data)
|
||||
#define DEBUG_EVT_HCI_PHY_EVT_RX_PKT_RECEIVED(data)
|
||||
#define DEBUG_EVT_HCI_PHY_EVT_RX_PKT_DROPPED(data)
|
||||
#define DEBUG_EVT_HCI_PHY_EVT_TX_ERROR(data)
|
||||
#define DEBUG_EVT_SLIP_PACKET_TX(data)
|
||||
#define DEBUG_EVT_SLIP_ACK_TX(data)
|
||||
#define DEBUG_EVT_SLIP_PACKET_TXED(data)
|
||||
#define DEBUG_EVT_SLIP_ACK_TXED(data)
|
||||
#define DEBUG_EVT_SLIP_PACKET_RXED(data)
|
||||
#define DEBUG_EVT_SLIP_ACK_RXED(data)
|
||||
#define DEBUG_EVT_SLIP_ERR_RXED(data)
|
||||
#define DEBUG_EVT_TIMEOUT(data)
|
||||
#define DEBUG_HCI_RETX(data)
|
||||
#define DEBUG_EVT_MAIN_BUSY(data)
|
||||
#define DEBUG_EVT_TX_REQ(data)
|
||||
|
||||
#else
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//Low level hardware events
|
||||
typedef enum
|
||||
{
|
||||
HCI_PHY_EVT_TX_PKT_SENT,
|
||||
HCI_PHY_EVT_BUF_REQUEST,
|
||||
HCI_PHY_EVT_RX_PKT_RECEIVED,
|
||||
HCI_PHY_EVT_RX_PKT_DROPPED,
|
||||
HCI_PHY_EVT_TX_ERROR,
|
||||
HCI_SLIP_EVT_PACKET_TX,
|
||||
HCI_SLIP_EVT_ACK_TX,
|
||||
HCI_SLIP_EVT_PACKET_TXED,
|
||||
HCI_SLIP_EVT_ACK_TXED,
|
||||
HCI_SLIP_EVT_PACKET_RXED,
|
||||
HCI_SLIP_EVT_ACK_RXED,
|
||||
HCI_SLIP_EVT_ERR_RXED,
|
||||
HCI_TIMER_EVT_TIMEOUT,
|
||||
HCI_RETX,
|
||||
HCI_MAIN_BUSY,
|
||||
HCI_TX_REQ,
|
||||
HCI_PHY_EVT_MAX
|
||||
} hci_dbg_evt_type_t;
|
||||
|
||||
|
||||
//Low level hardware event definition
|
||||
typedef struct
|
||||
{
|
||||
hci_dbg_evt_type_t evt;
|
||||
uint32_t data;
|
||||
} hci_dbg_evt_t;
|
||||
|
||||
typedef void (*hci_dbg_event_handler_t)(hci_dbg_evt_t event);
|
||||
|
||||
void debug_init(hci_dbg_event_handler_t evt_callback);
|
||||
|
||||
void debug_evt(hci_dbg_evt_type_t evt, uint32_t data);
|
||||
|
||||
|
||||
#define DEBUG_EVT(event_type, data) \
|
||||
do { \
|
||||
debug_evt(event_type, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_HCI_PHY_EVT_TX_PKT_SENT(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_PHY_EVT_TX_PKT_SENT, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_HCI_PHY_EVT_BUF_REQUEST(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_PHY_EVT_BUF_REQUEST, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_HCI_PHY_EVT_RX_PKT_RECEIVED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_PHY_EVT_RX_PKT_RECEIVED, data); \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define DEBUG_EVT_HCI_PHY_EVT_RX_PKT_DROPPED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_PHY_EVT_RX_PKT_DROPPED, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_HCI_PHY_EVT_TX_ERROR(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_PHY_EVT_TX_ERROR, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_SLIP_PACKET_TX(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_SLIP_EVT_PACKET_TX, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_SLIP_ACK_TX(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_SLIP_EVT_ACK_TX, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_SLIP_PACKET_TXED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_SLIP_EVT_PACKET_TXED, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_SLIP_ACK_TXED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_SLIP_EVT_ACK_TXED, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_SLIP_PACKET_RXED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_SLIP_EVT_PACKET_RXED, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_SLIP_ACK_RXED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_SLIP_EVT_ACK_RXED, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_SLIP_ERR_RXED(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_SLIP_EVT_ERR_RXED, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_TIMEOUT(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_TIMER_EVT_TIMEOUT, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_HCI_RETX(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_RETX, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_MAIN_BUSY(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_MAIN_BUSY, data); \
|
||||
} while (0);
|
||||
|
||||
#define DEBUG_EVT_TX_REQ(data) \
|
||||
do { \
|
||||
DEBUG_EVT(HCI_TX_REQ, data); \
|
||||
} while (0);
|
||||
|
||||
#endif // SER_PHY_HCI_DEBUG_ENABLE
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SER_PHY_DEBUG_COMM_H__
|
||||
Reference in New Issue
Block a user