summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2012-09-22 15:47:10 +0200
committerVegard Storheil Eriksen <zyp@jvnv.net>2012-09-22 15:47:10 +0200
commitecf7dae267b27a705009528ea18113235d674f65 (patch)
tree615aff655edf6e5f41dd08963144a07f1c9e281d
parentd1ea6b91d1441f0bf423c2d27339b0386300a295 (diff)
Output received audio data over I2S.
m---------laks0
-rw-r--r--main.cpp64
2 files changed, 59 insertions, 5 deletions
diff --git a/laks b/laks
-Subproject 95729b7fd4de6704823ab8033593abe35213491
+Subproject 0ca572bc7a0fbe26b216cab519d89187ae49a28
diff --git a/main.cpp b/main.cpp
index 4c3b661..4b36241 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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);