Crate si4703

Source
Expand description

This is a platform agnostic Rust driver for the Si4702 and Si4703 FM radio turners (receivers) using the embedded-hal traits and I2C.

This driver allows you to:

Introductory blog post

§The devices

The Si4702/03-C19 extends Silicon Laboratories Si4700/Si4701 FM tuner family, and further increases the ease and attractiveness of adding FM radio reception to mobile devices through small size and board area, minimum component count, flexible programmability, and superior, proven performance.

The device offers significant programmability, and caters to the subjective nature of FM listeners and variable FM broadcast environments world-wide through a simplified programming interface and mature functionality.

The Si4703-C incorporates a digital processor for the European Radio Data System (RDS) and the US Radio Broadcast Data System (RBDS) including all required symbol decoding, block synchronization, error detection, and error correction functions.

RDS enables data such as station identification and song name to be displayed to the user. The Si4703-C offers a detailed RDS view and a standard view, allowing adopters to selectively choose granularity of RDS status, data, and block errors.

Datasheets:

Further documentation:

§Usage (see also examples folder)

To use this driver, import this crate and an embedded_hal implementation, then instantiate the appropriate device. In the following examples an instance of the device Si4703 will be created as an example. An instance of the Si4702 device can be created with: Si4703::new_si4702(...).

Please find additional examples using hardware in this repository: driver-examples.

§Seek a channel, listen for 5 seconds, then seek again

use embedded_hal::blocking::delay::DelayMs;
use linux_embedded_hal::{Delay, I2cdev, Pin};
use si4703::{
    reset_and_select_i2c_method1, ChannelSpacing, DeEmphasis, ErrorWithPin, SeekDirection,
    SeekMode, Si4703, Volume,
};

let mut delay = Delay {};
{
    // Reset and communication protocol selection must be done beforehand
    let mut sda = Pin::new(2);
    let mut rst = Pin::new(17);
    reset_and_select_i2c_method1(&mut rst, &mut sda, &mut delay).unwrap();
}
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut radio = Si4703::new(dev);
radio.enable_oscillator().unwrap();
// Wait for the oscillator to stabilize
delay.delay_ms(500_u16);
radio.enable().unwrap();
// Wait for powerup
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();

// use STC interrupt pin method
let stc_int = Pin::new(27);
loop {
    match radio.seek_with_stc_int_pin(SeekMode::Wrap, SeekDirection::Up, &stc_int) {
        Err(nb::Error::WouldBlock) => {
            let channel = radio.channel().unwrap_or(-1.0);
            println!("Trying channel at {:1} MHz", channel);
        }
        Err(nb::Error::Other(ErrorWithPin::SeekFailed)) => {
            println!("Seek Failed");
        }
        Err(e) => {
            println!("Error: {:?}", e);
        }
        Ok(_) => {
            let channel = radio.channel().unwrap_or(-1.0);
            println!("Found channel at {:1} MHz", channel);
            delay.delay_ms(5000_u16); // listen for 5 seconds, then seek again
        }
    }
    delay.delay_ms(50_u8);
}

Structs§

RdsBlockData
RDS block data
RdsData
RDS data data
RdsRadioText
RDS radio text
Si4703
Si4703 device driver

Enums§

Band
Band
ChannelSpacing
Channel spacing
DeEmphasis
De-emphasis
Error
Errors in this crate
ErrorWithPin
Errors for operations involving I2C communication as well as interaction with pins
Gpio1Config
GPIO1 configuration
Gpio2Config
GPIO2 configuration
Gpio3Config
GPIO3 configuration
OutputMode
Output mode
RdsBlockErrors
RDS block errors
RdsMode
RDS mode
RdsRadioTextData
RDS radio text data
SeekDirection
Seek direction
SeekFmImpulseThreshold
Allowable number of FM impulses for a valid seek channel.
SeekMode
Seek mode
SeekSnrThreshold
Required channel SNR for a valid seek.
SoftmuteAttenuation
Softmute Attenuation
SoftmuteRate
Softmute Attack/Recover Rate
StereoToMonoBlendLevel
Stereo to mono blend level
TuneChannel
Tune channel frequency
Volume
Volume

Functions§

fill_with_rds_radio_text
Fill char array with radio text with the RDS data.
get_rds_radio_text
Get radio text from RDS data.
reset_and_select_i2c_method1
Reset the device and select I2C communication (method 1, no GPIO3)
reset_and_select_i2c_method2
Reset the device and select I2C communication (method 2)
reset_and_select_i2c_method1_with_gpio3
Reset the device and select I2C communication (method 1 including GPIO3)