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(not(any(
20        feature = "usb-buffer-1k",
21        feature = "usb-buffer-4k",
22        feature = "usb-buffer-8k"
23    )))]
24    {
25        2048 // Default
26    }
27};
28
29/// Size of each USB endpoints buffer (Always guaranteed to be divisible by 4)
30pub const ALLOC_SIZE_MAX_PER_EP: usize = BUFFER_SIZE / 16;
31
32/// USB endpoint storage buffer, aligned to 4 bytes
33#[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    /// Allocates a fixed buffer of [`ALLOC_SIZE_MAX_PER_EP`]
80    pub fn allocate_buffer(&mut self) -> UsbResult<*mut u8> {
81        // Do all range checks first
82        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}