diff options
author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2012-09-22 15:47:10 +0200 |
---|---|---|
committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2012-09-22 15:47:10 +0200 |
commit | ecf7dae267b27a705009528ea18113235d674f65 (patch) | |
tree | 615aff655edf6e5f41dd08963144a07f1c9e281d | |
parent | d1ea6b91d1441f0bf423c2d27339b0386300a295 (diff) |
Output received audio data over I2S.
m--------- | laks | 0 | ||||
-rw-r--r-- | main.cpp | 64 |
2 files changed, 59 insertions, 5 deletions
diff --git a/laks b/laks -Subproject 95729b7fd4de6704823ab8033593abe35213491 +Subproject 0ca572bc7a0fbe26b216cab519d89187ae49a28 @@ -3,6 +3,21 @@ #include <os/time.h> #include <usb/usb.h> #include <usb/descriptor.h> +#include <spi/spi.h> +#include <dma/dma.h> + +Pin& i2s_mck = PC7; +Pin& i2s_sck = PC10; +Pin& i2s_sd = PC12; +Pin& i2s_ws = PA4; + +Pin& usb_vbus = PA9; +Pin& usb_dm = PA11; +Pin& usb_dp = PA12; + +const uint32_t audio_buf_size = 256; +uint16_t audio_buf[audio_buf_size]; +uint32_t audio_buf_pos = 0; struct AS_General_desc { uint8_t bLength; @@ -64,10 +79,6 @@ auto conf_desc = configuration_desc(2, 1, 0, 0xc0, 0, desc_t dev_desc_p = {sizeof(dev_desc), (void*)&dev_desc}; desc_t conf_desc_p = {sizeof(conf_desc), (void*)&conf_desc}; -Pin& usb_vbus = PA9; -Pin& usb_dm = PA11; -Pin& usb_dp = PA12; - USB_otg usb(OTG_FS, dev_desc_p, conf_desc_p); class USB_Audio : public USB_class_driver { @@ -129,20 +140,63 @@ class USB_Audio : public USB_class_driver { } else if(ep == 1) { usb_rblog.log("Received audio frame with %d bytes.", len); - //uint32_t r_len = usb.read(ep, buf, len); + + if(audio_buf_pos + (len >> 1) >= audio_buf_size) { + usb.read(1, (uint32_t*)&audio_buf[audio_buf_pos], (audio_buf_size - audio_buf_pos) << 1); + len -= (audio_buf_size - audio_buf_pos) << 1; + audio_buf_pos = 0; + } + + if(len) { + usb.read(1, (uint32_t*)&audio_buf[audio_buf_pos], len); + audio_buf_pos += len >> 1; + } } } }; USB_Audio usb_audio(usb); + int main() { // Initialize system timer. STK.LOAD = 168000000 / 8 / 1000; // 1000 Hz. STK.CTRL = 0x03; RCC.enable(RCC.GPIOA); + RCC.enable(RCC.GPIOB); + RCC.enable(RCC.GPIOC); + + // Initialize I2S. + i2s_mck.set_mode(Pin::AF); + i2s_mck.set_af(6); + i2s_sck.set_mode(Pin::AF); + i2s_sck.set_af(6); + i2s_sd.set_mode(Pin::AF); + i2s_sd.set_af(6); + i2s_ws.set_mode(Pin::AF); + i2s_ws.set_af(6); + + RCC.PLLI2SCFGR = (3 << 28) | (258 << 6); + RCC.CR |= 1 << 26; + while(!(RCC.CR & (1 << 27))); + + RCC.enable(RCC.SPI3); + + SPI3.reg.I2SPR = 0x303; + SPI3.reg.I2SCFGR = 0xe00; + SPI3.reg.CR2 = 2; + + // Initialize DMA. + RCC.enable(RCC.DMA1); + + DMA1.reg.S[7].CR = (0 << 25) | (1 << 13) | (1 << 11) | (1 << 10) | (1 << 8) | (1 << 6); + DMA1.reg.S[7].PAR = uint32_t(&SPI3.reg.DR); + DMA1.reg.S[7].M0AR = uint32_t(&audio_buf); + DMA1.reg.S[7].NDTR = audio_buf_size; + DMA1.reg.S[7].CR |= 1; + // Initialize USB. usb_vbus.set_mode(Pin::Input); usb_dm.set_mode(Pin::AF); usb_dm.set_af(10); |