You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As a learning exercise I have being trying to organizing some of these examples with a setup() function for the HAL/hardware specific part of the code. This makes it easier to generalize the example to use with other boards. (More on that when I get further.) The example si4703-fm-radio-display-bp is a bit difficult because of the seek control pins in addition to the i2c. This code seems like it is almost working but I am having type mismatch / trait problems
Click to expand
#![deny(unsafe_code)]
#![no_std]
#![no_main]
use core::fmt::Write;
use cortex_m_rt::entry;
use embedded_graphics::{
fonts::{Font6x8, Text},
pixelcolor::BinaryColor,
prelude::*,
style::TextStyleBuilder,
};
use embedded_hal::digital::v2::{InputPin, OutputPin};
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use si4703::{
reset_and_select_i2c_method1 as reset_si4703, ChannelSpacing, DeEmphasis, ErrorWithPin,
SeekDirection, SeekMode, Si4703, Volume,
};
use ssd1306::{prelude::*, Builder, I2CDIBuilder};
pub trait LED {
// depending on board wiring, on may be set_high or set_low, with off also reversed
// implementation should deal with this difference
fn on(&mut self) -> ();
fn off(&mut self) -> ();
// default methods
fn blink(&mut self, time: u16, delay: &mut Delay) -> () {
self.on();
delay.delay_ms(time);
self.off();
delay.delay_ms(time); // consider delay.delay_ms(500u16);
}
}
pub struct SeekPins<T, U> {
p_seekup: T,
p_seekdown: U,
//p_stcint: V,
}
pub trait SEEK {
fn seekup(&mut self) -> bool;
fn seekdown(&mut self) -> bool;
//fn stcint(&mut self) -> ;
}
// setup() does all hal/MCU specific setup and returns generic hal device for use in main code.
use stm32f1xx_hal::{
delay::Delay,
gpio::{
gpiob::{PB10, PB11, PB6},
gpioc::PC13,
Input, Output, PullDown, PullUp, PushPull,
},
i2c::{BlockingI2c, DutyCycle, Mode, Pins},
pac::{CorePeripherals, Peripherals, I2C1},
prelude::*,
};
fn setup() -> (
BlockingI2c<I2C1, impl Pins<I2C1>>,
impl LED,
Delay,
impl SEEK,
PB6<Input<PullUp>>,
) {
let cp = CorePeripherals::take().unwrap();
let dp = Peripherals::take().unwrap();
let mut flash = dp.FLASH.constrain();
let mut rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.freeze(&mut flash.acr);
let mut afio = dp.AFIO.constrain(&mut rcc.apb2);
let mut gpiob = dp.GPIOB.split(&mut rcc.apb2);
let scl = gpiob.pb8.into_alternate_open_drain(&mut gpiob.crh);
//let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh); //OutputPin is not implemented
let sda = gpiob.pb9.into_push_pull_output(&mut gpiob.crh); //trait Pins<I2C1> not implemented
let i2c = BlockingI2c::i2c1(
dp.I2C1,
(scl, sda),
&mut afio.mapr,
Mode::Fast {
frequency: 400_000.hz(),
duty_cycle: DutyCycle::Ratio2to1,
},
clocks,
&mut rcc.apb1,
1000,
10,
1000,
1000,
);
let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);
let led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
let delay = Delay::new(cp.SYST, clocks);
impl LED for PC13<Output<PushPull>> {
fn on(&mut self) -> () {
self.set_low().unwrap()
}
fn off(&mut self) -> () {
self.set_high().unwrap()
}
}
let stcint = gpiob.pb6.into_pull_up_input(&mut gpiob.crl);
let buttons: SeekPins<PB10<Input<PullDown>>, PB11<Input<PullDown>>> = SeekPins{
p_seekup : gpiob.pb10.into_pull_down_input(&mut gpiob.crh),
p_seekdown : gpiob.pb11.into_pull_down_input(&mut gpiob.crh)
};
impl SEEK for SeekPins<PB10<Input<PullDown>>, PB11<Input<PullDown>>> {
fn seekup(&mut self) -> bool {
self.p_seekup.is_high().unwrap()
}
fn seekdown(&mut self) -> bool {
self.p_seekdown.is_high().unwrap()
}
}
let mut rst = gpiob.pb7.into_push_pull_output(&mut gpiob.crl);
//let z = reset_si4703(&mut rst, &mut sda, &mut delay).unwrap();
let _z = reset_si4703(&mut rst, &mut sda, &mut delay);
(i2c, led, delay, buttons, stcint)
}
// End of hal/MCU specific setup. Following should be generic code.
#[entry]
fn main() -> ! {
rtt_init_print!();
rprintln!("Si4703 example");
let (i2c, mut led, mut delay, mut buttons, mut stcint) = setup();
let manager = shared_bus::BusManager::<cortex_m::interrupt::Mutex<_>, _>::new(i2c);
let interface = I2CDIBuilder::new().init(manager.acquire());
let mut disp: GraphicsMode<_> = Builder::new().connect(interface).into();
disp.init().unwrap();
disp.flush().unwrap();
let text_style = TextStyleBuilder::new(Font6x8)
.text_color(BinaryColor::On)
.build();
let mut radio = Si4703::new(manager.acquire());
radio.enable_oscillator().unwrap();
delay.delay_ms(500_u16);
radio.enable().unwrap();
delay.delay_ms(110_u16);
radio.set_volume(Volume::Dbfsm28).unwrap();
radio.set_deemphasis(DeEmphasis::Us50).unwrap();
radio.set_channel_spacing(ChannelSpacing::Khz100).unwrap();
radio.unmute().unwrap();
let mut buffer: heapless::String<64> = heapless::String::new();
loop {
// Blink LED 0 every time a new seek is started
// to check that everything is actually running.
led.blink(50_u16, &mut delay);
let should_seek_down = buttons.seekdown();
let should_seek_up = buttons.seekup();
if should_seek_down || should_seek_up {
buffer.clear();
write!(buffer, "Seeking...").unwrap();
disp.clear();
Text::new(&buffer, Point::zero())
.into_styled(text_style)
.draw(&mut disp)
.unwrap();
disp.flush().unwrap();
let direction = if should_seek_down {
SeekDirection::Down
} else {
SeekDirection::Up
};
buffer.clear();
loop {
match radio.seek_with_stc_int_pin(SeekMode::Wrap, direction, &stcint) {
Err(nb::Error::WouldBlock) => {}
Err(nb::Error::Other(ErrorWithPin::SeekFailed)) => {
write!(buffer, "Seek Failed! ").unwrap();
break;
}
Err(_) => {
write!(buffer, "Error! ").unwrap();
break;
}
Ok(_) => {
let channel = radio.channel().unwrap_or(-1.0);
write!(buffer, "Found {:1} MHz ", channel).unwrap();
break;
}
}
}
disp.clear();
Text::new(&buffer, Point::zero())
.into_styled(text_style)
.draw(&mut disp)
.unwrap();
disp.flush().unwrap();
}
}
}
with the code as shown, sda as in your code, I get
error[E0277]: the trait bound `(PB8<Alternate<OpenDrain>>, PB9<Output<PushPull>>): stm32f1xx_hal::i2c::Pins<I2C1>` is not satisfied
--> examples/zz.rs:87:15
|
87 | let i2c = BlockingI2c::i2c1(
| ^^^^^^^^^^^^^^^^^ the trait `stm32f1xx_hal::i2c::Pins<I2C1>` is not implemented for `(PB8<Alternate<OpenDrain>>, PB9<Output<PushPull>>)`
|
= help: the following implementations were found:
<(PB10<Alternate<OpenDrain>>, PB11<Alternate<OpenDrain>>) as stm32f1xx_hal::i2c::Pins<I2C2>>
<(PB6<Alternate<OpenDrain>>, PB7<Alternate<OpenDrain>>) as stm32f1xx_hal::i2c::Pins<I2C1>>
<(PB8<Alternate<OpenDrain>>, PB9<Alternate<OpenDrain>>) as stm32f1xx_hal::i2c::Pins<I2C1>>
= note: required by `BlockingI2c::<I2C1, PINS>::i2c1`
error[E0277]: the trait bound `(PB8<Alternate<OpenDrain>>, PB9<Output<PushPull>>): stm32f1xx_hal::i2c::Pins<I2C1>` is not satisfied
--> examples/zz.rs:65:23
|
65 | BlockingI2c<I2C1, impl Pins<I2C1>>,
| ^^^^^^^^^^^^^^^ the trait `stm32f1xx_hal::i2c::Pins<I2C1>` is not implemented for `(PB8<Alternate<OpenDrain>>, PB9<Output<PushPull>>)`
|
= help: the following implementations were found:
<(PB10<Alternate<OpenDrain>>, PB11<Alternate<OpenDrain>>) as stm32f1xx_hal::i2c::Pins<I2C2>>
<(PB6<Alternate<OpenDrain>>, PB7<Alternate<OpenDrain>>) as stm32f1xx_hal::i2c::Pins<I2C1>>
<(PB8<Alternate<OpenDrain>>, PB9<Alternate<OpenDrain>>) as stm32f1xx_hal::i2c::Pins<I2C1>>
error: aborting due to 2 previous errors
and with
let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh); //OutputPin is not implemented
I get
error[E0271]: type mismatch resolving `<PB9<Alternate<OpenDrain>> as embedded_hal::digital::v2::OutputPin>::Error == Infallible`
--> examples/zz.rs:134:14
|
134 | let _z = reset_si4703(&mut rst, &mut sda, &mut delay);
| ^^^^^^^^^^^^ expected enum `Infallible`, found `()`
|
::: /home/paul/.cargo/git/checkouts/si4703-rs-df77d9d8ce5b9ec0/7d40805/src/reset.rs:12:20
|
12 | SDA: OutputPin<Error = E>,
| --------- required by this bound in `reset_and_select_i2c_method1`
error[E0277]: the trait bound `PB9<Alternate<OpenDrain>>: embedded_hal::digital::OutputPin` is not satisfied
--> examples/zz.rs:134:14
|
134 | let _z = reset_si4703(&mut rst, &mut sda, &mut delay);
| ^^^^^^^^^^^^ the trait `embedded_hal::digital::OutputPin` is not implemented for `PB9<Alternate<OpenDrain>>`
|
::: /home/paul/.cargo/git/checkouts/si4703-rs-df77d9d8ce5b9ec0/7d40805/src/reset.rs:12:10
|
12 | SDA: OutputPin<Error = E>,
| -------------------- required by this bound in `reset_and_select_i2c_method1`
|
= note: required because of the requirements on the impl of `embedded_hal::digital::v2::OutputPin` for `PB9<Alternate<OpenDrain>>`
error: aborting due to 2 previous errors
I do not have this problem with i2c in the other examples, in which I use
let sda = gpiob.pb9.into_alternate_open_drain(&mut gpiob.crh);
I am using an up-to-date fork of driver-examples and current github version of stm32f1xx_hal.
Suggestions?
(BTW, I am not really happy with my struct seekPins and trait SEEK, I think they should be tied more closely to radio. Suggestions on that also appreciated.)
The text was updated successfully, but these errors were encountered:
As a learning exercise I have being trying to organizing some of these examples with a
setup()
function for the HAL/hardware specific part of the code. This makes it easier to generalize the example to use with other boards. (More on that when I get further.) The examplesi4703-fm-radio-display-bp
is a bit difficult because of the seek control pins in addition to thei2c
. This code seems like it is almost working but I am having type mismatch / trait problemsClick to expand
with the code as shown,
sda
as in your code, I getand with
I get
I do not have this problem with i2c in the other examples, in which I use
I am using an up-to-date fork of
driver-examples
and current github version ofstm32f1xx_hal
.Suggestions?
(BTW, I am not really happy with my
struct seekPins
andtrait SEEK
, I think they should be tied more closely toradio
. Suggestions on that also appreciated.)The text was updated successfully, but these errors were encountered: