crazyflie_lib/subsystems/memory/
mod.rs1use crate::{crtp_utils::WaitForPacket, Error, Result};
12use crazyflie_link::Packet;
13use flume as channel;
14use std::{collections::HashMap, convert::{TryFrom, TryInto}};
15use std::sync::Arc;
16use tokio::sync::Mutex;
17
18mod memory_types;
19mod eeprom_config;
20mod raw;
21mod ow;
22
23use crate::crazyflie::MEMORY_PORT;
24
25pub use memory_types::*;
26pub use eeprom_config::*;
27pub use raw::*;
28pub use ow::*;
29
30#[derive(Debug)]
35pub struct Memory {
36 memories: Vec<MemoryDevice>,
37 backends: Vec<Mutex<Option<MemoryBackend>>>,
38 memory_read_dispatcher: MemoryDispatcher,
39 memory_write_dispatcher: MemoryDispatcher,
40}
41
42const INFO_CHANNEL: u8 = 0;
43const READ_CHANNEL: u8 = 1;
44const WRITE_CHANNEL: u8 = 2;
45
46const _CMD_INFO_VER: u8 = 0;
47const CMD_INFO_NBR: u8 = 1;
48const CMD_INFO_DETAILS: u8 = 2;
49
50#[derive(Debug)]
51struct MemoryDispatcher {
52 senders: Arc<Mutex<HashMap<u8, channel::Sender<Packet>>>>,
53}
54
55impl MemoryDispatcher {
56 fn new(downlink: channel::Receiver<Packet>, channel: u8) -> Self {
57
58 let senders: Arc<Mutex<HashMap<u8, channel::Sender<Packet>>>> = Arc::new(Mutex::new(HashMap::new()));
59 let internal_senders = senders.clone();
60
61 tokio::spawn(async move {
62 while let Ok(pk) = downlink.recv_async().await {
63 if pk.get_channel() == channel {
64 let memory_id = pk.get_data()[0];
65 if let Some(sender) = internal_senders.lock().await.get(&memory_id) {
66 let _ = sender.send_async(pk).await;
67 } else {
68 println!("Warning: Received memory read response for unknown memory ID {}", memory_id);
69 }
70 } else {
71 println!("Warning: Received packet on unexpected channel {}", pk.get_channel());
72 }
73 }
74 });
75
76 Self {
77 senders: senders,
78 }
79 }
80
81 async fn get_channel(&mut self, memory_id: u8) -> channel::Receiver<Packet> {
82 if !self.senders.lock().await.contains_key(&memory_id) {
83 let (tx, rx) = channel::unbounded();
84 self.senders.lock().await.insert(memory_id, tx);
85 rx
86 } else {
87 panic!("Channel for memory ID {} already exists", memory_id)
88 }
89 }
90}
91
92impl Memory {
93 pub(crate) async fn new(
94 downlink: channel::Receiver<Packet>,
95 uplink: channel::Sender<Packet>,
96 ) -> Result<Self> {
97 let (info_channel_downlink, read_channel_downlink, write_channel_downlink, _misc_downlink) =
98 crate::crtp_utils::crtp_channel_dispatcher(downlink);
99
100 let mut memory = Self {
101 memories: Vec::new(),
102 backends: Vec::new(),
103 memory_read_dispatcher: MemoryDispatcher::new(read_channel_downlink.clone(), READ_CHANNEL),
104 memory_write_dispatcher: MemoryDispatcher::new(write_channel_downlink.clone(), WRITE_CHANNEL),
105 };
106
107 memory.update_memories(uplink.clone(), info_channel_downlink).await?;
108
109 Ok(memory)
110 }
111
112 async fn update_memories(&mut self, uplink: channel::Sender<Packet>, downlink: channel::Receiver<Packet>) -> Result<()> {
113 let pk = Packet::new(MEMORY_PORT, INFO_CHANNEL, vec![CMD_INFO_NBR]);
114 uplink
115 .send_async(pk)
116 .await
117 .map_err(|_| Error::Disconnected)?;
118
119 let pk = downlink.wait_packet(MEMORY_PORT, INFO_CHANNEL, &[CMD_INFO_NBR]).await?;
120 let memory_count = pk.get_data()[1];
121
122 for i in 0..memory_count {
123 let pk = Packet::new(MEMORY_PORT, INFO_CHANNEL, vec![CMD_INFO_DETAILS, i]);
124 uplink
125 .send_async(pk)
126 .await
127 .map_err(|_| Error::Disconnected)?;
128
129 let pk = downlink.wait_packet(MEMORY_PORT, INFO_CHANNEL, &[CMD_INFO_DETAILS, i]).await?;
130 let data = pk.get_data();
131 let memory_id = data[1];
132 let memory_type = MemoryType::try_from(data[2])?;
133 let memory_size = u32::from_le_bytes(data[3..7].try_into()?);
134
135 self.memories.push(MemoryDevice {
136 memory_id: memory_id,
137 memory_type: memory_type,
138 size: memory_size
139 });
140
141 self.backends.push(Mutex::new(Some(MemoryBackend {
142 memory_id: memory_id,
143 memory_type: memory_type,
144 uplink: uplink.clone(),
145 read_downlink: self.memory_read_dispatcher.get_channel(memory_id).await,
146 write_downlink: self.memory_write_dispatcher.get_channel(memory_id).await,
147 })));
148 }
149 Ok(())
150
151 }
152
153 pub fn get_memories(&self, memory_type: Option<MemoryType>) -> Vec<&MemoryDevice> {
186 match memory_type {
187 Some(ty) => self.memories.iter().filter(|m| m.memory_type == ty).collect(),
188 None => self.memories.iter().collect(),
189 }
190 }
191
192 pub async fn open_memory<T: FromMemoryBackend>(&self, memory: MemoryDevice) -> Option<Result<T>> {
199 let backend = self.backends.get(memory.memory_id as usize)?.lock().await.take()?;
200 Some(T::from_memory_backend(backend).await)
201 }
202
203 pub async fn close_memory<T: FromMemoryBackend>(&self, device: T) {
209 let backend = device.close_memory();
210 if let Some(mutex) = self.backends.get(backend.memory_id as usize) {
211 let mut guard = mutex.lock().await;
212 if guard.is_none() {
213 *guard = Some(backend);
214 } else {
215 println!("Warning: Attempted to close memory ID {} which is already closed", backend.memory_id);
216 }
217 } else {
218 println!("Warning: Attempted to close memory ID {} which does not exist", backend.memory_id);
219 }
220 }
221
222 pub async fn initialize_memory<T: FromMemoryBackend>(&self, memory: MemoryDevice) -> Option<Result<T>> {
230 let backend = self.backends.get(memory.memory_id as usize)?.lock().await.take()?;
231 Some(T::initialize_memory_backend(backend).await)
232 }
233
234}