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.
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.
Solved.
In order to use the Macro NRF_LIBUARTE_ASYNC_DEFINE,you have to confirm:
1) include all files needed:
nrfx_ppi.c
nrfx_timer.c
nrf_libuarte_drv.c
nrf_libuarte_async.c
(there is problem if you try to use RTC timer)
2)enable these drivers in sdk_config.h;
This is the main source of error.
As my case:
NRF_LIBUARTE_ASYNC_DEFINE(m_libuarte, 0, 1, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 2, NRF_SDH_BLE_GATT_MAX_MTU_SIZE * 2, 3);
I use UARTE0,TIMER1,TIMER2.
You should not just enbale NRFX drivers, you have to enable legacy TIMER1 & TIMER2 driver.
Problems come mainly from here.



The Macro does not think the TIMERx is enabled if you did not enable legacy drivers,and the tip info provided by NRF_LIBUARTE_ASYNC_DEFINE is meaningless.
These kind of info should include into the official explaination,I spend many hours to try error.