osal_rs/freertos/
event_group.rs

1/***************************************************************************
2 *
3 * osal-rs
4 * Copyright (C) 2023/2026 Antonio Salsi <passy.linux@zresa.it>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 *
18 ***************************************************************************/
19
20use core::fmt::{Debug, Display, Formatter};
21use core::ops::Deref;
22use core::ptr::null_mut;
23
24use super::ffi::{EventGroupHandle, pdFAIL, pdFALSE, vEventGroupDelete, xEventGroupClearBits, xEventGroupClearBitsFromISR, xEventGroupCreate, xEventGroupGetBitsFromISR, xEventGroupSetBits, xEventGroupSetBitsFromISR};
25use super::system::System;
26use super::types::{BaseType, EventBits, TickType};
27use crate::traits::{ToTick, EventGroupFn, SystemFn};
28use crate::utils::{Result, Error};
29use crate::xEventGroupGetBits;
30
31pub struct EventGroup (EventGroupHandle);
32
33unsafe impl Send for EventGroup {}
34unsafe impl Sync for EventGroup {}
35
36impl EventGroup {
37    pub fn wait_with_to_tick(&self, mask: EventBits, timeout_ticks: impl ToTick) -> EventBits {
38        self.wait(mask, timeout_ticks.to_ticks())
39    }
40}
41
42impl EventGroupFn for EventGroup {
43    fn new() -> Result<Self> {
44        let handle = unsafe { xEventGroupCreate() };
45        if handle.is_null() {
46            Err(Error::OutOfMemory)
47        } else {
48            Ok(Self (handle))
49        }
50    }
51
52    fn set(&self, bits: EventBits) -> EventBits {
53        unsafe { xEventGroupSetBits(self.0, bits) }
54    }
55
56    fn set_from_isr(&self, bits: EventBits) -> Result<()> {
57
58        let mut higher_priority_task_woken: BaseType = pdFALSE;
59
60        let ret = unsafe { xEventGroupSetBitsFromISR(self.0, bits, &mut higher_priority_task_woken) };
61        if ret != pdFAIL {
62
63            System::yield_from_isr(higher_priority_task_woken);
64            
65            Ok(())
66        } else {
67            Err(Error::QueueFull)
68        }
69    }
70
71    fn get(&self) -> EventBits {
72        xEventGroupGetBits!(self.0) 
73    }
74
75    fn get_from_isr(&self) -> EventBits{
76        unsafe { xEventGroupGetBitsFromISR(self.0) }
77    }
78
79
80    fn clear(&self, bits: EventBits) -> EventBits {
81        unsafe { xEventGroupClearBits(self.0, bits) }
82    }
83
84    fn clear_from_isr(&self, bits: EventBits) -> Result<()> {
85        let ret = unsafe { xEventGroupClearBitsFromISR(self.0, bits) };
86        if ret != pdFAIL {
87            Ok(())
88        } else {
89            Err(Error::QueueFull)
90        }
91    }
92
93    fn wait(&self, mask: EventBits, timeout_ticks: TickType) -> EventBits {
94        unsafe {
95            crate::freertos::ffi::xEventGroupWaitBits(
96                self.0,
97                mask,
98                pdFALSE, 
99                pdFALSE, 
100                timeout_ticks,
101            )
102        }
103    }
104
105    fn delete(&mut self) {
106        unsafe {
107            vEventGroupDelete(self.0);
108            self.0 = null_mut();
109        }
110    }
111}
112
113impl Drop for EventGroup {
114    fn drop(&mut self) {
115        if self.0.is_null() {
116            return;
117        }
118        self.delete();
119    }
120}
121
122impl Deref for EventGroup {
123    type Target = EventGroupHandle;
124
125    fn deref(&self) -> &Self::Target {
126        &self.0
127    }
128}
129
130impl Debug for EventGroup {
131    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
132        write!(f, "EventGroup {{ handle: {:?} }}", self.0)
133    }
134}
135
136impl Display for EventGroup {
137    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
138        write!(f, "EventGroup {{ handle: {:?} }}", self.0)
139    }
140}