9names / bl702-hal

Rust Embedded HAL for Boufallo BL702 microcontroller
MIT License
10 stars 4 forks source link

Blinky works with GPIO23/25 but not GPIO24 #8

Closed mattthebaker closed 1 year ago

mattthebaker commented 1 year ago

Hi, I'm working with your project to build something with the m0-sense from sipeed: https://wiki.sipeed.com/hardware/en/maixzero/sense/maix_zero_sense.html

The blinky example works for the red and blue LEDs on 23/25, but not the green on 24. I tried about everything I could think of (except that I do not have a risc-v core debugger). Mostly working down to direct PAC writes for 24, but nothing could make it work.

Writing to the cfgctl12 or possibly the cfgctl34 for output enable typically turns on all three leds.

Do you have any idea what might cause this on bl702?

I added lines to add the GPIOs up to 31:

    Pin23: (pin23, gpio_cfgctl11, UartSig7, sig7, sclk, sda, gpio_23, gpio_int_mode_set3,23),
    Pin24: (pin24, gpio_cfgctl12, UartSig0, sig0, miso, scl, gpio_24, gpio_int_mode_set3,24),
    Pin25: (pin25, gpio_cfgctl12, UartSig1, sig1, mosi, sda, gpio_25, gpio_int_mode_set3,25),
    Pin26: (pin26, gpio_cfgctl13, UartSig2, sig2, ss, scl, gpio_26, gpio_int_mode_set3,26),
    Pin27: (pin27, gpio_cfgctl13, UartSig3, sig3, sclk, sda, gpio_27, gpio_int_mode_set3,27),
    Pin28: (pin28, gpio_cfgctl14, UartSig4, sig4, miso, scl, gpio_28, gpio_int_mode_set3,28),
    Pin29: (pin29, gpio_cfgctl14, UartSig5, sig5, mosi, sda, gpio_29, gpio_int_mode_set3,29),
    Pin30: (pin30, gpio_cfgctl15, UartSig6, sig6, ss, scl, gpio_30, gpio_int_mode_set4,30),
    Pin31: (pin31, gpio_cfgctl15, UartSig7, sig7, sclk, sda, gpio_31, gpio_int_mode_set4,31),
9names commented 1 year ago

No idea to be honest! GPIO24 wasn't broken out on any of my other boards. And while I did check things when copying over GPIO support from bl602 it's possible I got them wrong. I do have an M0 sense, so I can test it out locally + I'll review your pin configs and see if something stands out...

9names commented 1 year ago

Oh.. do the pin numbers have some weird offsets here? I'll have to check the RM...

    Pin9: (pin9, gpio_cfgctl4, UartSig1, sig1, mosi, sda, gpio_9, gpio_int_mode_set1,9), 
    Pin10: (pin10, gpio_cfgctl5, UartSig2, sig2, ss, scl, gpio_10, gpio_int_mode_set2,11), // Should we have jumped to 11 here
...
    Pin22: (pin22, gpio_cfgctl11, UartSig6, sig6, ss, scl, gpio_22, gpio_int_mode_set3,23),
    Pin23: (pin23, gpio_cfgctl11, UartSig7, sig7, sclk, sda, gpio_23, gpio_int_mode_set3,23), // shouldn't this be 24?
9names commented 1 year ago

I incorporated your changes (with a co-author tag) + a fix to the pin numbers + updated from the older riscv/riscv-rt, was intending to push it to a branch but instead I pushed it to main :sweat_smile: I tested it on all the pins exposed on my XT-ZB1 board, so pins 0,1,2,7,8,9,14,15,17,25,27,28 Haven't been able to get my M0 sense into bootloader mode, so testing on that will have to wait until I get a debugger on it.

9names commented 1 year ago

Finally worked it out, what a pain! Anyway, after these changes I tested with pins 23, 24, and 25. pin 23 blinks blue pin 24 blinks green pin 25 blinks red This matches what the schematic says should happen. And, it means your code should have worked. No idea why it wasn't. I removed the LCD to avoid damaging it, but I can't imaging that being required...

9names commented 1 year ago

With the LCD attached: blue blinks green stays lit at all times red blinks Umm. after retesting, green stays lit after being enabled even without the LCD attached. maybe I tested it wrong the first time?

mattthebaker commented 1 year ago

Hmm, switching pin to gpio24 still causes all three LEDs to turn on, very unusual.

Trying to remember different things I tried:

It seemed that in some instances changing between debug and release build, and switching between units would sometimes produce slightly different behavior.

As far as I can tell, all of the values for gpio24 related registers in the pac seem correct, or at least they match the datasheet values.

Unfortunately my older model segger can't connect so I couldn't read registers. I'm mostly out of ideas to try other than maybe trying to run a C blinky with the bl_mcu_sdk to try to rule out hardware. Will need to get one of the sipeed debuggers or similar to inspect the registers surrounding writes.

For reference I'm using the cargo objcopy to generate the bin and bflb-mcu-tool for loading on a windows host.

9names commented 1 year ago

I have a newer j-link, plus a bunch an ftdi-based probe that could check registers (via probe-rs or openocd). But it's no use, once I load the Rust firmware it can't connect. Works fine while it's still in the bootloader though (the ROM bootloader, the one you need to jumper 3V and BOOT pins to enter, not the sipeed one you need to flash first then press boot and reset buttons). So either we're doing something, not doing something, or the ROM bootloader is messing with things.

Have you tested this out with the C SDK yet? That's next on my list for testing...

9names commented 1 year ago

Official blinky (in bl_mcu_sdk) does not work with GPIO24. Unlike the Rust one, the green LED stays off the whole time, instead of staying lit the whole time.

9names commented 1 year ago

the M0sense_BL702_example version definitely cycles through green successfully. now we have something to check!

9names commented 1 year ago

the M0sense code uses an older version of the SDK, maybe that's it? trawling through the init code I find this: https://github.com/bouffalolab/bl_mcu_sdk/blob/4b4e4c95449e902206e0d92025c6dc05f3e355d5/drivers/bl702_driver/std_drv/src/bl702_glb.c#L3101 not sure if this is a smoking gun yet but it looks promising. I'm going to stop my investigation for now, hopefully this is a good lead.

mattthebaker commented 1 year ago

That does look promising. It should apply to the m0sense, being an integrated flash device. I made an attempt to implement it in the Rust, but still can't get the green to come on.

AFAICT, what they're doing in the init for gpio 23-28 is:

I added the missing registers manually to the pac, so I may have screwed something up, but it doesn't seem to help for GPIO24. Going to add the registers to try for 25 and see if it works for that LED.

mattthebaker commented 1 year ago

I do have it blinking now, nothing related to gpio33 seems to be required, but still testing to see what the minimum is to get it to function.

It appears on the surface that clearing the IE bit for gpio24 in particular also stops the output from working

mattthebaker commented 1 year ago

Okay, I did more testing and it seems to come entirely down to the GP24IE bit, clearing it seems to also disable the output buffer. In this minimal code snippet, its still required to set GP24FUNC to 0xB even though it should be the reset default. It is also unusual that GP24 supposedly has the pulldown on by default according to the RM, so unless it is a typo, something seems different about GP24 in particular. Or it may be that startup code is messing with it.

    glb.gpio_cfgctl12.modify(|_, w| unsafe {
        w.reg_gpio_24_func_sel().bits(11) // required
                                          //.reg_gpio_24_ie() // disables output
                                          //.clear_bit()
    });
    glb.gpio_cfgctl34
        .modify(|_, w| w.reg_gpio_24_oe().set_bit());
    loop {
        glb.gpio_cfgctl32.modify(|_, w| w.reg_gpio_24_o().set_bit());
        d.delay_ms(1000).unwrap();

        glb.gpio_cfgctl32.modify(|_, w| w.reg_gpio_24_o().clear_bit());
        d.delay_ms(1000).unwrap();
    }

The simplest fix might just be to leave the input buffer and schmitt trigger on for all pins even when set to output mode. I don't think the chip will be setting any records for low power consumption (current isn't even in the data) so burning a little more current may be a fair compromise. Planning to play with a simple fix in the hal crate now.

9names commented 1 year ago

Resolved by #9