stm32f4xx-hal
stm32f4xx-hal copied to clipboard
wip: Serial audio interface (SAI)
This PR contains some preliminary code for the SAI. In the stm32f7xx-hal a driver already exists iirc, but that driver is limited to duplex I2S. This API is slightly more flexible, yet similarly easy to use.
Usage example:
// Initialize clocks.
let rcc = ctx.device.RCC.constrain();
let clocks = rcc
.cfgr
.use_hse(8.mhz())
.saia_clk(172.mhz())
.saib_clk(172.mhz())
.freeze();
// Test that the SAI clock is suitable for 48000KHz audio.
assert!(clocks.saia_clk().unwrap() == 172.mhz().into());
assert!(clocks.saib_clk().unwrap() == 172.mhz().into());
let gpioe = ctx.device.GPIOE.split();
// SAIB is made synchronous to A.
let (saia, saib) = ctx.device.SAI.split_sync_b();
let protocol = Protocol {
sync: Synchronization::I2S,
word_size: 16,
slot_size: 16,
num_slots: 2,
};
let tx = saia.master_tx(
(
gpioe.pe2.into_alternate_af6(),
gpioe.pe4.into_alternate_af6(),
gpioe.pe5.into_alternate_af6(),
gpioe.pe6.into_alternate_af6(),
),
protocol,
48000.hz(),
clocks,
);
let rx = saib.slave_rx(gpioe.pe3.into_alternate_af6(), protocol);
let mut duplex = Duplex::new(rx, tx);
duplex.start();
loop {
duplex.try_send(0xaaaa, 0xf0f0).ok();
let _input = duplex.try_read();
}
Bits still missing:
- DMA
- Implementation of the new embedded-hal I2S traits
- Support for everything but the STM32F429 (should be very simple)
- Functions to deinitialize the SAI and release the pins
- Documentation on how to set the SAI clock
Any progress on this?