atsamd_hal/peripherals/usb/d11/
buffer.rs1use core::ops::{Deref, DerefMut};
2use cortex_m::singleton;
3use usb_device::{Result as UsbResult, UsbError};
4
5pub const BUFFER_SIZE: usize = {
7 #[cfg(feature = "usb-buffer-1k")]
8 {
9 1024
10 }
11 #[cfg(feature = "usb-buffer-4k")]
12 {
13 4098
14 }
15 #[cfg(feature = "usb-buffer-8k")]
16 {
17 8192
18 }
19 #[cfg(feature = "usb-buffer-16k")]
20 {
21 16384
22 }
23 #[cfg(not(any(
24 feature = "usb-buffer-1k",
25 feature = "usb-buffer-4k",
26 feature = "usb-buffer-8k",
27 feature = "usb-buffer-16k"
28 )))]
29 {
30 2048 }
32};
33
34pub const ALLOC_SIZE_MAX_PER_EP: usize = BUFFER_SIZE / 16;
36
37#[repr(C, align(4))]
39pub struct Buffer {
40 inner: [u8; BUFFER_SIZE],
41}
42
43impl Default for Buffer {
44 fn default() -> Self {
45 Self {
46 inner: [0; BUFFER_SIZE],
47 }
48 }
49}
50
51impl Deref for Buffer {
52 type Target = [u8; BUFFER_SIZE];
53 fn deref(&self) -> &Self::Target {
54 &self.inner
55 }
56}
57
58impl DerefMut for Buffer {
59 fn deref_mut(&mut self) -> &mut Self::Target {
60 &mut self.inner
61 }
62}
63
64fn buffer() -> &'static mut Buffer {
65 singleton!(: Buffer = Buffer::default() ).unwrap()
66}
67
68pub struct BufferAllocator {
69 buffers: &'static mut Buffer,
70 next_buf: usize,
71}
72
73impl Default for BufferAllocator {
74 fn default() -> Self {
75 Self {
76 next_buf: 0,
77 buffers: buffer(),
78 }
79 }
80}
81
82impl BufferAllocator {
83 pub fn allocate_buffer(&mut self) -> UsbResult<*mut u8> {
85 if self.next_buf >= self.buffers.len()
87 || self.next_buf + ALLOC_SIZE_MAX_PER_EP > self.buffers.len()
88 {
89 return Err(UsbError::EndpointMemoryOverflow);
90 }
91
92 let start_addr = &mut self.buffers[self.next_buf] as *mut u8;
93 self.next_buf += ALLOC_SIZE_MAX_PER_EP;
94 Ok(start_addr)
95 }
96}