use core::ptr;
use esp_idf_sys::*;
use crate::rmt::{RmtChannel, TxChannelDriver};
pub struct SyncManager<'d, const N: usize> {
handle: rmt_sync_manager_handle_t,
channels: Option<[TxChannelDriver<'d>; N]>,
}
impl<'d, const N: usize> SyncManager<'d, N> {
pub fn new(channels: [TxChannelDriver<'d>; N]) -> Result<Self, EspError> {
let mut this = Self {
handle: ptr::null_mut(),
channels: Some(channels),
};
let mut iter = this.channels_mut().iter().map(TxChannelDriver::handle);
let handles = [(); N].map(|_| iter.next().unwrap());
let sys_config = rmt_sync_manager_config_t {
tx_channel_array: handles.as_ptr(),
array_size: handles.len(),
};
esp!(unsafe { rmt_new_sync_manager(&sys_config, &mut this.handle) })?;
Ok(this)
}
pub fn reset(&mut self) -> Result<(), EspError> {
esp!(unsafe { rmt_sync_reset(self.handle) })
}
pub fn channels_mut(&mut self) -> &mut [TxChannelDriver<'d>; N] {
unsafe { self.channels.as_mut().unwrap_unchecked() }
}
pub fn channels(&self) -> &[TxChannelDriver<'d>; N] {
unsafe { self.channels.as_ref().unwrap_unchecked() }
}
pub fn into_channels(mut self) -> [TxChannelDriver<'d>; N] {
unsafe { self.channels.take().unwrap_unchecked() }
}
}
impl<'d, const N: usize> Drop for SyncManager<'d, N> {
fn drop(&mut self) {
unsafe { rmt_del_sync_manager(self.handle) };
}
}