123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- #ifndef UART_ASYNC_H
- #define UART_ASYNC_H
- #include <stdint.h>
- #include "sdk_errors.h"
- #include "nrf_balloc.h"
- #include "nrf_queue.h"
- #include "nrfx_ppi.h"
- #include "nrfx_timer.h"
- #include "nrfx_rtc.h"
- #include "nrf_libuarte_drv.h"
- #include <hal/nrf_uarte.h>
- #ifndef NRF_LIBUARTE_ASYNC_WITH_APP_TIMER
- #warning "sdk_config.h is missing NRF_LIBUARTE_ASYNC_WITH_APP_TIMER option"
- #define NRF_LIBUARTE_ASYNC_WITH_APP_TIMER 0
- #endif
- #if NRF_LIBUARTE_ASYNC_WITH_APP_TIMER
- #include "app_timer.h"
- #endif
- typedef enum
- {
- NRF_LIBUARTE_ASYNC_EVT_RX_DATA,
- NRF_LIBUARTE_ASYNC_EVT_TX_DONE,
- NRF_LIBUARTE_ASYNC_EVT_ERROR,
- NRF_LIBUARTE_ASYNC_EVT_OVERRUN_ERROR
- } nrf_libuarte_async_evt_type_t;
- typedef enum
- {
- NRF_LIBUARTE_ASYNC_PPI_CH_RXRDY_CLEAR,
- NRF_LIBUARTE_ASYNC_PPI_CH_COMPARE_SHUTDOWN,
- NRF_LIBUARTE_ASYNC_PPI_CH_MAX
- } nrf_libuarte_async_ppi_channel_t;
- typedef struct
- {
- uint8_t * p_data;
- size_t length;
- } nrf_libuarte_async_data_t;
- typedef struct
- {
- uint32_t overrun_length;
- } nrf_libuarte_async_overrun_err_evt_t;
- typedef struct
- {
- nrf_libuarte_async_evt_type_t type;
- union {
- nrf_libuarte_async_data_t rxtx;
- uint8_t errorsrc;
- nrf_libuarte_async_overrun_err_evt_t overrun_err;
- } data;
- } nrf_libuarte_async_evt_t;
- typedef void (*nrf_libuarte_async_evt_handler_t)(void * context, nrf_libuarte_async_evt_t * p_evt);
- typedef struct
- {
- uint32_t rx_pin;
- uint32_t tx_pin;
- uint32_t cts_pin;
- uint32_t rts_pin;
- uint32_t timeout_us;
- nrf_uarte_hwfc_t hwfc;
- nrf_uarte_parity_t parity;
- nrf_uarte_baudrate_t baudrate;
- bool pullup_rx;
- uint8_t int_prio;
- } nrf_libuarte_async_config_t;
- typedef struct {
- nrf_libuarte_async_evt_handler_t evt_handler;
- void * context;
- nrf_ppi_channel_t ppi_channels[NRF_LIBUARTE_ASYNC_PPI_CH_MAX];
- int32_t alloc_cnt;
- uint32_t rx_count;
- uint32_t sub_rx_count;
- uint8_t * p_curr_rx_buf;
- uint32_t rx_free_cnt;
- uint32_t timeout_us;
- bool app_timer_created;
- bool hwfc;
- bool rx_halted;
- bool enabled;
- } nrf_libuarte_async_ctrl_blk_t;
- typedef struct {
- uint32_t rx_count;
- uint32_t timestamp;
- bool activate;
- } nrf_libuarte_app_timer_ctrl_blk_t;
- typedef struct {
- const nrf_balloc_t * p_rx_pool;
- const nrf_queue_t * p_rx_queue;
- const nrfx_rtc_t * p_rtc;
- const nrfx_timer_t * p_timer;
- #if NRF_LIBUARTE_ASYNC_WITH_APP_TIMER
- const app_timer_id_t * p_app_timer;
- #else
- void ** p_app_timer;
- #endif
- nrf_libuarte_app_timer_ctrl_blk_t * p_app_timer_ctrl_blk;
- const nrf_libuarte_drv_t * p_libuarte;
- nrf_libuarte_async_ctrl_blk_t * p_ctrl_blk;
- nrfx_rtc_handler_t rtc_handler;
- uint32_t rx_buf_size;
- } nrf_libuarte_async_t;
- void nrf_libuarte_async_timeout_handler(const nrf_libuarte_async_t * p_libuarte);
- #define NRF_LIBUARTE_PERIPHERAL_NOT_USED 255
- #define LIBUARTE_ASYNC_DEBRACKET(...) __VA_ARGS__
- #define __LIBUARTE_ASYNC_ARG_2(ignore_this, val, ...) val
- #define __LIBUARTE_ASYNC_ARG_2_DEBRACKET(ignore_this, val, ...) LIBUARTE_ASYNC_DEBRACKET val
- #define _LIBUARTE_ASYNC_EVAL(_eval_flag, _iftrue, _iffalse) \
- _LIBUARTE_ASYNC_EVAL1(_eval_flag, _iftrue, _iffalse)
- #define _LIBUARTE_ASYNC_EVAL1(_eval_flag, _iftrue, _iffalse) \
- _LIBUARTE_ASYNC_EVAL2(_LIBUARTE_ASYNC_ZZZZ##_eval_flag, _iftrue, _iffalse)
- #define _LIBUARTE_ASYNC_ZZZZ1 _LIBUARTE_ASYNC_YYYY,
- #define _LIBUARTE_ASYNC_EVAL2(one_or_two_args, _iftrue, _iffalse) \
- __LIBUARTE_ASYNC_ARG_2_DEBRACKET(one_or_two_args _iftrue, _iffalse)
- #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);\
- \
- _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);),\
- ())\
- \
- _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);),\
- ())\
- _LIBUARTE_ASYNC_EVAL(NRFX_CONCAT_3(NRFX_TIMER, _timer1_idx, _ENABLED),\
- (),\
- (_LIBUARTE_ASYNC_EVAL(NRFX_CONCAT_3(NRFX_RTC, _rtc1_idx, _ENABLED),(), \
- (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);),\
- ()) \
- \
- static const nrf_libuarte_async_t _name = {\
- .p_rx_pool = &CONCAT_2(_name,_rx_pool),\
- .p_rx_queue = &CONCAT_2(_name,_rxdata_queue),\
- \
- .p_rtc = _LIBUARTE_ASYNC_EVAL(NRFX_CONCAT_3(NRFX_RTC, _rtc1_idx, _ENABLED), (&CONCAT_2(_name, _rtc)), (NULL)),\
- \
- .p_timer = _LIBUARTE_ASYNC_EVAL(NRFX_CONCAT_3(NRFX_TIMER, _timer1_idx, _ENABLED), (&CONCAT_2(_name, _timer)), (NULL)),\
- \
- .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)),\
- ()\
- )\
- };\
- \
- _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);\
- }\
- ),\
- ()\
- )
- ret_code_t nrf_libuarte_async_init(const nrf_libuarte_async_t * const p_libuarte,
- nrf_libuarte_async_config_t const * p_config,
- nrf_libuarte_async_evt_handler_t evt_handler,
- void * context);
- void nrf_libuarte_async_uninit(const nrf_libuarte_async_t * const p_libuarte);
- void nrf_libuarte_async_enable(const nrf_libuarte_async_t * const p_libuarte);
- void nrf_libuarte_async_rts_clear(const nrf_libuarte_async_t * const p_libuarte);
- void nrf_libuarte_async_rts_set(const nrf_libuarte_async_t * const p_libuarte);
- ret_code_t nrf_libuarte_async_tx(const nrf_libuarte_async_t * const p_libuarte,
- uint8_t * p_data, size_t length);
- void nrf_libuarte_async_rx_free(const nrf_libuarte_async_t * const p_libuarte,
- uint8_t * p_data, size_t length);
- #endif
|