michaelkamprath / i2c-character-display

Rust library for controlling HD44780-based character displays using I2C adapters.
MIT License
1 stars 1 forks source link

add support for factory method #4

Closed gdoct closed 1 day ago

gdoct commented 3 weeks ago

This crate looks really useful as an abstraction for working with the LCD1602 with a PCF8574T through I2C. But to use it in more than just the main() method, I'd like to pass around a reference to the BaseCharacterDisplay struct. However, the current code does not seem to allow this. One generic in the returned BaseCharacterDisplay type is private, and thus cannot be used in method signatures.

to clarify, see the function create_display below. The return value would be of type

BaseCharacterDisplay<rp2040_hal::I2C<I2C1, (rp2040_hal::gpio::Pin<Gpio18, FunctionI2c, PullUp>, rp2040_hal::gpio::Pin<Gpio19, FunctionI2c, PullUp>)>, &mut dyn embedded_hal::delay::DelayNs, i2c_character_display::adapter_config::GenericPCF8574TConfig<rp2040_hal::I2C<I2C1, (rp2040_hal::gpio::Pin<Gpio18, FunctionI2c, PullUp>, rp2040_hal::gpio::Pin<Gpio19, FunctionI2c, PullUp>)>>>

and the issue with that is, that i2c_character_display::adapter_config is private, so the compiler does not allow to use i2c_character_display::adapter_config::GenericPCF8574TConfig<> as the return type, and therefore fails with this error

_module `adapter_config` is private
private modulerustc[Click for full compiler diagnostic](rust-analyzer-diagnostics-view:/diagnostic message [5]?5#file:///src/main.rs)
main.rs(91, 240): struct `GenericPCF8574TConfig` is not publicly re-exported_

here is the basic factory method - I was unable to define the return type

fn create_display(clocks: &ClocksManager, pins: &mut hal::gpio::Pins, delay: &mut dyn DelayNs) -> Option<...>  { 
let mut pac = pac::Peripherals::take().unwrap();
    let (sda_pin, scl_pin) = (pins.gpio18.reconfigure(), pins.gpio19.reconfigure()); 
    let i2c_freq = 400_000u32.Hz();
    let mut i2c = hal::I2C::i2c1(
        pac.I2C1,
        sda_pin,
        scl_pin, 
        i2c_freq,
        &mut pac.RESETS,
        &clocks.system_clock,
    );
    let display = CharacterDisplayPCF8574T::new(i2c, LcdDisplayType::Lcd16x2, delay);
    Some(display)
}

Perhaps I'm doing it wrong, but I was unable to get this to work. making the adapter_config accessible would probably solve the issue.

michaelkamprath commented 3 weeks ago

@gdoct I see you closed this issue. Were you able to get it to work?