初始版本
This commit is contained in:
317
components/libraries/cli/ble_uart/nrf_cli_ble_uart.c
Normal file
317
components/libraries/cli/ble_uart/nrf_cli_ble_uart.c
Normal file
@@ -0,0 +1,317 @@
|
||||
/**
|
||||
* 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 "sdk_common.h"
|
||||
#if NRF_MODULE_ENABLED(NRF_CLI_BLE_UART)
|
||||
#include "nrf_cli_ble_uart.h"
|
||||
#include "ble_nus.h"
|
||||
#include "nrf_ringbuf.h"
|
||||
#include "app_timer.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "nrf_ble_gatt.h"
|
||||
#define NRF_LOG_MODULE_NAME cli_ble
|
||||
|
||||
#if NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED
|
||||
#define NRF_LOG_LEVEL NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL
|
||||
#define NRF_LOG_INFO_COLOR NRF_CLI_BLE_UART_CONFIG_INFO_COLOR
|
||||
#define NRF_LOG_DEBUG_COLOR NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR
|
||||
|
||||
#else //NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED
|
||||
#define NRF_LOG_LEVEL 0
|
||||
#endif //NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED
|
||||
#include "nrf_log.h"
|
||||
NRF_LOG_MODULE_REGISTER();
|
||||
|
||||
#if NRF_CLI_BLE_UART_MAX_CLIENTS > NRF_SDH_BLE_TOTAL_LINK_COUNT
|
||||
#error "Too few BLE peripheral links are supported by the BLE SDH module for the maximal number \
|
||||
of BLE transport instances"
|
||||
#endif
|
||||
|
||||
#define NRF_CLI_BLE_UART_TIMEOUT_MS 50
|
||||
#define OVERHEAD_LENGTH (OPCODE_LENGTH + HANDLE_LENGTH)
|
||||
|
||||
BLE_NUS_DEF(m_nus, NRF_CLI_BLE_UART_MAX_CLIENTS);
|
||||
BLE_LINK_CTX_MANAGER_DEF(m_link_ctx_storage,
|
||||
NRF_CLI_BLE_UART_MAX_CLIENTS,
|
||||
sizeof(nrf_cli_ble_uart_internal_t *));
|
||||
|
||||
static void tx_try(nrf_cli_ble_uart_internal_t * p_instance, uint32_t threshold)
|
||||
{
|
||||
uint8_t * p_out_data;
|
||||
size_t out_data_len =
|
||||
nrf_ble_gatt_eff_mtu_get(p_instance->p_gatt, p_instance->p_cb->conn_handle) -
|
||||
OVERHEAD_LENGTH;
|
||||
|
||||
ret_code_t err_code = nrf_ringbuf_get(p_instance->p_tx_ringbuf,
|
||||
&p_out_data,
|
||||
&out_data_len,
|
||||
true);
|
||||
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
if (out_data_len >= threshold)
|
||||
{
|
||||
size_t req_data_len = out_data_len;
|
||||
err_code = ble_nus_data_send(&m_nus,
|
||||
p_out_data,
|
||||
(uint16_t*)&out_data_len,
|
||||
p_instance->p_cb->conn_handle);
|
||||
|
||||
if ((err_code == NRF_ERROR_BUSY) || (err_code == NRF_ERROR_RESOURCES))
|
||||
{
|
||||
out_data_len = 0;
|
||||
}
|
||||
NRF_LOG_INFO("Conn_handle:%d TX req_len: %d, len: %d",
|
||||
p_instance->p_cb->conn_handle, req_data_len, out_data_len);
|
||||
NRF_LOG_HEXDUMP_DEBUG(p_out_data, out_data_len);
|
||||
err_code = nrf_ringbuf_free(p_instance->p_tx_ringbuf, out_data_len);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = nrf_ringbuf_free(p_instance->p_tx_ringbuf, 0);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void nus_data_handler(ble_nus_evt_t * p_nus_evt)
|
||||
{
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
nrf_cli_ble_uart_internal_t * p_instance;
|
||||
nrf_cli_ble_uart_internal_t ** pp_instance;
|
||||
|
||||
err_code = blcm_link_ctx_get(&m_link_ctx_storage, p_nus_evt->conn_handle, (void *) &pp_instance);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
|
||||
p_instance = *pp_instance;
|
||||
|
||||
switch (p_nus_evt->type)
|
||||
{
|
||||
case BLE_NUS_EVT_RX_DATA:
|
||||
{
|
||||
NRF_LOG_INFO("Conn_handle:%d, Received: %d",
|
||||
p_instance->p_cb->conn_handle, p_nus_evt->params.rx_data.length);
|
||||
NRF_LOG_HEXDUMP_DEBUG(p_nus_evt->params.rx_data.p_data, p_nus_evt->params.rx_data.length);
|
||||
size_t len = ((size_t) p_nus_evt->params.rx_data.length) & 0x0000FFFF;
|
||||
err_code = nrf_ringbuf_cpy_put(p_instance->p_rx_ringbuf,
|
||||
p_nus_evt->params.rx_data.p_data,
|
||||
(size_t *)&len);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
|
||||
p_instance->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY, p_instance->p_cb->p_context);
|
||||
break;
|
||||
}
|
||||
case BLE_NUS_EVT_TX_RDY:
|
||||
{
|
||||
//TX_Complete
|
||||
uint32_t max_tx_len = nrf_ble_gatt_eff_mtu_get(p_instance->p_gatt,
|
||||
p_instance->p_cb->conn_handle) -
|
||||
OVERHEAD_LENGTH;
|
||||
tx_try(p_instance, max_tx_len);
|
||||
p_instance->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_instance->p_cb->p_context);
|
||||
break;
|
||||
}
|
||||
case BLE_NUS_EVT_COMM_STARTED:
|
||||
p_instance->p_cb->service_started = true;
|
||||
err_code = app_timer_start(*p_instance->p_timer,
|
||||
APP_TIMER_TICKS(NRF_CLI_BLE_UART_TIMEOUT_MS),
|
||||
p_instance);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
NRF_LOG_INFO("Conn_handle:%d, communication started", p_instance->p_cb->conn_handle);
|
||||
break;
|
||||
case BLE_NUS_EVT_COMM_STOPPED:
|
||||
(void)app_timer_stop(*p_instance->p_timer);
|
||||
p_instance->p_cb->service_started = false;
|
||||
NRF_LOG_INFO("Conn_handle:%d, communication stopped", p_instance->p_cb->conn_handle);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void timer_handler(void * p_context)
|
||||
{
|
||||
nrf_cli_ble_uart_internal_t * p_instance = (nrf_cli_ble_uart_internal_t *) p_context;
|
||||
tx_try(p_instance, 1);
|
||||
|
||||
ret_code_t err_code = app_timer_start(*p_instance->p_timer,
|
||||
APP_TIMER_TICKS(NRF_CLI_BLE_UART_TIMEOUT_MS), (void *)p_instance);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
UNUSED_VARIABLE(err_code);
|
||||
UNUSED_PARAMETER(p_context);
|
||||
}
|
||||
|
||||
ret_code_t nrf_cli_ble_uart_service_init(void)
|
||||
{
|
||||
ble_nus_init_t nus_init;
|
||||
|
||||
memset(&nus_init, 0, sizeof(nus_init));
|
||||
nus_init.data_handler = nus_data_handler;
|
||||
|
||||
return ble_nus_init(&m_nus, &nus_init);
|
||||
}
|
||||
|
||||
static ret_code_t cli_ble_uart_init(nrf_cli_transport_t const * p_transport,
|
||||
void const * p_config,
|
||||
nrf_cli_transport_handler_t evt_handler,
|
||||
void * p_context)
|
||||
{
|
||||
ret_code_t err_code;
|
||||
nrf_cli_ble_uart_internal_t ** pp_instance;
|
||||
nrf_cli_ble_uart_internal_t * p_instance =
|
||||
CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
|
||||
nrf_cli_ble_uart_config_t * p_ble_uart_config = (nrf_cli_ble_uart_config_t *)p_config;
|
||||
|
||||
p_instance->p_cb->handler = evt_handler;
|
||||
p_instance->p_cb->p_context = p_context;
|
||||
p_instance->p_cb->service_started = false;
|
||||
p_instance->p_cb->conn_handle = p_ble_uart_config->conn_handle;
|
||||
|
||||
NRF_LOG_INFO("Conn_handle:%d init.", p_ble_uart_config->conn_handle);
|
||||
nrf_ringbuf_init(p_instance->p_rx_ringbuf);
|
||||
nrf_ringbuf_init(p_instance->p_tx_ringbuf);
|
||||
|
||||
err_code = blcm_link_ctx_get(&m_link_ctx_storage,
|
||||
p_ble_uart_config->conn_handle,
|
||||
(void *) &pp_instance);
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
*pp_instance = p_instance;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
static ret_code_t cli_ble_uart_uninit(nrf_cli_transport_t const * p_transport)
|
||||
{
|
||||
nrf_cli_ble_uart_internal_t * p_instance =
|
||||
CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
|
||||
|
||||
NRF_LOG_INFO("Conn_handle:%d uninit.", p_instance->p_cb->conn_handle);
|
||||
ret_code_t ret = app_timer_stop(*p_instance->p_timer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ret_code_t cli_ble_uart_enable(nrf_cli_transport_t const * p_transport, bool blocking)
|
||||
{
|
||||
nrf_cli_ble_uart_internal_t * p_instance =
|
||||
CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
|
||||
|
||||
|
||||
NRF_LOG_INFO("Conn_handle:%d, enable blocking:%d", blocking, p_instance->p_cb->conn_handle);
|
||||
if (blocking)
|
||||
{
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
if (!p_instance->p_cb->timer_created)
|
||||
{
|
||||
err_code = app_timer_create(p_instance->p_timer,
|
||||
APP_TIMER_MODE_SINGLE_SHOT,
|
||||
timer_handler);
|
||||
p_instance->p_cb->timer_created = true;
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
}
|
||||
|
||||
static ret_code_t cli_ble_uart_read(nrf_cli_transport_t const * p_transport,
|
||||
void * p_data,
|
||||
size_t length,
|
||||
size_t * p_cnt)
|
||||
{
|
||||
ASSERT(p_cnt);
|
||||
nrf_cli_ble_uart_internal_t * p_instance =
|
||||
CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
|
||||
*p_cnt = length;
|
||||
ret_code_t err_code = nrf_ringbuf_cpy_get(p_instance->p_rx_ringbuf, p_data, p_cnt);
|
||||
|
||||
if (*p_cnt)
|
||||
{
|
||||
NRF_LOG_INFO("Conn_handle:%d, read req_len:%d read_len: %d",
|
||||
p_instance->p_cb->conn_handle,
|
||||
length,
|
||||
*p_cnt);
|
||||
NRF_LOG_HEXDUMP_DEBUG(p_data, *p_cnt);
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static ret_code_t cli_ble_uart_write(nrf_cli_transport_t const * p_transport,
|
||||
const void * p_data,
|
||||
size_t length,
|
||||
size_t * p_cnt)
|
||||
{
|
||||
ASSERT(p_cnt);
|
||||
nrf_cli_ble_uart_internal_t * p_instance =
|
||||
CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
if (p_instance->p_cb->service_started)
|
||||
{
|
||||
*p_cnt = length;
|
||||
err_code = nrf_ringbuf_cpy_put(p_instance->p_tx_ringbuf, p_data, p_cnt);
|
||||
|
||||
NRF_LOG_INFO("Conn_handle:%d, write req:%d, buffered:%d",
|
||||
p_instance->p_cb->conn_handle, length, *p_cnt);
|
||||
NRF_LOG_HEXDUMP_DEBUG(p_data, *p_cnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF_LOG_INFO("Conn_handle:%d, write req:%d. Notifications not enabled",
|
||||
p_instance->p_cb->conn_handle, length);
|
||||
*p_cnt = length;
|
||||
p_instance->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_instance->p_cb->p_context);
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
const nrf_cli_transport_api_t nrf_cli_ble_uart_transport_api = {
|
||||
.init = cli_ble_uart_init,
|
||||
.uninit = cli_ble_uart_uninit,
|
||||
.enable = cli_ble_uart_enable,
|
||||
.read = cli_ble_uart_read,
|
||||
.write = cli_ble_uart_write,
|
||||
};
|
||||
|
||||
#endif //NRF_MODULE_ENABLED(NRF_CLI_BLE_UART)
|
||||
123
components/libraries/cli/ble_uart/nrf_cli_ble_uart.h
Normal file
123
components/libraries/cli/ble_uart/nrf_cli_ble_uart.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* 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 NRF_CLI_BLE_UART_H__
|
||||
#define NRF_CLI_BLE_UART_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "nrf_cli.h"
|
||||
#include "ble.h"
|
||||
#include "app_timer.h"
|
||||
#include "nrf_ringbuf.h"
|
||||
#include "nordic_common.h"
|
||||
#include "nrf_ble_gatt.h"
|
||||
/**@file
|
||||
*
|
||||
* @defgroup nrf_cli_ble_uart BLE UART command line interface transport layer
|
||||
* @ingroup nrf_cli
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Command line interface transport.
|
||||
*/
|
||||
|
||||
ret_code_t nrf_cli_ble_uart_service_init(void);
|
||||
|
||||
extern const nrf_cli_transport_api_t nrf_cli_ble_uart_transport_api;
|
||||
|
||||
typedef struct nrf_cli_ble_uart_internal_s nrf_cli_ble_uart_internal_t;
|
||||
|
||||
typedef struct {
|
||||
nrf_cli_transport_handler_t handler;
|
||||
void * p_context;
|
||||
uint16_t conn_handle;
|
||||
bool timer_created;
|
||||
bool service_started;
|
||||
} nrf_cli_ble_uart_internal_cb_t;
|
||||
|
||||
|
||||
struct nrf_cli_ble_uart_internal_s {
|
||||
nrf_cli_transport_t transport;
|
||||
nrf_cli_ble_uart_internal_cb_t * p_cb;
|
||||
app_timer_id_t const * p_timer;
|
||||
nrf_ringbuf_t const * p_rx_ringbuf;
|
||||
nrf_ringbuf_t const * p_tx_ringbuf;
|
||||
nrf_ble_gatt_t const * p_gatt;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint16_t conn_handle;
|
||||
} nrf_cli_ble_uart_config_t;
|
||||
|
||||
/**@brief CLI Bluetooth transport definition.
|
||||
*
|
||||
* @param _name Name of the instance.
|
||||
* @param _p_gatt Pointer to the nrf_ble_gatt module.
|
||||
* @param _tx_buf_sz Size of TX ring buffer.
|
||||
* @param _rx_buf_sz Size of RX ring buffer.
|
||||
*/
|
||||
#define NRF_CLI_BLE_UART_DEF(_name, _p_gatt, _tx_buf_sz, _rx_buf_sz) \
|
||||
APP_TIMER_DEF(CONCAT_2(_name, _timer)); \
|
||||
NRF_RINGBUF_DEF(CONCAT_2(_name,_tx_ringbuf), _tx_buf_sz); \
|
||||
NRF_RINGBUF_DEF(CONCAT_2(_name,_rx_ringbuf), _rx_buf_sz); \
|
||||
static nrf_cli_ble_uart_internal_cb_t CONCAT_2(_name, _cb); \
|
||||
static const nrf_cli_ble_uart_internal_t _name = { \
|
||||
.transport = {.p_api = &nrf_cli_ble_uart_transport_api}, \
|
||||
.p_cb = &CONCAT_2(_name, _cb), \
|
||||
.p_timer = &CONCAT_2(_name, _timer), \
|
||||
.p_rx_ringbuf = &CONCAT_2(_name,_rx_ringbuf), \
|
||||
.p_tx_ringbuf = &CONCAT_2(_name,_tx_ringbuf), \
|
||||
.p_gatt = _p_gatt, \
|
||||
}
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NRF_CLI_BLE_UART_H__ */
|
||||
243
components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.c
Normal file
243
components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.c
Normal file
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
* 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 "sdk_common.h"
|
||||
#if NRF_MODULE_ENABLED(NRF_CLI_CDC_ACM)
|
||||
#include "nrf_cli_cdc_acm.h"
|
||||
#include "nrf_queue.h"
|
||||
#include "app_error.h"
|
||||
#include "nrf_assert.h"
|
||||
|
||||
|
||||
#if APP_USBD_CONFIG_EVENT_QUEUE_ENABLE
|
||||
#error "Current CLI CDC implementation supports only USB with event queue disabled (see APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)"
|
||||
#endif
|
||||
|
||||
static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
|
||||
app_usbd_cdc_acm_user_event_t event);
|
||||
|
||||
/*lint -save -e26 -e40 -e64 -e123 -e505 -e651*/
|
||||
|
||||
/**
|
||||
* @brief CDC_ACM class instance.
|
||||
* */
|
||||
APP_USBD_CDC_ACM_GLOBAL_DEF(nrf_cli_cdc_acm,
|
||||
cdc_acm_user_ev_handler,
|
||||
NRF_CLI_CDC_ACM_COMM_INTERFACE,
|
||||
NRF_CLI_CDC_ACM_DATA_INTERFACE,
|
||||
NRF_CLI_CDC_ACM_COMM_EPIN,
|
||||
NRF_CLI_CDC_ACM_DATA_EPIN,
|
||||
NRF_CLI_CDC_ACM_DATA_EPOUT,
|
||||
APP_USBD_CDC_COMM_PROTOCOL_AT_V250
|
||||
);
|
||||
|
||||
/*lint -restore*/
|
||||
|
||||
NRF_QUEUE_DEF(uint8_t,
|
||||
m_rx_queue,
|
||||
2*NRF_DRV_USBD_EPSIZE,
|
||||
NRF_QUEUE_MODE_OVERFLOW);
|
||||
|
||||
static char m_rx_buffer[NRF_DRV_USBD_EPSIZE];
|
||||
|
||||
static nrf_cli_cdc_acm_internal_t * mp_internal;
|
||||
|
||||
/**
|
||||
* @brief Set new buffer and process any data if already present
|
||||
*
|
||||
* This is internal function.
|
||||
* The result of its execution is the library waiting for the event of the new data.
|
||||
* If there is already any data that was returned from the CDC internal buffer
|
||||
* it would be processed here.
|
||||
*/
|
||||
static void cdc_acm_process_and_prepare_buffer(app_usbd_cdc_acm_t const * p_cdc_acm)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (!nrf_queue_is_empty(&m_rx_queue))
|
||||
{
|
||||
mp_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY, mp_internal->p_cb->p_context);
|
||||
}
|
||||
ret_code_t ret = app_usbd_cdc_acm_read_any(&nrf_cli_cdc_acm,
|
||||
m_rx_buffer,
|
||||
sizeof(m_rx_buffer));
|
||||
if (ret == NRF_SUCCESS)
|
||||
{
|
||||
size_t size = app_usbd_cdc_acm_rx_size(p_cdc_acm);
|
||||
size_t qsize = nrf_queue_in(&m_rx_queue, m_rx_buffer, size);
|
||||
ASSERT(size == qsize);
|
||||
UNUSED_VARIABLE(qsize);
|
||||
}
|
||||
else if (ret == NRF_ERROR_IO_PENDING)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_ERROR_CHECK(ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief User event handler.
|
||||
* */
|
||||
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:
|
||||
{
|
||||
/*Setup first transfer*/
|
||||
cdc_acm_process_and_prepare_buffer(p_cdc_acm);
|
||||
break;
|
||||
}
|
||||
case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
|
||||
mp_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, mp_internal->p_cb->p_context);
|
||||
break;
|
||||
case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
|
||||
mp_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, mp_internal->p_cb->p_context);
|
||||
break;
|
||||
case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
|
||||
{
|
||||
/*Get amount of data transfered*/
|
||||
size_t size = app_usbd_cdc_acm_rx_size(p_cdc_acm);
|
||||
size_t qsize = nrf_queue_in(&m_rx_queue, m_rx_buffer, size);
|
||||
ASSERT(size == qsize);
|
||||
UNUSED_VARIABLE(qsize);
|
||||
|
||||
/*Setup next transfer*/
|
||||
cdc_acm_process_and_prepare_buffer(p_cdc_acm);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static ret_code_t cli_cdc_acm_init(nrf_cli_transport_t const * p_transport,
|
||||
void const * p_config,
|
||||
nrf_cli_transport_handler_t evt_handler,
|
||||
void * p_context)
|
||||
{
|
||||
UNUSED_PARAMETER(p_config);
|
||||
nrf_cli_cdc_acm_internal_t * p_internal =
|
||||
CONTAINER_OF(p_transport, nrf_cli_cdc_acm_internal_t, transport);
|
||||
p_internal->p_cb->handler = evt_handler;
|
||||
p_internal->p_cb->p_context = p_context;
|
||||
|
||||
mp_internal = p_internal;
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
static ret_code_t cli_cdc_acm_uninit(nrf_cli_transport_t const * p_transport)
|
||||
{
|
||||
UNUSED_PARAMETER(p_transport);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
static ret_code_t cli_cdc_acm_enable(nrf_cli_transport_t const * p_transport,
|
||||
bool blocking)
|
||||
{
|
||||
UNUSED_PARAMETER(p_transport);
|
||||
if (blocking)
|
||||
{
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static ret_code_t cli_cdc_acm_read(nrf_cli_transport_t const * p_transport,
|
||||
void * p_data,
|
||||
size_t length,
|
||||
size_t * p_cnt)
|
||||
{
|
||||
ASSERT(p_cnt);
|
||||
UNUSED_PARAMETER(p_transport);
|
||||
size_t size = nrf_queue_out(&m_rx_queue, p_data, length);
|
||||
*p_cnt = size;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
static ret_code_t cli_cdc_acm_write(nrf_cli_transport_t const * p_transport,
|
||||
void const * p_data,
|
||||
size_t length,
|
||||
size_t * p_cnt)
|
||||
{
|
||||
ASSERT(p_cnt);
|
||||
UNUSED_PARAMETER(p_transport);
|
||||
ret_code_t ret;
|
||||
|
||||
ret = app_usbd_cdc_acm_write(&nrf_cli_cdc_acm, p_data, length);
|
||||
if (ret == NRF_SUCCESS || ret == NRF_ERROR_INVALID_STATE)
|
||||
{
|
||||
*p_cnt = length;
|
||||
ret = NRF_SUCCESS;
|
||||
}
|
||||
else if (ret == NRF_ERROR_BUSY)
|
||||
{
|
||||
*p_cnt = 0;
|
||||
ret = NRF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const nrf_cli_transport_api_t nrf_cli_cdc_acm_transport_api = {
|
||||
.init = cli_cdc_acm_init,
|
||||
.uninit = cli_cdc_acm_uninit,
|
||||
.enable = cli_cdc_acm_enable,
|
||||
.read = cli_cdc_acm_read,
|
||||
.write = cli_cdc_acm_write,
|
||||
};
|
||||
|
||||
#endif // NRF_MODULE_ENABLED(NRF_CLI_CDC_ACM)
|
||||
95
components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.h
Normal file
95
components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* 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 NRF_CLI_CDC_ACM_H__
|
||||
#define NRF_CLI_CDC_ACM_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "nrf_cli.h"
|
||||
#include "app_usbd_cdc_acm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@file
|
||||
*
|
||||
* @defgroup nrf_cli_cdc_acm CDC ACM command line interface transport layer
|
||||
* @ingroup nrf_cli
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Command line interface transport.
|
||||
*/
|
||||
extern const nrf_cli_transport_api_t nrf_cli_cdc_acm_transport_api;
|
||||
|
||||
/**
|
||||
* @brief Command line interface class instance.
|
||||
*/
|
||||
extern const app_usbd_cdc_acm_t nrf_cli_cdc_acm;
|
||||
|
||||
typedef struct {
|
||||
nrf_cli_transport_handler_t handler;
|
||||
void * p_context;
|
||||
} nrf_cli_cdc_acm_internal_cb_t;
|
||||
|
||||
typedef struct {
|
||||
nrf_cli_transport_t transport;
|
||||
nrf_cli_cdc_acm_internal_cb_t * p_cb;
|
||||
} nrf_cli_cdc_acm_internal_t;
|
||||
|
||||
/**@brief CLI USB transport definition */
|
||||
#define NRF_CLI_CDC_ACM_DEF(_name_) \
|
||||
static nrf_cli_cdc_acm_internal_cb_t CONCAT_2(_name_, _cb); \
|
||||
static const nrf_cli_cdc_acm_internal_t _name_ = { \
|
||||
.transport = {.p_api = &nrf_cli_cdc_acm_transport_api}, \
|
||||
.p_cb = &CONCAT_2(_name_, _cb), \
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NRF_CLI_CDC_ACM_H__ */
|
||||
164
components/libraries/cli/cli_utils_cmds.c
Normal file
164
components/libraries/cli/cli_utils_cmds.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Copyright (c) 2018 - 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_cli.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
static void cmd_reset(nrf_cli_t const * p_cli, size_t argc, char **argv)
|
||||
{
|
||||
UNUSED_PARAMETER(argc);
|
||||
UNUSED_PARAMETER(argv);
|
||||
|
||||
if (nrf_cli_help_requested(p_cli))
|
||||
{
|
||||
nrf_cli_help_print(p_cli, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
|
||||
static void cmd_error(nrf_cli_t const * p_cli, size_t argc, char **argv)
|
||||
{
|
||||
UNUSED_PARAMETER(argc);
|
||||
UNUSED_PARAMETER(argv);
|
||||
|
||||
if (nrf_cli_help_requested(p_cli))
|
||||
{
|
||||
nrf_cli_help_print(p_cli, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
|
||||
}
|
||||
|
||||
|
||||
static void cmd_app_size(nrf_cli_t const * p_cli, size_t argc, char **argv)
|
||||
{
|
||||
UNUSED_PARAMETER(argc);
|
||||
UNUSED_PARAMETER(argv);
|
||||
|
||||
if (nrf_cli_help_requested(p_cli))
|
||||
{
|
||||
nrf_cli_help_print(p_cli, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
nrf_cli_fprintf(p_cli,
|
||||
NRF_CLI_NORMAL,
|
||||
"Application address:%d (0x%08X), size: %d (0x%08X)\r\n",
|
||||
CODE_START,
|
||||
CODE_START,
|
||||
CODE_SIZE,
|
||||
CODE_SIZE);
|
||||
}
|
||||
|
||||
|
||||
static void cmd_log_msg_error(nrf_cli_t const * p_cli, size_t argc, char **argv)
|
||||
{
|
||||
if (nrf_cli_help_requested(p_cli))
|
||||
{
|
||||
nrf_cli_help_print(p_cli, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (argc-1)
|
||||
{
|
||||
case 0:
|
||||
NRF_LOG_ERROR("test error message");
|
||||
break;
|
||||
case 1:
|
||||
NRF_LOG_ERROR("test error message: %d", strtol(argv[1], NULL, 10));
|
||||
break;
|
||||
case 2:
|
||||
NRF_LOG_ERROR("test error message: %d %d", strtol(argv[1], NULL, 10),
|
||||
strtol(argv[2], NULL, 10));
|
||||
break;
|
||||
default:
|
||||
NRF_LOG_ERROR("test error message with more than 3 arguments");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void cmd_log_msg_warning(nrf_cli_t const * p_cli, size_t argc, char **argv)
|
||||
{
|
||||
if (nrf_cli_help_requested(p_cli))
|
||||
{
|
||||
nrf_cli_help_print(p_cli, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (argc-1)
|
||||
{
|
||||
case 0:
|
||||
NRF_LOG_WARNING("test warning message");
|
||||
break;
|
||||
case 1:
|
||||
NRF_LOG_WARNING("test warning message: %d", strtol(argv[1], NULL, 10));
|
||||
break;
|
||||
case 2:
|
||||
NRF_LOG_WARNING("test warning message: %d %d", strtol(argv[1], NULL, 10),
|
||||
strtol(argv[2], NULL, 10));
|
||||
break;
|
||||
default:
|
||||
NRF_LOG_WARNING("test warning message with more than 3 arguments");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Command set array
|
||||
* */
|
||||
|
||||
NRF_CLI_CMD_REGISTER(reset, NULL, "System reset.", cmd_reset);
|
||||
|
||||
NRF_CLI_CMD_REGISTER(error, NULL, "Trigger error.", cmd_error);
|
||||
|
||||
NRF_CLI_CMD_REGISTER(app_size, NULL, "Print application size.", cmd_app_size);
|
||||
|
||||
NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_log_msg)
|
||||
{
|
||||
NRF_CLI_CMD(error, NULL, "Error log message with parameters", cmd_log_msg_error),
|
||||
NRF_CLI_CMD(warning, NULL, "Warning log message with parameters", cmd_log_msg_warning),
|
||||
NRF_CLI_SUBCMD_SET_END
|
||||
};
|
||||
|
||||
NRF_CLI_CMD_REGISTER(log_msg, &m_sub_log_msg, "Trigger log message with decimal arguments", NULL);
|
||||
252
components/libraries/cli/libuarte/nrf_cli_libuarte.c
Normal file
252
components/libraries/cli/libuarte/nrf_cli_libuarte.c
Normal file
@@ -0,0 +1,252 @@
|
||||
/**
|
||||
* Copyright (c) 2018 - 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 "sdk_common.h"
|
||||
#include "nrf_cli_libuarte.h"
|
||||
#include "nrf_libuarte_async.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "nrf_atomic.h"
|
||||
#define NRF_LOG_MODULE_NAME cli_libuarte
|
||||
#if NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED
|
||||
#define NRF_LOG_LEVEL NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL
|
||||
#define NRF_LOG_INFO_COLOR NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR
|
||||
#define NRF_LOG_DEBUG_COLOR NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR
|
||||
#else //NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED
|
||||
#define NRF_LOG_LEVEL 0
|
||||
#endif //NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED
|
||||
#include "nrf_log.h"
|
||||
NRF_LOG_MODULE_REGISTER();
|
||||
|
||||
static cli_libuarte_internal_t * mp_internal;
|
||||
static nrf_atomic_flag_t m_uart_busy;
|
||||
|
||||
NRF_LIBUARTE_ASYNC_DEFINE(libuarte,
|
||||
NRF_CLI_LIBUARTE_UARTE_INSTANCE,
|
||||
NRF_CLI_LIBUARTE_TIMER_INSTANCE,
|
||||
NRF_CLI_LIBUARTE_TIMEOUT_RTC_INSTANCE,
|
||||
NRF_CLI_LIBUARTE_TIMEOUT_TIMER_INSTANCE,
|
||||
3, 255);
|
||||
|
||||
static void uart_event_handler(void * context, nrf_libuarte_async_evt_t * p_event)
|
||||
{
|
||||
cli_libuarte_internal_t * p_internal = mp_internal;
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
size_t len;
|
||||
UNUSED_VARIABLE(err_code);
|
||||
switch (p_event->type)
|
||||
{
|
||||
case NRF_LIBUARTE_ASYNC_EVT_ERROR:
|
||||
NRF_LOG_WARNING("(evt) ERROR");
|
||||
|
||||
break;
|
||||
|
||||
case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
|
||||
{
|
||||
len = (size_t)((uint32_t)p_event->data.rxtx.length & 0x0000FFFF);
|
||||
err_code = nrf_ringbuf_cpy_put(p_internal->p_rx_ringbuf,
|
||||
p_event->data.rxtx.p_data,
|
||||
&len);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
|
||||
if (len != p_event->data.rxtx.length)
|
||||
{
|
||||
NRF_LOG_WARNING("Data lost, no room in RX ringbuf");
|
||||
}
|
||||
nrf_libuarte_async_rx_free(&libuarte, p_event->data.rxtx.p_data, p_event->data.rxtx.length);
|
||||
|
||||
if (p_event->data.rxtx.length)
|
||||
{
|
||||
NRF_LOG_DEBUG("(evt) RXRDY length:%d", p_event->data.rxtx.length);
|
||||
NRF_LOG_HEXDUMP_DEBUG(p_event->data.rxtx.p_data, p_event->data.rxtx.length);
|
||||
p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY,
|
||||
p_internal->p_cb->p_context);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
|
||||
err_code = nrf_ringbuf_free(p_internal->p_tx_ringbuf, p_event->data.rxtx.length);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
uint8_t * p_data;
|
||||
len = 255;
|
||||
err_code = nrf_ringbuf_get(p_internal->p_tx_ringbuf, &p_data, &len, true);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
if (len)
|
||||
{
|
||||
NRF_LOG_DEBUG("(evt) Started TX (%d).", len);
|
||||
err_code = nrf_libuarte_async_tx(&libuarte, p_data, len);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uart_busy = false;
|
||||
}
|
||||
p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_internal->p_cb->p_context);
|
||||
NRF_LOG_DEBUG("(evt) TX completed (%d)", p_event->data.rxtx.length);
|
||||
break;
|
||||
|
||||
default:
|
||||
NRF_LOG_ERROR("(evt) Unknown event");
|
||||
ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static ret_code_t cli_libuarte_init(nrf_cli_transport_t const * p_transport,
|
||||
void const * p_config,
|
||||
nrf_cli_transport_handler_t evt_handler,
|
||||
void * p_context)
|
||||
{
|
||||
cli_libuarte_internal_t * p_internal = CONTAINER_OF(p_transport,
|
||||
cli_libuarte_internal_t,
|
||||
transport);
|
||||
mp_internal = p_internal;
|
||||
m_uart_busy = false;
|
||||
|
||||
p_internal->p_cb->handler = evt_handler;
|
||||
p_internal->p_cb->p_context = p_context;
|
||||
p_internal->p_cb->blocking = false;
|
||||
|
||||
cli_libuarte_config_t const * p_cli_libuarte_config = (cli_libuarte_config_t *)p_config;
|
||||
nrf_libuarte_async_config_t uart_async_config = {
|
||||
.tx_pin = p_cli_libuarte_config->tx_pin,
|
||||
.rx_pin = p_cli_libuarte_config->rx_pin,
|
||||
.baudrate = p_cli_libuarte_config->baudrate,
|
||||
.parity = p_cli_libuarte_config->parity,
|
||||
.hwfc = p_cli_libuarte_config->hwfc,
|
||||
.timeout_us = 100,
|
||||
.int_prio = APP_IRQ_PRIORITY_LOW
|
||||
};
|
||||
ret_code_t err_code = nrf_libuarte_async_init(&libuarte, &uart_async_config, uart_event_handler, NULL);
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
nrf_ringbuf_init(p_internal->p_rx_ringbuf);
|
||||
nrf_ringbuf_init(p_internal->p_tx_ringbuf);
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static ret_code_t cli_libuarte_uninit(nrf_cli_transport_t const * p_transport)
|
||||
{
|
||||
UNUSED_PARAMETER(p_transport);
|
||||
nrf_libuarte_async_uninit(&libuarte);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
static ret_code_t cli_libuarte_enable(nrf_cli_transport_t const * p_transport,
|
||||
bool blocking)
|
||||
{
|
||||
UNUSED_PARAMETER(p_transport);
|
||||
if (blocking)
|
||||
{
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
nrf_libuarte_async_enable(&libuarte);
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
static ret_code_t cli_libuarte_read(nrf_cli_transport_t const * p_transport,
|
||||
void * p_data,
|
||||
size_t length,
|
||||
size_t * p_cnt)
|
||||
{
|
||||
ASSERT(p_cnt);
|
||||
cli_libuarte_internal_t * p_instance =
|
||||
CONTAINER_OF(p_transport, cli_libuarte_internal_t, transport);
|
||||
|
||||
*p_cnt = length;
|
||||
ret_code_t err_code = nrf_ringbuf_cpy_get(p_instance->p_rx_ringbuf, p_data, p_cnt);
|
||||
|
||||
if (*p_cnt)
|
||||
{
|
||||
NRF_LOG_DEBUG("Read %d bytes (requested %d)", *p_cnt, length);
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static ret_code_t cli_libuarte_write(nrf_cli_transport_t const * p_transport,
|
||||
void const * p_data,
|
||||
size_t length,
|
||||
size_t * p_cnt)
|
||||
{
|
||||
ASSERT(p_cnt);
|
||||
cli_libuarte_internal_t * p_instance = CONTAINER_OF(p_transport,
|
||||
cli_libuarte_internal_t,
|
||||
transport);
|
||||
*p_cnt = length;
|
||||
ret_code_t err_code = nrf_ringbuf_cpy_put(p_instance->p_tx_ringbuf, p_data, p_cnt);
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
NRF_LOG_DEBUG("Requested write: %d, copied to ringbuf: %d.", length, *p_cnt);
|
||||
|
||||
if (nrf_atomic_flag_set_fetch(&m_uart_busy))
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
|
||||
uint8_t * p_buf;
|
||||
size_t len = 255;
|
||||
if (nrf_ringbuf_get(p_instance->p_tx_ringbuf, &p_buf, &len, true) == NRF_SUCCESS)
|
||||
{
|
||||
NRF_LOG_DEBUG("Started TX (%d).", len);
|
||||
|
||||
err_code = nrf_libuarte_async_tx(&libuarte, p_buf, len);
|
||||
if (p_instance->p_cb->blocking && (err_code == NRF_SUCCESS))
|
||||
{
|
||||
(void)nrf_ringbuf_free(p_instance->p_tx_ringbuf, len);
|
||||
m_uart_busy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
const nrf_cli_transport_api_t cli_libuarte_transport_api = {
|
||||
.init = cli_libuarte_init,
|
||||
.uninit = cli_libuarte_uninit,
|
||||
.enable = cli_libuarte_enable,
|
||||
.read = cli_libuarte_read,
|
||||
.write = cli_libuarte_write,
|
||||
};
|
||||
|
||||
112
components/libraries/cli/libuarte/nrf_cli_libuarte.h
Normal file
112
components/libraries/cli/libuarte/nrf_cli_libuarte.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Copyright (c) 2018 - 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_LOG_BACKEND_LIBUARTE_H__
|
||||
#define NRF_LOG_BACKEND_LIBUARTE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "nrf_cli.h"
|
||||
#include "nrf_ringbuf.h"
|
||||
#include "app_timer.h"
|
||||
#include "nrf_uarte.h"
|
||||
|
||||
/**@file
|
||||
*
|
||||
* @defgroup nrf_cli_libuarte libUARTE command line interface transport layer.
|
||||
* @ingroup nrf_cli
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Command line interface transport.
|
||||
* */
|
||||
extern const nrf_cli_transport_api_t cli_libuarte_transport_api;
|
||||
|
||||
typedef struct cli_libuarte_internal_s cli_libuarte_internal_t;
|
||||
|
||||
typedef struct {
|
||||
nrf_cli_transport_handler_t handler;
|
||||
void * p_context;
|
||||
bool blocking;
|
||||
} cli_libuarte_internal_cb_t;
|
||||
|
||||
struct cli_libuarte_internal_s {
|
||||
nrf_cli_transport_t transport;
|
||||
cli_libuarte_internal_cb_t * p_cb;
|
||||
nrf_ringbuf_t const * p_rx_ringbuf;
|
||||
nrf_ringbuf_t const * p_tx_ringbuf;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t tx_pin;
|
||||
uint32_t rx_pin;
|
||||
nrf_uarte_hwfc_t hwfc; ///< Flow control configuration.
|
||||
nrf_uarte_parity_t parity; ///< Parity configuration.
|
||||
nrf_uarte_baudrate_t baudrate; ///< Baudrate.
|
||||
} cli_libuarte_config_t;
|
||||
|
||||
/**@brief CLI libUARTE transport definition.
|
||||
*
|
||||
* @param _name Name of instance.
|
||||
* @param _tx_buf_sz Size of TX ring buffer.
|
||||
* @param _rx_buf_sz Size of RX ring buffer.
|
||||
*/
|
||||
#define NRF_CLI_LIBUARTE_DEF(_name, _tx_buf_sz, _rx_buf_sz) \
|
||||
NRF_RINGBUF_DEF(CONCAT_2(_name,_tx_ringbuf), _tx_buf_sz); \
|
||||
NRF_RINGBUF_DEF(CONCAT_2(_name,_rx_ringbuf), _rx_buf_sz); \
|
||||
static cli_libuarte_internal_cb_t CONCAT_2(_name, _cb); \
|
||||
static const cli_libuarte_internal_t _name = { \
|
||||
.transport = {.p_api = &cli_libuarte_transport_api}, \
|
||||
.p_cb = &CONCAT_2(_name, _cb), \
|
||||
.p_rx_ringbuf = &CONCAT_2(_name,_rx_ringbuf), \
|
||||
.p_tx_ringbuf = &CONCAT_2(_name,_tx_ringbuf), \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NRF_LOG_BACKEND_LIBUARTE_H__ */
|
||||
3700
components/libraries/cli/nrf_cli.c
Normal file
3700
components/libraries/cli/nrf_cli.c
Normal file
File diff suppressed because it is too large
Load Diff
704
components/libraries/cli/nrf_cli.h
Normal file
704
components/libraries/cli/nrf_cli.h
Normal file
@@ -0,0 +1,704 @@
|
||||
/**
|
||||
* 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 NRF_CLI_H__
|
||||
#define NRF_CLI_H__
|
||||
|
||||
#include "sdk_common.h"
|
||||
#include "nrf_cli_types.h"
|
||||
#include "nrf_section.h"
|
||||
#include "nrf_log_backend_interface.h"
|
||||
#include "nrf_queue.h"
|
||||
#include "nrf_log_ctrl.h"
|
||||
#include "app_util_platform.h"
|
||||
#include "nrf_memobj.h"
|
||||
|
||||
#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
|
||||
#include "task_manager.h"
|
||||
#endif
|
||||
|
||||
#include "nrf_fprintf.h"
|
||||
#include "nrf_fprintf_format.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NRF_CLI_RX_BUFF_SIZE 16
|
||||
|
||||
/* CLI reserves top task manager flags, bits 0...18 are available for application. */
|
||||
#define NRF_CLI_TRANSPORT_TX_RDY_TASK_EVT (1UL << 19)
|
||||
#define NRF_CLI_TRANSPORT_RX_RDY_TASK_EVT (1UL << 20)
|
||||
#define NRF_CLI_LOG_PENDING_TASK_EVT (1UL << 21)
|
||||
#define NRF_CLI_CMD_EXECUTE_EVT (1UL << 22)
|
||||
#define NRF_CLI_KILL_TASK_EVT (1UL << 23)
|
||||
|
||||
#define NRF_CLI_TASK_EVTS (NRF_CLI_TRANSPORT_TX_RDY_TASK_EVT | \
|
||||
NRF_CLI_TRANSPORT_RX_RDY_TASK_EVT | \
|
||||
NRF_CLI_LOG_PENDING_TASK_EVT | \
|
||||
NRF_CLI_CMD_EXECUTE_EVT | \
|
||||
NRF_CLI_KILL_TASK_EVT)
|
||||
/**
|
||||
* @defgroup nrf_cli Command Line Interface
|
||||
* @ingroup app_common
|
||||
*
|
||||
* @brief Module for unified command line handling.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Aliases to: @ref nrf_cli, @ref nrf_cli_cmd_entry, and @ref nrf_cli_static_entry.
|
||||
* Must be created here to satisfy module declaration order dependencies.
|
||||
*/
|
||||
typedef struct nrf_cli nrf_cli_t;
|
||||
typedef struct nrf_cli_cmd_entry nrf_cli_cmd_entry_t;
|
||||
typedef struct nrf_cli_static_entry nrf_cli_static_entry_t;
|
||||
|
||||
/**
|
||||
* @brief CLI dynamic command descriptor.
|
||||
*
|
||||
* @details Function shall fill the received @ref nrf_cli_static_entry structure with requested (idx)
|
||||
* dynamic subcommand data. If there is more than one dynamic subcommand available,
|
||||
* the function shall ensure that the returned commands: p_static->p_syntax are sorted in
|
||||
* alphabetical order. If idx exceeds the available dynamic subcommands, the function must write
|
||||
* to p_static->p_syntax NULL value. This will indicate to the CLI module that
|
||||
* there are no more dynamic commands to read.
|
||||
*/
|
||||
typedef void (*nrf_cli_dynamic_get)(size_t idx, nrf_cli_static_entry_t * p_static);
|
||||
|
||||
/**
|
||||
* @brief CLI command descriptor.
|
||||
*/
|
||||
struct nrf_cli_cmd_entry
|
||||
{
|
||||
bool is_dynamic;
|
||||
union
|
||||
{
|
||||
nrf_cli_dynamic_get p_dynamic_get; //!< Pointer to function returning dynamic commands.
|
||||
nrf_cli_static_entry_t const * p_static; //!< Pointer to array of static commands.
|
||||
} u;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief CLI command handler prototype.
|
||||
*/
|
||||
typedef void (*nrf_cli_cmd_handler)(nrf_cli_t const * p_cli, size_t argc, char **argv);
|
||||
|
||||
/**
|
||||
* @brief CLI static command descriptor.
|
||||
*/
|
||||
struct nrf_cli_static_entry
|
||||
{
|
||||
char const * p_syntax; //!< Command syntax strings.
|
||||
char const * p_help; //!< Command help string.
|
||||
|
||||
nrf_cli_cmd_entry_t const * p_subcmd; //!< Pointer to subcommand.
|
||||
|
||||
nrf_cli_cmd_handler handler; //!< Command handler.
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Macro for defining and adding a root command (level 0).
|
||||
*
|
||||
* @note Each root command shall have unique syntax.
|
||||
*
|
||||
* @param[in] p_syntax Command syntax (for example: history).
|
||||
* @param[in] p_subcmd Pointer to a subcommands array.
|
||||
* @param[in] p_help Pointer to a command help string.
|
||||
* @param[in] p_handler Pointer to a function handler.
|
||||
*/
|
||||
#define NRF_CLI_CMD_REGISTER(p_syntax, p_subcmd, p_help, p_handler) \
|
||||
nrf_cli_static_entry_t const CONCAT_3(nrf_cli_, p_syntax, _raw) = \
|
||||
NRF_CLI_CMD(p_syntax, p_subcmd, p_help, p_handler); \
|
||||
NRF_SECTION_ITEM_REGISTER(cli_command, \
|
||||
nrf_cli_cmd_entry_t const CONCAT_3(nrf_cli_, p_syntax, _const)) = { \
|
||||
.is_dynamic = false, \
|
||||
.u = {.p_static = &CONCAT_3(nrf_cli_, p_syntax, _raw)} \
|
||||
}; \
|
||||
NRF_SECTION_ITEM_REGISTER(cli_sorted_cmd_ptrs, char const * CONCAT_2(p_syntax, _str_ptr))
|
||||
|
||||
/**
|
||||
* @brief Macro for creating a subcommand set. It must be used outside of any function body.
|
||||
*
|
||||
* @param[in] name Name of the subcommand set.
|
||||
*/
|
||||
#define NRF_CLI_CREATE_STATIC_SUBCMD_SET(name) \
|
||||
/*lint -save -e85 -e31*/ \
|
||||
static nrf_cli_static_entry_t const CONCAT_2(name, _raw)[]; \
|
||||
static nrf_cli_cmd_entry_t const name = { \
|
||||
.is_dynamic = false, \
|
||||
.u = {.p_static = CONCAT_2(name, _raw) } \
|
||||
}; \
|
||||
static nrf_cli_static_entry_t const CONCAT_2(name, _raw)[] = /*lint -restore*/
|
||||
|
||||
/**
|
||||
* @brief Define ending subcommands set.
|
||||
*
|
||||
*/
|
||||
#define NRF_CLI_SUBCMD_SET_END {NULL}
|
||||
|
||||
/**
|
||||
* @brief Macro for creating a dynamic entry.
|
||||
*
|
||||
* @param[in] name Name of the dynamic entry.
|
||||
* @param[in] p_get Pointer to the function returning dynamic commands array @ref nrf_cli_dynamic_get.
|
||||
*/
|
||||
#define NRF_CLI_CREATE_DYNAMIC_CMD(name, p_get) \
|
||||
/*lint -save -e19*/ \
|
||||
static nrf_cli_cmd_entry_t const name = { \
|
||||
.is_dynamic = true, \
|
||||
.u = { .p_dynamic_get = p_get } \
|
||||
}; /*lint -restore*/
|
||||
|
||||
/** @brief Macro for creating subcommands when C++ compiler is used.
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* NRF_CLI_CPP_CREATE_STATIC_SUBCMD_SET(cmd_syntax,
|
||||
* NRF_CLI_CMD(abc, ...),
|
||||
* NRF_CLI_CMD(def, ...),
|
||||
* NRF_CLI_SUBCMD_SET_END
|
||||
* );
|
||||
* @endcode
|
||||
*/
|
||||
#define NRF_CLI_CPP_CREATE_STATIC_SUBCMD_SET(name, ...) \
|
||||
static nrf_cli_static_entry_t const CONCAT_2(name, _raw)[] = { \
|
||||
__VA_ARGS__ \
|
||||
}; \
|
||||
static nrf_cli_cmd_entry_t const name = { \
|
||||
.is_dynamic = false, \
|
||||
.u = { .p_static = CONCAT_2(name, _raw) } \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes a CLI command (@ref nrf_cli_static_entry).
|
||||
*
|
||||
* @param[in] _p_syntax Command syntax (for example: history).
|
||||
* @param[in] _p_subcmd Pointer to a subcommands array.
|
||||
* @param[in] _p_help Pointer to a command help string.
|
||||
* @param[in] _p_handler Pointer to a function handler.
|
||||
*/
|
||||
#define NRF_CLI_CMD(_p_syntax, _p_subcmd, _p_help, _p_handler) { \
|
||||
.p_syntax = (const char *) STRINGIFY(_p_syntax), \
|
||||
.p_help = (const char *) _p_help, \
|
||||
.p_subcmd = _p_subcmd, \
|
||||
.handler = _p_handler \
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal @brief Internal CLI state in response to data received from the terminal.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_CLI_RECEIVE_DEFAULT,
|
||||
NRF_CLI_RECEIVE_ESC,
|
||||
NRF_CLI_RECEIVE_ESC_SEQ,
|
||||
NRF_CLI_RECEIVE_TILDE_EXP
|
||||
} nrf_cli_receive_t;
|
||||
|
||||
|
||||
/**
|
||||
* @internal @brief Internal CLI state.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_CLI_STATE_UNINITIALIZED, //!< State uninitialized.
|
||||
NRF_CLI_STATE_INITIALIZED, //!< State initialized but not active.
|
||||
NRF_CLI_STATE_ACTIVE, //!< State active.
|
||||
NRF_CLI_STATE_PANIC_MODE_ACTIVE, //!< State panic mode activated.
|
||||
NRF_CLI_STATE_PANIC_MODE_INACTIVE //!< State panic mode requested but not supported.
|
||||
} nrf_cli_state_t;
|
||||
|
||||
/**
|
||||
* @brief Event type from CLI transport.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_CLI_TRANSPORT_EVT_RX_RDY,
|
||||
NRF_CLI_TRANSPORT_EVT_TX_RDY
|
||||
} nrf_cli_transport_evt_t;
|
||||
|
||||
typedef void (*nrf_cli_transport_handler_t)(nrf_cli_transport_evt_t evt_type, void * p_context);
|
||||
|
||||
typedef struct nrf_cli_transport_s nrf_cli_transport_t;
|
||||
|
||||
/**
|
||||
* @brief Unified CLI transport interface.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* @brief Function for initializing the CLI transport interface.
|
||||
*
|
||||
* @param[in] p_transport Pointer to the transfer instance.
|
||||
* @param[in] p_config Pointer to instance configuration.
|
||||
* @param[in] evt_handler Event handler.
|
||||
* @param[in] p_context Pointer to the context passed to event handler.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
ret_code_t (*init)(nrf_cli_transport_t const * p_transport,
|
||||
void const * p_config,
|
||||
nrf_cli_transport_handler_t evt_handler,
|
||||
void * p_context);
|
||||
|
||||
/**
|
||||
* @brief Function for uninitializing the CLI transport interface.
|
||||
*
|
||||
* @param[in] p_transport Pointer to the transfer instance.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
ret_code_t (*uninit)(nrf_cli_transport_t const * p_transport);
|
||||
|
||||
/**
|
||||
* @brief Function for reconfiguring the transport to work in blocking mode.
|
||||
*
|
||||
* @param p_transport Pointer to the transfer instance.
|
||||
* @param blocking If true, the transport is enabled in blocking mode.
|
||||
*
|
||||
* @return NRF_SUCCESS on successful enabling, error otherwise (also if not supported).
|
||||
*/
|
||||
ret_code_t (*enable)(nrf_cli_transport_t const * p_transport,
|
||||
bool blocking);
|
||||
|
||||
/**
|
||||
* @brief Function for writing data to the transport interface.
|
||||
*
|
||||
* @param[in] p_transport Pointer to the transfer instance.
|
||||
* @param[in] p_data Pointer to the source buffer.
|
||||
* @param[in] length Source buffer length.
|
||||
* @param[in] p_cnt Pointer to the sent bytes counter.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
ret_code_t (*write)(nrf_cli_transport_t const * p_transport,
|
||||
const void * p_data,
|
||||
size_t length,
|
||||
size_t * p_cnt);
|
||||
|
||||
/**
|
||||
* @brief Function for reading data from the transport interface.
|
||||
*
|
||||
* @param[in] p_transport Pointer to the transfer instance.
|
||||
* @param[in] p_data Pointer to the destination buffer.
|
||||
* @param[in] length Destination buffer length.
|
||||
* @param[in] p_cnt Pointer to the received bytes counter.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
ret_code_t (*read)(nrf_cli_transport_t const * p_transport,
|
||||
void * p_data,
|
||||
size_t length,
|
||||
size_t * p_cnt);
|
||||
|
||||
} nrf_cli_transport_api_t;
|
||||
|
||||
struct nrf_cli_transport_s
|
||||
{
|
||||
nrf_cli_transport_api_t const * p_api;
|
||||
};
|
||||
|
||||
#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
|
||||
/**
|
||||
* @brief CLI history object header.
|
||||
*/
|
||||
typedef PACKED_STRUCT
|
||||
{
|
||||
nrf_memobj_t * p_prev; //!< Pointer to the next object.
|
||||
nrf_memobj_t * p_next; //!< Pointer to the previous object.
|
||||
nrf_cli_cmd_len_t cmd_len; //!< Command length.
|
||||
} nrf_cli_memobj_header_t;
|
||||
#endif
|
||||
|
||||
#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
|
||||
typedef struct
|
||||
{
|
||||
uint32_t log_lost_cnt; //!< Lost log counter.
|
||||
} nrf_cli_statistics_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @internal @brief Flags for internal CLI usage.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t insert_mode : 1; //!< Enables or disables console insert mode for text introduction.
|
||||
uint32_t show_help : 1; //!< Shows help if the command was called with -h or --help parameter.
|
||||
uint32_t use_colors : 1; //!< Enables or disables colored syntax.
|
||||
uint32_t echo : 1; //!< Enables or disables CLI echo.
|
||||
uint32_t processing : 1; //!< CLI is executing process function.
|
||||
uint32_t tx_rdy : 1;
|
||||
uint32_t last_nl : 8; //!< The last received newline character.
|
||||
} nrf_cli_flag_t;
|
||||
STATIC_ASSERT(sizeof(nrf_cli_flag_t) == sizeof(uint32_t));
|
||||
|
||||
/**
|
||||
* @internal @brief Union for internal CLI usage.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
uint32_t value;
|
||||
nrf_cli_flag_t flag;
|
||||
} nrf_cli_internal_t;
|
||||
|
||||
/**
|
||||
* @brief CLI instance context.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
nrf_cli_state_t state; //!< Internal module state.
|
||||
nrf_cli_receive_t receive_state; //!< Escape sequence indicator.
|
||||
|
||||
nrf_cli_static_entry_t active_cmd; //!< Currently executed command
|
||||
|
||||
nrf_cli_vt100_ctx_t vt100_ctx; //!< VT100 color and cursor position, terminal width.
|
||||
|
||||
nrf_cli_cmd_len_t cmd_buff_len; //!< Command length.
|
||||
nrf_cli_cmd_len_t cmd_buff_pos; //!< Command buffer cursor position.
|
||||
|
||||
#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
|
||||
nrf_cli_cmd_len_t cmd_tmp_buff_len; //!< Command length in tmp buffer
|
||||
#endif
|
||||
|
||||
char cmd_buff[NRF_CLI_CMD_BUFF_SIZE]; //!< Command input buffer.
|
||||
char temp_buff[NRF_CLI_CMD_BUFF_SIZE]; //!< Temporary buffer used by various functions.
|
||||
char printf_buff[NRF_CLI_PRINTF_BUFF_SIZE]; //!< Printf buffer size.
|
||||
|
||||
#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
|
||||
nrf_cli_statistics_t statistics; //!< CLI statistics.
|
||||
#endif
|
||||
|
||||
#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
|
||||
task_id_t task_id;
|
||||
#endif
|
||||
|
||||
#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
|
||||
nrf_memobj_t * p_cmd_list_head; //!< Pointer to the head of history list.
|
||||
nrf_memobj_t * p_cmd_list_tail; //!< Pointer to the tail of history list.
|
||||
nrf_memobj_t * p_cmd_list_element; //!< Pointer to an element of history list.
|
||||
#endif
|
||||
volatile nrf_cli_internal_t internal; //!< Internal CLI data
|
||||
} nrf_cli_ctx_t;
|
||||
|
||||
extern const nrf_log_backend_api_t nrf_log_backend_cli_api;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
nrf_queue_t const * p_queue;
|
||||
void * p_context;
|
||||
nrf_cli_t const * p_cli;
|
||||
} nrf_cli_log_backend_t;
|
||||
|
||||
#if NRF_CLI_LOG_BACKEND && NRF_MODULE_ENABLED(NRF_LOG)
|
||||
#define NRF_LOG_BACKEND_CLI_DEF(_name_, _queue_size_) \
|
||||
NRF_QUEUE_DEF(nrf_log_entry_t, \
|
||||
CONCAT_2(_name_, _queue),_queue_size_, NRF_QUEUE_MODE_NO_OVERFLOW); \
|
||||
static nrf_cli_log_backend_t CONCAT_2(cli_log_backend,_name_) = { \
|
||||
.p_queue = &CONCAT_2(_name_, _queue), \
|
||||
}; \
|
||||
NRF_LOG_BACKEND_DEF(_name_, nrf_log_backend_cli_api, &CONCAT_2(cli_log_backend,_name_))
|
||||
|
||||
#define NRF_CLI_BACKEND_PTR(_name_) &CONCAT_2(_name_, _log_backend)
|
||||
#else
|
||||
#define NRF_LOG_BACKEND_CLI_DEF(_name_, _queue_sz_)
|
||||
#define NRF_CLI_BACKEND_PTR(_name_) NULL
|
||||
#endif
|
||||
|
||||
#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
|
||||
/* Header consists memory for cmd length and pointer to: prev and next element. */
|
||||
#define NRF_CLI_HISTORY_HEADER_SIZE (sizeof(nrf_cli_memobj_header_t))
|
||||
|
||||
#define NRF_CLI_HISTORY_MEM_OBJ(name) \
|
||||
NRF_MEMOBJ_POOL_DEF(CONCAT_2(name, _cmd_hist_memobj), \
|
||||
NRF_CLI_HISTORY_HEADER_SIZE + \
|
||||
NRF_CLI_HISTORY_ELEMENT_SIZE, \
|
||||
NRF_CLI_HISTORY_ELEMENT_COUNT)
|
||||
|
||||
#define NRF_CLI_MEMOBJ_PTR(_name_) &CONCAT_2(_name_, _cmd_hist_memobj)
|
||||
#else
|
||||
#define NRF_CLI_MEMOBJ_PTR(_name_) NULL
|
||||
#define NRF_CLI_HISTORY_MEM_OBJ(name)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief CLI instance internals.
|
||||
*
|
||||
* @ref nrf_cli_t
|
||||
*/
|
||||
struct nrf_cli
|
||||
{
|
||||
char const * const p_name; //!< Terminal name.
|
||||
|
||||
nrf_cli_transport_t const * p_iface; //!< Transport interface.
|
||||
nrf_cli_ctx_t * p_ctx; //!< Internal context.
|
||||
nrf_log_backend_t const * p_log_backend; //!< Logger backend.
|
||||
nrf_fprintf_ctx_t * p_fprintf_ctx; //!< fprintf context.
|
||||
nrf_memobj_pool_t const * p_cmd_hist_mempool; //!< Memory reserved for commands history.
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Macro for defining a command line interface instance.
|
||||
*
|
||||
* @param[in] name Instance name.
|
||||
* @param[in] cli_prefix CLI prefix string.
|
||||
* @param[in] p_transport_iface Pointer to the transport interface.
|
||||
* @param[in] newline_ch Deprecated parameter, not used any more. Any uint8_t value can be used.
|
||||
* @param[in] log_queue_size Logger processing queue size.
|
||||
*/
|
||||
#define NRF_CLI_DEF(name, cli_prefix, p_transport_iface, newline_ch, log_queue_size) \
|
||||
static nrf_cli_t const name; \
|
||||
static nrf_cli_ctx_t CONCAT_2(name, _ctx); \
|
||||
NRF_FPRINTF_DEF(CONCAT_2(name, _fprintf_ctx), \
|
||||
&name, \
|
||||
CONCAT_2(name, _ctx).printf_buff, \
|
||||
NRF_CLI_PRINTF_BUFF_SIZE, \
|
||||
false, \
|
||||
nrf_cli_print_stream); \
|
||||
NRF_LOG_BACKEND_CLI_DEF(CONCAT_2(name, _log_backend), log_queue_size); \
|
||||
NRF_CLI_HISTORY_MEM_OBJ(name); \
|
||||
/*lint -save -e31*/ \
|
||||
static nrf_cli_t const name = { \
|
||||
.p_name = cli_prefix, \
|
||||
.p_iface = p_transport_iface, \
|
||||
.p_ctx = &CONCAT_2(name, _ctx), \
|
||||
.p_log_backend = NRF_CLI_BACKEND_PTR(name), \
|
||||
.p_fprintf_ctx = &CONCAT_2(name, _fprintf_ctx), \
|
||||
.p_cmd_hist_mempool = NRF_CLI_MEMOBJ_PTR(name), \
|
||||
} /*lint -restore*/
|
||||
|
||||
/**
|
||||
* @brief Function for initializing a transport layer and internal CLI state.
|
||||
*
|
||||
* @param[in] p_cli Pointer to CLI instance.
|
||||
* @param[in] p_transport_config Configuration forwarded to the transport during initialization.
|
||||
* @param[in] use_colors Enables colored prints.
|
||||
* @param[in] log_backend If true, the console will be used as logger backend.
|
||||
* @param[in] init_lvl Default severity level for the logger.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
ret_code_t nrf_cli_init(nrf_cli_t const * p_cli,
|
||||
void const * p_transport_config,
|
||||
bool use_colors,
|
||||
bool log_backend,
|
||||
nrf_log_severity_t init_lvl);
|
||||
|
||||
ret_code_t nrf_cli_task_create(nrf_cli_t const * p_cli);
|
||||
|
||||
/**
|
||||
* @brief Function for uninitializing a transport layer and internal CLI state.
|
||||
* If function returns NRF_ERROR_BUSY, you must call @ref nrf_cli_process before calling
|
||||
* nrf_cli_uninit again.
|
||||
*
|
||||
* @param p_cli Pointer to CLI instance.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
ret_code_t nrf_cli_uninit(nrf_cli_t const * p_cli);
|
||||
|
||||
/**
|
||||
* @brief Function for starting CLI processing.
|
||||
*
|
||||
* @param p_cli Pointer to the CLI instance.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
ret_code_t nrf_cli_start(nrf_cli_t const * p_cli);
|
||||
|
||||
/**
|
||||
* @brief Function for stopping CLI processing.
|
||||
*
|
||||
* @param p_cli Pointer to CLI instance.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
ret_code_t nrf_cli_stop(nrf_cli_t const * p_cli);
|
||||
|
||||
/**
|
||||
* @brief CLI colors for @ref nrf_cli_fprintf function.
|
||||
*/
|
||||
#define NRF_CLI_DEFAULT NRF_CLI_VT100_COLOR_DEFAULT /**< Turn off character attributes. */
|
||||
#define NRF_CLI_NORMAL NRF_CLI_VT100_COLOR_WHITE /**< Normal color printf. */
|
||||
#define NRF_CLI_INFO NRF_CLI_VT100_COLOR_GREEN /**< Info color printf. */
|
||||
#define NRF_CLI_OPTION NRF_CLI_VT100_COLOR_CYAN /**< Option color printf. */
|
||||
#define NRF_CLI_WARNING NRF_CLI_VT100_COLOR_YELLOW /**< Warning color printf. */
|
||||
#define NRF_CLI_ERROR NRF_CLI_VT100_COLOR_RED /**< Error color printf. */
|
||||
|
||||
/**
|
||||
* @brief Printf-like function which sends formatted data stream to the CLI.
|
||||
* This function shall not be used outside of the CLI module or CLI command context.
|
||||
*
|
||||
* @param[in] p_cli Pointer to the CLI instance.
|
||||
* @param[in] color Printf color.
|
||||
* @param[in] p_fmt Format string.
|
||||
* @param[in] ... List of parameters to print.
|
||||
*/
|
||||
void nrf_cli_fprintf(nrf_cli_t const * p_cli,
|
||||
nrf_cli_vt100_color_t color,
|
||||
char const * p_fmt,
|
||||
...);
|
||||
|
||||
/**
|
||||
* @brief Print an info message to the CLI.
|
||||
*
|
||||
* See @ref nrf_cli_fprintf.
|
||||
*
|
||||
* @param[in] _p_cli Pointer to the CLI instance.
|
||||
* @param[in] _ft Format string.
|
||||
* @param[in] ... List of parameters to print.
|
||||
*/
|
||||
#define nrf_cli_info(_p_cli, _ft, ...) \
|
||||
nrf_cli_fprintf(_p_cli, NRF_CLI_INFO, _ft "\n", ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Print a normal message to the CLI.
|
||||
*
|
||||
* See @ref nrf_cli_fprintf.
|
||||
*
|
||||
* @param[in] _p_cli Pointer to the CLI instance.
|
||||
* @param[in] _ft Format string.
|
||||
* @param[in] ... List of parameters to print.
|
||||
*/
|
||||
#define nrf_cli_print(_p_cli, _ft, ...) \
|
||||
nrf_cli_fprintf(_p_cli, NRF_CLI_DEFAULT, _ft "\n", ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Print a warning message to the CLI.
|
||||
*
|
||||
* See @ref nrf_cli_fprintf.
|
||||
*
|
||||
* @param[in] _p_cli Pointer to the CLI instance.
|
||||
* @param[in] _ft Format string.
|
||||
* @param[in] ... List of parameters to print.
|
||||
*/
|
||||
#define nrf_cli_warn(_p_cli, _ft, ...) \
|
||||
nrf_cli_fprintf(_p_cli, NRF_CLI_WARNING, _ft "\n", ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Print an error message to the CLI.
|
||||
*
|
||||
* See @ref nrf_cli_fprintf.
|
||||
*
|
||||
* @param[in] _p_cli Pointer to the CLI instance.
|
||||
* @param[in] _ft Format string.
|
||||
* @param[in] ... List of parameters to print.
|
||||
*/
|
||||
#define nrf_cli_error(_p_cli, _ft, ...) \
|
||||
nrf_cli_fprintf(_p_cli, NRF_CLI_ERROR, _ft "\n", ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Process function, which should be executed when data is ready in the transport interface.
|
||||
*
|
||||
* @param[in] p_cli Pointer to the CLI instance.
|
||||
*/
|
||||
void nrf_cli_process(nrf_cli_t const * p_cli);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Option descriptor.
|
||||
*/
|
||||
typedef struct nrf_cli_getopt_option
|
||||
{
|
||||
char const * p_optname; //!< Option long name.
|
||||
char const * p_optname_short; //!< Option short name.
|
||||
char const * p_optname_help; //!< Option help string.
|
||||
} nrf_cli_getopt_option_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Option structure initializer @ref nrf_cli_getopt_option.
|
||||
*
|
||||
* @param[in] _p_optname Option name long.
|
||||
* @param[in] _p_shortname Option name short.
|
||||
* @param[in] _p_help Option help string.
|
||||
*/
|
||||
#define NRF_CLI_OPT(_p_optname, _p_shortname, _p_help) { \
|
||||
.p_optname = _p_optname, \
|
||||
.p_optname_short = _p_shortname, \
|
||||
.p_optname_help = _p_help, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Informs that a command has been called with -h or --help option.
|
||||
*
|
||||
* @param[in] p_cli Pointer to the CLI instance.
|
||||
*
|
||||
* @return True if help has been requested.
|
||||
*/
|
||||
__STATIC_INLINE bool nrf_cli_help_requested(nrf_cli_t const * p_cli);
|
||||
|
||||
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
||||
__STATIC_INLINE bool nrf_cli_help_requested(nrf_cli_t const * p_cli)
|
||||
{
|
||||
return p_cli->p_ctx->internal.flag.show_help;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Prints the current command help.
|
||||
* @details Function will print a help string with: the currently entered command, its options,
|
||||
* and subcommands (if they exist).
|
||||
*
|
||||
* @param[in] p_cli Pointer to the CLI instance.
|
||||
* @param[in] p_opt Pointer to the optional option array.
|
||||
* @param[in] opt_len Option array size.
|
||||
*/
|
||||
void nrf_cli_help_print(nrf_cli_t const * p_cli,
|
||||
nrf_cli_getopt_option_t const * p_opt,
|
||||
size_t opt_len);
|
||||
|
||||
/**
|
||||
* @internal @brief This function shall not be used directly, it is required by the
|
||||
* nrf_fprintf module.
|
||||
*
|
||||
* @param[in] p_user_ctx Pointer to the context for the CLI instance.
|
||||
* @param[in] p_data Pointer to the data buffer.
|
||||
* @param[in] data_len Data buffer size.
|
||||
*/
|
||||
void nrf_cli_print_stream(void const * p_user_ctx, char const * p_data, size_t data_len);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NRF_CLI_H__ */
|
||||
102
components/libraries/cli/nrf_cli_types.h
Normal file
102
components/libraries/cli/nrf_cli_types.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* 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 NRF_CLI_TYPES_H__
|
||||
#define NRF_CLI_TYPES_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "sdk_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if (NRF_CLI_CMD_BUFF_SIZE > 65535)
|
||||
typedef uint32_t nrf_cli_cmd_len_t;
|
||||
#elif (NRF_CLI_CMD_BUFF_SIZE > 255)
|
||||
typedef uint16_t nrf_cli_cmd_len_t;
|
||||
#else
|
||||
typedef uint8_t nrf_cli_cmd_len_t;
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NRF_CLI_VT100_COLOR_DEFAULT,
|
||||
NRF_CLI_VT100_COLOR_BLACK,
|
||||
NRF_CLI_VT100_COLOR_RED,
|
||||
NRF_CLI_VT100_COLOR_GREEN,
|
||||
NRF_CLI_VT100_COLOR_YELLOW,
|
||||
NRF_CLI_VT100_COLOR_BLUE,
|
||||
NRF_CLI_VT100_COLOR_MAGENTA,
|
||||
NRF_CLI_VT100_COLOR_CYAN,
|
||||
NRF_CLI_VT100_COLOR_WHITE,
|
||||
|
||||
VT100_COLOR_END
|
||||
} nrf_cli_vt100_color_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
nrf_cli_vt100_color_t col; // text color
|
||||
nrf_cli_vt100_color_t bgcol; // background color
|
||||
} nrf_cli_vt100_colors_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
nrf_cli_cmd_len_t cur_x; // horizontal cursor position in edited command line
|
||||
nrf_cli_cmd_len_t cur_x_end; // horizontal cursor position at the end of command
|
||||
nrf_cli_cmd_len_t cur_y; // vertical cursor position in edited command
|
||||
nrf_cli_cmd_len_t cur_y_end; // vertical cursor position at the end of command
|
||||
nrf_cli_cmd_len_t terminal_hei; // terminal screen height
|
||||
nrf_cli_cmd_len_t terminal_wid; // terminal screen width
|
||||
uint8_t name_len; // console name length
|
||||
} nrf_cli_multiline_cons_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
nrf_cli_multiline_cons_t cons;
|
||||
nrf_cli_vt100_colors_t col;
|
||||
nrf_cli_cmd_len_t printed_cmd; // printed commands counter
|
||||
} nrf_cli_vt100_ctx_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NRF_CLI_TYPES_H__ */
|
||||
|
||||
632
components/libraries/cli/nrf_cli_vt100.h
Normal file
632
components/libraries/cli/nrf_cli_vt100.h
Normal file
@@ -0,0 +1,632 @@
|
||||
/**
|
||||
* 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 NRF_CLI_VT100_H__
|
||||
#define NRF_CLI_VT100_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NRF_CLI_VT100_ASCII_ESC (0x1b)
|
||||
#define NRF_CLI_VT100_ASCII_DEL (0x7F)
|
||||
#define NRF_CLI_VT100_ASCII_BSPACE (0x08)
|
||||
#define NRF_CLI_VT100_ASCII_CTRL_A (0x1)
|
||||
#define NRF_CLI_VT100_ASCII_CTRL_C (0x03)
|
||||
#define NRF_CLI_VT100_ASCII_CTRL_E (0x5)
|
||||
#define NRF_CLI_VT100_ASCII_CTRL_L (0x0C)
|
||||
#define NRF_CLI_VT100_ASCII_CTRL_U (0x15)
|
||||
#define NRF_CLI_VT100_ASCII_CTRL_W (0x17)
|
||||
|
||||
|
||||
#define NRF_CLI_VT100_SETNL \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '2', '0', 'h', '\0' \
|
||||
} /* Set new line mode */
|
||||
#define NRF_CLI_VT100_SETAPPL \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '1', 'h', '\0' \
|
||||
} /* Set cursor key to application */
|
||||
#define NRF_CLI_VT100_SETCOL_132 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '3', 'h', '\0' \
|
||||
} /* Set number of columns to 132 */
|
||||
#define NRF_CLI_VT100_SETSMOOTH \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '4', 'h', '\0' \
|
||||
} /* Set smooth scrolling */
|
||||
#define NRF_CLI_VT100_SETREVSCRN \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '5', 'h', '\0' \
|
||||
} /* Set reverse video on screen */
|
||||
#define NRF_CLI_VT100_SETORGREL \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '6', 'h', '\0' \
|
||||
} /* Set origin to relative */
|
||||
#define NRF_CLI_VT100_SETWRAP_ON \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '7', 'h', '\0' \
|
||||
} /* Set auto-wrap mode */
|
||||
#define NRF_CLI_VT100_SETWRAP_OFF \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '7', 'l', '\0' \
|
||||
} /* Set auto-wrap mode */
|
||||
|
||||
#define NRF_CLI_VT100_SETREP \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '8', 'h', '\0' \
|
||||
} /* Set auto-repeat mode */
|
||||
#define NRF_CLI_VT100_SETINTER \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '9', 'h', '\0' \
|
||||
} /* Set interlacing mode */
|
||||
|
||||
#define NRF_CLI_VT100_SETLF \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '2', '0', 'l', '\0' \
|
||||
} /* Set line feed mode */
|
||||
#define NRF_CLI_VT100_SETCURSOR \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '1', 'l', '\0' \
|
||||
} /* Set cursor key to cursor */
|
||||
#define NRF_CLI_VT100_SETVT52 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '2', 'l', '\0' \
|
||||
} /* Set VT52 (versus ANSI) */
|
||||
#define NRF_CLI_VT100_SETCOL_80 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '3', 'l', '\0' \
|
||||
} /* Set number of columns to 80 */
|
||||
#define NRF_CLI_VT100_SETJUMP \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '4', 'l', '\0' \
|
||||
} /* Set jump scrolling */
|
||||
#define NRF_CLI_VT100_SETNORMSCRN \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '5', 'l', '\0' \
|
||||
} /* Set normal video on screen */
|
||||
#define NRF_CLI_VT100_SETORGABS \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '6', 'l', '\0' \
|
||||
} /* Set origin to absolute */
|
||||
#define NRF_CLI_VT100_RESETWRAP \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '7', 'l', '\0' \
|
||||
} /* Reset auto-wrap mode */
|
||||
#define NRF_CLI_VT100_RESETREP \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '8', 'l', '\0' \
|
||||
} /* Reset auto-repeat mode */
|
||||
#define NRF_CLI_VT100_RESETINTER \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '9', 'l', '\0' \
|
||||
} /* Reset interlacing mode */
|
||||
|
||||
#define NRF_CLI_VT100_ALTKEYPAD \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '=', '\0' \
|
||||
} /* Set alternate keypad mode */
|
||||
#define NRF_CLI_VT100_NUMKEYPAD \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '>', '\0' \
|
||||
} /* Set numeric keypad mode */
|
||||
|
||||
#define NRF_CLI_VT100_SETUKG0 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '(', 'A', '\0' \
|
||||
} /* Set United Kingdom G0 character set */
|
||||
#define NRF_CLI_VT100_SETUKG1 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, ')', 'A', '\0' \
|
||||
} /* Set United Kingdom G1 character set */
|
||||
#define NRF_CLI_VT100_SETUSG0 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '(', 'B', '\0' \
|
||||
} /* Set United States G0 character set */
|
||||
#define NRF_CLI_VT100_SETUSG1 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, ')', 'B', '\0' \
|
||||
} /* Set United States G1 character set */
|
||||
#define NRF_CLI_VT100_SETSPECG0 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '(', '0', '\0' \
|
||||
} /* Set G0 special chars. & line set */
|
||||
#define NRF_CLI_VT100_SETSPECG1 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, ')', '0', '\0' \
|
||||
} /* Set G1 special chars. & line set */
|
||||
#define NRF_CLI_VT100_SETALTG0 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '(', '1', '\0' \
|
||||
} /* Set G0 alternate character ROM */
|
||||
#define NRF_CLI_VT100_SETALTG1 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, ')', '1', '\0' \
|
||||
} /* Set G1 alternate character ROM */
|
||||
#define NRF_CLI_VT100_SETALTSPECG0 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '(', '2', '\0' \
|
||||
} /* Set G0 alt char ROM and spec. graphics */
|
||||
#define NRF_CLI_VT100_SETALTSPECG1 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, ')', '2', '\0' \
|
||||
} /* Set G1 alt char ROM and spec. graphics */
|
||||
|
||||
#define NRF_CLI_VT100_SETSS2 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'N', '\0' \
|
||||
} /* Set single shift 2 */
|
||||
#define NRF_CLI_VT100_SETSS3 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', '\0' \
|
||||
} /* Set single shift 3 */
|
||||
|
||||
#define NRF_CLI_VT100_MODESOFF \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', 'm', '\0' \
|
||||
} /* Turn off character attributes */
|
||||
#define NRF_CLI_VT100_MODESOFF_ \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '0', 'm', '\0' \
|
||||
} /* Turn off character attributes */
|
||||
#define NRF_CLI_VT100_BOLD \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '1', 'm', '\0' \
|
||||
} /* Turn bold mode on */
|
||||
#define NRF_CLI_VT100_LOWINT \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '2', 'm', '\0' \
|
||||
} /* Turn low intensity mode on */
|
||||
#define NRF_CLI_VT100_UNDERLINE \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '4', 'm', '\0' \
|
||||
} /* Turn underline mode on */
|
||||
#define NRF_CLI_VT100_BLINK \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '5', 'm', '\0' \
|
||||
} /* Turn blinking mode on */
|
||||
#define NRF_CLI_VT100_REVERSE \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '7', 'm', '\0' \
|
||||
} /* Turn reverse video on */
|
||||
#define NRF_CLI_VT100_INVISIBLE \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '8', 'm', '\0' \
|
||||
} /* Turn invisible text mode on */
|
||||
|
||||
#define NRF_CLI_VT100_SETWIN(t, b) \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', (t), ';', (b), 'r', '\0' \
|
||||
} /* Set top and bottom line#s of a window */
|
||||
|
||||
#define NRF_CLI_VT100_CURSORUP(n) \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', (n), 'A', '\0' \
|
||||
} /* Move cursor up n lines */
|
||||
#define NRF_CLI_VT100_CURSORDN(n) \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', (n), 'B', '\0' \
|
||||
} /* Move cursor down n lines */
|
||||
#define NRF_CLI_VT100_CURSORRT(n) \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', (n), 'C', '\0' \
|
||||
} /* Move cursor right n lines */
|
||||
#define NRF_CLI_VT100_CURSORLF(n) \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', (n), 'D', '\0' \
|
||||
} /* Move cursor left n lines */
|
||||
#define NRF_CLI_VT100_CURSORHOME \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', 'H', '\0' \
|
||||
} /* Move cursor to upper left corner */
|
||||
#define NRF_CLI_VT100_CURSORHOME_ \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', ';', 'H', '\0' \
|
||||
} /* Move cursor to upper left corner */
|
||||
#define NRF_CLI_VT100_CURSORPOS(v, h) \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', (v), ';', (h), 'H', '\0' \
|
||||
} /* Move cursor to screen location v,h */
|
||||
|
||||
#define NRF_CLI_VT100_HVHOME \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', 'f', '\0' \
|
||||
} /* Move cursor to upper left corner */
|
||||
#define NRF_CLI_VT100_HVHOME_ \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', ';', 'f', '\0' \
|
||||
} /* Move cursor to upper left corner */
|
||||
#define NRF_CLI_VT100_HVPOS(v, h) \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', (v), ';', (h), 'f', '\0' \
|
||||
} /* Move cursor to screen location v,h */
|
||||
#define NRF_CLI_VT100_INDEX \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'D', '\0' \
|
||||
} /* Move/scroll window up one line */
|
||||
#define NRF_CLI_VT100_REVINDEX \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'M', '\0' \
|
||||
} /* Move/scroll window down one line */
|
||||
#define NRF_CLI_VT100_NEXTLINE \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'E', '\0' \
|
||||
} /* Move to next line */
|
||||
#define NRF_CLI_VT100_SAVECURSOR \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '7', '\0' \
|
||||
} /* Save cursor position and attributes */
|
||||
#define NRF_CLI_VT100_RESTORECURSOR \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '8', '\0' \
|
||||
} /* Restore cursor position and attribute */
|
||||
|
||||
#define NRF_CLI_VT100_TABSET \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'H', '\0' \
|
||||
} /* Set a tab at the current column */
|
||||
#define NRF_CLI_VT100_TABCLR \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', 'g', '\0' \
|
||||
} /* Clear a tab at the current column */
|
||||
#define NRF_CLI_VT100_TABCLR_ \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '0', 'g', '\0' \
|
||||
} /* Clear a tab at the current column */
|
||||
#define NRF_CLI_VT100_TABCLRALL \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '3', 'g', '\0' \
|
||||
} /* Clear all tabs */
|
||||
|
||||
#define NRF_CLI_VT100_DHTOP \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '#', '3', '\0' \
|
||||
} /* Double-height letters, top half */
|
||||
#define NRF_CLI_VT100_DHBOT \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '#', '4', '\0' \
|
||||
} /* Double-height letters, bottom hal */
|
||||
#define NRF_CLI_VT100_SWSH \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '#', '5', '\0' \
|
||||
} /* Single width, single height letters */
|
||||
#define NRF_CLI_VT100_DWSH \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '#', '6', '\0' \
|
||||
} /* Double width, single height letters */
|
||||
|
||||
#define NRF_CLI_VT100_CLEAREOL \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', 'K', '\0' \
|
||||
} /* Clear line from cursor right */
|
||||
#define NRF_CLI_VT100_CLEAREOL_ \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '0', 'K', '\0' \
|
||||
} /* Clear line from cursor right */
|
||||
#define NRF_CLI_VT100_CLEARBOL \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '1', 'K', '\0' \
|
||||
} /* Clear line from cursor left */
|
||||
#define NRF_CLI_VT100_CLEARLINE \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '2', 'K', '\0' \
|
||||
} /* Clear entire line */
|
||||
|
||||
#define NRF_CLI_VT100_CLEAREOS \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', 'J', '\0' \
|
||||
} /* Clear screen from cursor down */
|
||||
#define NRF_CLI_VT100_CLEAREOS_ \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '0', 'J', '\0' \
|
||||
} /* Clear screen from cursor down */
|
||||
#define NRF_CLI_VT100_CLEARBOS \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '1', 'J', '\0' \
|
||||
} /* Clear screen from cursor up */
|
||||
#define NRF_CLI_VT100_CLEARSCREEN \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '2', 'J', '\0' \
|
||||
} /* Clear entire screen */
|
||||
|
||||
#define NRF_CLI_VT100_DEVSTAT \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '5', 'n', '\0' \
|
||||
} /* Device status report */
|
||||
#define NRF_CLI_VT100_TERMOK \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '0', 'n', '\0' \
|
||||
} /* Response: terminal is OK */
|
||||
#define NRF_CLI_VT100_TERMNOK \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '3', 'n', '\0' \
|
||||
} /* Response: terminal is not OK */
|
||||
|
||||
#define NRF_CLI_VT100_GETCURSOR \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '6', 'n', '\0' \
|
||||
} /* Get cursor position */
|
||||
#define NRF_CLI_VT100_CURSORPOSAT \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, (v), ';', (h), 'R', '\0' \
|
||||
} /* Response: cursor is at v,h */
|
||||
|
||||
#define NRF_CLI_VT100_IDENT \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', 'c', '\0' \
|
||||
} /* Identify what terminal type */
|
||||
#define NRF_CLI_VT100_IDENT_ \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '0', 'c', '\0' \
|
||||
} /* Identify what terminal type */
|
||||
#define NRF_CLI_VT100_GETTYPE \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '?', '1', ';', (n), '0', 'c', '\0'\
|
||||
} /* Response: terminal type code n */
|
||||
|
||||
#define NRF_CLI_VT100_RESET \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'c', '\0' \
|
||||
} /* Reset terminal to initial state */
|
||||
|
||||
#define NRF_CLI_VT100_ALIGN \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '#', '8', '\0' \
|
||||
} /* Screen alignment display */
|
||||
#define NRF_CLI_VT100_TESTPU \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '1', 'y', '\0' \
|
||||
} /* Confidence power up test */
|
||||
#define NRF_CLI_VT100_TESTLB \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '2', 'y', '\0' \
|
||||
} /* Confidence loopback test */
|
||||
#define NRF_CLI_VT100_TESTPUREP \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '9', 'y', '\0' \
|
||||
} /* Repeat power up test */
|
||||
#define NRF_CLI_VT100_TESTLBREP \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '1', '0', 'y', '\0' \
|
||||
} /* Repeat loopback test */
|
||||
|
||||
#define NRF_CLI_VT100_LEDSOFF \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '0', 'q', '\0' \
|
||||
} /* Turn off all four leds */
|
||||
#define NRF_CLI_VT100_LED1 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '1', 'q', '\0' \
|
||||
} /* Turn on LED #1 */
|
||||
#define NRF_CLI_VT100_LED2 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '2', 'q', '\0' \
|
||||
} /* Turn on LED #2 */
|
||||
#define NRF_CLI_VT100_LED3 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '3', 'q', '\0' \
|
||||
} /* Turn on LED #3 */
|
||||
#define NRF_CLI_VT100_LED4 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '4', 'q', '\0' \
|
||||
} /* Turn on LED #4 */
|
||||
|
||||
/* Function Keys */
|
||||
|
||||
#define NRF_CLI_VT100_PF1 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'P', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_PF2 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'Q', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_PF3 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'R', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_PF4 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'S', '\0' \
|
||||
}
|
||||
|
||||
/* Arrow keys */
|
||||
|
||||
#define NRF_CLI_VT100_UP_RESET \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'A', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_UP_SET \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'A', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_DOWN_RESET \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'B', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_DOWN_SET \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'B', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_RIGHT_RESET \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'C', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_RIGHT_SET \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'C', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_LEFT_RESET \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'D', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_LEFT_SET \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'D', '\0' \
|
||||
}
|
||||
|
||||
/* Numeric Keypad Keys */
|
||||
|
||||
#define NRF_CLI_VT100_NUMERIC_0 \
|
||||
{ \
|
||||
'0', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_ALT_0 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'p', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_NUMERIC_1 \
|
||||
{ \
|
||||
'1', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_ALT_1 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'q', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_NUMERIC_2 \
|
||||
{ \
|
||||
'2', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_ALT_2 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'r', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_NUMERIC_3 \
|
||||
{ \
|
||||
'3', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_ALT_3 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 's', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_NUMERIC_4 \
|
||||
{ \
|
||||
'4', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_ALT_4 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 't', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_NUMERIC_5 \
|
||||
{ \
|
||||
'5', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_ALT_5 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'u', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_NUMERIC_6 \
|
||||
{ \
|
||||
'6', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_ALT_6 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'v', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_NUMERIC_7 \
|
||||
{ \
|
||||
'7', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_ALT_7 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'w', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_NUMERIC_8 \
|
||||
{ \
|
||||
'8', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_ALT_8 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'x', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_NUMERIC_9 \
|
||||
{ \
|
||||
'9', '\0'
|
||||
#define NRF_CLI_VT100_ALT_9 \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'y' \
|
||||
}
|
||||
#define NRF_CLI_VT100_NUMERIC_MINUS \
|
||||
{ \
|
||||
'-', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_ALT_MINUS \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'm', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_NUMERIC_COMMA \
|
||||
{ \
|
||||
',', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_ALT_COMMA \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'l', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_NUMERIC_PERIOD \
|
||||
{ \
|
||||
'.', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_ALT_PERIOD \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'n', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_NUMERIC_ENTER \
|
||||
{ \
|
||||
ASCII_CR \
|
||||
}
|
||||
#define NRF_CLI_VT100_ALT_ENTER \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, 'O', 'M', '\0' \
|
||||
}
|
||||
|
||||
#define NRF_CLI_VT100_COLOR(__col) \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '1', ';', '3', '0' + (__col), 'm', '\0' \
|
||||
}
|
||||
#define NRF_CLI_VT100_BGCOLOR(__col) \
|
||||
{ \
|
||||
NRF_CLI_VT100_ASCII_ESC, '[', '4', '0' + (__col), 'm', '\0' \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NRF_CLI_VT100_H__ */
|
||||
|
||||
223
components/libraries/cli/rtt/nrf_cli_rtt.c
Normal file
223
components/libraries/cli/rtt/nrf_cli_rtt.c
Normal file
@@ -0,0 +1,223 @@
|
||||
/**
|
||||
* 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 "sdk_common.h"
|
||||
#if NRF_MODULE_ENABLED(NRF_CLI_RTT)
|
||||
#include <SEGGER_RTT_Conf.h>
|
||||
#include <SEGGER_RTT.h>
|
||||
#include "nrf_cli_rtt.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "nrf_delay.h"
|
||||
|
||||
#define RTT_RX_TIMEOUT 100
|
||||
|
||||
static bool m_host_present;
|
||||
|
||||
static void timer_handler(void * p_context)
|
||||
{
|
||||
nrf_cli_rtt_internal_t * p_internal = (nrf_cli_rtt_internal_t *)p_context;
|
||||
if (SEGGER_RTT_HasData(0))
|
||||
{
|
||||
p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY, p_internal->p_cb->p_context);
|
||||
}
|
||||
p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_internal->p_cb->p_context);
|
||||
|
||||
ret_code_t err_code = app_timer_start(*p_internal->p_timer,
|
||||
APP_TIMER_TICKS(RTT_RX_TIMEOUT),
|
||||
p_context);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
UNUSED_VARIABLE(err_code);
|
||||
}
|
||||
|
||||
static ret_code_t cli_rtt_init(nrf_cli_transport_t const * p_transport,
|
||||
void const * p_config,
|
||||
nrf_cli_transport_handler_t evt_handler,
|
||||
void * p_context)
|
||||
{
|
||||
UNUSED_PARAMETER(p_config);
|
||||
|
||||
nrf_cli_rtt_internal_t * p_internal =
|
||||
CONTAINER_OF(p_transport, nrf_cli_rtt_internal_t, transport);
|
||||
p_internal->p_cb->handler = evt_handler;
|
||||
p_internal->p_cb->p_context = p_context;
|
||||
p_internal->p_cb->timer_created = false;
|
||||
|
||||
SEGGER_RTT_Init();
|
||||
|
||||
m_host_present = true;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
static ret_code_t cli_rtt_uninit(nrf_cli_transport_t const * p_transport)
|
||||
{
|
||||
nrf_cli_rtt_internal_t * p_internal =
|
||||
CONTAINER_OF(p_transport, nrf_cli_rtt_internal_t, transport);
|
||||
|
||||
return app_timer_stop(*p_internal->p_timer);
|
||||
}
|
||||
|
||||
static ret_code_t cli_rtt_enable(nrf_cli_transport_t const * p_transport,
|
||||
bool blocking)
|
||||
{
|
||||
nrf_cli_rtt_internal_t * p_internal =
|
||||
CONTAINER_OF(p_transport, nrf_cli_rtt_internal_t, transport);
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
|
||||
if (p_internal->p_cb->timer_created)
|
||||
{
|
||||
err_code = app_timer_stop(*p_internal->p_timer); //Timer may be running or inactive
|
||||
if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE))
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_SUCCESS;
|
||||
}
|
||||
}
|
||||
if (!blocking)
|
||||
{
|
||||
if (!p_internal->p_cb->timer_created)
|
||||
{
|
||||
err_code = app_timer_create(p_internal->p_timer,
|
||||
APP_TIMER_MODE_SINGLE_SHOT,
|
||||
timer_handler);
|
||||
p_internal->p_cb->timer_created = true;
|
||||
}
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
err_code = app_timer_start(*p_internal->p_timer,
|
||||
APP_TIMER_TICKS(RTT_RX_TIMEOUT),
|
||||
p_internal);
|
||||
SEGGER_RTT_Init();
|
||||
}
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
static ret_code_t cli_rtt_read(nrf_cli_transport_t const * p_transport,
|
||||
void * p_data,
|
||||
size_t length,
|
||||
size_t * p_cnt)
|
||||
{
|
||||
ASSERT(p_cnt);
|
||||
UNUSED_PARAMETER(p_transport);
|
||||
|
||||
size_t rcnt = SEGGER_RTT_Read(NRF_CLI_RTT_TERMINAL_ID, p_data, length);
|
||||
*p_cnt = rcnt;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
static ret_code_t cli_rtt_write(nrf_cli_transport_t const * p_transport,
|
||||
const void * p_data,
|
||||
size_t length,
|
||||
size_t * p_cnt)
|
||||
{
|
||||
ASSERT(p_cnt);
|
||||
UNUSED_PARAMETER(p_transport);
|
||||
|
||||
if (!(CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk))
|
||||
{
|
||||
/* If an RTT session is not active, but the RTT console is processed, the program may hang.
|
||||
* Workaround: If the debugger is not connected, always return NRF_SUCCESS.
|
||||
*/
|
||||
*p_cnt = length;
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
size_t idx = 0;
|
||||
uint32_t processed;
|
||||
uint32_t watchdog_counter = NRF_CLI_RTT_TX_RETRY_CNT;
|
||||
const uint8_t * p_buffer = (const uint8_t *)p_data;
|
||||
do {
|
||||
processed = SEGGER_RTT_Write(NRF_CLI_RTT_TERMINAL_ID, &p_buffer[idx], length);
|
||||
if (processed == 0)
|
||||
{
|
||||
/* There are two possible reasons for not writing any data to RTT:
|
||||
* - The host is not connected and not reading the data.
|
||||
* - The buffer got full and will be read by the host.
|
||||
* These two situations are distinguished using the following algorithm.
|
||||
* At the begining, the module assumes that the host is active,
|
||||
* so when no data is read, it busy waits and retries.
|
||||
* If, after retrying, the host reads the data, the module assumes that the host is active.
|
||||
* If it fails, the module assumes that the host is inactive and stores that information. On next
|
||||
* call, only one attempt takes place. The host is marked as active if the attempt is successful.
|
||||
*/
|
||||
if (!m_host_present)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
nrf_delay_ms(NRF_CLI_RTT_TX_RETRY_DELAY_MS);
|
||||
watchdog_counter--;
|
||||
if (watchdog_counter == 0)
|
||||
{
|
||||
m_host_present = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_host_present = true;
|
||||
idx += processed;
|
||||
length -= processed;
|
||||
} while (length);
|
||||
|
||||
if (idx > 0)
|
||||
{
|
||||
*p_cnt = idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p_cnt = length;
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
const nrf_cli_transport_api_t nrf_cli_rtt_transport_api = {
|
||||
.init = cli_rtt_init,
|
||||
.uninit = cli_rtt_uninit,
|
||||
.enable = cli_rtt_enable,
|
||||
.read = cli_rtt_read,
|
||||
.write = cli_rtt_write,
|
||||
};
|
||||
|
||||
#endif
|
||||
100
components/libraries/cli/rtt/nrf_cli_rtt.h
Normal file
100
components/libraries/cli/rtt/nrf_cli_rtt.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* 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 NRF_CLI_RTT_H__
|
||||
#define NRF_CLI_RTT_H__
|
||||
|
||||
#include "nrf_cli.h"
|
||||
#include "app_timer.h"
|
||||
#include "nordic_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@file
|
||||
*
|
||||
* @defgroup nrf_cli_rtt RTT command line interface transport layer
|
||||
* @ingroup nrf_cli
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Command line interface transport.
|
||||
*/
|
||||
extern const nrf_cli_transport_api_t nrf_cli_rtt_transport_api;
|
||||
|
||||
/**
|
||||
* @brief CLI RTT transport control block structure.
|
||||
*/
|
||||
typedef struct {
|
||||
nrf_cli_transport_handler_t handler; //!< Event handler
|
||||
void * p_context; //!< User context.
|
||||
bool timer_created;//!< Flag indicating whether a timer is created.
|
||||
} nrf_cli_rtt_internal_cb_t;
|
||||
|
||||
/**
|
||||
* @brief CLI RTT transport instance structure.
|
||||
*/
|
||||
typedef struct {
|
||||
nrf_cli_transport_t transport; //!< Transport structure.
|
||||
nrf_cli_rtt_internal_cb_t * p_cb; //!< Pointer to the instance control block.
|
||||
app_timer_id_t const * p_timer; //!< Pointer to the app_timer instance.
|
||||
} nrf_cli_rtt_internal_t;
|
||||
|
||||
/**@brief CLI RTT transport definition */
|
||||
#define NRF_CLI_RTT_DEF(_name_) \
|
||||
APP_TIMER_DEF(CONCAT_2(_name_, _timer)); \
|
||||
static nrf_cli_rtt_internal_cb_t CONCAT_2(_name_, _cb); \
|
||||
static const nrf_cli_rtt_internal_t _name_ = { \
|
||||
.transport = {.p_api = &nrf_cli_rtt_transport_api}, \
|
||||
.p_cb = &CONCAT_2(_name_, _cb), \
|
||||
.p_timer = &CONCAT_2(_name_, _timer) \
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NRF_CLI_RTT_H__ */
|
||||
308
components/libraries/cli/uart/nrf_cli_uart.c
Normal file
308
components/libraries/cli/uart/nrf_cli_uart.c
Normal file
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
* 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 "sdk_common.h"
|
||||
#if NRF_MODULE_ENABLED(NRF_CLI_UART)
|
||||
#include "nrf_cli_uart.h"
|
||||
#include "nrf_drv_uart.h"
|
||||
#include "nrf_assert.h"
|
||||
|
||||
#define NRF_LOG_MODULE_NAME cli_uart
|
||||
|
||||
#define NRF_LOG_LEVEL (NRF_CLI_UART_CONFIG_LOG_ENABLED ? NRF_CLI_UART_CONFIG_LOG_LEVEL : 0)
|
||||
#define NRF_LOG_INFO_COLOR NRF_CLI_UART_CONFIG_INFO_COLOR
|
||||
#define NRF_LOG_DEBUG_COLOR NRF_CLI_UART_CONFIG_DEBUG_COLOR
|
||||
|
||||
#include "nrf_log.h"
|
||||
NRF_LOG_MODULE_REGISTER();
|
||||
|
||||
#define CLI_UART_RX_TIMEOUT 100
|
||||
|
||||
static ret_code_t rx_try(nrf_cli_uart_internal_t * p_internal)
|
||||
{
|
||||
ret_code_t err_code;
|
||||
size_t len = 255;
|
||||
uint8_t * p_data;
|
||||
|
||||
err_code = nrf_ringbuf_alloc(p_internal->p_rx_ringbuf, &p_data, &len, true);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
|
||||
if ((err_code == NRF_SUCCESS) && len)
|
||||
{
|
||||
err_code = nrf_drv_uart_rx(p_internal->p_uart, p_data, len);
|
||||
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
err_code = app_timer_start(*p_internal->p_timer,
|
||||
APP_TIMER_TICKS(CLI_UART_RX_TIMEOUT),
|
||||
p_internal);
|
||||
}
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context)
|
||||
{
|
||||
nrf_cli_uart_internal_t * p_internal = (nrf_cli_uart_internal_t *)p_context;
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
UNUSED_VARIABLE(err_code);
|
||||
uint8_t * p_data;
|
||||
size_t len = 255;
|
||||
switch (p_event->type)
|
||||
{
|
||||
case NRF_DRV_UART_EVT_ERROR:
|
||||
NRF_LOG_WARNING("id:%d, evt: ERROR:%d",
|
||||
p_internal->p_uart->inst_idx,
|
||||
p_event->data.error.error_mask);
|
||||
err_code = nrf_ringbuf_put(p_internal->p_rx_ringbuf, p_event->data.error.rxtx.bytes);
|
||||
ASSERT((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM));
|
||||
err_code = rx_try(p_internal);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
|
||||
break;
|
||||
|
||||
case NRF_DRV_UART_EVT_RX_DONE:
|
||||
err_code = nrf_ringbuf_put(p_internal->p_rx_ringbuf, p_event->data.rxtx.bytes);
|
||||
ASSERT((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM));
|
||||
|
||||
if (p_event->data.rxtx.bytes)
|
||||
{
|
||||
NRF_LOG_INFO("id:%d, evt: RXRDY len:%d",
|
||||
p_internal->p_uart->inst_idx,
|
||||
p_event->data.rxtx.bytes);
|
||||
NRF_LOG_HEXDUMP_DEBUG(p_event->data.rxtx.p_data, p_event->data.rxtx.bytes);
|
||||
p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY,
|
||||
p_internal->p_cb->p_context);
|
||||
}
|
||||
err_code = rx_try(p_internal);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
|
||||
break;
|
||||
|
||||
case NRF_DRV_UART_EVT_TX_DONE:
|
||||
err_code = nrf_ringbuf_free(p_internal->p_tx_ringbuf, p_event->data.rxtx.bytes);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
len = 255;
|
||||
err_code = nrf_ringbuf_get(p_internal->p_tx_ringbuf, &p_data, &len, true);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
if (len)
|
||||
{
|
||||
NRF_LOG_INFO("id:%d, evt uart_tx, len:%d", p_internal->p_uart->inst_idx, len);
|
||||
err_code = nrf_drv_uart_tx(p_internal->p_uart, p_data, len);
|
||||
ASSERT(err_code == NRF_SUCCESS);
|
||||
}
|
||||
p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_internal->p_cb->p_context);
|
||||
NRF_LOG_INFO("id:%d, evt: TXRDY, len:%d",
|
||||
p_internal->p_uart->inst_idx,
|
||||
p_event->data.rxtx.bytes);
|
||||
break;
|
||||
|
||||
default:
|
||||
NRF_LOG_ERROR("Unknown event");
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
static void timer_handler(void * p_context)
|
||||
{
|
||||
nrf_cli_uart_internal_t * p_internal = (nrf_cli_uart_internal_t *)p_context;
|
||||
NRF_LOG_DEBUG("id:%d, evt: Timeout", p_internal->p_uart->inst_idx);
|
||||
nrf_drv_uart_rx_abort(p_internal->p_uart);
|
||||
}
|
||||
|
||||
static ret_code_t cli_uart_init(nrf_cli_transport_t const * p_transport,
|
||||
void const * p_config,
|
||||
nrf_cli_transport_handler_t evt_handler,
|
||||
void * p_context)
|
||||
{
|
||||
nrf_cli_uart_internal_t * p_internal =
|
||||
CONTAINER_OF(p_transport,
|
||||
nrf_cli_uart_internal_t,
|
||||
transport);
|
||||
p_internal->p_cb->handler = evt_handler;
|
||||
p_internal->p_cb->p_context = p_context;
|
||||
p_internal->p_cb->timer_created = false;
|
||||
p_internal->p_cb->blocking = false;
|
||||
|
||||
nrf_drv_uart_config_t * p_uart_config = (nrf_drv_uart_config_t *)p_config;
|
||||
memcpy(&p_internal->p_cb->uart_config, p_uart_config, sizeof(nrf_drv_uart_config_t));
|
||||
p_uart_config->p_context = (void *)p_internal;
|
||||
ret_code_t err_code = nrf_drv_uart_init(p_internal->p_uart,
|
||||
p_uart_config,
|
||||
uart_event_handler);
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
nrf_ringbuf_init(p_internal->p_rx_ringbuf);
|
||||
nrf_ringbuf_init(p_internal->p_tx_ringbuf);
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static ret_code_t cli_uart_uninit(nrf_cli_transport_t const * p_transport)
|
||||
{
|
||||
nrf_cli_uart_internal_t * p_internal =
|
||||
CONTAINER_OF(p_transport,
|
||||
nrf_cli_uart_internal_t,
|
||||
transport);
|
||||
|
||||
nrf_drv_uart_uninit(p_internal->p_uart);
|
||||
|
||||
return app_timer_stop(*p_internal->p_timer);
|
||||
}
|
||||
|
||||
static ret_code_t cli_uart_enable(nrf_cli_transport_t const * p_transport,
|
||||
bool blocking)
|
||||
{
|
||||
nrf_cli_uart_internal_t * p_internal =
|
||||
CONTAINER_OF(p_transport,
|
||||
nrf_cli_uart_internal_t,
|
||||
transport);
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
|
||||
if (p_internal->p_cb->timer_created)
|
||||
{
|
||||
err_code = app_timer_stop(*p_internal->p_timer); //Timer may be running or inactive
|
||||
if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE))
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = NRF_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (blocking)
|
||||
{
|
||||
nrf_drv_uart_uninit(p_internal->p_uart);
|
||||
err_code = nrf_drv_uart_init(p_internal->p_uart, &p_internal->p_cb->uart_config, NULL);
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
p_internal->p_cb->blocking = true;
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!p_internal->p_cb->timer_created)
|
||||
{
|
||||
err_code = app_timer_create(p_internal->p_timer,
|
||||
APP_TIMER_MODE_SINGLE_SHOT,
|
||||
timer_handler);
|
||||
p_internal->p_cb->timer_created = true;
|
||||
}
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
err_code = rx_try(p_internal);
|
||||
}
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static ret_code_t cli_uart_read(nrf_cli_transport_t const * p_transport,
|
||||
void * p_data,
|
||||
size_t length,
|
||||
size_t * p_cnt)
|
||||
{
|
||||
ASSERT(p_cnt);
|
||||
nrf_cli_uart_internal_t * p_instance =
|
||||
CONTAINER_OF(p_transport, nrf_cli_uart_internal_t, transport);
|
||||
|
||||
*p_cnt = length;
|
||||
ret_code_t err_code = nrf_ringbuf_cpy_get(p_instance->p_rx_ringbuf, p_data, p_cnt);
|
||||
|
||||
if (*p_cnt)
|
||||
{
|
||||
NRF_LOG_INFO("id:%d, read:%d", p_instance->p_uart->inst_idx, *p_cnt);
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static ret_code_t cli_uart_write(nrf_cli_transport_t const * p_transport,
|
||||
void const * p_data,
|
||||
size_t length,
|
||||
size_t * p_cnt)
|
||||
{
|
||||
ASSERT(p_cnt);
|
||||
nrf_cli_uart_internal_t * p_instance =
|
||||
CONTAINER_OF(p_transport, nrf_cli_uart_internal_t, transport);
|
||||
ret_code_t err_code;
|
||||
*p_cnt = length;
|
||||
err_code = nrf_ringbuf_cpy_put(p_instance->p_tx_ringbuf, p_data, p_cnt);
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
NRF_LOG_INFO("id:%d, write, req:%d, done:%d",
|
||||
p_instance->p_uart->inst_idx,
|
||||
length,
|
||||
*p_cnt);
|
||||
|
||||
if (!nrf_drv_uart_tx_in_progress(p_instance->p_uart))
|
||||
{
|
||||
uint8_t * p_buf;
|
||||
size_t len = 255;
|
||||
if (nrf_ringbuf_get(p_instance->p_tx_ringbuf, &p_buf, &len, true) == NRF_SUCCESS)
|
||||
{
|
||||
NRF_LOG_INFO("id:%d, uart_tx, len:%d", p_instance->p_uart->inst_idx, len);
|
||||
|
||||
err_code = nrf_drv_uart_tx(p_instance->p_uart, p_buf, len);
|
||||
if (p_instance->p_cb->blocking && (err_code == NRF_SUCCESS))
|
||||
{
|
||||
(void)nrf_ringbuf_free(p_instance->p_tx_ringbuf, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
const nrf_cli_transport_api_t nrf_cli_uart_transport_api = {
|
||||
.init = cli_uart_init,
|
||||
.uninit = cli_uart_uninit,
|
||||
.enable = cli_uart_enable,
|
||||
.read = cli_uart_read,
|
||||
.write = cli_uart_write,
|
||||
};
|
||||
|
||||
#endif
|
||||
115
components/libraries/cli/uart/nrf_cli_uart.h
Normal file
115
components/libraries/cli/uart/nrf_cli_uart.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* 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 NRF_CLI_UART_H__
|
||||
#define NRF_CLI_UART_H__
|
||||
|
||||
#include "nrf_cli.h"
|
||||
#include "nrf_drv_uart.h"
|
||||
#include "nrf_ringbuf.h"
|
||||
#include "app_timer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@file
|
||||
*
|
||||
* @defgroup nrf_cli_uart UART command line interface transport layer
|
||||
* @ingroup nrf_cli
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Command line interface transport.
|
||||
*/
|
||||
extern const nrf_cli_transport_api_t nrf_cli_uart_transport_api;
|
||||
|
||||
typedef struct nrf_cli_uart_internal_s nrf_cli_uart_internal_t;
|
||||
|
||||
typedef struct {
|
||||
nrf_cli_transport_handler_t handler;
|
||||
void * p_context;
|
||||
nrf_drv_uart_config_t uart_config;
|
||||
bool timer_created;
|
||||
bool blocking;
|
||||
} nrf_cli_uart_internal_cb_t;
|
||||
|
||||
struct nrf_cli_uart_internal_s {
|
||||
nrf_cli_transport_t transport;
|
||||
nrf_cli_uart_internal_cb_t * p_cb;
|
||||
app_timer_id_t const * p_timer;
|
||||
nrf_ringbuf_t const * p_rx_ringbuf;
|
||||
nrf_ringbuf_t const * p_tx_ringbuf;
|
||||
nrf_drv_uart_t const * p_uart;
|
||||
};
|
||||
|
||||
typedef nrf_drv_uart_config_t nrf_cli_uart_config_t;
|
||||
|
||||
/**@brief CLI UART transport definition.
|
||||
*
|
||||
* @param _name Name of the instance.
|
||||
* @param _uart_id UART instance ID.
|
||||
* @param _tx_buf_sz Size of TX ring buffer.
|
||||
* @param _rx_buf_sz Size of RX ring buffer.
|
||||
*/
|
||||
#define NRF_CLI_UART_DEF(_name, _uart_id, _tx_buf_sz, _rx_buf_sz) \
|
||||
APP_TIMER_DEF(CONCAT_2(_name, _timer)); \
|
||||
NRF_RINGBUF_DEF(CONCAT_2(_name,_tx_ringbuf), _tx_buf_sz); \
|
||||
NRF_RINGBUF_DEF(CONCAT_2(_name,_rx_ringbuf), _rx_buf_sz); \
|
||||
static const nrf_drv_uart_t CONCAT_2(_name,_uart) = \
|
||||
NRF_DRV_UART_INSTANCE(_uart_id); \
|
||||
static nrf_cli_uart_internal_cb_t CONCAT_2(_name, _cb); \
|
||||
static const nrf_cli_uart_internal_t _name = { \
|
||||
.transport = {.p_api = &nrf_cli_uart_transport_api}, \
|
||||
.p_cb = &CONCAT_2(_name, _cb), \
|
||||
.p_timer = &CONCAT_2(_name, _timer), \
|
||||
.p_rx_ringbuf = &CONCAT_2(_name,_rx_ringbuf), \
|
||||
.p_tx_ringbuf = &CONCAT_2(_name,_tx_ringbuf), \
|
||||
.p_uart = &CONCAT_2(_name,_uart), \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NRF_CLI_UART_H__ */
|
||||
Reference in New Issue
Block a user