1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//! Represents the bluetooth module and abstracts away some of the technical details for other consumers.

use stm32f4xx_hal::{
    dma::{config::DmaConfig, PeripheralToMemory, Stream2, StreamsTuple, Transfer},
    gpio::{PA10, PB6},
    pac::{DMA2, USART1},
    prelude::*,
    rcc::Clocks,
    serial::{self, Rx, Serial},
};

pub type USART1RxBufferInt =
    &'static mut [u8; adafruit_bluefruit_protocol::MAX_CONTROLLER_MESSAGE_LENGTH];
pub type USART1RxBuffer = Option<USART1RxBufferInt>;
pub type USART1RxTransfer =
    Transfer<Stream2<DMA2>, 4_u8, Rx<USART1>, PeripheralToMemory, USART1RxBufferInt>;

/// Represents the [Adafruit Bluefruit LE UART Friend](https://learn.adafruit.com/introducing-the-adafruit-bluefruit-le-uart-friend)
/// connected via USART and with DMA enabled for USART.
pub struct BluefruitLEUARTFriend {
    pub rx_transfer: USART1RxTransfer,
    pub rx_buffer: USART1RxBuffer,
}

impl BluefruitLEUARTFriend {
    /// set up the Adafruit Bluefruit UART LE Friend connected on PB6 & PA10
    ///
    /// note: it will use DMA for the UART connection, the corresponding interrupt must be handled.
    pub fn new(
        pac_usart1: USART1,
        pac_dma2: DMA2,
        tx_pin: PB6,
        rx_pin: PA10,
        clocks: &Clocks,
    ) -> BluefruitLEUARTFriend {
        // set up USART1
        let usart1 = Serial::new(
            pac_usart1,
            (tx_pin.into_alternate(), rx_pin.into_alternate()),
            serial::Config::default()
                .baudrate(9600.bps())
                .dma(serial::config::DmaConfig::Rx),
            clocks,
        )
        .expect("USART1 can be set up");

        let (_usart1_tx, mut usart1_rx) = usart1.split();
        usart1_rx.listen_idle();

        // set up DMA for USART1 RX
        let streams = StreamsTuple::new(pac_dma2);
        let rx_stream = streams.2;
        let rx_buffer = cortex_m::singleton!(: [u8; adafruit_bluefruit_protocol::MAX_CONTROLLER_MESSAGE_LENGTH] = [0; adafruit_bluefruit_protocol::MAX_CONTROLLER_MESSAGE_LENGTH])
            .expect("RX buffer singleton created");
        let mut rx_transfer = Transfer::init_peripheral_to_memory(
            rx_stream,
            usart1_rx,
            rx_buffer,
            None,
            DmaConfig::default()
                .memory_increment(true)
                .fifo_enable(true)
                .fifo_error_interrupt(true)
                .transfer_complete_interrupt(true),
        );
        rx_transfer.start(|_rx| {});
        let rx_buffer = cortex_m::singleton!(: [u8; adafruit_bluefruit_protocol::MAX_CONTROLLER_MESSAGE_LENGTH] = [0; adafruit_bluefruit_protocol::MAX_CONTROLLER_MESSAGE_LENGTH])
            .expect("RX buffer singleton created");

        BluefruitLEUARTFriend {
            rx_transfer,
            rx_buffer: Some(rx_buffer),
        }
    }
}