I want to use the async driver,but did not find the example or explanation.
I have looked for the whole examples with "nrf_libuarte_async.h", found nothing,a little strange,I guess the NRF_LOG should useed this lib,but not check yet.
I want to use the async driver,but did not find the example or explanation.
I have looked for the whole examples with "nrf_libuarte_async.h", found nothing,a little strange,I guess the NRF_LOG should useed this lib,but not check yet.
found one:nRF5_SDK_17.1.0_ddde560\examples\peripheral\libuarte.
defined :
NRF_LIBUARTE_ASYNC_DEFINE(m_libuarte, 0, 0,0,NRF_LIBUARTE_PERIPHERAL_NOT_USED, NRF_SDH_BLE_GATT_MAX_MTU_SIZE, 2)
error:
Build target 'UART2BLEnrf52810_xxaa' compiling app_uarte.c... ..\..\..\app_uarte.c(7): error: #94: the size of an array must be greater than zero NRF_LIBUARTE_ASYNC_DEFINE(m_libuarte, 0, 0,0,NRF_LIBUARTE_PERIPHERAL_NOT_USED, NRF_SDH_BLE_GATT_MAX_MTU_SIZE, 2) ..\..\..\app_uarte.c(7): error: #94: the size of an array must be greater than zero NRF_LIBUARTE_ASYNC_DEFINE(m_libuarte, 0, 0,0,NRF_LIBUARTE_PERIPHERAL_NOT_USED, NRF_SDH_BLE_GATT_MAX_MTU_SIZE, 2) ..\..\..\app_uarte.c(7): error: #20: identifier "NRFX_TIMER0_INST_IDX" is undefined NRF_LIBUARTE_ASYNC_DEFINE(m_libuarte, 0, 0,0,NRF_LIBUARTE_PERIPHERAL_NOT_USED, NRF_SDH_BLE_GATT_MAX_MTU_SIZE, 2) ..\..\..\app_uarte.c: 0 warnings, 3 errors ".\_build\UART2BLEnrf52810_xxaa.axf" - 3 Error(s), 0 Warning(s).
It is hard to understand the detail information:
/**
* @brief Macro for creating instance of libuarte_async.
*
* Libuarte_async requires one timer-like peripheral (RTC or TIMER) for triggering RX timeout.
* Macro will create instance only for peripheral which is used.
*
* @param _name Instance name.
* @param _uarte_idx UARTE instance used.
* @param _timer0_idx TIMER instance used by libuarte for bytes counting.
* @param _rtc1_idx RTC instance used for timeout. If set to NRF_LIBUARTE_PERIPHERAL_NOT_USED
* then TIMER instance is used or app_timer instance if _timer1_idx is also set
* to NRF_LIBUARTE_PERIPHERAL_NOT_USED.
* @param _timer1_idx TIMER instance used for timeout. If set to NRF_LIBUARTE_PERIPHERAL_NOT_USED
* then RTC instance is used or app_timer instance if _rtc1_idx is also set
* to NRF_LIBUARTE_PERIPHERAL_NOT_USED.
* @param _rx_buf_size Size of single RX buffer. Size impacts accepted latency between buffer
* request and providing next buffer. Next must be provided within before
* _rx_buf_size bytes is received.
* @param _rx_buf_cnt Number of buffers in the RX buffer pool. Size impacts accepted latency
* between NRF_LIBUARTE_ASYNC_EVT_RX_DATA event and
* @ref nrf_libuarte_async_rx_free.
*/
#define NRF_LIBUARTE_ASYNC_DEFINE(_name, _uarte_idx, _timer0_idx,\
_rtc1_idx, _timer1_idx,\
_rx_buf_size, _rx_buf_cnt) \
STATIC_ASSERT(_rx_buf_cnt >= 3, "Wrong number of RX buffers");\
STATIC_ASSERT(!((NRF_LIBUARTE_ASYNC_WITH_APP_TIMER == 0) && \
(_rtc1_idx == NRF_LIBUARTE_PERIPHERAL_NOT_USED) && \
(_timer1_idx == NRF_LIBUARTE_PERIPHERAL_NOT_USED)), \
"App timer support disabled");\
NRF_LIBUARTE_DRV_DEFINE(CONCAT_2(_name, _libuarte), _uarte_idx, _timer0_idx);\
NRF_QUEUE_DEF(uint8_t *, CONCAT_2(_name,_rxdata_queue), _rx_buf_cnt, NRF_QUEUE_MODE_NO_OVERFLOW);\
NRF_BALLOC_DEF(CONCAT_2(_name,_rx_pool), _rx_buf_size, _rx_buf_cnt);\
/* Create TIMER instance only if _timer1_idx != NRF_LIBUARTE_PERIPHERAL_NOT_USED */ \
_LIBUARTE_ASYNC_EVAL(\
NRFX_CONCAT_3(NRFX_TIMER, _timer1_idx, _ENABLED),\
(STATIC_ASSERT((_timer1_idx == NRF_LIBUARTE_PERIPHERAL_NOT_USED) || (CONCAT_3(NRFX_TIMER,_timer1_idx, _ENABLED) == 1), "TIMER instance not enabled");\
static const nrfx_timer_t CONCAT_2(_name, _timer) = NRFX_TIMER_INSTANCE(_timer1_idx);),\
(/* empty */))\
/* Create RTC instance only if _timer1_idx != NRF_LIBUARTE_PERIPHERAL_NOT_USED */ \
_LIBUARTE_ASYNC_EVAL(\
NRFX_CONCAT_3(NRFX_RTC, _rtc1_idx, _ENABLED),\
(STATIC_ASSERT((_rtc1_idx == NRF_LIBUARTE_PERIPHERAL_NOT_USED) || (CONCAT_3(NRFX_RTC,_rtc1_idx, _ENABLED) == 1), "RTC instance not enabled");\
static const nrfx_rtc_t CONCAT_2(_name, _rtc) = NRFX_RTC_INSTANCE(_rtc1_idx);),\
(/* empty */))\
_LIBUARTE_ASYNC_EVAL(NRFX_CONCAT_3(NRFX_TIMER, _timer1_idx, _ENABLED),\
(/* empty */),\
(_LIBUARTE_ASYNC_EVAL(NRFX_CONCAT_3(NRFX_RTC, _rtc1_idx, _ENABLED),(/* empty */), \
(APP_TIMER_DEF(CONCAT_2(_name,_app_timer)); \
nrf_libuarte_app_timer_ctrl_blk_t CONCAT_2(_name,_app_timer_ctrl_blk);))) \
)\
static nrf_libuarte_async_ctrl_blk_t CONCAT_2(_name, ctrl_blk);\
_LIBUARTE_ASYNC_EVAL(\
NRFX_CONCAT_3(NRFX_RTC, _rtc1_idx, _ENABLED), \
(static void CONCAT_2(_name, _rtc_handler)(nrfx_rtc_int_type_t int_type);),\
(/* empty */)) \
\
static const nrf_libuarte_async_t _name = {\
.p_rx_pool = &CONCAT_2(_name,_rx_pool),\
.p_rx_queue = &CONCAT_2(_name,_rxdata_queue),\
/* If p_rtc is not NULL it means that RTC is used for RX timeout */ \
.p_rtc = _LIBUARTE_ASYNC_EVAL(NRFX_CONCAT_3(NRFX_RTC, _rtc1_idx, _ENABLED), (&CONCAT_2(_name, _rtc)), (NULL)),\
/* If p_timer is not NULL it means that RTC is used for RX timeout */ \
.p_timer = _LIBUARTE_ASYNC_EVAL(NRFX_CONCAT_3(NRFX_TIMER, _timer1_idx, _ENABLED), (&CONCAT_2(_name, _timer)), (NULL)),\
/* If p_time and p_rtc is NULL it means that app_timer is used for RX timeout */ \
.p_app_timer = _LIBUARTE_ASYNC_EVAL(NRFX_CONCAT_3(NRFX_TIMER, _timer1_idx, _ENABLED),\
(NULL),\
(_LIBUARTE_ASYNC_EVAL(NRFX_CONCAT_3(NRFX_RTC, _rtc1_idx, _ENABLED),(NULL), \
(&CONCAT_2(_name,_app_timer)))) \
),\
.p_app_timer_ctrl_blk = _LIBUARTE_ASYNC_EVAL(NRFX_CONCAT_3(NRFX_TIMER, _timer1_idx, _ENABLED),\
(NULL),\
(_LIBUARTE_ASYNC_EVAL(NRFX_CONCAT_3(NRFX_RTC, _rtc1_idx, _ENABLED),(NULL), \
(&CONCAT_2(_name,_app_timer_ctrl_blk)))) \
),\
.p_libuarte = &CONCAT_2(_name, _libuarte),\
.p_ctrl_blk = &CONCAT_2(_name, ctrl_blk),\
.rx_buf_size = _rx_buf_size,\
_LIBUARTE_ASYNC_EVAL(\
NRFX_CONCAT_3(NRFX_RTC, _rtc1_idx, _ENABLED),\
(.rtc_handler =CONCAT_2(_name, _rtc_handler)),\
()\
)\
};\
/* RTC compare event is not periodic but need to be enabled again in the callback. */ \
_LIBUARTE_ASYNC_EVAL(\
NRFX_CONCAT_3(NRFX_RTC, _rtc1_idx, _ENABLED),\
(\
static void CONCAT_2(_name, _rtc_handler)(nrfx_rtc_int_type_t int_type)\
{ \
(void)nrfx_rtc_cc_set(_name.p_rtc, 0, _name.p_ctrl_blk->timeout_us/32, true);\
nrf_libuarte_async_timeout_handler(&_name);\
}\
),\
()\
)
I should define these instance first?
* @param _uarte_idx UARTE instance used. * @param _timer0_idx TIMER instance used by libuarte for bytes counting. * @param _rtc1_idx RTC instance used for timeout. If set to NRF_LIBUARTE_PERIPHERAL_NOT_USED * then TIMER instance is used or app_timer instance if _timer1_idx is also set * to NRF_LIBUARTE_PERIPHERAL_NOT_USED. * @param _timer1_idx TIMER instance used for timeout. If set to NRF_LIBUARTE_PERIPHERAL_NOT_USED * then RTC instance is used or app_timer instance if _rtc1_idx is also set * to NRF_LIBUARTE_PERIPHERAL_NOT_USED.
get reply from gemini:
_uarte_idx:
用途: 指定要使用的 UARTE 硬件实例的索引。
安全值: 在 nRF52810 上,只有一个 UARTE 外设,所以该值必须是 0。
_timer0_idx:
用途: 这是底层 nrf_libuarte_drv 驱动内部使用的定时器。它用于管理 EasyDMA 传输和缓冲区切换。
安全值: SoftDevice 会使用 TIMER0,因此你不能使用 0。你应该选择一个空闲的定时器,例如 1 或 2。
_rtc1_idx 和 _timer1_idx:
用途: 这两个参数用于异步超时机制。库会根据你的 sdk_config.h 配置选择一个作为超时计时器。它会从 TIMER1、RTC1 和 App Timer 中选择一个。
安全值: RTC0 通常被 SoftDevice 占用,所以 RTC1 是一个安全的选择。TIMER1 和 TIMER2 通常也是可用的。
如何选择:
如果你想使用 TIMER1 作为超时计时器,将 _timer1_idx 设置为 1,并将 _rtc1_idx 设置为 NRF_LIBUARTE_PERIPHERAL_NOT_USED。
如果你想使用 RTC1 作为超时计时器,将 _rtc1_idx 设置为 1,并将 _timer1_idx 设置为 NRF_LIBUARTE_PERIPHERAL_NOT_USED。
如果你想使用 app_timer,则将 _rtc1_idx 和 _timer1_idx 都设置为 NRF_LIBUARTE_PERIPHERAL_NOT_USED。
I defined like this :
NRF_LIBUARTE_ASYNC_DEFINE(m_libuarte, 0, 1, NRF_LIBUARTE_PERIPHERAL_NOT_USED,2, NRF_SDH_BLE_GATT_MAX_MTU_SIZE,3);
It report error
..\..\..\app_uarte.c(14): error: #94: the size of an array must be greater than zero NRF_LIBUARTE_ASYNC_DEFINE(m_libuarte, 0, 1, NRF_LIBUARTE_PERIPHERAL_NOT_USED,2, NRF_SDH_BLE_GATT_MAX_MTU_SIZE,3);
this is the extend result of NRF_LIBUARTE_ASYNC_DEFINE:
extern char (*_do_assert(void)) [sizeof(char[1 - 2* !(3 >= 3)])];
extern char (*_do_assert(void)) [sizeof(char[1 - 2* !(!((1 == 0) && (255 == 255) && (2 == 255)))])];
extern char (*_do_assert(void)) [sizeof(char[1 - 2* !(0 < 1)])];
extern char (*_do_assert(void)) [sizeof(char[1 - 2* !(1 == 1)])];
extern char (*_do_assert(void)) [sizeof(char[1 - 2* !(0 == 1)])];
static nrf_libuarte_drv_ctrl_blk_t m_libuarte_libuartectrl_blk;
static const nrf_libuarte_drv_t m_libuarte_libuarte = {
. ctrl_blk = &m_libuarte_libuartectrl_blk,
. timer = { . p_reg = ((NRF_TIMER_Type*) 0x40009000UL),
. instance_id = 1, . cc_channel_count = 4, },
. uarte = ((NRF_UARTE_Type*) 0x40002000UL), };
static uint8_t * m_libuarte_rxdata_queue_nrf_queue_buffer[(3) + 1];
static nrf_queue_cb_t m_libuarte_rxdata_queue_nrf_queue_cb;
;
const nrf_queue_t m_libuarte_rxdata_queue __attribute__ ((section("nrf_queue"))) __attribute__((used)) = {
. p_cb = &m_libuarte_rxdata_queue_nrf_queue_cb,
. p_buffer = m_libuarte_rxdata_queue_nrf_queue_buffer,
. size = (3), . element_size = sizeof(uint8_t *),
. mode = NRF_QUEUE_MODE_NO_OVERFLOW, };
extern char (*_do_assert(void)) [sizeof(char[1 - 2* !((3) <= 255)])];
static uint8_t m_libuarte_rx_pool_nrf_balloc_pool_stack[(3)];
static uint32_t m_libuarte_rx_pool_nrf_balloc_pool_mem [((((52)) - 1) + (sizeof(uint32_t)) - ((((52)) - 1) % (sizeof(uint32_t)))) * (3) / sizeof(uint32_t)];
static nrf_balloc_cb_t m_libuarte_rx_pool_nrf_balloc_cb; ;
const nrf_balloc_t m_libuarte_rx_pool __attribute__ ((section("nrf_balloc"))) __attribute__((used)) = {
. p_cb = &m_libuarte_rx_pool_nrf_balloc_cb,
. p_stack_base = m_libuarte_rx_pool_nrf_balloc_pool_stack,
. p_stack_limit = m_libuarte_rx_pool_nrf_balloc_pool_stack + (3),
. p_memory_begin = m_libuarte_rx_pool_nrf_balloc_pool_mem,
. block_size = ((((52)) - 1) + (sizeof(uint32_t)) - ((((52)) - 1) % (sizeof(uint32_t)))), };
;
static app_timer_t m_libuarte_app_timer_data = { . end_val = 0xFFFFFFFFFFFFFFFFULL, };
static const app_timer_id_t m_libuarte_app_timer = &m_libuarte_app_timer_data; nrf_libuarte_app_timer_ctrl_blk_t m_libuarte_app_timer_ctrl_blk;
static nrf_libuarte_async_ctrl_blk_t m_libuartectrl_blk;
static const nrf_libuarte_async_t m_libuarte = {
. p_rx_pool = &m_libuarte_rx_pool,
. p_rx_queue = &m_libuarte_rxdata_queue,
. p_rtc = 0,
. p_timer = 0,
. p_app_timer = &m_libuarte_app_timer,
. p_app_timer_ctrl_blk = &m_libuarte_app_timer_ctrl_blk,
. p_libuarte = &m_libuarte_libuarte,
. p_ctrl_blk = &m_libuartectrl_blk,
. rx_buf_size = 52, };
;
this is false, but what triggered this?
extern char (*_do_assert(void)) [sizeof(char[1 - 2* !(0 == 1)])];
I'm useing nrf52810,nrf52 SDK 17.1,S113.
BLE peripheral, use UARTE + BLE SD to bridge between my MCU & Server instead of NUS.
I have disabled LOG,so no conflict on UARTE.
TIMER1 & TIMER2 enabled.
Hi OldXiao,
First of all, the nRF5 SDK is in maintenance mode and is not recommended for new project. If you are working on a new project, I strongly recommend using the nRF Connect SDK (NCS), where setting up complex features is a lot faster. We provide online course here to help you ramp up quickly with NCS: Nordic Semiconductor Online Learning Platform - Nordic Developer Academy.
If for some reason you must use the nRF5 SDK:
I cannot comment on the result that Gemini give you as I don't understand the text.
Rather than diving into the code and trying to figure it out, I recommend you go over the documentation instead:
nRF5 SDK v17.1.0: Libuarte - advanced UARTE driver
nRF5 SDK v17.1.0: libUARTE asynchronous library
nRF5 SDK v17.1.0: libUARTE driver
nRF5 SDK v17.1.0: Libuarte Example
From the API documentation and the codes you provided, it seems the size of the RX buffer was not enough. Please try increasing it.
In general, I would suggest trying to keep the parameters exactly the same as the example and have things working first. You would also want to go over the documentation and understand the general concepts as well as any API of interest before tweaking the configurations.
Hieu
Thanks for guides.
I missed some file, the "_IDX" problem disappeared after added them and delete the symbols I added in sdk_confg.h (some "_IDX" definition).
But a problem raised again,and I don't know how to work around.
Current config:
NRF_LIBUARTE_ASYNC_DEFINE(m_libuarte, 0, 1, 1, NRF_LIBUARTE_PERIPHERAL_NOT_USED, NRF_SDH_BLE_GATT_MAX_MTU_SIZE * 2, 3);
error:
.\_build\UART2BLEnrf52810_xxaa.axf: Error: L6200E: Symbol RTC1_IRQHandler multiply defined (by drv_rtc.o and nrfx_rtc.o).
I have tried many parameter composition for NRF_LIBUARTE_ASYNC_DEFINE, there are always errors,and current config with least error count.
I browsed this web,found 1 post related,but I did not get the meaning, you suggest remove the related files,remove nrfx_rtc.c & drv_rtc.c? then what to do?
Or I just delete one of the RTC1_IRQHandler definition?