Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stm32wb gatt_server example stops responding after 16 writes to characteristic #3563

Open
crfellows2 opened this issue Nov 22, 2024 · 0 comments

Comments

@crfellows2
Copy link

crfellows2 commented Nov 22, 2024

First discovered this with a stm32wb55cgu on a custom board, but have noticed it is also an issue with the gatt_server example on a stm32 nucleo.

Using two different BLE testing apps (ST BLE Toolbox and my custom app), I can successfully write to the characteristic Uuid16(0x502) 16 times, but the 17th does not show up in the trace and Bluetooth stops responding entirely.
trace.txt

I'm thinking its an issue with how the copro is initially configured, such as an incorrect buffer size / one that isn't being cleared since it works 16 times before the copro stops responding and ipcc receive gets stuck on Pending in embassy-stm32/src/ipcc.rs?

    pub async fn receive<R>(channel: IpccChannel, mut f: impl FnMut() -> Option<R>) -> R {
        let regs = IPCC::regs();

        loop {
            // This is a race, but is nice for debugging
            if !regs.cpu(1).sr().read().chf(channel as usize) {
                trace!("ipcc: ch {}: wait for rx occupied", channel as u8);
            }

            poll_fn(|cx| {
                IPCC::state().rx_waker_for(channel).register(cx.waker());
                // If bit is set to 1 then interrupt is disabled; we want to enable the interrupt
                regs.cpu(0).mr().modify(|w| w.set_chom(channel as usize, false));

                compiler_fence(Ordering::SeqCst);

                if regs.cpu(1).sr().read().chf(channel as usize) {
                    // If bit is set to 1 then interrupt is disabled; we want to disable the interrupt
                    regs.cpu(0).mr().modify(|w| w.set_chfm(channel as usize, true));

                    Poll::Ready(())
                } else {
                    Poll::Pending
                }
            })
            .await;

            trace!("ipcc: ch {}: read data", channel as u8);

            match f() {
                Some(ret) => return ret,
                None => {}
            }

            trace!("ipcc: ch {}: clear rx", channel as u8);
            compiler_fence(Ordering::SeqCst);
            // If the channel is clear and the read function returns none, fetch more data
            regs.cpu(0).scr().write(|w| w.set_chc(channel as usize, true));
        }
    }

I'll continue investigating but thought I'd put this out there in case someone more experienced sees an obvious issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant