Skip to main content

atsamd_hal/peripherals/usb/d11/
buffer.rs

1use core::ops::{Deref, DerefMut};
2use cortex_m::singleton;
3use usb_device::{Result as UsbResult, UsbError};
4
5/// Size of the buffer that holds ALL USB endpoint buffers
6pub 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 // Default
31    }
32};
33
34/// Size of each USB endpoints buffer (Always guaranteed to be divisible by 4)
35pub const ALLOC_SIZE_MAX_PER_EP: usize = BUFFER_SIZE / 16;
36
37/// USB endpoint storage buffer, aligned to 4 bytes
38#[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    /// Allocates a fixed buffer of [`ALLOC_SIZE_MAX_PER_EP`]
84    pub fn allocate_buffer(&mut self) -> UsbResult<*mut u8> {
85        // Do all range checks first
86        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}