Reading serial data using interrupt

755 Views Asked by At

I am trying to read a series of bytes from the serial pin, the interrupt is being called but I only read the first byte of the data each time. I am using the library stm32f1xx-hal.

The idea is to store the data I receive in a buffer to use it whenever I need it later on the program. I got inspired by the example in the library.

Here is my code :

const BUFFER_LEN: usize = 20;
static mut BUFFER: &mut [u8; BUFFER_LEN] = &mut [0; BUFFER_LEN];
static mut WIDX: usize = 0;

static mut RX: Option<Rx<USART1>> = None;

static mut RX_PIN : MaybeUninit<stm32f1xx_hal::gpio::gpioa::PA10<Input<Floating>>> = MaybeUninit::uninit();

#[interrupt]
unsafe fn USART1() {
    INT_COUNTER += 1;
    cortex_m::interrupt::free(|_| {
        if let Some(rx) = RX.as_mut() {
            while rx.is_rx_not_empty() {
                if let Ok(w) = nb::block!(rx.read()) {
                    BUFFER[WIDX] = w;
                    WIDX += 1;
                    if WIDX >= BUFFER_LEN - 1 {
                        WIDX = 0;
                    }
                }
                rx.listen_idle();
            }
            if rx.is_idle() {
                rx.unlisten_idle();
                WIDX = 0;
            }
        }
    })
}

#[entry]
fn main() -> ! {
    let mut dp: Peripherals = pac::Peripherals::take().unwrap();
    let cp = cortex_m::Peripherals::take().unwrap();
    let mut rcc: Rcc = dp.RCC.constrain();
    let mut gpioc = dp.GPIOC.split();
    let mut flash = dp.FLASH.constrain();
    let mut gpioa = dp.GPIOA.split();
    let mut afio = dp.AFIO.constrain();

    let clocks_serial = rcc.cfgr.freeze(&mut flash.acr);

    // USART1 on Pins A9 and A10
    let pin_tx = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh);
    let mut pin_rx = gpioa.pa10;


    unsafe {
        pac::NVIC::unmask(pac::Interrupt::USART1);
    }

    let serial = Serial::usart1(
        dp.USART1,
        (pin_tx, pin_rx),
        &mut afio.mapr,
        Config::default().baudrate(115200.bps()), // baud rate defined in herkulex doc : 115200
        clocks_serial.clone(),
        // &mut rcc.apb2,
    );

    // separate into tx and rx channels
    let (mut tx, mut rx) = serial.split();

    rx.listen();
    rx.listen_idle();

    cortex_m::interrupt::free(|_| unsafe {
        RX.replace(rx);
    });


    loop {
        // It is my sender, I can confirm I receive the message on the logical analyzer.
        let message = servo.stat();
        send_message(message, &mut tx);

        cortex_m::asm::wfi(); // important

        unsafe {
            hprintln!("{:?}", BUFFER);
        }
    }
}
0

There are 0 best solutions below