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(not(any(
20 feature = "usb-buffer-1k",
21 feature = "usb-buffer-4k",
22 feature = "usb-buffer-8k"
23 )))]
24 {
25 2048 }
27};
28
29pub const ALLOC_SIZE_MAX_PER_EP: usize = BUFFER_SIZE / 16;
31
32#[repr(C, align(4))]
34pub struct Buffer {
35 inner: [u8; BUFFER_SIZE],
36}
37
38impl Default for Buffer {
39 fn default() -> Self {
40 Self {
41 inner: [0; BUFFER_SIZE],
42 }
43 }
44}
45
46impl Deref for Buffer {
47 type Target = [u8; BUFFER_SIZE];
48 fn deref(&self) -> &Self::Target {
49 &self.inner
50 }
51}
52
53impl DerefMut for Buffer {
54 fn deref_mut(&mut self) -> &mut Self::Target {
55 &mut self.inner
56 }
57}
58
59fn buffer() -> &'static mut Buffer {
60 singleton!(: Buffer = Buffer::default() ).unwrap()
61}
62
63pub struct BufferAllocator {
64 buffers: &'static mut Buffer,
65 next_buf: usize,
66}
67
68impl Default for BufferAllocator {
69 fn default() -> Self {
70 Self {
71 next_buf: 0,
72 buffers: buffer(),
73 }
74 }
75}
76
77impl BufferAllocator {
78
79 pub fn allocate_buffer(&mut self) -> UsbResult<*mut u8> {
81 if self.next_buf >= self.buffers.len()
83 || self.next_buf + ALLOC_SIZE_MAX_PER_EP > self.buffers.len()
84 {
85 return Err(UsbError::EndpointMemoryOverflow);
86 }
87
88 let start_addr = &mut self.buffers[self.next_buf] as *mut u8;
89 self.next_buf += ALLOC_SIZE_MAX_PER_EP;
90 Ok(start_addr)
91 }
92}