esp-idf/components/hal/rmt_hal.c
morris 2fb43820c2 driver_ng: implement new rmt driver
The legacy driver can't handle the breaking change between esp chips

very well.

And it's not elegant to extend new feature like DMA, ETM.

The new driver can return a opaque handle for each RMT channel.

An obvious transaction concept was also introduced.

TX and RX functionalities are splited out.
2022-05-07 10:34:50 +00:00

48 lines
1.9 KiB
C

/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/rmt_hal.h"
#include "hal/rmt_ll.h"
#include "soc/soc_caps.h"
void rmt_hal_init(rmt_hal_context_t *hal)
{
hal->regs = &RMT;
rmt_ll_power_down_mem(hal->regs, false); // turn on RMTMEM power domain
rmt_ll_enable_mem_access_nonfifo(hal->regs, true); // APB access the RMTMEM in nonfifo mode
rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interupt events
rmt_ll_clear_interrupt_status(hal->regs, UINT32_MAX); // clear all pending events
#if SOC_RMT_SUPPORT_TX_SYNCHRO
rmt_ll_tx_clear_sync_group(hal->regs);
#endif // SOC_RMT_SUPPORT_TX_SYNCHRO
}
void rmt_hal_deinit(rmt_hal_context_t *hal)
{
rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interupt events
rmt_ll_clear_interrupt_status(hal->regs, UINT32_MAX); // clear all pending events
rmt_ll_power_down_mem(hal->regs, true); // turn off RMTMEM power domain
hal->regs = NULL;
}
void rmt_hal_tx_channel_reset(rmt_hal_context_t *hal, uint32_t channel)
{
rmt_ll_tx_reset_channels_clock_div(hal->regs, 1 << channel);
rmt_ll_tx_reset_pointer(hal->regs, channel);
#if SOC_RMT_SUPPORT_TX_LOOP_COUNT
rmt_ll_tx_reset_loop_count(hal->regs, channel);
#endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT
rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_MASK(channel), false);
rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_MASK(channel));
}
void rmt_hal_rx_channel_reset(rmt_hal_context_t *hal, uint32_t channel)
{
rmt_ll_rx_reset_channels_clock_div(hal->regs, 1 << channel);
rmt_ll_rx_reset_pointer(hal->regs, channel);
rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_RX_MASK(channel), false);
rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_RX_MASK(channel));
}